diff options
| author | Thomas Niederprüm <niederp@physik.uni-kl.de> | 2015-01-21 18:01:58 -0500 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-01-27 12:13:25 -0500 |
| commit | f04b1e760a51120f358826d815d12c3f8ecdf1b4 (patch) | |
| tree | 15ab3cf75b2dd1d2622c0874532890514e418d05 | |
| parent | 1c34c876c4abb219381dcb7096206f1a609f119b (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.txt | 92 | ||||
| -rw-r--r-- | include/sound/sta32x.h | 18 | ||||
| -rw-r--r-- | sound/soc/codecs/sta32x.c | 108 |
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 @@ | |||
| 1 | STA32X audio CODEC | ||
| 2 | |||
| 3 | The driver for this device only supports I2C. | ||
| 4 | |||
| 5 | Required 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 | |||
| 20 | Optional 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 | |||
| 74 | Example: | ||
| 75 | |||
| 76 | codec: 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 | ||
| 26 | struct sta32x_platform_data { | 26 | struct 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 | ||
| 1018 | static const struct of_device_id st32x_dt_ids[] = { | ||
| 1019 | { .compatible = "st,sta32x", }, | ||
| 1020 | { } | ||
| 980 | }; | 1021 | }; |
| 1022 | MODULE_DEVICE_TABLE(of, st32x_dt_ids); | ||
| 1023 | |||
| 1024 | static 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 | ||
| 982 | static int sta32x_i2c_probe(struct i2c_client *i2c, | 1077 | static 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, |
