19 #define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__
21 #include <linux/module.h>
26 #include <linux/i2c.h>
29 #include <linux/slab.h>
42 #define STA32X_RATES (SNDRV_PCM_RATE_32000 | \
43 SNDRV_PCM_RATE_44100 | \
44 SNDRV_PCM_RATE_48000 | \
45 SNDRV_PCM_RATE_88200 | \
46 SNDRV_PCM_RATE_96000 | \
47 SNDRV_PCM_RATE_176400 | \
48 SNDRV_PCM_RATE_192000)
50 #define STA32X_FORMATS \
51 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \
52 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \
53 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
54 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \
55 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \
56 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
106 static const char *sta32x_supply_names[] = {
131 static const char *sta32x_drc_ac[] = {
132 "Anti-Clipping",
"Dynamic Range Compression" };
133 static const char *sta32x_auto_eq_mode[] = {
134 "User",
"Preset",
"Loudness" };
135 static const char *sta32x_auto_gc_mode[] = {
136 "User",
"AC no clipping",
"AC limited clipping (10%)",
137 "DRC nighttime listening mode" };
138 static const char *sta32x_auto_xo_mode[] = {
139 "User",
"80Hz",
"100Hz",
"120Hz",
"140Hz",
"160Hz",
"180Hz",
"200Hz",
140 "220Hz",
"240Hz",
"260Hz",
"280Hz",
"300Hz",
"320Hz",
"340Hz",
"360Hz" };
141 static const char *sta32x_preset_eq_mode[] = {
142 "Flat",
"Rock",
"Soft Rock",
"Jazz",
"Classical",
"Dance",
"Pop",
"Soft",
143 "Hard",
"Party",
"Vocal",
"Hip-Hop",
"Dialog",
"Bass-boost #1",
144 "Bass-boost #2",
"Bass-boost #3",
"Loudness 1",
"Loudness 2",
145 "Loudness 3",
"Loudness 4",
"Loudness 5",
"Loudness 6",
"Loudness 7",
146 "Loudness 8",
"Loudness 9",
"Loudness 10",
"Loudness 11",
"Loudness 12",
147 "Loudness 13",
"Loudness 14",
"Loudness 15",
"Loudness 16" };
148 static const char *sta32x_limiter_select[] = {
149 "Limiter Disabled",
"Limiter #1",
"Limiter #2" };
150 static const char *sta32x_limiter_attack_rate[] = {
151 "3.1584",
"2.7072",
"2.2560",
"1.8048",
"1.3536",
"0.9024",
152 "0.4512",
"0.2256",
"0.1504",
"0.1123",
"0.0902",
"0.0752",
153 "0.0645",
"0.0564",
"0.0501",
"0.0451" };
154 static const char *sta32x_limiter_release_rate[] = {
155 "0.5116",
"0.1370",
"0.0744",
"0.0499",
"0.0360",
"0.0299",
156 "0.0264",
"0.0208",
"0.0198",
"0.0172",
"0.0147",
"0.0137",
157 "0.0134",
"0.0117",
"0.0110",
"0.0104" };
159 static const unsigned int sta32x_limiter_ac_attack_tlv[] = {
165 static const unsigned int sta32x_limiter_ac_release_tlv[] = {
174 static const unsigned int sta32x_limiter_drc_attack_tlv[] = {
181 static const unsigned int sta32x_limiter_drc_release_tlv[] = {
190 static const struct soc_enum sta32x_drc_ac_enum =
193 static const struct soc_enum sta32x_auto_eq_enum =
195 3, sta32x_auto_eq_mode);
196 static const struct soc_enum sta32x_auto_gc_enum =
198 4, sta32x_auto_gc_mode);
199 static const struct soc_enum sta32x_auto_xo_enum =
201 16, sta32x_auto_xo_mode);
202 static const struct soc_enum sta32x_preset_eq_enum =
204 32, sta32x_preset_eq_mode);
205 static const struct soc_enum sta32x_limiter_ch1_enum =
207 3, sta32x_limiter_select);
208 static const struct soc_enum sta32x_limiter_ch2_enum =
210 3, sta32x_limiter_select);
211 static const struct soc_enum sta32x_limiter_ch3_enum =
213 3, sta32x_limiter_select);
214 static const struct soc_enum sta32x_limiter1_attack_rate_enum =
216 16, sta32x_limiter_attack_rate);
217 static const struct soc_enum sta32x_limiter2_attack_rate_enum =
219 16, sta32x_limiter_attack_rate);
220 static const struct soc_enum sta32x_limiter1_release_rate_enum =
222 16, sta32x_limiter_release_rate);
223 static const struct soc_enum sta32x_limiter2_release_rate_enum =
225 16, sta32x_limiter_release_rate);
234 static int sta32x_coefficient_info(
struct snd_kcontrol *kcontrol,
239 uinfo->
count = 3 * numcoef;
243 static int sta32x_coefficient_get(
struct snd_kcontrol *kcontrol,
261 else if (numcoef == 5)
265 for (i = 0; i < 3 * numcoef; i++)
266 ucontrol->
value.bytes.data[i] =
272 static int sta32x_coefficient_put(
struct snd_kcontrol *kcontrol,
276 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
291 (ucontrol->
value.bytes.data[3 * i] << 16)
292 | (ucontrol->
value.bytes.data[3 * i + 1] << 8)
293 | (ucontrol->
value.bytes.data[3 * i + 2]);
294 for (i = 0; i < 3 * numcoef; i++)
296 ucontrol->
value.bytes.data[i]);
299 else if (numcoef == 5)
307 static int sta32x_sync_coef_shadow(
struct snd_soc_codec *codec)
309 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
341 sta32x_sync_coef_shadow(codec);
353 unsigned int confa, confa_cached;
360 if (confa != confa_cached) {
362 sta32x_cache_sync(codec);
370 static void sta32x_watchdog_start(
struct sta32x_priv *sta32x)
372 if (sta32x->
pdata->needs_esd_watchdog) {
379 static void sta32x_watchdog_stop(
struct sta32x_priv *sta32x)
381 if (sta32x->
pdata->needs_esd_watchdog) {
387 #define SINGLE_COEF(xname, index) \
388 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
389 .info = sta32x_coefficient_info, \
390 .get = sta32x_coefficient_get,\
391 .put = sta32x_coefficient_put, \
392 .private_value = index | (1 << 16) }
394 #define BIQUAD_COEFS(xname, index) \
395 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
396 .info = sta32x_coefficient_info, \
397 .get = sta32x_coefficient_get,\
398 .put = sta32x_coefficient_put, \
399 .private_value = index | (5 << 16) }
411 SOC_ENUM(
"Compressor/Limiter Switch", sta32x_drc_ac_enum),
416 SOC_ENUM(
"Automode EQ", sta32x_auto_eq_enum),
417 SOC_ENUM(
"Automode GC", sta32x_auto_gc_enum),
418 SOC_ENUM(
"Automode XO", sta32x_auto_xo_enum),
419 SOC_ENUM(
"Preset EQ", sta32x_preset_eq_enum),
427 SOC_ENUM(
"Ch1 Limiter Select", sta32x_limiter_ch1_enum),
428 SOC_ENUM(
"Ch2 Limiter Select", sta32x_limiter_ch2_enum),
429 SOC_ENUM(
"Ch3 Limiter Select", sta32x_limiter_ch3_enum),
432 SOC_ENUM(
"Limiter1 Attack Rate (dB/ms)", sta32x_limiter1_attack_rate_enum),
433 SOC_ENUM(
"Limiter2 Attack Rate (dB/ms)", sta32x_limiter2_attack_rate_enum),
434 SOC_ENUM(
"Limiter1 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
435 SOC_ENUM(
"Limiter2 Release Rate (dB/ms)", sta32x_limiter1_release_rate_enum),
441 16, 0, sta32x_limiter_ac_attack_tlv),
443 16, 0, sta32x_limiter_ac_attack_tlv),
445 16, 0, sta32x_limiter_ac_release_tlv),
447 16, 0, sta32x_limiter_ac_release_tlv),
449 16, 0, sta32x_limiter_drc_attack_tlv),
451 16, 0, sta32x_limiter_drc_attack_tlv),
453 16, 0, sta32x_limiter_drc_release_tlv),
455 16, 0, sta32x_limiter_drc_release_tlv),
489 {
"LEFT",
NULL,
"DAC" },
490 {
"RIGHT",
NULL,
"DAC" },
491 {
"SUB",
NULL,
"DAC" },
498 } interpolation_ratios[] = {
512 } mclk_ratios[3][7] = {
513 { { 768, 0 }, { 512, 1 }, { 384, 2 }, { 256, 3 },
514 { 128, 4 }, { 576, 5 }, { 0, 0 } },
515 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
516 { { 384, 2 }, { 256, 3 }, { 192, 4 }, { 128, 5 }, {64, 0 }, { 0, 0 } },
539 static int sta32x_set_dai_sysclk(
struct snd_soc_dai *codec_dai,
540 int clk_id,
unsigned int freq,
int dir)
543 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
545 unsigned int rates = 0;
546 unsigned int rate_min = -1;
547 unsigned int rate_max = 0;
553 for (i = 0; i <
ARRAY_SIZE(interpolation_ratios); i++) {
554 ir = interpolation_ratios[
i].ir;
555 fs = interpolation_ratios[
i].fs;
556 for (j = 0; mclk_ratios[
ir][
j].ratio; j++) {
557 if (mclk_ratios[ir][j].
ratio * fs == freq) {
571 dev_err(codec->
dev,
"could not find a valid sample rate\n");
581 codec_dai->
driver->playback.rates = rates;
582 codec_dai->
driver->playback.rate_min = rate_min;
583 codec_dai->
driver->playback.rate_max = rate_max;
595 static int sta32x_set_dai_fmt(
struct snd_soc_dai *codec_dai,
599 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
651 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
653 int i,
mcs = -1, ir = -1;
658 for (i = 0; i <
ARRAY_SIZE(interpolation_ratios); i++)
659 if (interpolation_ratios[i].fs == rate) {
660 ir = interpolation_ratios[
i].ir;
665 for (i = 0; mclk_ratios[
ir][
i].ratio; i++)
666 if (mclk_ratios[ir][i].
ratio * rate == sta32x->
mclk) {
667 mcs = mclk_ratios[
ir][
i].mcs;
768 static int sta32x_set_bias_level(
struct snd_soc_codec *codec,
772 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
792 "Failed to enable supplies: %d\n", ret);
796 sta32x_cache_sync(codec);
797 sta32x_watchdog_start(sta32x);
814 sta32x_watchdog_stop(sta32x);
824 .hw_params = sta32x_hw_params,
825 .set_sysclk = sta32x_set_dai_sysclk,
826 .set_fmt = sta32x_set_dai_fmt,
832 .stream_name =
"Playback",
838 .ops = &sta32x_dai_ops,
854 #define sta32x_suspend NULL
855 #define sta32x_resume NULL
860 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
861 int i, ret = 0, thermal = 0;
864 sta32x->
pdata = dev_get_platdata(codec->
dev);
869 dev_err(codec->
dev,
"Failed to enable supplies: %d\n", ret);
879 dev_err(codec->
dev,
"failed to set cache I/O (ret=%i)\n", ret);
911 sta32x->
pdata->output_conf
917 sta32x->
pdata->ch1_output_mapping
921 sta32x->
pdata->ch2_output_mapping
925 sta32x->
pdata->ch3_output_mapping
929 for (i = 4; i <= 49; i += 5)
931 for (i = 50; i <= 54; i++)
939 if (sta32x->
pdata->needs_esd_watchdog)
955 struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec);
957 sta32x_watchdog_stop(sta32x);
964 static bool sta32x_reg_is_volatile(
struct device *
dev,
unsigned int reg)
975 .probe = sta32x_probe,
976 .remove = sta32x_remove,
979 .set_bias_level = sta32x_set_bias_level,
980 .controls = sta32x_snd_controls,
981 .num_controls =
ARRAY_SIZE(sta32x_snd_controls),
982 .dapm_widgets = sta32x_dapm_widgets,
983 .num_dapm_widgets =
ARRAY_SIZE(sta32x_dapm_widgets),
984 .dapm_routes = sta32x_dapm_routes,
985 .num_dapm_routes =
ARRAY_SIZE(sta32x_dapm_routes),
988 static const struct regmap_config sta32x_regmap = {
992 .reg_defaults = sta32x_regs,
995 .volatile_reg = sta32x_reg_is_volatile,
1011 sta32x->
supplies[i].supply = sta32x_supply_names[i];
1016 dev_err(&i2c->
dev,
"Failed to request supplies: %d\n", ret);
1021 if (IS_ERR(sta32x->
regmap)) {
1022 ret = PTR_ERR(sta32x->
regmap);
1023 dev_err(&i2c->
dev,
"Failed to init regmap: %d\n", ret);
1027 i2c_set_clientdata(i2c, sta32x);
1031 dev_err(&i2c->
dev,
"Failed to register codec (%d)\n", ret);
1050 static struct i2c_driver sta32x_i2c_driver = {
1055 .probe = sta32x_i2c_probe,
1057 .id_table = sta32x_i2c_id,