GNU Linux-libre 4.14.332-gnu1
[releases.git] / drivers / staging / vc04_services / bcm2835-audio / bcm2835-ctl.c
1 /*****************************************************************************
2  * Copyright 2011 Broadcom Corporation.  All rights reserved.
3  *
4  * Unless you and Broadcom execute a separate written software license
5  * agreement governing use of this software, this software is licensed to you
6  * under the terms of the GNU General Public License version 2, available at
7  * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8  *
9  * Notwithstanding the above, under no circumstances may you combine this
10  * software in any way with any other Broadcom software provided under a
11  * license other than the GPL, without Broadcom's express prior written
12  * consent.
13  *****************************************************************************/
14
15 #include <linux/platform_device.h>
16 #include <linux/init.h>
17 #include <linux/io.h>
18 #include <linux/jiffies.h>
19 #include <linux/slab.h>
20 #include <linux/time.h>
21 #include <linux/wait.h>
22 #include <linux/delay.h>
23 #include <linux/moduleparam.h>
24 #include <linux/sched.h>
25
26 #include <sound/core.h>
27 #include <sound/control.h>
28 #include <sound/pcm.h>
29 #include <sound/pcm_params.h>
30 #include <sound/rawmidi.h>
31 #include <sound/initval.h>
32 #include <sound/tlv.h>
33 #include <sound/asoundef.h>
34
35 #include "bcm2835.h"
36
37 /* volume maximum and minimum in terms of 0.01dB */
38 #define CTRL_VOL_MAX 400
39 #define CTRL_VOL_MIN -10239 /* originally -10240 */
40
41 static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol,
42                                 struct snd_ctl_elem_info *uinfo)
43 {
44         if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
45                 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
46                 uinfo->count = 1;
47                 uinfo->value.integer.min = CTRL_VOL_MIN;
48                 uinfo->value.integer.max = CTRL_VOL_MAX; /* 2303 */
49         } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
50                 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
51                 uinfo->count = 1;
52                 uinfo->value.integer.min = 0;
53                 uinfo->value.integer.max = 1;
54         } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
55                 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
56                 uinfo->count = 1;
57                 uinfo->value.integer.min = 0;
58                 uinfo->value.integer.max = AUDIO_DEST_MAX - 1;
59         }
60         return 0;
61 }
62
63 /* toggles mute on or off depending on the value of nmute, and returns
64  * 1 if the mute value was changed, otherwise 0
65  */
66 static int toggle_mute(struct bcm2835_chip *chip, int nmute)
67 {
68         /* if settings are ok, just return 0 */
69         if (chip->mute == nmute)
70                 return 0;
71
72         /* if the sound is muted then we need to unmute */
73         if (chip->mute == CTRL_VOL_MUTE) {
74                 chip->volume = chip->old_volume; /* copy the old volume back */
75                 audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
76         } else /* otherwise we mute */ {
77                 chip->old_volume = chip->volume;
78                 chip->volume = 26214; /* set volume to minimum level AKA mute */
79                 audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume);
80         }
81
82         chip->mute = nmute;
83         return 1;
84 }
85
86 static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol,
87                                struct snd_ctl_elem_value *ucontrol)
88 {
89         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
90
91         if (mutex_lock_interruptible(&chip->audio_mutex))
92                 return -EINTR;
93
94         BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK));
95
96         if (kcontrol->private_value == PCM_PLAYBACK_VOLUME)
97                 ucontrol->value.integer.value[0] = chip2alsa(chip->volume);
98         else if (kcontrol->private_value == PCM_PLAYBACK_MUTE)
99                 ucontrol->value.integer.value[0] = chip->mute;
100         else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE)
101                 ucontrol->value.integer.value[0] = chip->dest;
102
103         mutex_unlock(&chip->audio_mutex);
104         return 0;
105 }
106
107 static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol,
108                                 struct snd_ctl_elem_value *ucontrol)
109 {
110         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
111         int changed = 0;
112
113         if (mutex_lock_interruptible(&chip->audio_mutex))
114                 return -EINTR;
115
116         if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) {
117                 audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int)ucontrol->value.integer.value[0]);
118                 if (chip->mute == CTRL_VOL_MUTE) {
119                         /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */
120                         changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */
121                         goto unlock;
122                 }
123                 if (changed || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) {
124                         chip->volume = alsa2chip(ucontrol->value.integer.value[0]);
125                         changed = 1;
126                 }
127
128         } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) {
129                 /* Now implemented */
130                 audio_info(" Mute attempted\n");
131                 changed = toggle_mute(chip, ucontrol->value.integer.value[0]);
132
133         } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) {
134                 if (ucontrol->value.integer.value[0] != chip->dest) {
135                         chip->dest = ucontrol->value.integer.value[0];
136                         changed = 1;
137                 }
138         }
139
140         if (changed && bcm2835_audio_set_ctls(chip))
141                 dev_err(chip->card->dev, "Failed to set ALSA controls..\n");
142
143 unlock:
144         mutex_unlock(&chip->audio_mutex);
145         return changed;
146 }
147
148 static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1);
149
150 static struct snd_kcontrol_new snd_bcm2835_ctl[] = {
151         {
152                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
153                 .name = "PCM Playback Volume",
154                 .index = 0,
155                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
156                 .private_value = PCM_PLAYBACK_VOLUME,
157                 .info = snd_bcm2835_ctl_info,
158                 .get = snd_bcm2835_ctl_get,
159                 .put = snd_bcm2835_ctl_put,
160                 .count = 1,
161                 .tlv = {.p = snd_bcm2835_db_scale}
162         },
163         {
164                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
165                 .name = "PCM Playback Switch",
166                 .index = 0,
167                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
168                 .private_value = PCM_PLAYBACK_MUTE,
169                 .info = snd_bcm2835_ctl_info,
170                 .get = snd_bcm2835_ctl_get,
171                 .put = snd_bcm2835_ctl_put,
172                 .count = 1,
173         },
174         {
175                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
176                 .name = "PCM Playback Route",
177                 .index = 0,
178                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
179                 .private_value = PCM_PLAYBACK_DEVICE,
180                 .info = snd_bcm2835_ctl_info,
181                 .get = snd_bcm2835_ctl_get,
182                 .put = snd_bcm2835_ctl_put,
183                 .count = 1,
184         },
185 };
186
187 static int snd_bcm2835_spdif_default_info(struct snd_kcontrol *kcontrol,
188         struct snd_ctl_elem_info *uinfo)
189 {
190         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
191         uinfo->count = 1;
192         return 0;
193 }
194
195 static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol,
196         struct snd_ctl_elem_value *ucontrol)
197 {
198         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
199         int i;
200
201         if (mutex_lock_interruptible(&chip->audio_mutex))
202                 return -EINTR;
203
204         for (i = 0; i < 4; i++)
205                 ucontrol->value.iec958.status[i] =
206                         (chip->spdif_status >> (i * 8)) & 0xff;
207
208         mutex_unlock(&chip->audio_mutex);
209         return 0;
210 }
211
212 static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol,
213         struct snd_ctl_elem_value *ucontrol)
214 {
215         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
216         unsigned int val = 0;
217         int i, change;
218
219         if (mutex_lock_interruptible(&chip->audio_mutex))
220                 return -EINTR;
221
222         for (i = 0; i < 4; i++)
223                 val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
224
225         change = val != chip->spdif_status;
226         chip->spdif_status = val;
227
228         mutex_unlock(&chip->audio_mutex);
229         return change;
230 }
231
232 static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol *kcontrol,
233         struct snd_ctl_elem_info *uinfo)
234 {
235         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
236         uinfo->count = 1;
237         return 0;
238 }
239
240 static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol,
241         struct snd_ctl_elem_value *ucontrol)
242 {
243         /*
244          * bcm2835 supports only consumer mode and sets all other format flags
245          * automatically. So the only thing left is signalling non-audio content
246          */
247         ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO;
248         return 0;
249 }
250
251 static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol,
252         struct snd_ctl_elem_info *uinfo)
253 {
254         uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
255         uinfo->count = 1;
256         return 0;
257 }
258
259 static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol,
260         struct snd_ctl_elem_value *ucontrol)
261 {
262         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
263         int i;
264
265         if (mutex_lock_interruptible(&chip->audio_mutex))
266                 return -EINTR;
267
268         for (i = 0; i < 4; i++)
269                 ucontrol->value.iec958.status[i] =
270                 (chip->spdif_status >> (i * 8)) & 0xff;
271
272         mutex_unlock(&chip->audio_mutex);
273         return 0;
274 }
275
276 static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol,
277         struct snd_ctl_elem_value *ucontrol)
278 {
279         struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol);
280         unsigned int val = 0;
281         int i, change;
282
283         if (mutex_lock_interruptible(&chip->audio_mutex))
284                 return -EINTR;
285
286         for (i = 0; i < 4; i++)
287                 val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
288         change = val != chip->spdif_status;
289         chip->spdif_status = val;
290
291         mutex_unlock(&chip->audio_mutex);
292         return change;
293 }
294
295 static struct snd_kcontrol_new snd_bcm2835_spdif[] = {
296         {
297                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
298                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
299                 .info = snd_bcm2835_spdif_default_info,
300                 .get = snd_bcm2835_spdif_default_get,
301                 .put = snd_bcm2835_spdif_default_put
302         },
303         {
304                 .access = SNDRV_CTL_ELEM_ACCESS_READ,
305                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
306                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
307                 .info = snd_bcm2835_spdif_mask_info,
308                 .get = snd_bcm2835_spdif_mask_get,
309         },
310         {
311                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
312                 SNDRV_CTL_ELEM_ACCESS_INACTIVE,
313                 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
314                 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM),
315                 .info = snd_bcm2835_spdif_stream_info,
316                 .get = snd_bcm2835_spdif_stream_get,
317                 .put = snd_bcm2835_spdif_stream_put,
318         },
319 };
320
321 int snd_bcm2835_new_ctl(struct bcm2835_chip *chip)
322 {
323         int err;
324         unsigned int idx;
325
326         strcpy(chip->card->mixername, "Broadcom Mixer");
327         for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) {
328                 err = snd_ctl_add(chip->card,
329                                   snd_ctl_new1(&snd_bcm2835_ctl[idx], chip));
330                 if (err < 0)
331                         return err;
332         }
333         for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) {
334                 err = snd_ctl_add(chip->card,
335                                   snd_ctl_new1(&snd_bcm2835_spdif[idx], chip));
336                 if (err < 0)
337                         return err;
338         }
339         return 0;
340 }
341
342 static struct snd_kcontrol_new snd_bcm2835_headphones_ctl[] = {
343         {
344                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
345                 .name = "Headphone Playback Volume",
346                 .index = 0,
347                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
348                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
349                 .private_value = PCM_PLAYBACK_VOLUME,
350                 .info = snd_bcm2835_ctl_info,
351                 .get = snd_bcm2835_ctl_get,
352                 .put = snd_bcm2835_ctl_put,
353                 .count = 1,
354                 .tlv = {.p = snd_bcm2835_db_scale}
355         },
356         {
357                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
358                 .name = "Headphone Playback Switch",
359                 .index = 0,
360                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
361                 .private_value = PCM_PLAYBACK_MUTE,
362                 .info = snd_bcm2835_ctl_info,
363                 .get = snd_bcm2835_ctl_get,
364                 .put = snd_bcm2835_ctl_put,
365                 .count = 1,
366         }
367 };
368
369 int snd_bcm2835_new_headphones_ctl(struct bcm2835_chip *chip)
370 {
371         int err;
372         unsigned int idx;
373
374         strcpy(chip->card->mixername, "Broadcom Mixer");
375         for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_headphones_ctl); idx++) {
376                 err = snd_ctl_add(chip->card,
377                                   snd_ctl_new1(&snd_bcm2835_headphones_ctl[idx],
378                                                chip));
379                 if (err)
380                         return err;
381         }
382         return 0;
383 }
384
385 static struct snd_kcontrol_new snd_bcm2835_hdmi[] = {
386         {
387                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
388                 .name = "HDMI Playback Volume",
389                 .index = 0,
390                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
391                           SNDRV_CTL_ELEM_ACCESS_TLV_READ,
392                 .private_value = PCM_PLAYBACK_VOLUME,
393                 .info = snd_bcm2835_ctl_info,
394                 .get = snd_bcm2835_ctl_get,
395                 .put = snd_bcm2835_ctl_put,
396                 .count = 1,
397                 .tlv = {.p = snd_bcm2835_db_scale}
398         },
399         {
400                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
401                 .name = "HDMI Playback Switch",
402                 .index = 0,
403                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
404                 .private_value = PCM_PLAYBACK_MUTE,
405                 .info = snd_bcm2835_ctl_info,
406                 .get = snd_bcm2835_ctl_get,
407                 .put = snd_bcm2835_ctl_put,
408                 .count = 1,
409         }
410 };
411
412 int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip)
413 {
414         int err;
415         unsigned int idx;
416
417         strcpy(chip->card->mixername, "Broadcom Mixer");
418         for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_hdmi); idx++) {
419                 err = snd_ctl_add(chip->card,
420                                   snd_ctl_new1(&snd_bcm2835_hdmi[idx], chip));
421                 if (err)
422                         return err;
423         }
424         return 0;
425 }
426