* [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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.