hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/adau17x1.c
....@@ -1,10 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Common code for ADAU1X61 and ADAU1X81 codecs
34 *
45 * Copyright 2011-2014 Analog Devices Inc.
56 * Author: Lars-Peter Clausen <lars@metafoo.de>
6
- *
7
- * Licensed under the GPL-2 or later.
87 */
98
109 #include <linux/module.h>
....@@ -21,10 +20,17 @@
2120 #include <linux/i2c.h>
2221 #include <linux/spi/spi.h>
2322 #include <linux/regmap.h>
23
+#include <asm/unaligned.h>
2424
2525 #include "sigmadsp.h"
2626 #include "adau17x1.h"
2727 #include "adau-utils.h"
28
+
29
+#define ADAU17X1_SAFELOAD_TARGET_ADDRESS 0x0006
30
+#define ADAU17X1_SAFELOAD_TRIGGER 0x0007
31
+#define ADAU17X1_SAFELOAD_DATA 0x0001
32
+#define ADAU17X1_SAFELOAD_DATA_SIZE 20
33
+#define ADAU17X1_WORD_SIZE 4
2834
2935 static const char * const adau17x1_capture_mixer_boost_text[] = {
3036 "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3",
....@@ -59,6 +65,9 @@
5965
6066 SOC_ENUM("Mic Bias Mode", adau17x1_mic_bias_mode_enum),
6167 };
68
+
69
+static int adau17x1_setup_firmware(struct snd_soc_component *component,
70
+ unsigned int rate);
6271
6372 static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
6473 struct snd_kcontrol *kcontrol, int event)
....@@ -313,7 +322,7 @@
313322 { "Capture", NULL, "Right Decimator" },
314323 };
315324
316
-bool adau17x1_has_dsp(struct adau *adau)
325
+static bool adau17x1_has_dsp(struct adau *adau)
317326 {
318327 switch (adau->type) {
319328 case ADAU1761:
....@@ -324,7 +333,17 @@
324333 return false;
325334 }
326335 }
327
-EXPORT_SYMBOL_GPL(adau17x1_has_dsp);
336
+
337
+static bool adau17x1_has_safeload(struct adau *adau)
338
+{
339
+ switch (adau->type) {
340
+ case ADAU1761:
341
+ case ADAU1781:
342
+ return true;
343
+ default:
344
+ return false;
345
+ }
346
+}
328347
329348 static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,
330349 int source, unsigned int freq_in, unsigned int freq_out)
....@@ -366,7 +385,7 @@
366385 case ADAU17X1_CLK_SRC_PLL_AUTO:
367386 if (!adau->mclk)
368387 return -EINVAL;
369
- /* Fall-through */
388
+ fallthrough;
370389 case ADAU17X1_CLK_SRC_PLL:
371390 is_pll = true;
372391 break;
....@@ -450,7 +469,7 @@
450469 ret = adau17x1_auto_pll(dai, params);
451470 if (ret)
452471 return ret;
453
- /* Fall-through */
472
+ fallthrough;
454473 case ADAU17X1_CLK_SRC_PLL:
455474 freq = adau->pll_freq;
456475 break;
....@@ -836,7 +855,7 @@
836855 }
837856 EXPORT_SYMBOL_GPL(adau17x1_volatile_register);
838857
839
-int adau17x1_setup_firmware(struct snd_soc_component *component,
858
+static int adau17x1_setup_firmware(struct snd_soc_component *component,
840859 unsigned int rate)
841860 {
842861 int ret;
....@@ -880,7 +899,6 @@
880899
881900 return ret;
882901 }
883
-EXPORT_SYMBOL_GPL(adau17x1_setup_firmware);
884902
885903 int adau17x1_add_widgets(struct snd_soc_component *component)
886904 {
....@@ -957,6 +975,56 @@
957975 }
958976 EXPORT_SYMBOL_GPL(adau17x1_resume);
959977
978
+static int adau17x1_safeload(struct sigmadsp *sigmadsp, unsigned int addr,
979
+ const uint8_t bytes[], size_t len)
980
+{
981
+ uint8_t buf[ADAU17X1_WORD_SIZE];
982
+ uint8_t data[ADAU17X1_SAFELOAD_DATA_SIZE];
983
+ unsigned int addr_offset;
984
+ unsigned int nbr_words;
985
+ int ret;
986
+
987
+ /* write data to safeload addresses. Check if len is not a multiple of
988
+ * 4 bytes, if so we need to zero pad.
989
+ */
990
+ nbr_words = len / ADAU17X1_WORD_SIZE;
991
+ if ((len - nbr_words * ADAU17X1_WORD_SIZE) == 0) {
992
+ ret = regmap_raw_write(sigmadsp->control_data,
993
+ ADAU17X1_SAFELOAD_DATA, bytes, len);
994
+ } else {
995
+ nbr_words++;
996
+ memset(data, 0, ADAU17X1_SAFELOAD_DATA_SIZE);
997
+ memcpy(data, bytes, len);
998
+ ret = regmap_raw_write(sigmadsp->control_data,
999
+ ADAU17X1_SAFELOAD_DATA, data,
1000
+ nbr_words * ADAU17X1_WORD_SIZE);
1001
+ }
1002
+
1003
+ if (ret < 0)
1004
+ return ret;
1005
+
1006
+ /* Write target address, target address is offset by 1 */
1007
+ addr_offset = addr - 1;
1008
+ put_unaligned_be32(addr_offset, buf);
1009
+ ret = regmap_raw_write(sigmadsp->control_data,
1010
+ ADAU17X1_SAFELOAD_TARGET_ADDRESS, buf, ADAU17X1_WORD_SIZE);
1011
+ if (ret < 0)
1012
+ return ret;
1013
+
1014
+ /* write nbr of words to trigger address */
1015
+ put_unaligned_be32(nbr_words, buf);
1016
+ ret = regmap_raw_write(sigmadsp->control_data,
1017
+ ADAU17X1_SAFELOAD_TRIGGER, buf, ADAU17X1_WORD_SIZE);
1018
+ if (ret < 0)
1019
+ return ret;
1020
+
1021
+ return 0;
1022
+}
1023
+
1024
+static const struct sigmadsp_ops adau17x1_sigmadsp_ops = {
1025
+ .safeload = adau17x1_safeload,
1026
+};
1027
+
9601028 int adau17x1_probe(struct device *dev, struct regmap *regmap,
9611029 enum adau17x1_type type, void (*switch_mode)(struct device *dev),
9621030 const char *firmware_name)
....@@ -1002,8 +1070,13 @@
10021070 dev_set_drvdata(dev, adau);
10031071
10041072 if (firmware_name) {
1005
- adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap, NULL,
1006
- firmware_name);
1073
+ if (adau17x1_has_safeload(adau)) {
1074
+ adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap,
1075
+ &adau17x1_sigmadsp_ops, firmware_name);
1076
+ } else {
1077
+ adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap,
1078
+ NULL, firmware_name);
1079
+ }
10071080 if (IS_ERR(adau->sigmadsp)) {
10081081 dev_warn(dev, "Could not find firmware file: %ld\n",
10091082 PTR_ERR(adau->sigmadsp));