aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Niederprüm <niederp@physik.uni-kl.de>2015-01-21 18:01:58 -0500
committerMark Brown <broonie@kernel.org>2015-01-27 12:13:25 -0500
commitf04b1e760a51120f358826d815d12c3f8ecdf1b4 (patch)
tree15ab3cf75b2dd1d2622c0874532890514e418d05
parent1c34c876c4abb219381dcb7096206f1a609f119b (diff)
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: Thomas Niederprüm <niederp@physik.uni-kl.de> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/st,sta32x.txt92
-rw-r--r--include/sound/sta32x.h18
-rw-r--r--sound/soc/codecs/sta32x.c108
3 files changed, 211 insertions, 7 deletions
diff --git a/Documentation/devicetree/bindings/sound/st,sta32x.txt b/Documentation/devicetree/bindings/sound/st,sta32x.txt
new file mode 100644
index 000000000000..255de3ae5b2f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/st,sta32x.txt
@@ -0,0 +1,92 @@
1STA32X audio CODEC
2
3The driver for this device only supports I2C.
4
5Required properties:
6
7 - compatible: "st,sta32x"
8 - reg: the I2C address of the device for I2C
9 - reset-gpios: a GPIO spec for the reset pin. If specified, it will be
10 deasserted before communication to the codec starts.
11
12 - power-down-gpios: a GPIO spec for the power down pin. If specified,
13 it will be deasserted before communication to the codec
14 starts.
15
16 - Vdda-supply: regulator spec, providing 3.3V
17 - Vdd3-supply: regulator spec, providing 3.3V
18 - Vcc-supply: regulator spec, providing 5V - 26V
19
20Optional properties:
21
22 - st,output-conf: number, Selects the output configuration:
23 0: 2-channel (full-bridge) power, 2-channel data-out
24 1: 2 (half-bridge). 1 (full-bridge) on-board power
25 2: 2 Channel (Full-Bridge) Power, 1 Channel FFX
26 3: 1 Channel Mono-Parallel
27 If parameter is missing, mode 0 will be enabled.
28 This property has to be specified as '/bits/ 8' value.
29
30 - st,ch1-output-mapping: Channel 1 output mapping
31 - st,ch2-output-mapping: Channel 2 output mapping
32 - st,ch3-output-mapping: Channel 3 output mapping
33 0: Channel 1
34 1: Channel 2
35 2: Channel 3
36 If parameter is missing, channel 1 is chosen.
37 This properties have to be specified as '/bits/ 8' values.
38
39 - st,thermal-warning-recover:
40 If present, thermal warning recovery is enabled.
41
42 - st,thermal-warning-adjustment:
43 If present, thermal warning adjustment is enabled.
44
45 - st,fault-detect-recovery:
46 If present, then fault recovery will be enabled.
47
48 - st,drop-compensation-ns: number
49 Only required for "st,ffx-power-output-mode" ==
50 "variable-drop-compensation".
51 Specifies the drop compensation in nanoseconds.
52 The value must be in the range of 0..300, and only
53 multiples of 20 are allowed. Default is 140ns.
54
55 - st,max-power-use-mpcc:
56 If present, then MPCC bits are used for MPC coefficients,
57 otherwise standard MPC coefficients are used.
58
59 - st,max-power-corr:
60 If present, power bridge correction for THD reduction near maximum
61 power output is enabled.
62
63 - st,am-reduction-mode:
64 If present, FFX mode runs in AM reduction mode, otherwise normal
65 FFX mode is used.
66
67 - st,odd-pwm-speed-mode:
68 If present, PWM speed mode run on odd speed mode (341.3 kHz) on all
69 channels. If not present, normal PWM spped mode (384 kHz) will be used.
70
71 - st,invalid-input-detect-mute:
72 If present, automatic invalid input detect mute is enabled.
73
74Example:
75
76codec: sta32x@38 {
77 compatible = "st,sta32x";
78 reg = <0x1c>;
79 reset-gpios = <&gpio1 19 0>;
80 power-down-gpios = <&gpio1 16 0>;
81 st,output-conf = /bits/ 8 <0x3>; // set output to 2-channel
82 // (full-bridge) power,
83 // 2-channel data-out
84 st,ch1-output-mapping = /bits/ 8 <0>; // set channel 1 output ch 1
85 st,ch2-output-mapping = /bits/ 8 <0>; // set channel 2 output ch 1
86 st,ch3-output-mapping = /bits/ 8 <0>; // set channel 3 output ch 1
87 st,max-power-correction; // enables power bridge
88 // correction for THD reduction
89 // near maximum power output
90 st,invalid-input-detect-mute; // mute if no valid digital
91 // audio signal is provided.
92};
diff --git a/include/sound/sta32x.h b/include/sound/sta32x.h
index 8d93b0357a14..a894f7d17b1a 100644
--- a/include/sound/sta32x.h
+++ b/include/sound/sta32x.h
@@ -24,12 +24,20 @@
24#define STA32X_THERMAL_RECOVERY_ENABLE 2 24#define STA32X_THERMAL_RECOVERY_ENABLE 2
25 25
26struct sta32x_platform_data { 26struct sta32x_platform_data {
27 int output_conf; 27 u8 output_conf;
28 int ch1_output_mapping; 28 u8 ch1_output_mapping;
29 int ch2_output_mapping; 29 u8 ch2_output_mapping;
30 int ch3_output_mapping; 30 u8 ch3_output_mapping;
31 int thermal_conf;
32 int needs_esd_watchdog; 31 int needs_esd_watchdog;
32 u8 drop_compensation_ns;
33 unsigned int thermal_warning_recovery:1;
34 unsigned int thermal_warning_adjustment:1;
35 unsigned int fault_detect_recovery:1;
36 unsigned int max_power_use_mpcc:1;
37 unsigned int max_power_correction:1;
38 unsigned int am_reduction_mode:1;
39 unsigned int odd_pwm_speed_mode:1;
40 unsigned int invalid_input_detect_mute:1;
33}; 41};
34 42
35#endif /* __LINUX_SND__STA32X_H */ 43#endif /* __LINUX_SND__STA32X_H */
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index ec2372498c92..669b67f8cee3 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -24,6 +24,8 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/pm.h> 25#include <linux/pm.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/of_device.h>
28#include <linux/of_gpio.h>
27#include <linux/regmap.h> 29#include <linux/regmap.h>
28#include <linux/regulator/consumer.h> 30#include <linux/regulator/consumer.h>
29#include <linux/gpio/consumer.h> 31#include <linux/gpio/consumer.h>
@@ -893,15 +895,49 @@ static int sta32x_probe(struct snd_soc_codec *codec)
893 dev_err(codec->dev, "Failed to startup device\n"); 895 dev_err(codec->dev, "Failed to startup device\n");
894 return ret; 896 return ret;
895 } 897 }
896 /* set thermal warning adjustment and recovery */ 898
899 /* CONFA */
897 if (!pdata->thermal_warning_recovery) 900 if (!pdata->thermal_warning_recovery)
898 thermal |= STA32X_CONFA_TWAB; 901 thermal |= STA32X_CONFA_TWAB;
899 if (!pdata->thermal_warning_adjustment) 902 if (!pdata->thermal_warning_adjustment)
900 thermal |= STA32X_CONFA_TWRB; 903 thermal |= STA32X_CONFA_TWRB;
904 if (!pdata->fault_detect_recovery)
905 thermal |= STA32X_CONFA_FDRB;
901 regmap_update_bits(sta32x->regmap, STA32X_CONFA, 906 regmap_update_bits(sta32x->regmap, STA32X_CONFA,
902 STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, 907 STA32X_CONFA_TWAB | STA32X_CONFA_TWRB |
908 STA32X_CONFA_FDRB,
903 thermal); 909 thermal);
904 910
911 /* CONFC */
912 regmap_update_bits(sta32x->regmap, STA32X_CONFC,
913 STA32X_CONFC_CSZ_MASK,
914 pdata->drop_compensation_ns
915 << STA32X_CONFC_CSZ_SHIFT);
916
917 /* CONFE */
918 regmap_update_bits(sta32x->regmap, STA32X_CONFE,
919 STA32X_CONFE_MPCV,
920 pdata->max_power_use_mpcc ?
921 STA32X_CONFE_MPCV : 0);
922 regmap_update_bits(sta32x->regmap, STA32X_CONFE,
923 STA32X_CONFE_MPC,
924 pdata->max_power_correction ?
925 STA32X_CONFE_MPC : 0);
926 regmap_update_bits(sta32x->regmap, STA32X_CONFE,
927 STA32X_CONFE_AME,
928 pdata->am_reduction_mode ?
929 STA32X_CONFE_AME : 0);
930 regmap_update_bits(sta32x->regmap, STA32X_CONFE,
931 STA32X_CONFE_PWMS,
932 pdata->odd_pwm_speed_mode ?
933 STA32X_CONFE_PWMS : 0);
934
935 /* CONFF */
936 regmap_update_bits(sta32x->regmap, STA32X_CONFF,
937 STA32X_CONFF_IDE,
938 pdata->invalid_input_detect_mute ?
939 STA32X_CONFF_IDE : 0);
940
905 /* select output configuration */ 941 /* select output configuration */
906 regmap_update_bits(sta32x->regmap, STA32X_CONFF, 942 regmap_update_bits(sta32x->regmap, STA32X_CONFF,
907 STA32X_CONFF_OCFG_MASK, 943 STA32X_CONFF_OCFG_MASK,
@@ -977,7 +1013,66 @@ static const struct regmap_config sta32x_regmap = {
977 .rd_table = &sta32x_read_regs, 1013 .rd_table = &sta32x_read_regs,
978 .volatile_table = &sta32x_volatile_regs, 1014 .volatile_table = &sta32x_volatile_regs,
979}; 1015};
1016
1017#ifdef CONFIG_OF
1018static const struct of_device_id st32x_dt_ids[] = {
1019 { .compatible = "st,sta32x", },
1020 { }
980}; 1021};
1022MODULE_DEVICE_TABLE(of, st32x_dt_ids);
1023
1024static int sta32x_probe_dt(struct device *dev, struct sta32x_priv *sta32x)
1025{
1026 struct device_node *np = dev->of_node;
1027 struct sta32x_platform_data *pdata;
1028 u16 tmp;
1029
1030 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
1031 if (!pdata)
1032 return -ENOMEM;
1033
1034 of_property_read_u8(np, "st,output-conf",
1035 &pdata->output_conf);
1036 of_property_read_u8(np, "st,ch1-output-mapping",
1037 &pdata->ch1_output_mapping);
1038 of_property_read_u8(np, "st,ch2-output-mapping",
1039 &pdata->ch2_output_mapping);
1040 of_property_read_u8(np, "st,ch3-output-mapping",
1041 &pdata->ch3_output_mapping);
1042
1043 if (of_get_property(np, "st,thermal-warning-recovery", NULL))
1044 pdata->thermal_warning_recovery = 1;
1045 if (of_get_property(np, "st,thermal-warning-adjustment", NULL))
1046 pdata->thermal_warning_adjustment = 1;
1047 if (of_get_property(np, "st,needs_esd_watchdog", NULL))
1048 pdata->needs_esd_watchdog = 1;
1049
1050 tmp = 140;
1051 of_property_read_u16(np, "st,drop-compensation-ns", &tmp);
1052 pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20;
1053
1054 /* CONFE */
1055 if (of_get_property(np, "st,max-power-use-mpcc", NULL))
1056 pdata->max_power_use_mpcc = 1;
1057
1058 if (of_get_property(np, "st,max-power-correction", NULL))
1059 pdata->max_power_correction = 1;
1060
1061 if (of_get_property(np, "st,am-reduction-mode", NULL))
1062 pdata->am_reduction_mode = 1;
1063
1064 if (of_get_property(np, "st,odd-pwm-speed-mode", NULL))
1065 pdata->odd_pwm_speed_mode = 1;
1066
1067 /* CONFF */
1068 if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
1069 pdata->invalid_input_detect_mute = 1;
1070
1071 sta32x->pdata = pdata;
1072
1073 return 0;
1074}
1075#endif
981 1076
982static int sta32x_i2c_probe(struct i2c_client *i2c, 1077static int sta32x_i2c_probe(struct i2c_client *i2c,
983 const struct i2c_device_id *id) 1078 const struct i2c_device_id *id)
@@ -994,6 +1089,14 @@ static int sta32x_i2c_probe(struct i2c_client *i2c,
994 mutex_init(&sta32x->coeff_lock); 1089 mutex_init(&sta32x->coeff_lock);
995 sta32x->pdata = dev_get_platdata(dev); 1090 sta32x->pdata = dev_get_platdata(dev);
996 1091
1092#ifdef CONFIG_OF
1093 if (dev->of_node) {
1094 ret = sta32x_probe_dt(dev, sta32x);
1095 if (ret < 0)
1096 return ret;
1097 }
1098#endif
1099
997 /* GPIOs */ 1100 /* GPIOs */
998 sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset"); 1101 sta32x->gpiod_nreset = devm_gpiod_get(dev, "reset");
999 if (IS_ERR(sta32x->gpiod_nreset)) { 1102 if (IS_ERR(sta32x->gpiod_nreset)) {
@@ -1051,6 +1154,7 @@ static struct i2c_driver sta32x_i2c_driver = {
1051 .driver = { 1154 .driver = {
1052 .name = "sta32x", 1155 .name = "sta32x",
1053 .owner = THIS_MODULE, 1156 .owner = THIS_MODULE,
1157 .of_match_table = of_match_ptr(st32x_dt_ids),
1054 }, 1158 },
1055 .probe = sta32x_i2c_probe, 1159 .probe = sta32x_i2c_probe,
1056 .remove = sta32x_i2c_remove, 1160 .remove = sta32x_i2c_remove,