* [PATCH 1/3] ASoC: tas5086: move two variables into private struct
@ 2013-10-01 12:48 Daniel Mack
2013-10-01 12:48 ` [PATCH 2/3] ASoC: tas5086: move initialization code to own functions Daniel Mack
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Daniel Mack @ 2013-10-01 12:48 UTC (permalink / raw)
To: alsa-devel; +Cc: broonie, s.neumann, Daniel Mack
We need to access the charge_period and start_mid_z values from other
places later, so move them to the private struct.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
sound/soc/codecs/tas5086.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index 6d31d88..31b5868 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -244,6 +244,8 @@ struct tas5086_private {
unsigned int mclk, sclk;
unsigned int format;
bool deemph;
+ unsigned int charge_period;
+ unsigned int pwm_start_mid_z;
/* Current sample rate for de-emphasis control */
int rate;
/* GPIO driving Reset pin, if any */
@@ -720,13 +722,15 @@ static const int tas5086_charge_period[] = {
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 */
- u8 pwm_start_mid_z = 0;
int i, ret;
+ priv->pwm_start_mid_z = 0;
+ priv->charge_period = 1300000; /* hardware default is 1300 ms */
+
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);
+ of_property_read_u32(of_node, "ti,charge-period",
+ &priv->charge_period);
for (i = 0; i < 6; i++) {
char name[25];
@@ -735,7 +739,7 @@ static int tas5086_probe(struct snd_soc_codec *codec)
"ti,mid-z-channel-%d", i + 1);
if (of_get_property(of_node, name, NULL) != NULL)
- pwm_start_mid_z |= 1 << i;
+ priv->pwm_start_mid_z |= 1 << i;
}
}
@@ -744,25 +748,25 @@ static int tas5086_probe(struct snd_soc_codec *codec)
* configure 'part 1' of the PWM starts to use Mid-Z, and tell
* all configured mid-z channels to start start under 'part 1'.
*/
- if (pwm_start_mid_z)
+ if (priv->pwm_start_mid_z)
regmap_write(priv->regmap, TAS5086_PWM_START,
TAS5086_PWM_START_MIDZ_FOR_START_1 |
- pwm_start_mid_z);
+ priv->pwm_start_mid_z);
/* lookup and set split-capacitor charge period */
- if (charge_period == 0) {
+ if (priv->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);
+ priv->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);
+ priv->charge_period);
}
/* enable factory trim */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] ASoC: tas5086: move initialization code to own functions
2013-10-01 12:48 [PATCH 1/3] ASoC: tas5086: move two variables into private struct Daniel Mack
@ 2013-10-01 12:48 ` Daniel Mack
2013-10-01 12:48 ` [PATCH 3/3] ASoC: tas5086: add suspend callback Daniel Mack
2013-10-03 13:14 ` [PATCH 1/3] ASoC: tas5086: move two variables into private struct Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Mack @ 2013-10-01 12:48 UTC (permalink / raw)
To: alsa-devel; +Cc: broonie, s.neumann, Daniel Mack
We'll need to call code to initialize and reset the codec again at
resume time, so factor it out first.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
sound/soc/codecs/tas5086.c | 128 +++++++++++++++++++++++++--------------------
1 file changed, 72 insertions(+), 56 deletions(-)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index 31b5868..3a88c68 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -458,6 +458,75 @@ static int tas5086_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
return regmap_write(priv->regmap, TAS5086_SOFT_MUTE, val);
}
+static void tas5086_reset(struct tas5086_private *priv)
+{
+ if (gpio_is_valid(priv->gpio_nreset)) {
+ /* Reset codec - minimum assertion time is 400ns */
+ gpio_direction_output(priv->gpio_nreset, 0);
+ udelay(1);
+ gpio_set_value(priv->gpio_nreset, 1);
+
+ /* Codec needs ~15ms to wake up */
+ msleep(15);
+ }
+}
+
+/* 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_init(struct device *dev, struct tas5086_private *priv)
+{
+ int ret, i;
+
+ /*
+ * If any of the channels is configured to start in Mid-Z mode,
+ * configure 'part 1' of the PWM starts to use Mid-Z, and tell
+ * all configured mid-z channels to start start under 'part 1'.
+ */
+ if (priv->pwm_start_mid_z)
+ regmap_write(priv->regmap, TAS5086_PWM_START,
+ TAS5086_PWM_START_MIDZ_FOR_START_1 |
+ priv->pwm_start_mid_z);
+
+ /* lookup and set split-capacitor charge period */
+ if (priv->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),
+ priv->charge_period);
+ if (i >= 0)
+ regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE,
+ i + 0x08);
+ else
+ dev_warn(dev,
+ "Invalid split-cap charge period of %d ns.\n",
+ priv->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;
+
+ /* mute all channels for now */
+ ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE,
+ TAS5086_SOFT_MUTE_ALL);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
/* TAS5086 controls */
static const DECLARE_TLV_DB_SCALE(tas5086_dac_tlv, -10350, 50, 1);
@@ -712,13 +781,6 @@ static const struct of_device_id tas5086_dt_ids[] = {
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);
@@ -729,6 +791,7 @@ static int tas5086_probe(struct snd_soc_codec *codec)
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",
&priv->charge_period);
@@ -743,39 +806,7 @@ static int tas5086_probe(struct snd_soc_codec *codec)
}
}
- /*
- * If any of the channels is configured to start in Mid-Z mode,
- * configure 'part 1' of the PWM starts to use Mid-Z, and tell
- * all configured mid-z channels to start start under 'part 1'.
- */
- if (priv->pwm_start_mid_z)
- regmap_write(priv->regmap, TAS5086_PWM_START,
- TAS5086_PWM_START_MIDZ_FOR_START_1 |
- priv->pwm_start_mid_z);
-
- /* lookup and set split-capacitor charge period */
- if (priv->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),
- priv->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",
- priv->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);
+ ret = tas5086_init(codec->dev, priv);
if (ret < 0)
return ret;
@@ -784,12 +815,6 @@ static int tas5086_probe(struct snd_soc_codec *codec)
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;
}
@@ -866,17 +891,8 @@ static int tas5086_i2c_probe(struct i2c_client *i2c,
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;
+ tas5086_reset(priv);
/* The TAS5086 always returns 0x03 in its TAS5086_DEV_ID register */
ret = regmap_read(priv->regmap, TAS5086_DEV_ID, &i);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] ASoC: tas5086: add suspend callback
2013-10-01 12:48 [PATCH 1/3] ASoC: tas5086: move two variables into private struct Daniel Mack
2013-10-01 12:48 ` [PATCH 2/3] ASoC: tas5086: move initialization code to own functions Daniel Mack
@ 2013-10-01 12:48 ` Daniel Mack
2013-10-03 13:14 ` [PATCH 1/3] ASoC: tas5086: move two variables into private struct Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Mack @ 2013-10-01 12:48 UTC (permalink / raw)
To: alsa-devel; +Cc: broonie, s.neumann, Daniel Mack
When going to suspend, shut down all channels and re-do the init
procedure at resume time.
Signed-off-by: Daniel Mack <zonque@gmail.com>
---
sound/soc/codecs/tas5086.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c
index 3a88c68..2996d2e 100644
--- a/sound/soc/codecs/tas5086.c
+++ b/sound/soc/codecs/tas5086.c
@@ -762,14 +762,39 @@ static struct snd_soc_dai_driver tas5086_dai = {
};
#ifdef CONFIG_PM
+static int tas5086_soc_suspend(struct snd_soc_codec *codec)
+{
+ struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+ int ret;
+
+ /* Shut down all channels */
+ ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x60);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int tas5086_soc_resume(struct snd_soc_codec *codec)
{
struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec);
+ int ret;
- /* Restore codec state */
- return regcache_sync(priv->regmap);
+ tas5086_reset(priv);
+ regcache_mark_dirty(priv->regmap);
+
+ ret = tas5086_init(codec->dev, priv);
+ if (ret < 0)
+ return ret;
+
+ ret = regcache_sync(priv->regmap);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
#else
+#define tas5086_soc_suspend NULL
#define tas5086_soc_resume NULL
#endif /* CONFIG_PM */
@@ -832,6 +857,7 @@ static int tas5086_remove(struct snd_soc_codec *codec)
static struct snd_soc_codec_driver soc_codec_dev_tas5086 = {
.probe = tas5086_probe,
.remove = tas5086_remove,
+ .suspend = tas5086_soc_suspend,
.resume = tas5086_soc_resume,
.controls = tas5086_controls,
.num_controls = ARRAY_SIZE(tas5086_controls),
--
1.8.3.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/3] ASoC: tas5086: move two variables into private struct
2013-10-01 12:48 [PATCH 1/3] ASoC: tas5086: move two variables into private struct Daniel Mack
2013-10-01 12:48 ` [PATCH 2/3] ASoC: tas5086: move initialization code to own functions Daniel Mack
2013-10-01 12:48 ` [PATCH 3/3] ASoC: tas5086: add suspend callback Daniel Mack
@ 2013-10-03 13:14 ` Mark Brown
2 siblings, 0 replies; 4+ messages in thread
From: Mark Brown @ 2013-10-03 13:14 UTC (permalink / raw)
To: Daniel Mack; +Cc: alsa-devel, s.neumann
[-- Attachment #1.1: Type: text/plain, Size: 207 bytes --]
On Tue, Oct 01, 2013 at 02:48:24PM +0200, Daniel Mack wrote:
> We need to access the charge_period and start_mid_z values from other
> places later, so move them to the private struct.
Applied all, thanks.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-10-03 13:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-01 12:48 [PATCH 1/3] ASoC: tas5086: move two variables into private struct Daniel Mack
2013-10-01 12:48 ` [PATCH 2/3] ASoC: tas5086: move initialization code to own functions Daniel Mack
2013-10-01 12:48 ` [PATCH 3/3] ASoC: tas5086: add suspend callback Daniel Mack
2013-10-03 13:14 ` [PATCH 1/3] ASoC: tas5086: move two variables into private struct Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).