[alsa-devel] [PATCH 1/5] ASoC: codecs: tas5086: fix documentation
The property 'ti,charge-period' must be given in nanoseconds, not microseconds.
Signed-off-by: Daniel Mack zonque@gmail.com --- Documentation/devicetree/bindings/sound/ti,tas5086.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/Documentation/devicetree/bindings/sound/ti,tas5086.txt index 8ea4f5b..e8310f1 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas5086.txt +++ b/Documentation/devicetree/bindings/sound/ti,tas5086.txt @@ -11,7 +11,7 @@ Optional properties: 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 + - ti,charge-period: This property should contain the time in nanoseconds that closely matches the external single-ended split-capacitor charge period. The hardware chip waits for this period of time before starting the
In order to support registers of unequal sizes, the I2C I/O has to be open-coded.
Signed-off-by: Daniel Mack zonque@gmail.com --- sound/soc/codecs/tas5086.c | 85 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 6c5470c..833bccd 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -119,6 +119,17 @@ static const struct reg_default tas5086_reg_defaults[] = { { 0x1c, 0x05 }, };
+static int tas5086_register_size(struct device *dev, unsigned int reg) +{ + switch (reg) { + case TAS5086_DEV_ID ... TAS5086_BKNDERR: + return 1; + } + + dev_err(dev, "Unsupported register address: %d\n", reg); + return 0; +} + static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) { return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); @@ -140,6 +151,76 @@ static bool tas5086_writeable_reg(struct device *dev, unsigned int reg) return tas5086_accessible_reg(dev, reg) && (reg != TAS5086_DEV_ID); }
+static int tas5086_reg_write(void *context, unsigned int reg, + unsigned int value) +{ + struct i2c_client *client = context; + unsigned int i, size; + uint8_t buf[5]; + int ret; + + size = tas5086_register_size(&client->dev, reg); + if (size == 0) + return -EINVAL; + + buf[0] = reg; + + for (i = size; i >= 1; --i) { + buf[i] = value; + value >>= 8; + } + + ret = i2c_master_send(client, buf, size + 1); + if (ret == size + 1) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +static int tas5086_reg_read(void *context, unsigned int reg, + unsigned int *value) +{ + struct i2c_client *client = context; + uint8_t send_buf, recv_buf[4]; + struct i2c_msg msgs[2]; + unsigned int size; + unsigned int i; + int ret; + + size = tas5086_register_size(&client->dev, reg); + if (size == 0) + return -EINVAL; + + send_buf = reg; + + msgs[0].addr = client->addr; + msgs[0].len = sizeof(send_buf); + msgs[0].buf = &send_buf; + msgs[0].flags = 0; + + msgs[1].addr = client->addr; + msgs[1].len = size; + msgs[1].buf = recv_buf; + msgs[1].flags = I2C_M_RD; + + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) + return ret; + else if (ret != ARRAY_SIZE(msgs)) + return -EIO; + + *value = 0; + + for (i = 0; i < size; i++) { + *value <<= 8; + *value |= recv_buf[i]; + } + + return 0; +} + struct tas5086_private { struct regmap *regmap; unsigned int mclk, sclk; @@ -508,6 +589,8 @@ static const struct regmap_config tas5086_regmap = { .volatile_reg = tas5086_volatile_reg, .writeable_reg = tas5086_writeable_reg, .readable_reg = tas5086_accessible_reg, + .reg_read = tas5086_reg_read, + .reg_write = tas5086_reg_write, };
static int tas5086_i2c_probe(struct i2c_client *i2c, @@ -522,7 +605,7 @@ static int tas5086_i2c_probe(struct i2c_client *i2c, if (!priv) return -ENOMEM;
- priv->regmap = devm_regmap_init_i2c(i2c, &tas5086_regmap); + priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap); if (IS_ERR(priv->regmap)) { ret = PTR_ERR(priv->regmap); dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
Add register definitions for input and output mux registers, and rewrite the tas5086_accessible_reg() function.
Signed-off-by: Daniel Mack zonque@gmail.com --- sound/soc/codecs/tas5086.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 833bccd..b2aea5d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -83,6 +83,10 @@ #define TAS5086_SPLIT_CAP_CHARGE 0x1a /* Split cap charge period register */ #define TAS5086_OSC_TRIM 0x1b /* Oscillator trim register */ #define TAS5086_BKNDERR 0x1c +#define TAS5086_INPUT_MUX 0x20 +#define TAS5086_PWM_OUTPUT_MUX 0x25 + +#define TAS5086_MAX_REGISTER TAS5086_PWM_OUTPUT_MUX
/* * Default TAS5086 power-up configuration @@ -124,6 +128,9 @@ static int tas5086_register_size(struct device *dev, unsigned int reg) switch (reg) { case TAS5086_DEV_ID ... TAS5086_BKNDERR: return 1; + case TAS5086_INPUT_MUX: + case TAS5086_PWM_OUTPUT_MUX: + return 4; }
dev_err(dev, "Unsupported register address: %d\n", reg); @@ -132,7 +139,14 @@ static int tas5086_register_size(struct device *dev, unsigned int reg)
static bool tas5086_accessible_reg(struct device *dev, unsigned int reg) { - return !((reg == 0x0f) || (reg >= 0x11 && reg <= 0x17)); + switch (reg) { + case 0x0f: + case 0x11 ... 0x17: + case 0x1d ... 0x1f: + return false; + default: + return true; + } }
static bool tas5086_volatile_reg(struct device *dev, unsigned int reg) @@ -581,8 +595,8 @@ 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), + .val_bits = 32, + .max_register = TAS5086_MAX_REGISTER, .reg_defaults = tas5086_reg_defaults, .num_reg_defaults = ARRAY_SIZE(tas5086_reg_defaults), .cache_type = REGCACHE_RBTREE,
The TAS5086 has two muxes, one for connecting I2S inputs to internal channels, and another one for selecting which internal channel should be routed to which PWM output pin.
This patch adds DAPM widgets and routes for this driver.
Signed-off-by: Daniel Mack zonque@gmail.com --- sound/soc/codecs/tas5086.c | 200 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+)
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index b2aea5d..99e190d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -471,6 +471,202 @@ static const struct snd_kcontrol_new tas5086_controls[] = { tas5086_get_deemph, tas5086_put_deemph), };
+/* Input mux controls */ +static const char *tas5086_dapm_sdin_texts[] = +{ + "SDIN1-L", "SDIN1-R", "SDIN2-L", "SDIN2-R", + "SDIN3-L", "SDIN3-R", "Ground (0)", "nc" +}; + +static const struct soc_enum tas5086_dapm_input_mux_enum[] = { + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 20, 8, tas5086_dapm_sdin_texts), + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 16, 8, tas5086_dapm_sdin_texts), + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 12, 8, tas5086_dapm_sdin_texts), + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 8, 8, tas5086_dapm_sdin_texts), + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 4, 8, tas5086_dapm_sdin_texts), + SOC_ENUM_SINGLE(TAS5086_INPUT_MUX, 0, 8, tas5086_dapm_sdin_texts), +}; + +static const struct snd_kcontrol_new tas5086_dapm_input_mux_controls[] = { + SOC_DAPM_ENUM("Channel 1 input", tas5086_dapm_input_mux_enum[0]), + SOC_DAPM_ENUM("Channel 2 input", tas5086_dapm_input_mux_enum[1]), + SOC_DAPM_ENUM("Channel 3 input", tas5086_dapm_input_mux_enum[2]), + SOC_DAPM_ENUM("Channel 4 input", tas5086_dapm_input_mux_enum[3]), + SOC_DAPM_ENUM("Channel 5 input", tas5086_dapm_input_mux_enum[4]), + SOC_DAPM_ENUM("Channel 6 input", tas5086_dapm_input_mux_enum[5]), +}; + +/* Output mux controls */ +static const char *tas5086_dapm_channel_texts[] = + { "Channel 1 Mux", "Channel 2 Mux", "Channel 3 Mux", + "Channel 4 Mux", "Channel 5 Mux", "Channel 6 Mux" }; + +static const struct soc_enum tas5086_dapm_output_mux_enum[] = { + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 20, 6, tas5086_dapm_channel_texts), + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 16, 6, tas5086_dapm_channel_texts), + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 12, 6, tas5086_dapm_channel_texts), + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 8, 6, tas5086_dapm_channel_texts), + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 4, 6, tas5086_dapm_channel_texts), + SOC_ENUM_SINGLE(TAS5086_PWM_OUTPUT_MUX, 0, 6, tas5086_dapm_channel_texts), +}; + +static const struct snd_kcontrol_new tas5086_dapm_output_mux_controls[] = { + SOC_DAPM_ENUM("PWM1 Output", tas5086_dapm_output_mux_enum[0]), + SOC_DAPM_ENUM("PWM2 Output", tas5086_dapm_output_mux_enum[1]), + SOC_DAPM_ENUM("PWM3 Output", tas5086_dapm_output_mux_enum[2]), + SOC_DAPM_ENUM("PWM4 Output", tas5086_dapm_output_mux_enum[3]), + SOC_DAPM_ENUM("PWM5 Output", tas5086_dapm_output_mux_enum[4]), + SOC_DAPM_ENUM("PWM6 Output", tas5086_dapm_output_mux_enum[5]), +}; + +static const struct snd_soc_dapm_widget tas5086_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("SDIN1-L"), + SND_SOC_DAPM_INPUT("SDIN1-R"), + SND_SOC_DAPM_INPUT("SDIN2-L"), + SND_SOC_DAPM_INPUT("SDIN2-R"), + SND_SOC_DAPM_INPUT("SDIN3-L"), + SND_SOC_DAPM_INPUT("SDIN3-R"), + SND_SOC_DAPM_INPUT("SDIN4-L"), + SND_SOC_DAPM_INPUT("SDIN4-R"), + + SND_SOC_DAPM_OUTPUT("PWM1"), + SND_SOC_DAPM_OUTPUT("PWM2"), + SND_SOC_DAPM_OUTPUT("PWM3"), + SND_SOC_DAPM_OUTPUT("PWM4"), + SND_SOC_DAPM_OUTPUT("PWM5"), + SND_SOC_DAPM_OUTPUT("PWM6"), + + SND_SOC_DAPM_MUX("Channel 1 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[0]), + SND_SOC_DAPM_MUX("Channel 2 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[1]), + SND_SOC_DAPM_MUX("Channel 3 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[2]), + SND_SOC_DAPM_MUX("Channel 4 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[3]), + SND_SOC_DAPM_MUX("Channel 5 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[4]), + SND_SOC_DAPM_MUX("Channel 6 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_input_mux_controls[5]), + + SND_SOC_DAPM_MUX("PWM1 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[0]), + SND_SOC_DAPM_MUX("PWM2 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[1]), + SND_SOC_DAPM_MUX("PWM3 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[2]), + SND_SOC_DAPM_MUX("PWM4 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[3]), + SND_SOC_DAPM_MUX("PWM5 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[4]), + SND_SOC_DAPM_MUX("PWM6 Mux", SND_SOC_NOPM, 0, 0, + &tas5086_dapm_output_mux_controls[5]), +}; + +static const struct snd_soc_dapm_route tas5086_dapm_routes[] = { + /* SDIN inputs -> channel muxes */ + { "Channel 1 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 1 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 1 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 1 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 1 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 1 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 3 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 3 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 3 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 3 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 3 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 3 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 4 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 4 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 4 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 4 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 4 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 4 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 5 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 5 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 5 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 5 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 5 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 5 Mux", "SDIN3-R", "SDIN3-R" }, + + { "Channel 6 Mux", "SDIN1-L", "SDIN1-L" }, + { "Channel 6 Mux", "SDIN1-R", "SDIN1-R" }, + { "Channel 6 Mux", "SDIN2-L", "SDIN2-L" }, + { "Channel 6 Mux", "SDIN2-R", "SDIN2-R" }, + { "Channel 6 Mux", "SDIN3-L", "SDIN3-L" }, + { "Channel 6 Mux", "SDIN3-R", "SDIN3-R" }, + + /* Channel muxes -> PWM muxes */ + { "PWM1 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + { "PWM2 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + { "PWM3 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + { "PWM4 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + { "PWM5 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + { "PWM6 Mux", "Channel 1 Mux", "Channel 1 Mux" }, + + { "PWM1 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + { "PWM2 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + { "PWM3 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + { "PWM4 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + { "PWM5 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + { "PWM6 Mux", "Channel 2 Mux", "Channel 2 Mux" }, + + { "PWM1 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + { "PWM2 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + { "PWM3 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + { "PWM4 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + { "PWM5 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + { "PWM6 Mux", "Channel 3 Mux", "Channel 3 Mux" }, + + { "PWM1 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + { "PWM2 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + { "PWM3 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + { "PWM4 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + { "PWM5 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + { "PWM6 Mux", "Channel 4 Mux", "Channel 4 Mux" }, + + { "PWM1 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + { "PWM2 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + { "PWM3 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + { "PWM4 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + { "PWM5 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + { "PWM6 Mux", "Channel 5 Mux", "Channel 5 Mux" }, + + { "PWM1 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + { "PWM2 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + { "PWM3 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + { "PWM4 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + { "PWM5 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + { "PWM6 Mux", "Channel 6 Mux", "Channel 6 Mux" }, + + /* The PWM muxes are directly connected to the PWM outputs */ + { "PWM1", NULL, "PWM1 Mux" }, + { "PWM2", NULL, "PWM2 Mux" }, + { "PWM3", NULL, "PWM3 Mux" }, + { "PWM4", NULL, "PWM4 Mux" }, + { "PWM5", NULL, "PWM5 Mux" }, + { "PWM6", NULL, "PWM6 Mux" }, + +}; + static const struct snd_soc_dai_ops tas5086_dai_ops = { .hw_params = tas5086_hw_params, .set_sysclk = tas5086_set_dai_sysclk, @@ -585,6 +781,10 @@ static struct snd_soc_codec_driver soc_codec_dev_tas5086 = { .resume = tas5086_soc_resume, .controls = tas5086_controls, .num_controls = ARRAY_SIZE(tas5086_controls), + .dapm_widgets = tas5086_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tas5086_dapm_widgets), + .dapm_routes = tas5086_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(tas5086_dapm_routes), };
static const struct i2c_device_id tas5086_i2c_id[] = {
The TAS5086 has two alternative modes to start its PWM channels, Mid-Z and Low-Z. Which one to use depends on how the PWM power stages are connected to the TAS5086.
This patch adds 6 optional boolean properties to the DT bindings of the driver which allow the user to configure each individual channel to the Mid-Z scheme, and leaves all the others to the default (Low-Z).
Signed-off-by: Daniel Mack zonque@gmail.com --- .../devicetree/bindings/sound/ti,tas5086.txt | 11 +++++++++++ sound/soc/codecs/tas5086.c | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+)
diff --git a/Documentation/devicetree/bindings/sound/ti,tas5086.txt b/Documentation/devicetree/bindings/sound/ti,tas5086.txt index e8310f1..f199f7d 100644 --- a/Documentation/devicetree/bindings/sound/ti,tas5086.txt +++ b/Documentation/devicetree/bindings/sound/ti,tas5086.txt @@ -20,6 +20,17 @@ Optional properties: When not specified, the hardware default of 1300ms is retained.
+ - ti,mid-z-channel-X: Boolean properties, X being a number from 1 to 6. + If given, channel X will start with the Mid-Z start + sequence, otherwise the default Low-Z scheme is used. + + The correct configuration depends on how the power + stages connected to the PWM output pins work. Not all + power stages are compatible to Mid-Z - please refer + to the datasheets for more details. + + Most systems should not set any of these properties. + Examples:
i2c_bus { diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index 99e190d..fec9a28 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -88,6 +88,10 @@
#define TAS5086_MAX_REGISTER TAS5086_PWM_OUTPUT_MUX
+#define TAS5086_PWM_START_MIDZ_FOR_START_1 (1 << 7) +#define TAS5086_PWM_START_MIDZ_FOR_START_2 (1 << 6) +#define TAS5086_PWM_START_CHANNEL_MASK (0x3f) + /* * Default TAS5086 power-up configuration */ @@ -717,13 +721,31 @@ 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 = TAS5086_PWM_START_CHANNEL_MASK; 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); + + for (i = 0; i < 6; i++) { + char name[25]; + + snprintf(name, sizeof(name), + "ti,mid-z-channel-%d", i + 1); + + if (of_get_property(of_node, name, NULL) != NULL) + pwm_start &= ~(1 << i); + } }
+ /* + * Configure 'part 2' of the PWM starts to always use MID-Z, and tell + * all configured mid-z channels to start start under 'part 2'. + */ + regmap_write(priv->regmap, TAS5086_PWM_START, + TAS5086_PWM_START_MIDZ_FOR_START_2 | pwm_start); + /* lookup and set split-capacitor charge period */ if (charge_period == 0) { regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0);
On Mon, Jun 24, 2013 at 04:25:28PM +0200, Daniel Mack wrote:
The property 'ti,charge-period' must be given in nanoseconds, not microseconds.
Applied al, thanks. Though specifying this in nanoseconds does seem absurdly high resolution...
Not sure where the "codecs: " in the subject line came from either.
On 24.06.2013 18:05, Mark Brown wrote:
On Mon, Jun 24, 2013 at 04:25:28PM +0200, Daniel Mack wrote:
The property 'ti,charge-period' must be given in nanoseconds, not microseconds.
Applied al, thanks. Though specifying this in nanoseconds does seem absurdly high resolution...
Meh, I was confused, sorry. That first patch need to be revered (or dropped), the documentation was correct as it stood. The time values are given in fractions of milliseconds, not microseconds. My bad.
Not sure where the "codecs: " in the subject line came from either.
No problem, I can drop that in my future submissions.
Thanks, Daniel
On Mon, Jun 24, 2013 at 06:46:48PM +0200, Daniel Mack wrote:
On 24.06.2013 18:05, Mark Brown wrote:
Applied al, thanks. Though specifying this in nanoseconds does seem absurdly high resolution...
Meh, I was confused, sorry. That first patch need to be revered (or dropped), the documentation was correct as it stood. The time values are given in fractions of milliseconds, not microseconds. My bad.
Dropped.
participants (2)
-
Daniel Mack
-
Mark Brown