Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f04b1e76 authored by Thomas Niederprüm's avatar Thomas Niederprüm Committed by Mark Brown
Browse files

ASoC: sta32x: add device tree binding.



make the sta32x driver usable with device tree configs.  Code is heavily based
on the sta350 driver.

Signed-off-by: default avatarThomas Niederprüm <niederp@physik.uni-kl.de>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1c34c876
Loading
Loading
Loading
Loading
+92 −0
Original line number Diff line number Diff line
STA32X audio CODEC

The driver for this device only supports I2C.

Required properties:

  - compatible: "st,sta32x"
  - reg: the I2C address of the device for I2C
  - reset-gpios: a GPIO spec for the reset pin. If specified, it will be
		 deasserted before communication to the codec starts.

  - power-down-gpios: a GPIO spec for the power down pin. If specified,
		      it will be deasserted before communication to the codec
		      starts.

  - Vdda-supply: regulator spec, providing 3.3V
  - Vdd3-supply: regulator spec, providing 3.3V
  - Vcc-supply: regulator spec, providing 5V - 26V

Optional properties:

  -  st,output-conf: number, Selects the output configuration:
	0: 2-channel (full-bridge) power, 2-channel data-out
	1: 2 (half-bridge). 1 (full-bridge) on-board power
	2: 2 Channel (Full-Bridge) Power, 1 Channel FFX
	3: 1 Channel Mono-Parallel
	If parameter is missing, mode 0 will be enabled.
	This property has to be specified as '/bits/ 8' value.

  -  st,ch1-output-mapping: Channel 1 output mapping
  -  st,ch2-output-mapping: Channel 2 output mapping
  -  st,ch3-output-mapping: Channel 3 output mapping
	0: Channel 1
	1: Channel 2
	2: Channel 3
	If parameter is missing, channel 1 is chosen.
	This properties have to be specified as '/bits/ 8' values.

  -  st,thermal-warning-recover:
	If present, thermal warning recovery is enabled.

  -  st,thermal-warning-adjustment:
	If present, thermal warning adjustment is enabled.

  -  st,fault-detect-recovery:
	If present, then fault recovery will be enabled.

  -  st,drop-compensation-ns: number
	Only required for "st,ffx-power-output-mode" ==
	"variable-drop-compensation".
	Specifies the drop compensation in nanoseconds.
	The value must be in the range of 0..300, and only
	multiples of 20 are allowed. Default is 140ns.

  -  st,max-power-use-mpcc:
	If present, then MPCC bits are used for MPC coefficients,
	otherwise standard MPC coefficients are used.

  -  st,max-power-corr:
	If present, power bridge correction for THD reduction near maximum
	power output is enabled.

  -  st,am-reduction-mode:
	If present, FFX mode runs in AM reduction mode, otherwise normal
	FFX mode is used.

  -  st,odd-pwm-speed-mode:
	If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
	channels. If not present, normal PWM spped mode (384 kHz) will be used.

  -  st,invalid-input-detect-mute:
	If present, automatic invalid input detect mute is enabled.

Example:

codec: sta32x@38 {
	compatible = "st,sta32x";
	reg = <0x1c>;
	reset-gpios = <&gpio1 19 0>;
	power-down-gpios = <&gpio1 16 0>;
	st,output-conf = /bits/ 8  <0x3>;	// set output to 2-channel
						// (full-bridge) power,
						// 2-channel data-out
	st,ch1-output-mapping = /bits/ 8 <0>;	// set channel 1 output ch 1
	st,ch2-output-mapping = /bits/ 8 <0>;	// set channel 2 output ch 1
	st,ch3-output-mapping = /bits/ 8 <0>;	// set channel 3 output ch 1
	st,max-power-correction;		// enables power bridge
						// correction for THD reduction
						// near maximum power output
	st,invalid-input-detect-mute;		// mute if no valid digital
						// audio signal is provided.
};
+13 −5
Original line number Diff line number Diff line
@@ -24,12 +24,20 @@
#define STA32X_THERMAL_RECOVERY_ENABLE		2

struct sta32x_platform_data {
	int output_conf;
	int ch1_output_mapping;
	int ch2_output_mapping;
	int ch3_output_mapping;
	int thermal_conf;
	u8 output_conf;
	u8 ch1_output_mapping;
	u8 ch2_output_mapping;
	u8 ch3_output_mapping;
	int needs_esd_watchdog;
	u8 drop_compensation_ns;
	unsigned int thermal_warning_recovery:1;
	unsigned int thermal_warning_adjustment:1;
	unsigned int fault_detect_recovery:1;
	unsigned int max_power_use_mpcc:1;
	unsigned int max_power_correction:1;
	unsigned int am_reduction_mode:1;
	unsigned int odd_pwm_speed_mode:1;
	unsigned int invalid_input_detect_mute:1;
};

#endif /* __LINUX_SND__STA32X_H */
+106 −2
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio/consumer.h>
@@ -893,15 +895,49 @@ static int sta32x_probe(struct snd_soc_codec *codec)
		dev_err(codec->dev, "Failed to startup device\n");
		return ret;
	}
	/* set thermal warning adjustment and recovery */

	/* CONFA */
	if (!pdata->thermal_warning_recovery)
		thermal |= STA32X_CONFA_TWAB;
	if (!pdata->thermal_warning_adjustment)
		thermal |= STA32X_CONFA_TWRB;
	if (!pdata->fault_detect_recovery)
		thermal |= STA32X_CONFA_FDRB;
	regmap_update_bits(sta32x->regmap, STA32X_CONFA,
			   STA32X_CONFA_TWAB | STA32X_CONFA_TWRB,
			   STA32X_CONFA_TWAB | STA32X_CONFA_TWRB |
			   STA32X_CONFA_FDRB,
			   thermal);

	/* CONFC */
	regmap_update_bits(sta32x->regmap, STA32X_CONFC,
			   STA32X_CONFC_CSZ_MASK,
			   pdata->drop_compensation_ns
				<< STA32X_CONFC_CSZ_SHIFT);

	/* CONFE */
	regmap_update_bits(sta32x->regmap, STA32X_CONFE,
			   STA32X_CONFE_MPCV,
			   pdata->max_power_use_mpcc ?
				STA32X_CONFE_MPCV : 0);
	regmap_update_bits(sta32x->regmap, STA32X_CONFE,
			   STA32X_CONFE_MPC,
			   pdata->max_power_correction ?
				STA32X_CONFE_MPC : 0);
	regmap_update_bits(sta32x->regmap, STA32X_CONFE,
			   STA32X_CONFE_AME,
			   pdata->am_reduction_mode ?
				STA32X_CONFE_AME : 0);
	regmap_update_bits(sta32x->regmap, STA32X_CONFE,
			   STA32X_CONFE_PWMS,
			   pdata->odd_pwm_speed_mode ?
				STA32X_CONFE_PWMS : 0);

	/*  CONFF */
	regmap_update_bits(sta32x->regmap, STA32X_CONFF,
			   STA32X_CONFF_IDE,
			   pdata->invalid_input_detect_mute ?
				STA32X_CONFF_IDE : 0);

	/* select output configuration  */
	regmap_update_bits(sta32x->regmap, STA32X_CONFF,
			   STA32X_CONFF_OCFG_MASK,
@@ -977,7 +1013,66 @@ static const struct regmap_config sta32x_regmap = {
	.rd_table =		&sta32x_read_regs,
	.volatile_table =	&sta32x_volatile_regs,
};

#ifdef CONFIG_OF
static const struct of_device_id st32x_dt_ids[] = {
	{ .compatible = "st,sta32x", },
	{ }
};
MODULE_DEVICE_TABLE(of, st32x_dt_ids);

static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)
{
	struct device_node *np = dev->of_node;
	struct sta32x_platform_data *pdata;
	u16 tmp;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	of_property_read_u8(np, "st,output-conf",
			    &pdata->output_conf);
	of_property_read_u8(np, "st,ch1-output-mapping",
			    &pdata->ch1_output_mapping);
	of_property_read_u8(np, "st,ch2-output-mapping",
			    &pdata->ch2_output_mapping);
	of_property_read_u8(np, "st,ch3-output-mapping",
			    &pdata->ch3_output_mapping);

	if (of_get_property(np, "st,thermal-warning-recovery", NULL))
		pdata->thermal_warning_recovery = 1;
	if (of_get_property(np, "st,thermal-warning-adjustment", NULL))
		pdata->thermal_warning_adjustment = 1;
	if (of_get_property(np, "st,needs_esd_watchdog", NULL))
		pdata->needs_esd_watchdog = 1;

	tmp = 140;
	of_property_read_u16(np, "st,drop-compensation-ns", &tmp);
	pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;

	/* CONFE */
	if (of_get_property(np, "st,max-power-use-mpcc", NULL))
		pdata->max_power_use_mpcc = 1;

	if (of_get_property(np, "st,max-power-correction", NULL))
		pdata->max_power_correction = 1;

	if (of_get_property(np, "st,am-reduction-mode", NULL))
		pdata->am_reduction_mode = 1;

	if (of_get_property(np, "st,odd-pwm-speed-mode", NULL))
		pdata->odd_pwm_speed_mode = 1;

	/* CONFF */
	if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
		pdata->invalid_input_detect_mute = 1;

	sta32x->pdata = pdata;

	return 0;
}
#endif

static int sta32x_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
@@ -994,6 +1089,14 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
	mutex_init(&sta32x->coeff_lock);
	sta32x->pdata = dev_get_platdata(dev);

#ifdef CONFIG_OF
	if (dev->of_node) {
		ret = sta32x_probe_dt(dev, sta32x);
		if (ret < 0)
			return ret;
	}
#endif

	/* GPIOs */
	sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset");
	if (IS_ERR(sta32x->gpiod_nreset)) {
@@ -1051,6 +1154,7 @@ static struct i2c_driver sta32x_i2c_driver = {
	.driver = {
		.name = "sta32x",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(st32x_dt_ids),
	},
	.probe =    sta32x_i2c_probe,
	.remove =   sta32x_i2c_remove,