1 /*****************************************************************************
2 * Copyright 2011 Broadcom Corporation. All rights reserved.
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").
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
13 *****************************************************************************/
15 #include <linux/platform_device.h>
16 #include <linux/init.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>
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>
37 /* volume maximum and minimum in terms of 0.01dB */
38 #define CTRL_VOL_MAX 400
39 #define CTRL_VOL_MIN -10239 /* originally -10240 */
41 static int snd_bcm2835_ctl_info(struct snd_kcontrol
*kcontrol
,
42 struct snd_ctl_elem_info
*uinfo
)
44 audio_info(" ... IN\n");
45 if (kcontrol
->private_value
== PCM_PLAYBACK_VOLUME
) {
46 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
48 uinfo
->value
.integer
.min
= CTRL_VOL_MIN
;
49 uinfo
->value
.integer
.max
= CTRL_VOL_MAX
; /* 2303 */
50 } else if (kcontrol
->private_value
== PCM_PLAYBACK_MUTE
) {
51 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BOOLEAN
;
53 uinfo
->value
.integer
.min
= 0;
54 uinfo
->value
.integer
.max
= 1;
55 } else if (kcontrol
->private_value
== PCM_PLAYBACK_DEVICE
) {
56 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_INTEGER
;
58 uinfo
->value
.integer
.min
= 0;
59 uinfo
->value
.integer
.max
= AUDIO_DEST_MAX
- 1;
61 audio_info(" ... OUT\n");
65 /* toggles mute on or off depending on the value of nmute, and returns
66 * 1 if the mute value was changed, otherwise 0
68 static int toggle_mute(struct bcm2835_chip
*chip
, int nmute
)
70 /* if settings are ok, just return 0 */
71 if (chip
->mute
== nmute
)
74 /* if the sound is muted then we need to unmute */
75 if (chip
->mute
== CTRL_VOL_MUTE
) {
76 chip
->volume
= chip
->old_volume
; /* copy the old volume back */
77 audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip
->old_volume
, chip
->volume
);
78 } else /* otherwise we mute */ {
79 chip
->old_volume
= chip
->volume
;
80 chip
->volume
= 26214; /* set volume to minimum level AKA mute */
81 audio_info("Muting, old_volume = %d, volume = %d ...\n", chip
->old_volume
, chip
->volume
);
88 static int snd_bcm2835_ctl_get(struct snd_kcontrol
*kcontrol
,
89 struct snd_ctl_elem_value
*ucontrol
)
91 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
93 if (mutex_lock_interruptible(&chip
->audio_mutex
))
96 BUG_ON(!chip
&& !(chip
->avail_substreams
& AVAIL_SUBSTREAMS_MASK
));
98 if (kcontrol
->private_value
== PCM_PLAYBACK_VOLUME
)
99 ucontrol
->value
.integer
.value
[0] = chip2alsa(chip
->volume
);
100 else if (kcontrol
->private_value
== PCM_PLAYBACK_MUTE
)
101 ucontrol
->value
.integer
.value
[0] = chip
->mute
;
102 else if (kcontrol
->private_value
== PCM_PLAYBACK_DEVICE
)
103 ucontrol
->value
.integer
.value
[0] = chip
->dest
;
105 mutex_unlock(&chip
->audio_mutex
);
109 static int snd_bcm2835_ctl_put(struct snd_kcontrol
*kcontrol
,
110 struct snd_ctl_elem_value
*ucontrol
)
112 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
115 if (mutex_lock_interruptible(&chip
->audio_mutex
))
118 if (kcontrol
->private_value
== PCM_PLAYBACK_VOLUME
) {
119 audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip
->volume
, (int) ucontrol
->value
.integer
.value
[0]);
120 if (chip
->mute
== CTRL_VOL_MUTE
) {
121 /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */
122 changed
= 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */
126 || (ucontrol
->value
.integer
.value
[0] != chip2alsa(chip
->volume
))) {
128 chip
->volume
= alsa2chip(ucontrol
->value
.integer
.value
[0]);
132 } else if (kcontrol
->private_value
== PCM_PLAYBACK_MUTE
) {
133 /* Now implemented */
134 audio_info(" Mute attempted\n");
135 changed
= toggle_mute(chip
, ucontrol
->value
.integer
.value
[0]);
137 } else if (kcontrol
->private_value
== PCM_PLAYBACK_DEVICE
) {
138 if (ucontrol
->value
.integer
.value
[0] != chip
->dest
) {
139 chip
->dest
= ucontrol
->value
.integer
.value
[0];
145 if (bcm2835_audio_set_ctls(chip
))
146 printk(KERN_ERR
"Failed to set ALSA controls..\n");
150 mutex_unlock(&chip
->audio_mutex
);
154 static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale
, CTRL_VOL_MIN
, 1, 1);
156 static struct snd_kcontrol_new snd_bcm2835_ctl
[] = {
158 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
159 .name
= "PCM Playback Volume",
161 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
| SNDRV_CTL_ELEM_ACCESS_TLV_READ
,
162 .private_value
= PCM_PLAYBACK_VOLUME
,
163 .info
= snd_bcm2835_ctl_info
,
164 .get
= snd_bcm2835_ctl_get
,
165 .put
= snd_bcm2835_ctl_put
,
167 .tlv
= {.p
= snd_bcm2835_db_scale
}
170 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
171 .name
= "PCM Playback Switch",
173 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
174 .private_value
= PCM_PLAYBACK_MUTE
,
175 .info
= snd_bcm2835_ctl_info
,
176 .get
= snd_bcm2835_ctl_get
,
177 .put
= snd_bcm2835_ctl_put
,
181 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
182 .name
= "PCM Playback Route",
184 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
,
185 .private_value
= PCM_PLAYBACK_DEVICE
,
186 .info
= snd_bcm2835_ctl_info
,
187 .get
= snd_bcm2835_ctl_get
,
188 .put
= snd_bcm2835_ctl_put
,
193 static int snd_bcm2835_spdif_default_info(struct snd_kcontrol
*kcontrol
,
194 struct snd_ctl_elem_info
*uinfo
)
196 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
201 static int snd_bcm2835_spdif_default_get(struct snd_kcontrol
*kcontrol
,
202 struct snd_ctl_elem_value
*ucontrol
)
204 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
207 if (mutex_lock_interruptible(&chip
->audio_mutex
))
210 for (i
= 0; i
< 4; i
++)
211 ucontrol
->value
.iec958
.status
[i
] =
212 (chip
->spdif_status
>> (i
* 8)) & 0xff;
214 mutex_unlock(&chip
->audio_mutex
);
218 static int snd_bcm2835_spdif_default_put(struct snd_kcontrol
*kcontrol
,
219 struct snd_ctl_elem_value
*ucontrol
)
221 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
222 unsigned int val
= 0;
225 if (mutex_lock_interruptible(&chip
->audio_mutex
))
228 for (i
= 0; i
< 4; i
++)
229 val
|= (unsigned int) ucontrol
->value
.iec958
.status
[i
] << (i
* 8);
231 change
= val
!= chip
->spdif_status
;
232 chip
->spdif_status
= val
;
234 mutex_unlock(&chip
->audio_mutex
);
238 static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol
*kcontrol
,
239 struct snd_ctl_elem_info
*uinfo
)
241 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
246 static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol
*kcontrol
,
247 struct snd_ctl_elem_value
*ucontrol
)
249 /* bcm2835 supports only consumer mode and sets all other format flags
250 * automatically. So the only thing left is signalling non-audio
252 ucontrol
->value
.iec958
.status
[0] = IEC958_AES0_NONAUDIO
;
256 static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol
*kcontrol
,
257 struct snd_ctl_elem_info
*uinfo
)
259 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_IEC958
;
264 static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol
*kcontrol
,
265 struct snd_ctl_elem_value
*ucontrol
)
267 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
270 if (mutex_lock_interruptible(&chip
->audio_mutex
))
273 for (i
= 0; i
< 4; i
++)
274 ucontrol
->value
.iec958
.status
[i
] =
275 (chip
->spdif_status
>> (i
* 8)) & 0xff;
277 mutex_unlock(&chip
->audio_mutex
);
281 static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol
*kcontrol
,
282 struct snd_ctl_elem_value
*ucontrol
)
284 struct bcm2835_chip
*chip
= snd_kcontrol_chip(kcontrol
);
285 unsigned int val
= 0;
288 if (mutex_lock_interruptible(&chip
->audio_mutex
))
291 for (i
= 0; i
< 4; i
++)
292 val
|= (unsigned int) ucontrol
->value
.iec958
.status
[i
] << (i
* 8);
293 change
= val
!= chip
->spdif_status
;
294 chip
->spdif_status
= val
;
296 mutex_unlock(&chip
->audio_mutex
);
300 static struct snd_kcontrol_new snd_bcm2835_spdif
[] = {
302 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
303 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, DEFAULT
),
304 .info
= snd_bcm2835_spdif_default_info
,
305 .get
= snd_bcm2835_spdif_default_get
,
306 .put
= snd_bcm2835_spdif_default_put
309 .access
= SNDRV_CTL_ELEM_ACCESS_READ
,
310 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
311 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, CON_MASK
),
312 .info
= snd_bcm2835_spdif_mask_info
,
313 .get
= snd_bcm2835_spdif_mask_get
,
316 .access
= SNDRV_CTL_ELEM_ACCESS_READWRITE
|
317 SNDRV_CTL_ELEM_ACCESS_INACTIVE
,
318 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
319 .name
= SNDRV_CTL_NAME_IEC958("", PLAYBACK
, PCM_STREAM
),
320 .info
= snd_bcm2835_spdif_stream_info
,
321 .get
= snd_bcm2835_spdif_stream_get
,
322 .put
= snd_bcm2835_spdif_stream_put
,
326 int snd_bcm2835_new_ctl(struct bcm2835_chip
*chip
)
331 strcpy(chip
->card
->mixername
, "Broadcom Mixer");
332 for (idx
= 0; idx
< ARRAY_SIZE(snd_bcm2835_ctl
); idx
++) {
333 err
= snd_ctl_add(chip
->card
,
334 snd_ctl_new1(&snd_bcm2835_ctl
[idx
], chip
));
338 for (idx
= 0; idx
< ARRAY_SIZE(snd_bcm2835_spdif
); idx
++) {
339 err
= snd_ctl_add(chip
->card
,
340 snd_ctl_new1(&snd_bcm2835_spdif
[idx
], chip
));