bcm27xx: import latest patches from the RPi foundation
[openwrt/staging/ynezz.git] / target / linux / bcm27xx / patches-5.4 / 950-1020-Update-Allo-Piano-Dac-Driver-for-5.4.y-kernels.patch
1 From 7f7ea09cdfa44c447c31db4884c1bb958d27f10a Mon Sep 17 00:00:00 2001
2 From: paul-1 <6473457+paul-1@users.noreply.github.com>
3 Date: Wed, 4 Nov 2020 19:11:37 -0500
4 Subject: [PATCH] Update Allo Piano Dac Driver for 5.4.y kernels
5
6 Add unique names to the individual dac coded drivers
7 Remove some of the codec controls that are not used.
8
9 Signed-off-by: Paul Hermann <paul@picoreplayer.org>
10 ---
11 sound/soc/bcm/allo-piano-dac-plus.c | 129 +++++++++++++++++++++-------
12 1 file changed, 97 insertions(+), 32 deletions(-)
13
14 --- a/sound/soc/bcm/allo-piano-dac-plus.c
15 +++ b/sound/soc/bcm/allo-piano-dac-plus.c
16 @@ -2,7 +2,8 @@
17 * ALSA ASoC Machine Driver for Allo Piano DAC Plus Subwoofer
18 *
19 * Author: Baswaraj K <jaikumar@cem-solutions.net>
20 - * Copyright 2016
21 + * Copyright 2020
22 + * based on code by David Knell <david.knell@gmail.com)
23 * based on code by Daniel Matuschek <info@crazy-audio.com>
24 * based on code by Florian Meier <florian.meier@koalo.de>
25 *
26 @@ -276,8 +277,15 @@ static int snd_allo_piano_dual_mode_put(
27 PCM512x_DIGITAL_VOLUME_2, 0xff);
28
29 list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
30 - if (!strncmp(kctl->id.name, "Digital Playback Volume",
31 - sizeof(kctl->id.name))) {
32 + if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
33 + sizeof(kctl->id.name))) {
34 + mc = (struct soc_mixer_control *)
35 + kctl->private_value;
36 + mc->rreg = mc->reg;
37 + break;
38 + }
39 + if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
40 + sizeof(kctl->id.name))) {
41 mc = (struct soc_mixer_control *)
42 kctl->private_value;
43 mc->rreg = mc->reg;
44 @@ -291,13 +299,20 @@ static int snd_allo_piano_dual_mode_put(
45 PCM512x_DIGITAL_VOLUME_3, &right_val);
46
47 list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
48 - if (!strncmp(kctl->id.name, "Digital Playback Volume",
49 - sizeof(kctl->id.name))) {
50 + if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
51 + sizeof(kctl->id.name))) {
52 mc = (struct soc_mixer_control *)
53 kctl->private_value;
54 mc->rreg = PCM512x_DIGITAL_VOLUME_3;
55 break;
56 }
57 + if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
58 + sizeof(kctl->id.name))) {
59 + mc = (struct soc_mixer_control *)
60 + kctl->private_value;
61 + mc->rreg = PCM512x_DIGITAL_VOLUME_2;
62 + break;
63 + }
64 }
65
66 snd_soc_component_write(rtd->codec_dais[0]->component,
67 @@ -344,13 +359,20 @@ static int snd_allo_piano_mode_put(struc
68 PCM512x_DIGITAL_VOLUME_2, &right_val);
69
70 list_for_each_entry(kctl, &snd_card_ptr->controls, list) {
71 - if (!strncmp(kctl->id.name, "Digital Playback Volume",
72 - sizeof(kctl->id.name))) {
73 + if (!strncmp(kctl->id.name, "Main Digital Playback Volume",
74 + sizeof(kctl->id.name))) {
75 mc = (struct soc_mixer_control *)
76 kctl->private_value;
77 mc->rreg = PCM512x_DIGITAL_VOLUME_3;
78 break;
79 }
80 + if (!strncmp(kctl->id.name, "Sub Digital Playback Volume",
81 + sizeof(kctl->id.name))) {
82 + mc = (struct soc_mixer_control *)
83 + kctl->private_value;
84 + mc->rreg = PCM512x_DIGITAL_VOLUME_2;
85 + break;
86 + }
87 }
88 snd_soc_component_write(rtd->codec_dais[0]->component,
89 PCM512x_DIGITAL_VOLUME_3, left_val);
90 @@ -434,12 +456,6 @@ static int pcm512x_set_reg_sub(struct sn
91 int ret = 0;
92
93 rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
94 - if (glb_ptr->dual_mode != 1) {
95 - ret = snd_soc_component_write(rtd->codec_dais[1]->component,
96 - PCM512x_DIGITAL_VOLUME_2, (~left_val));
97 - if (ret < 0)
98 - return ret;
99 - }
100
101 if (digital_gain_0db_limit) {
102 ret = snd_soc_limit_volume(card, "Subwoofer Playback Volume",
103 @@ -449,6 +465,13 @@ static int pcm512x_set_reg_sub(struct sn
104 ret);
105 }
106
107 + if (glb_ptr->dual_mode != 1) {
108 + ret = snd_soc_component_write(rtd->codec_dais[1]->component,
109 + PCM512x_DIGITAL_VOLUME_2, (~left_val));
110 + if (ret < 0)
111 + return ret;
112 + }
113 +
114 ret = snd_soc_component_write(rtd->codec_dais[1]->component,
115 PCM512x_DIGITAL_VOLUME_3, (~right_val));
116 if (ret < 0)
117 @@ -674,7 +697,7 @@ static const struct snd_kcontrol_new all
118
119 SOC_DOUBLE_R_EXT_TLV("Subwoofer Playback Volume",
120 PCM512x_DIGITAL_VOLUME_2,
121 - PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
122 + PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
123 pcm512x_get_reg_sub,
124 pcm512x_set_reg_sub,
125 digital_tlv_sub),
126 @@ -688,7 +711,7 @@ static const struct snd_kcontrol_new all
127
128 SOC_DOUBLE_R_EXT_TLV("Master Playback Volume",
129 PCM512x_DIGITAL_VOLUME_2,
130 - PCM512x_DIGITAL_VOLUME_3, 0, 255, 1,
131 + PCM512x_DIGITAL_VOLUME_3, 0, 207, 1,
132 pcm512x_get_reg_master,
133 pcm512x_set_reg_master,
134 digital_tlv_master),
135 @@ -701,10 +724,28 @@ static const struct snd_kcontrol_new all
136 pcm512x_set_reg_master_switch),
137 };
138
139 +static const char * const codec_ctl_pfx[] = { "Main", "Sub" };
140 +static const char * const codec_ctl_name[] = {
141 + "Digital Playback Volume",
142 + "Digital Playback Switch",
143 + "Auto Mute Mono Switch",
144 + "Auto Mute Switch",
145 + "Auto Mute Time Left",
146 + "Auto Mute Time Right",
147 + "Clock Missing Period",
148 + "Max Overclock DAC",
149 + "Max Overclock DSP",
150 + "Max Overclock PLL",
151 + "Volume Ramp Down Emergency Rate",
152 + "Volume Ramp Down Emergency Step"
153 +};
154 +
155 static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime *rtd)
156 {
157 struct snd_soc_card *card = rtd->card;
158 struct glb_pool *glb_ptr;
159 + struct snd_kcontrol *kctl;
160 + int i, j;
161
162 glb_ptr = kzalloc(sizeof(struct glb_pool), GFP_KERNEL);
163 if (!glb_ptr)
164 @@ -719,12 +760,37 @@ static int snd_allo_piano_dac_init(struc
165 if (digital_gain_0db_limit) {
166 int ret;
167
168 - ret = snd_soc_limit_volume(card, "Digital Playback Volume",
169 - 207);
170 - if (ret < 0)
171 - dev_warn(card->dev, "Failed to set volume limit: %d\n",
172 - ret);
173 + //Set volume limit on both dacs
174 + for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
175 + char cname[256];
176 +
177 + sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[0]);
178 + ret = snd_soc_limit_volume(card, cname, 207);
179 + if (ret < 0)
180 + dev_warn(card->dev, "Failed to set volume limit: %d\n",
181 + ret);
182 + }
183 + }
184 +
185 + // Remove codec controls
186 + for (i = 0; i < ARRAY_SIZE(codec_ctl_pfx); i++) {
187 + // Start at 1, leave the Digital Volume control.
188 + for (j = 1; j < ARRAY_SIZE(codec_ctl_name); j++) {
189 + char cname[256];
190 +
191 + sprintf(cname, "%s %s", codec_ctl_pfx[i], codec_ctl_name[j]);
192 + kctl = snd_soc_card_get_kcontrol(card, cname);
193 + if (!kctl) {
194 + dev_err(rtd->card->dev, "Control %s not found\n",
195 + cname);
196 + } else {
197 + kctl->vd[0].access =
198 + SNDRV_CTL_ELEM_ACCESS_READWRITE;
199 + snd_ctl_remove(card->snd_card, kctl);
200 + }
201 + }
202 }
203 +
204 return 0;
205 }
206
207 @@ -868,10 +934,10 @@ static struct snd_soc_dai_link_component
208 };
209
210 SND_SOC_DAILINK_DEFS(allo_piano_dai_plus,
211 - DAILINK_COMP_ARRAY(COMP_CPU("bcm2708-i2s.0")),
212 - DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi"),
213 - COMP_CODEC(NULL, "pcm512x-hifi")),
214 - DAILINK_COMP_ARRAY(COMP_PLATFORM("bcm2708-i2s.0")));
215 + DAILINK_COMP_ARRAY(COMP_EMPTY()),
216 + DAILINK_COMP_ARRAY(COMP_CODEC("pcm512x.1-004c", "pcm512x-hifi"),
217 + COMP_CODEC("pcm512x.1-004d", "pcm512x-hifi")),
218 + DAILINK_COMP_ARRAY(COMP_EMPTY()));
219
220 static struct snd_soc_dai_link snd_allo_piano_dac_dai[] = {
221 {
222 @@ -964,17 +1030,16 @@ static int snd_allo_piano_dac_probe(stru
223 snd_allo_piano_dac.set_bias_level =
224 snd_allo_piano_set_bias_level;
225
226 - ret = snd_soc_register_card(&snd_allo_piano_dac);
227 - if (ret < 0) {
228 - dev_err(&pdev->dev,
229 - "snd_soc_register_card() failed: %d\n", ret);
230 - return ret;
231 - }
232 -
233 if ((mute_gpio[0]) && (mute_gpio[1]))
234 snd_allo_piano_gpio_mute(&snd_allo_piano_dac);
235
236 - return 0;
237 + ret = devm_snd_soc_register_card(&pdev->dev, &snd_allo_piano_dac);
238 +
239 + if (ret && ret != -EPROBE_DEFER)
240 + dev_err(&pdev->dev,
241 + "snd_soc_register_card() failed: %d\n", ret);
242 + return ret;
243 +
244 }
245
246 return -EINVAL;