diff options
Diffstat (limited to 'drivers/staging/bcm2835-audio')
-rw-r--r-- | drivers/staging/bcm2835-audio/Kconfig | 7 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/Makefile | 5 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/TODO | 29 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835-ctl.c | 345 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835-pcm.c | 554 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835-vchiq.c | 912 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835.c | 250 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835.h | 167 | ||||
-rw-r--r-- | drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h | 108 |
9 files changed, 0 insertions, 2377 deletions
diff --git a/drivers/staging/bcm2835-audio/Kconfig b/drivers/staging/bcm2835-audio/Kconfig deleted file mode 100644 index 32a2ff9..0000000 --- a/drivers/staging/bcm2835-audio/Kconfig +++ /dev/null @@ -1,7 +0,0 @@ -config SND_BCM2835 - tristate "BCM2835 ALSA driver" - depends on ARCH_BCM2835 && BCM2835_VCHIQ && SND - select SND_PCM - help - Say Y or M if you want to support BCM2835 Alsa pcm card driver - diff --git a/drivers/staging/bcm2835-audio/Makefile b/drivers/staging/bcm2835-audio/Makefile deleted file mode 100644 index d7b88d1..0000000 --- a/drivers/staging/bcm2835-audio/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -obj-$(CONFIG_SND_BCM2835) += snd-bcm2835.o -snd-bcm2835-objs := bcm2835.o bcm2835-ctl.o bcm2835-pcm.o bcm2835-vchiq.o - -ccflags-y += -Idrivers/staging/vc04_services -D__VCCOREVER__=0x04000000 - diff --git a/drivers/staging/bcm2835-audio/TODO b/drivers/staging/bcm2835-audio/TODO deleted file mode 100644 index 73d41fa..0000000 --- a/drivers/staging/bcm2835-audio/TODO +++ /dev/null @@ -1,29 +0,0 @@ -***************************************************************************** -* * -* TODO: BCM2835-AUDIO * -* * -***************************************************************************** - - -1) Document the device tree node - -The downstream tree(the tree that the driver was imported from) at -http://www.github.com/raspberrypi/linux uses this node: - -audio: audio { - compatible = "brcm,bcm2835-audio"; - brcm,pwm-channels = <8>; -}; - -Since the driver requires the use of VCHIQ, it may be useful to have a link -in the device tree to the VCHIQ driver. - -2) Gracefully handle the case where VCHIQ is missing from the device tree or -it has not been initialized yet. - -3) Review error handling and remove duplicate code. - -4) Cleanup the logging mechanism. The driver should probably be using the -standard kernel logging mechanisms such as dev_info, dev_dbg, and friends. - -5) Fix the remaining checkpatch.pl errors and warnings. diff --git a/drivers/staging/bcm2835-audio/bcm2835-ctl.c b/drivers/staging/bcm2835-audio/bcm2835-ctl.c deleted file mode 100644 index a4ffa1b..0000000 --- a/drivers/staging/bcm2835-audio/bcm2835-ctl.c +++ /dev/null @@ -1,345 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#include <linux/platform_device.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/jiffies.h> -#include <linux/slab.h> -#include <linux/time.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/moduleparam.h> -#include <linux/sched.h> - -#include <sound/core.h> -#include <sound/control.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/rawmidi.h> -#include <sound/initval.h> -#include <sound/tlv.h> -#include <sound/asoundef.h> - -#include "bcm2835.h" - -/* volume maximum and minimum in terms of 0.01dB */ -#define CTRL_VOL_MAX 400 -#define CTRL_VOL_MIN -10239 /* originally -10240 */ - -static int snd_bcm2835_ctl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - audio_info(" ... IN\n"); - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = CTRL_VOL_MIN; - uinfo->value.integer.max = CTRL_VOL_MAX; /* 2303 */ - } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 1; - } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = AUDIO_DEST_MAX - 1; - } - audio_info(" ... OUT\n"); - return 0; -} - -/* toggles mute on or off depending on the value of nmute, and returns - * 1 if the mute value was changed, otherwise 0 - */ -static int toggle_mute(struct bcm2835_chip *chip, int nmute) -{ - /* if settings are ok, just return 0 */ - if (chip->mute == nmute) - return 0; - - /* if the sound is muted then we need to unmute */ - if (chip->mute == CTRL_VOL_MUTE) { - chip->volume = chip->old_volume; /* copy the old volume back */ - audio_info("Unmuting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); - } else /* otherwise we mute */ { - chip->old_volume = chip->volume; - chip->volume = 26214; /* set volume to minimum level AKA mute */ - audio_info("Muting, old_volume = %d, volume = %d ...\n", chip->old_volume, chip->volume); - } - - chip->mute = nmute; - return 1; -} - -static int snd_bcm2835_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - BUG_ON(!chip && !(chip->avail_substreams & AVAIL_SUBSTREAMS_MASK)); - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) - ucontrol->value.integer.value[0] = chip2alsa(chip->volume); - else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) - ucontrol->value.integer.value[0] = chip->mute; - else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) - ucontrol->value.integer.value[0] = chip->dest; - - mutex_unlock(&chip->audio_mutex); - return 0; -} - -static int snd_bcm2835_ctl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int changed = 0; - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - if (kcontrol->private_value == PCM_PLAYBACK_VOLUME) { - audio_info("Volume change attempted.. volume = %d new_volume = %d\n", chip->volume, (int) ucontrol->value.integer.value[0]); - if (chip->mute == CTRL_VOL_MUTE) { - /* changed = toggle_mute(chip, CTRL_VOL_UNMUTE); */ - changed = 1; /* should return 0 to signify no change but the mixer takes this as the opposite sign (no idea why) */ - goto unlock; - } - if (changed - || (ucontrol->value.integer.value[0] != chip2alsa(chip->volume))) { - - chip->volume = alsa2chip(ucontrol->value.integer.value[0]); - changed = 1; - } - - } else if (kcontrol->private_value == PCM_PLAYBACK_MUTE) { - /* Now implemented */ - audio_info(" Mute attempted\n"); - changed = toggle_mute(chip, ucontrol->value.integer.value[0]); - - } else if (kcontrol->private_value == PCM_PLAYBACK_DEVICE) { - if (ucontrol->value.integer.value[0] != chip->dest) { - chip->dest = ucontrol->value.integer.value[0]; - changed = 1; - } - } - - if (changed) { - if (bcm2835_audio_set_ctls(chip)) - printk(KERN_ERR "Failed to set ALSA controls..\n"); - } - -unlock: - mutex_unlock(&chip->audio_mutex); - return changed; -} - -static DECLARE_TLV_DB_SCALE(snd_bcm2835_db_scale, CTRL_VOL_MIN, 1, 1); - -static struct snd_kcontrol_new snd_bcm2835_ctl[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, - .private_value = PCM_PLAYBACK_VOLUME, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, - .count = 1, - .tlv = {.p = snd_bcm2835_db_scale} - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .private_value = PCM_PLAYBACK_MUTE, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, - .count = 1, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Route", - .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .private_value = PCM_PLAYBACK_DEVICE, - .info = snd_bcm2835_ctl_info, - .get = snd_bcm2835_ctl_get, - .put = snd_bcm2835_ctl_put, - .count = 1, - }, -}; - -static int snd_bcm2835_spdif_default_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int snd_bcm2835_spdif_default_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) & 0xff; - - mutex_unlock(&chip->audio_mutex); - return 0; -} - -static int snd_bcm2835_spdif_default_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - unsigned int val = 0; - int i, change; - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - for (i = 0; i < 4; i++) - val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8); - - change = val != chip->spdif_status; - chip->spdif_status = val; - - mutex_unlock(&chip->audio_mutex); - return change; -} - -static int snd_bcm2835_spdif_mask_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int snd_bcm2835_spdif_mask_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - /* bcm2835 supports only consumer mode and sets all other format flags - * automatically. So the only thing left is signalling non-audio - * content */ - ucontrol->value.iec958.status[0] = IEC958_AES0_NONAUDIO; - return 0; -} - -static int snd_bcm2835_spdif_stream_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; - uinfo->count = 1; - return 0; -} - -static int snd_bcm2835_spdif_stream_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - int i; - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - for (i = 0; i < 4; i++) - ucontrol->value.iec958.status[i] = - (chip->spdif_status >> (i * 8)) & 0xff; - - mutex_unlock(&chip->audio_mutex); - return 0; -} - -static int snd_bcm2835_spdif_stream_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct bcm2835_chip *chip = snd_kcontrol_chip(kcontrol); - unsigned int val = 0; - int i, change; - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - for (i = 0; i < 4; i++) - val |= (unsigned int) ucontrol->value.iec958.status[i] << (i * 8); - change = val != chip->spdif_status; - chip->spdif_status = val; - - mutex_unlock(&chip->audio_mutex); - return change; -} - -static struct snd_kcontrol_new snd_bcm2835_spdif[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .info = snd_bcm2835_spdif_default_info, - .get = snd_bcm2835_spdif_default_get, - .put = snd_bcm2835_spdif_default_put - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), - .info = snd_bcm2835_spdif_mask_info, - .get = snd_bcm2835_spdif_mask_get, - }, - { - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_INACTIVE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), - .info = snd_bcm2835_spdif_stream_info, - .get = snd_bcm2835_spdif_stream_get, - .put = snd_bcm2835_spdif_stream_put, - }, -}; - -int snd_bcm2835_new_ctl(struct bcm2835_chip *chip) -{ - int err; - unsigned int idx; - - strcpy(chip->card->mixername, "Broadcom Mixer"); - for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_ctl); idx++) { - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_bcm2835_ctl[idx], chip)); - if (err < 0) - return err; - } - for (idx = 0; idx < ARRAY_SIZE(snd_bcm2835_spdif); idx++) { - err = snd_ctl_add(chip->card, - snd_ctl_new1(&snd_bcm2835_spdif[idx], chip)); - if (err < 0) - return err; - } - return 0; -} diff --git a/drivers/staging/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/bcm2835-audio/bcm2835-pcm.c deleted file mode 100644 index 16127e0..0000000 --- a/drivers/staging/bcm2835-audio/bcm2835-pcm.c +++ /dev/null @@ -1,554 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#include <linux/interrupt.h> -#include <linux/slab.h> - -#include <sound/asoundef.h> - -#include "bcm2835.h" - -/* hardware definition */ -static struct snd_pcm_hardware snd_bcm2835_playback_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, - .periods_min = 1, - .periods_max = 128, -}; - -static struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000, - .rate_min = 44100, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 128 * 1024, - .period_bytes_min = 1 * 1024, - .period_bytes_max = 128 * 1024, - .periods_min = 1, - .periods_max = 128, -}; - -static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime) -{ - audio_info("Freeing up alsa stream here ..\n"); - if (runtime->private_data) - kfree(runtime->private_data); - runtime->private_data = NULL; -} - -void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream) -{ - unsigned int consumed = 0; - int new_period = 0; - - audio_info(" .. IN\n"); - - audio_info("alsa_stream=%p substream=%p\n", alsa_stream, - alsa_stream ? alsa_stream->substream : 0); - - if (alsa_stream->open) - consumed = bcm2835_audio_retrieve_buffers(alsa_stream); - - /* We get called only if playback was triggered, So, the number of buffers we retrieve in - * each iteration are the buffers that have been played out already - */ - - if (alsa_stream->period_size) { - if ((alsa_stream->pos / alsa_stream->period_size) != - ((alsa_stream->pos + consumed) / alsa_stream->period_size)) - new_period = 1; - } - audio_debug("updating pos cur: %d + %d max:%d period_bytes:%d, hw_ptr: %d new_period:%d\n", - alsa_stream->pos, - consumed, - alsa_stream->buffer_size, - (int) (alsa_stream->period_size * alsa_stream->substream->runtime->periods), - frames_to_bytes(alsa_stream->substream->runtime, alsa_stream->substream->runtime->status->hw_ptr), - new_period); - if (alsa_stream->buffer_size) { - alsa_stream->pos += consumed &~(1 << 30); - alsa_stream->pos %= alsa_stream->buffer_size; - } - - if (alsa_stream->substream) { - if (new_period) - snd_pcm_period_elapsed(alsa_stream->substream); - } else { - audio_warning(" unexpected NULL substream\n"); - } - audio_info(" .. OUT\n"); -} - -/* open callback */ -static int snd_bcm2835_playback_open_generic( - struct snd_pcm_substream *substream, int spdif) -{ - struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream; - int idx; - int err; - - audio_info(" .. IN (%d)\n", substream->number); - - if (mutex_lock_interruptible(&chip->audio_mutex)) { - audio_error("Interrupted whilst waiting for lock\n"); - return -EINTR; - } - audio_info("Alsa open (%d)\n", substream->number); - idx = substream->number; - - if (spdif && chip->opened) { - err = -EBUSY; - goto out; - } else if (!spdif && (chip->opened & (1 << idx))) { - err = -EBUSY; - goto out; - } - if (idx >= MAX_SUBSTREAMS) { - audio_error - ("substream(%d) device doesn't exist max(%d) substreams allowed\n", - idx, MAX_SUBSTREAMS); - err = -ENODEV; - goto out; - } - - /* Check if we are ready */ - if (!(chip->avail_substreams & (1 << idx))) { - /* We are not ready yet */ - audio_error("substream(%d) device is not ready yet\n", idx); - err = -EAGAIN; - goto out; - } - - alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL); - if (!alsa_stream) { - err = -ENOMEM; - goto out; - } - - /* Initialise alsa_stream */ - alsa_stream->chip = chip; - alsa_stream->substream = substream; - alsa_stream->idx = idx; - - sema_init(&alsa_stream->buffers_update_sem, 0); - sema_init(&alsa_stream->control_sem, 0); - spin_lock_init(&alsa_stream->lock); - - err = bcm2835_audio_open(alsa_stream); - if (err) { - kfree(alsa_stream); - goto out; - } - runtime->private_data = alsa_stream; - runtime->private_free = snd_bcm2835_playback_free; - if (spdif) { - runtime->hw = snd_bcm2835_playback_spdif_hw; - } else { - /* clear spdif status, as we are not in spdif mode */ - chip->spdif_status = 0; - runtime->hw = snd_bcm2835_playback_hw; - } - /* minimum 16 bytes alignment (for vchiq bulk transfers) */ - snd_pcm_hw_constraint_step(runtime, - 0, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, - 16); - - chip->alsa_stream[idx] = alsa_stream; - - chip->opened |= (1 << idx); - alsa_stream->open = 1; - alsa_stream->draining = 1; - -out: - mutex_unlock(&chip->audio_mutex); - - audio_info(" .. OUT =%d\n", err); - - return err; -} - -static int snd_bcm2835_playback_open(struct snd_pcm_substream *substream) -{ - return snd_bcm2835_playback_open_generic(substream, 0); -} - -static int snd_bcm2835_playback_spdif_open(struct snd_pcm_substream *substream) -{ - return snd_bcm2835_playback_open_generic(substream, 1); -} - -/* close callback */ -static int snd_bcm2835_playback_close(struct snd_pcm_substream *substream) -{ - /* the hardware-specific codes will be here */ - - struct bcm2835_chip *chip; - struct snd_pcm_runtime *runtime; - struct bcm2835_alsa_stream *alsa_stream; - - audio_info(" .. IN\n"); - - chip = snd_pcm_substream_chip(substream); - if (mutex_lock_interruptible(&chip->audio_mutex)) { - audio_error("Interrupted whilst waiting for lock\n"); - return -EINTR; - } - runtime = substream->runtime; - alsa_stream = runtime->private_data; - - audio_info("Alsa close\n"); - - /* - * Call stop if it's still running. This happens when app - * is force killed and we don't get a stop trigger. - */ - if (alsa_stream->running) { - int err; - err = bcm2835_audio_stop(alsa_stream); - alsa_stream->running = 0; - if (err) - audio_error(" Failed to STOP alsa device\n"); - } - - alsa_stream->period_size = 0; - alsa_stream->buffer_size = 0; - - if (alsa_stream->open) { - alsa_stream->open = 0; - bcm2835_audio_close(alsa_stream); - } - if (alsa_stream->chip) - alsa_stream->chip->alsa_stream[alsa_stream->idx] = NULL; - /* - * Do not free up alsa_stream here, it will be freed up by - * runtime->private_free callback we registered in *_open above - */ - - chip->opened &= ~(1 << substream->number); - - mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - - return 0; -} - -/* hw_params callback */ -static int snd_bcm2835_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - int err; - - audio_info(" .. IN\n"); - - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (err < 0) { - audio_error - (" pcm_lib_malloc failed to allocated pages for buffers\n"); - return err; - } - - alsa_stream->channels = params_channels(params); - alsa_stream->params_rate = params_rate(params); - alsa_stream->pcm_format_width = snd_pcm_format_width(params_format(params)); - audio_info(" .. OUT\n"); - - return err; -} - -/* hw_free callback */ -static int snd_bcm2835_pcm_hw_free(struct snd_pcm_substream *substream) -{ - audio_info(" .. IN\n"); - return snd_pcm_lib_free_pages(substream); -} - -/* prepare callback */ -static int snd_bcm2835_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct bcm2835_chip *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - int channels; - int err; - - audio_info(" .. IN\n"); - - if (mutex_lock_interruptible(&chip->audio_mutex)) - return -EINTR; - - /* notify the vchiq that it should enter spdif passthrough mode by - * setting channels=0 (see - * https://github.com/raspberrypi/linux/issues/528) */ - if (chip->spdif_status & IEC958_AES0_NONAUDIO) - channels = 0; - else - channels = alsa_stream->channels; - - err = bcm2835_audio_set_params(alsa_stream, channels, - alsa_stream->params_rate, - alsa_stream->pcm_format_width); - if (err < 0) { - audio_error(" error setting hw params\n"); - } - - bcm2835_audio_setup(alsa_stream); - - /* in preparation of the stream, set the controls (volume level) of the stream */ - bcm2835_audio_set_ctls(alsa_stream->chip); - - - memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect)); - - alsa_stream->pcm_indirect.hw_buffer_size = - alsa_stream->pcm_indirect.sw_buffer_size = - snd_pcm_lib_buffer_bytes(substream); - - alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream); - alsa_stream->period_size = snd_pcm_lib_period_bytes(substream); - alsa_stream->pos = 0; - - audio_debug("buffer_size=%d, period_size=%d pos=%d frame_bits=%d\n", - alsa_stream->buffer_size, alsa_stream->period_size, - alsa_stream->pos, runtime->frame_bits); - - mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - return 0; -} - -static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream, - struct snd_pcm_indirect *rec, size_t bytes) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - void *src = (void *) (substream->runtime->dma_area + rec->sw_data); - int err; - - err = bcm2835_audio_write(alsa_stream, bytes, src); - if (err) - audio_error(" Failed to transfer to alsa device (%d)\n", err); - -} - -static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect; - - pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max; - snd_pcm_indirect_playback_transfer(substream, pcm_indirect, - snd_bcm2835_pcm_transfer); - return 0; -} - -/* trigger callback */ -static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - int err = 0; - - audio_info(" .. IN\n"); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - audio_debug("bcm2835_AUDIO_TRIGGER_START running=%d\n", - alsa_stream->running); - if (!alsa_stream->running) { - err = bcm2835_audio_start(alsa_stream); - if (!err) { - alsa_stream->pcm_indirect.hw_io = - alsa_stream->pcm_indirect.hw_data = - bytes_to_frames(runtime, - alsa_stream->pos); - substream->ops->ack(substream); - alsa_stream->running = 1; - alsa_stream->draining = 1; - } else { - audio_error(" Failed to START alsa device (%d)\n", err); - } - } - break; - case SNDRV_PCM_TRIGGER_STOP: - audio_debug - ("bcm2835_AUDIO_TRIGGER_STOP running=%d draining=%d\n", - alsa_stream->running, runtime->status->state == SNDRV_PCM_STATE_DRAINING); - if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) { - audio_info("DRAINING\n"); - alsa_stream->draining = 1; - } else { - audio_info("DROPPING\n"); - alsa_stream->draining = 0; - } - if (alsa_stream->running) { - err = bcm2835_audio_stop(alsa_stream); - if (err != 0) - audio_error(" Failed to STOP alsa device (%d)\n", err); - alsa_stream->running = 0; - } - break; - default: - err = -EINVAL; - } - - audio_info(" .. OUT\n"); - return err; -} - -/* pointer callback */ -static snd_pcm_uframes_t -snd_bcm2835_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct bcm2835_alsa_stream *alsa_stream = runtime->private_data; - - audio_info(" .. IN\n"); - - audio_debug("pcm_pointer... (%d) hwptr=%d appl=%d pos=%d\n", 0, - frames_to_bytes(runtime, runtime->status->hw_ptr), - frames_to_bytes(runtime, runtime->control->appl_ptr), - alsa_stream->pos); - - audio_info(" .. OUT\n"); - return snd_pcm_indirect_playback_pointer(substream, - &alsa_stream->pcm_indirect, - alsa_stream->pos); -} - -static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - int ret = snd_pcm_lib_ioctl(substream, cmd, arg); - - audio_info(" .. substream=%p, cmd=%d, arg=%p (%x) ret=%d\n", substream, - cmd, arg, arg ? *(unsigned *) arg : 0, ret); - return ret; -} - -/* operators */ -static struct snd_pcm_ops snd_bcm2835_playback_ops = { - .open = snd_bcm2835_playback_open, - .close = snd_bcm2835_playback_close, - .ioctl = snd_bcm2835_pcm_lib_ioctl, - .hw_params = snd_bcm2835_pcm_hw_params, - .hw_free = snd_bcm2835_pcm_hw_free, - .prepare = snd_bcm2835_pcm_prepare, - .trigger = snd_bcm2835_pcm_trigger, - .pointer = snd_bcm2835_pcm_pointer, - .ack = snd_bcm2835_pcm_ack, -}; - -static struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = { - .open = snd_bcm2835_playback_spdif_open, - .close = snd_bcm2835_playback_close, - .ioctl = snd_bcm2835_pcm_lib_ioctl, - .hw_params = snd_bcm2835_pcm_hw_params, - .hw_free = snd_bcm2835_pcm_hw_free, - .prepare = snd_bcm2835_pcm_prepare, - .trigger = snd_bcm2835_pcm_trigger, - .pointer = snd_bcm2835_pcm_pointer, - .ack = snd_bcm2835_pcm_ack, -}; - -/* create a pcm device */ -int snd_bcm2835_new_pcm(struct bcm2835_chip *chip) -{ - struct snd_pcm *pcm; - int err; - - audio_info(" .. IN\n"); - mutex_init(&chip->audio_mutex); - if (mutex_lock_interruptible(&chip->audio_mutex)) { - audio_error("Interrupted whilst waiting for lock\n"); - return -EINTR; - } - err = snd_pcm_new(chip->card, "bcm2835 ALSA", 0, MAX_SUBSTREAMS, 0, &pcm); - if (err < 0) - goto out; - pcm->private_data = chip; - strcpy(pcm->name, "bcm2835 ALSA"); - chip->pcm = pcm; - chip->dest = AUDIO_DEST_AUTO; - chip->volume = alsa2chip(0); - chip->mute = CTRL_VOL_UNMUTE; /*disable mute on startup */ - /* set operators */ - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_bcm2835_playback_ops); - - /* pre-allocation of buffers */ - /* NOTE: this may fail */ - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - snd_bcm2835_playback_hw.buffer_bytes_max, - snd_bcm2835_playback_hw.buffer_bytes_max); - - -out: - mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - - return 0; -} - -int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip) -{ - struct snd_pcm *pcm; - int err; - - audio_info(" .. IN\n"); - if (mutex_lock_interruptible(&chip->audio_mutex)) { - audio_error("Interrupted whilst waiting for lock\n"); - return -EINTR; - } - err = snd_pcm_new(chip->card, "bcm2835 ALSA", 1, 1, 0, &pcm); - if (err < 0) - goto out; - - pcm->private_data = chip; - strcpy(pcm->name, "bcm2835 IEC958/HDMI"); - chip->pcm_spdif = pcm; - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_bcm2835_playback_spdif_ops); - - /* pre-allocation of buffers */ - /* NOTE: this may fail */ - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - snd_dma_continuous_data(GFP_KERNEL), - snd_bcm2835_playback_spdif_hw.buffer_bytes_max, snd_bcm2835_playback_spdif_hw.buffer_bytes_max); -out: - mutex_unlock(&chip->audio_mutex); - audio_info(" .. OUT\n"); - - return 0; -} diff --git a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c deleted file mode 100644 index fa23a13..0000000 --- a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c +++ /dev/null @@ -1,912 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#include <linux/device.h> -#include <sound/core.h> -#include <sound/initval.h> -#include <sound/pcm.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/mm.h> -#include <linux/syscalls.h> -#include <linux/uaccess.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/atomic.h> -#include <linux/module.h> -#include <linux/completion.h> - -#include "bcm2835.h" - -/* ---- Include Files -------------------------------------------------------- */ - -#include "interface/vchi/vchi.h" -#include "vc_vchi_audioserv_defs.h" - -/* ---- Private Constants and Types ------------------------------------------ */ - -#define BCM2835_AUDIO_STOP 0 -#define BCM2835_AUDIO_START 1 -#define BCM2835_AUDIO_WRITE 2 - -/* Logging macros (for remapping to other logging mechanisms, i.e., printf) */ -#ifdef AUDIO_DEBUG_ENABLE -#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) -#define LOG_WARN(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) -#define LOG_INFO(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) -#define LOG_DBG(fmt, arg...) pr_info("%s:%d " fmt, __func__, __LINE__, ##arg) -#else -#define LOG_ERR(fmt, arg...) pr_err("%s:%d " fmt, __func__, __LINE__, ##arg) -#define LOG_WARN(fmt, arg...) no_printk(fmt, ##arg) -#define LOG_INFO(fmt, arg...) no_printk(fmt, ##arg) -#define LOG_DBG(fmt, arg...) no_printk(fmt, ##arg) -#endif - -struct bcm2835_audio_instance { - unsigned int num_connections; - VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS]; - struct completion msg_avail_comp; - struct mutex vchi_mutex; - struct bcm2835_alsa_stream *alsa_stream; - int result; - short peer_version; -}; - -static bool force_bulk; - -/* ---- Private Variables ---------------------------------------------------- */ - -/* ---- Private Function Prototypes ------------------------------------------ */ - -/* ---- Private Functions ---------------------------------------------------- */ - -static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream); -static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream); -static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, void *src); - -// Routine to send a message across a service - -static int -bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, - void *data, - unsigned int size) -{ - return vchi_queue_kernel_message(handle, - data, - size); -} - -static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 | - 'M' << 8 | 'A'); -static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 | - 'T' << 8 | 'A'); - -struct bcm2835_audio_work { - struct work_struct my_work; - struct bcm2835_alsa_stream *alsa_stream; - int cmd; - void *src; - unsigned int count; -}; - -static void my_wq_function(struct work_struct *work) -{ - struct bcm2835_audio_work *w = - container_of(work, struct bcm2835_audio_work, my_work); - int ret = -9; - - LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->cmd); - switch (w->cmd) { - case BCM2835_AUDIO_START: - ret = bcm2835_audio_start_worker(w->alsa_stream); - break; - case BCM2835_AUDIO_STOP: - ret = bcm2835_audio_stop_worker(w->alsa_stream); - break; - case BCM2835_AUDIO_WRITE: - ret = bcm2835_audio_write_worker(w->alsa_stream, w->count, - w->src); - break; - default: - LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd); - break; - } - kfree((void *) work); - LOG_DBG(" .. OUT %d\n", ret); -} - -int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream) -{ - int ret = -1; - - LOG_DBG(" .. IN\n"); - if (alsa_stream->my_wq) { - struct bcm2835_audio_work *work; - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - /*--- Queue some work (item 1) ---*/ - if (work) { - INIT_WORK(&work->my_work, my_wq_function); - work->alsa_stream = alsa_stream; - work->cmd = BCM2835_AUDIO_START; - if (queue_work(alsa_stream->my_wq, &work->my_work)) - ret = 0; - } else - LOG_ERR(" .. Error: NULL work kmalloc\n"); - } - LOG_DBG(" .. OUT %d\n", ret); - return ret; -} - -int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream) -{ - int ret = -1; - - LOG_DBG(" .. IN\n"); - if (alsa_stream->my_wq) { - struct bcm2835_audio_work *work; - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - /*--- Queue some work (item 1) ---*/ - if (work) { - INIT_WORK(&work->my_work, my_wq_function); - work->alsa_stream = alsa_stream; - work->cmd = BCM2835_AUDIO_STOP; - if (queue_work(alsa_stream->my_wq, &work->my_work)) - ret = 0; - } else - LOG_ERR(" .. Error: NULL work kmalloc\n"); - } - LOG_DBG(" .. OUT %d\n", ret); - return ret; -} - -int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, void *src) -{ - int ret = -1; - - LOG_DBG(" .. IN\n"); - if (alsa_stream->my_wq) { - struct bcm2835_audio_work *work; - - work = kmalloc(sizeof(*work), GFP_ATOMIC); - /*--- Queue some work (item 1) ---*/ - if (work) { - INIT_WORK(&work->my_work, my_wq_function); - work->alsa_stream = alsa_stream; - work->cmd = BCM2835_AUDIO_WRITE; - work->src = src; - work->count = count; - if (queue_work(alsa_stream->my_wq, &work->my_work)) - ret = 0; - } else - LOG_ERR(" .. Error: NULL work kmalloc\n"); - } - LOG_DBG(" .. OUT %d\n", ret); - return ret; -} - -static void my_workqueue_init(struct bcm2835_alsa_stream *alsa_stream) -{ - alsa_stream->my_wq = alloc_workqueue("my_queue", WQ_HIGHPRI, 1); - return; -} - -static void my_workqueue_quit(struct bcm2835_alsa_stream *alsa_stream) -{ - if (alsa_stream->my_wq) { - flush_workqueue(alsa_stream->my_wq); - destroy_workqueue(alsa_stream->my_wq); - alsa_stream->my_wq = NULL; - } - return; -} - -static void audio_vchi_callback(void *param, - const VCHI_CALLBACK_REASON_T reason, - void *msg_handle) -{ - struct bcm2835_audio_instance *instance = param; - int status; - int msg_len; - struct vc_audio_msg m; - - LOG_DBG(" .. IN instance=%p, handle=%p, alsa=%p, reason=%d, handle=%p\n", - instance, instance ? instance->vchi_handle[0] : NULL, instance ? instance->alsa_stream : NULL, reason, msg_handle); - - if (reason != VCHI_CALLBACK_MSG_AVAILABLE) { - return; - } - if (!instance) { - LOG_ERR(" .. instance is null\n"); - BUG(); - return; - } - if (!instance->vchi_handle[0]) { - LOG_ERR(" .. instance->vchi_handle[0] is null\n"); - BUG(); - return; - } - status = vchi_msg_dequeue(instance->vchi_handle[0], - &m, sizeof(m), &msg_len, VCHI_FLAGS_NONE); - if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { - LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n", - instance, m.u.result.success); - instance->result = m.u.result.success; - complete(&instance->msg_avail_comp); - } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { - struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream; - - LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", - instance, m.u.complete.count); - if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || - m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) - LOG_ERR(" .. response is corrupt\n"); - else if (alsa_stream) { - atomic_add(m.u.complete.count, - &alsa_stream->retrieved); - bcm2835_playback_fifo(alsa_stream); - } else { - LOG_ERR(" .. unexpected alsa_stream=%p\n", - alsa_stream); - } - } else { - LOG_ERR(" .. unexpected m.type=%d\n", m.type); - } - LOG_DBG(" .. OUT\n"); -} - -static struct bcm2835_audio_instance * -vc_vchi_audio_init(VCHI_INSTANCE_T vchi_instance, - VCHI_CONNECTION_T **vchi_connections, - unsigned int num_connections) -{ - unsigned int i; - struct bcm2835_audio_instance *instance; - int status; - - LOG_DBG("%s: start", __func__); - - if (num_connections > VCHI_MAX_NUM_CONNECTIONS) { - LOG_ERR("%s: unsupported number of connections %u (max=%u)\n", - __func__, num_connections, VCHI_MAX_NUM_CONNECTIONS); - - return NULL; - } - /* Allocate memory for this instance */ - instance = kmalloc(sizeof(*instance), GFP_KERNEL); - if (!instance) - return NULL; - - memset(instance, 0, sizeof(*instance)); - instance->num_connections = num_connections; - - /* Create a lock for exclusive, serialized VCHI connection access */ - mutex_init(&instance->vchi_mutex); - /* Open the VCHI service connections */ - for (i = 0; i < num_connections; i++) { - SERVICE_CREATION_T params = { - VCHI_VERSION_EX(VC_AUDIOSERV_VER, VC_AUDIOSERV_MIN_VER), - VC_AUDIO_SERVER_NAME, // 4cc service code - vchi_connections[i], // passed in fn pointers - 0, // rx fifo size (unused) - 0, // tx fifo size (unused) - audio_vchi_callback, // service callback - instance, // service callback parameter - 1, //TODO: remove VCOS_FALSE, // unaligned bulk recieves - 1, //TODO: remove VCOS_FALSE, // unaligned bulk transmits - 0 // want crc check on bulk transfers - }; - - LOG_DBG("%s: about to open %i\n", __func__, i); - status = vchi_service_open(vchi_instance, ¶ms, - &instance->vchi_handle[i]); - LOG_DBG("%s: opened %i: %p=%d\n", __func__, i, instance->vchi_handle[i], status); - if (status) { - LOG_ERR("%s: failed to open VCHI service connection (status=%d)\n", - __func__, status); - - goto err_close_services; - } - /* Finished with the service for now */ - vchi_service_release(instance->vchi_handle[i]); - } - - LOG_DBG("%s: okay\n", __func__); - return instance; - -err_close_services: - for (i = 0; i < instance->num_connections; i++) { - LOG_ERR("%s: closing %i: %p\n", __func__, i, instance->vchi_handle[i]); - if (instance->vchi_handle[i]) - vchi_service_close(instance->vchi_handle[i]); - } - - kfree(instance); - LOG_ERR("%s: error\n", __func__); - - return NULL; -} - -static int vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) -{ - unsigned int i; - - LOG_DBG(" .. IN\n"); - - if (!instance) { - LOG_ERR("%s: invalid handle %p\n", __func__, instance); - - return -1; - } - - LOG_DBG(" .. about to lock (%d)\n", instance->num_connections); - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - - /* Close all VCHI service connections */ - for (i = 0; i < instance->num_connections; i++) { - int status; - - LOG_DBG(" .. %i:closing %p\n", i, instance->vchi_handle[i]); - vchi_service_use(instance->vchi_handle[i]); - - status = vchi_service_close(instance->vchi_handle[i]); - if (status) { - LOG_DBG("%s: failed to close VCHI service connection (status=%d)\n", - __func__, status); - } - } - - mutex_unlock(&instance->vchi_mutex); - - kfree(instance); - - LOG_DBG(" .. OUT\n"); - - return 0; -} - -static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream) -{ - static VCHI_INSTANCE_T vchi_instance; - static VCHI_CONNECTION_T *vchi_connection; - static int initted; - struct bcm2835_audio_instance *instance = - (struct bcm2835_audio_instance *)alsa_stream->instance; - int ret; - - LOG_DBG(" .. IN\n"); - - LOG_INFO("%s: start\n", __func__); - BUG_ON(instance); - if (instance) { - LOG_ERR("%s: VCHI instance already open (%p)\n", - __func__, instance); - instance->alsa_stream = alsa_stream; - alsa_stream->instance = instance; - ret = 0; // xxx todo -1; - goto err_free_mem; - } - - /* Initialize and create a VCHI connection */ - if (!initted) { - ret = vchi_initialise(&vchi_instance); - if (ret) { - LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", - __func__, ret); - - ret = -EIO; - goto err_free_mem; - } - ret = vchi_connect(NULL, 0, vchi_instance); - if (ret) { - LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", - __func__, ret); - - ret = -EIO; - goto err_free_mem; - } - initted = 1; - } - - /* Initialize an instance of the audio service */ - instance = vc_vchi_audio_init(vchi_instance, &vchi_connection, 1); - - if (!instance) { - LOG_ERR("%s: failed to initialize audio service\n", __func__); - - ret = -EPERM; - goto err_free_mem; - } - - instance->alsa_stream = alsa_stream; - alsa_stream->instance = instance; - - LOG_DBG(" success !\n"); - ret = 0; -err_free_mem: - LOG_DBG(" .. OUT\n"); - - return ret; -} - -int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) -{ - struct bcm2835_audio_instance *instance; - struct vc_audio_msg m; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - my_workqueue_init(alsa_stream); - - ret = bcm2835_audio_open_connection(alsa_stream); - if (ret) { - ret = -1; - goto exit; - } - instance = alsa_stream->instance; - LOG_DBG(" instance (%p)\n", instance); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_OPEN; - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); -exit: - LOG_DBG(" .. OUT\n"); - return ret; -} - -static int bcm2835_audio_set_ctls_chan(struct bcm2835_alsa_stream *alsa_stream, - struct bcm2835_chip *chip) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - LOG_INFO(" Setting ALSA dest(%d), volume(%d)\n", - chip->dest, chip->volume); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - instance->result = -1; - - m.type = VC_AUDIO_MSG_TYPE_CONTROL; - m.u.control.dest = chip->dest; - m.u.control.volume = chip->volume; - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - - /* We are expecting a reply from the videocore */ - wait_for_completion(&instance->msg_avail_comp); - - if (instance->result) { - LOG_ERR("%s: result=%d\n", __func__, instance->result); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - - LOG_DBG(" .. OUT\n"); - return ret; -} - -int bcm2835_audio_set_ctls(struct bcm2835_chip *chip) -{ - int i; - int ret = 0; - - LOG_DBG(" .. IN\n"); - LOG_DBG(" Setting ALSA dest(%d), volume(%d)\n", chip->dest, chip->volume); - - /* change ctls for all substreams */ - for (i = 0; i < MAX_SUBSTREAMS; i++) { - if (chip->avail_substreams & (1 << i)) { - if (!chip->alsa_stream[i]) { - LOG_DBG(" No ALSA stream available?! %i:%p (%x)\n", i, chip->alsa_stream[i], chip->avail_substreams); - ret = 0; - } else if (bcm2835_audio_set_ctls_chan(chip->alsa_stream[i], chip) != 0) { - LOG_ERR("Couldn't set the controls for stream %d\n", i); - ret = -1; - } else { - LOG_DBG(" Controls set for stream %d\n", i); - } - } - } - LOG_DBG(" .. OUT ret=%d\n", ret); - return ret; -} - -int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, - unsigned int channels, unsigned int samplerate, - unsigned int bps) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - LOG_INFO(" Setting ALSA channels(%d), samplerate(%d), bits-per-sample(%d)\n", - channels, samplerate, bps); - - /* resend ctls - alsa_stream may not have been open when first send */ - ret = bcm2835_audio_set_ctls_chan(alsa_stream, alsa_stream->chip); - if (ret) { - LOG_ERR(" Alsa controls not supported\n"); - return -EINVAL; - } - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - instance->result = -1; - - m.type = VC_AUDIO_MSG_TYPE_CONFIG; - m.u.config.channels = channels; - m.u.config.samplerate = samplerate; - m.u.config.bps = bps; - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - - /* We are expecting a reply from the videocore */ - wait_for_completion(&instance->msg_avail_comp); - - if (instance->result) { - LOG_ERR("%s: result=%d", __func__, instance->result); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - - LOG_DBG(" .. OUT\n"); - return ret; -} - -int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream) -{ - LOG_DBG(" .. IN\n"); - - LOG_DBG(" .. OUT\n"); - - return 0; -} - -static int bcm2835_audio_start_worker(struct bcm2835_alsa_stream *alsa_stream) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_START; - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - LOG_DBG(" .. OUT\n"); - return ret; -} - -static int bcm2835_audio_stop_worker(struct bcm2835_alsa_stream *alsa_stream) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_STOP; - m.u.stop.draining = alsa_stream->draining; - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - LOG_DBG(" .. OUT\n"); - return ret; -} - -int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - my_workqueue_quit(alsa_stream); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - m.type = VC_AUDIO_MSG_TYPE_CLOSE; - - /* Create the message available completion */ - init_completion(&instance->msg_avail_comp); - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - ret = -1; - goto unlock; - } - - /* We are expecting a reply from the videocore */ - wait_for_completion(&instance->msg_avail_comp); - - if (instance->result) { - LOG_ERR("%s: failed result (result=%d)\n", - __func__, instance->result); - - ret = -1; - goto unlock; - } - - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - - /* Stop the audio service */ - vc_vchi_audio_deinit(instance); - alsa_stream->instance = NULL; - - LOG_DBG(" .. OUT\n"); - return ret; -} - -static int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, void *src) -{ - struct vc_audio_msg m; - struct bcm2835_audio_instance *instance = alsa_stream->instance; - int status; - int ret; - - LOG_DBG(" .. IN\n"); - - LOG_INFO(" Writing %d bytes from %p\n", count, src); - - if (mutex_lock_interruptible(&instance->vchi_mutex)) { - LOG_DBG("Interrupted whilst waiting for lock on (%d)\n", - instance->num_connections); - return -EINTR; - } - vchi_service_use(instance->vchi_handle[0]); - - if (instance->peer_version == 0 && vchi_get_peer_version(instance->vchi_handle[0], &instance->peer_version) == 0) { - LOG_DBG("%s: client version %d connected\n", __func__, instance->peer_version); - } - m.type = VC_AUDIO_MSG_TYPE_WRITE; - m.u.write.count = count; - // old version uses bulk, new version uses control - m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000; - m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1; - m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2; - m.u.write.silence = src == NULL; - - /* Send the message to the videocore */ - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - &m, sizeof(m)); - - if (status) { - LOG_ERR("%s: failed on vchi_msg_queue (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - if (!m.u.write.silence) { - if (!m.u.write.max_packet) { - /* Send the message to the videocore */ - status = vchi_bulk_queue_transmit(instance->vchi_handle[0], - src, count, - 0 * - VCHI_FLAGS_BLOCK_UNTIL_QUEUED - + - 1 * - VCHI_FLAGS_BLOCK_UNTIL_DATA_READ, - NULL); - } else { - while (count > 0) { - int bytes = min((int) m.u.write.max_packet, (int) count); - - status = bcm2835_vchi_msg_queue(instance->vchi_handle[0], - src, bytes); - src = (char *)src + bytes; - count -= bytes; - } - } - if (status) { - LOG_ERR("%s: failed on vchi_bulk_queue_transmit (status=%d)\n", - __func__, status); - - ret = -1; - goto unlock; - } - } - ret = 0; - -unlock: - vchi_service_release(instance->vchi_handle[0]); - mutex_unlock(&instance->vchi_mutex); - LOG_DBG(" .. OUT\n"); - return ret; -} - -/** - * Returns all buffers from arm->vc - */ -void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream) -{ - LOG_DBG(" .. IN\n"); - LOG_DBG(" .. OUT\n"); - return; -} - -/** - * Forces VC to flush(drop) its filled playback buffers and - * return them the us. (VC->ARM) - */ -void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream) -{ - LOG_DBG(" .. IN\n"); - LOG_DBG(" .. OUT\n"); -} - -unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream) -{ - unsigned int count = atomic_read(&alsa_stream->retrieved); - - atomic_sub(count, &alsa_stream->retrieved); - return count; -} - -module_param(force_bulk, bool, 0444); -MODULE_PARM_DESC(force_bulk, "Force use of vchiq bulk for audio"); diff --git a/drivers/staging/bcm2835-audio/bcm2835.c b/drivers/staging/bcm2835-audio/bcm2835.c deleted file mode 100644 index 3a5e528..0000000 --- a/drivers/staging/bcm2835-audio/bcm2835.c +++ /dev/null @@ -1,250 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#include <linux/platform_device.h> - -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/of.h> - -#include "bcm2835.h" - -/* HACKY global pointers needed for successive probes to work : ssp - * But compared against the changes we will have to do in VC audio_ipc code - * to export 8 audio_ipc devices as a single IPC device and then monitor all - * four devices in a thread, this gets things done quickly and should be easier - * to debug if we run into issues - */ - -static struct snd_card *g_card; -static struct bcm2835_chip *g_chip; - -static int snd_bcm2835_free(struct bcm2835_chip *chip) -{ - kfree(chip); - return 0; -} - -/* component-destructor - * (see "Management of Cards and Components") - */ -static int snd_bcm2835_dev_free(struct snd_device *device) -{ - return snd_bcm2835_free(device->device_data); -} - -/* chip-specific constructor - * (see "Management of Cards and Components") - */ -static int snd_bcm2835_create(struct snd_card *card, - struct platform_device *pdev, - struct bcm2835_chip **rchip) -{ - struct bcm2835_chip *chip; - int err; - static struct snd_device_ops ops = { - .dev_free = snd_bcm2835_dev_free, - }; - - *rchip = NULL; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - - chip->card = card; - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - snd_bcm2835_free(chip); - return err; - } - - *rchip = chip; - return 0; -} - -static int snd_bcm2835_alsa_probe_dt(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct bcm2835_chip *chip; - struct snd_card *card; - u32 numchans; - int err, i; - - err = of_property_read_u32(dev->of_node, "brcm,pwm-channels", - &numchans); - if (err) { - dev_err(dev, "Failed to get DT property 'brcm,pwm-channels'"); - return err; - } - - if (numchans == 0 || numchans > MAX_SUBSTREAMS) { - numchans = MAX_SUBSTREAMS; - dev_warn(dev, "Illegal 'brcm,pwm-channels' value, will use %u\n", - numchans); - } - - err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); - if (err) { - dev_err(dev, "Failed to create soundcard structure\n"); - return err; - } - - snd_card_set_dev(card, dev); - strcpy(card->driver, "bcm2835"); - strcpy(card->shortname, "bcm2835 ALSA"); - sprintf(card->longname, "%s", card->shortname); - - err = snd_bcm2835_create(card, pdev, &chip); - if (err < 0) { - dev_err(dev, "Failed to create bcm2835 chip\n"); - goto err_free; - } - - err = snd_bcm2835_new_pcm(chip); - if (err < 0) { - dev_err(dev, "Failed to create new bcm2835 pcm device\n"); - goto err_free; - } - - err = snd_bcm2835_new_spdif_pcm(chip); - if (err < 0) { - dev_err(dev, "Failed to create new bcm2835 spdif pcm device\n"); - goto err_free; - } - - err = snd_bcm2835_new_ctl(chip); - if (err < 0) { - dev_err(dev, "Failed to create new bcm2835 ctl\n"); - goto err_free; - } - - for (i = 0; i < numchans; i++) { - chip->avail_substreams |= (1 << i); - chip->pdev[i] = pdev; - } - - err = snd_card_register(card); - if (err) { - dev_err(dev, "Failed to register bcm2835 ALSA card\n"); - goto err_free; - } - - g_card = card; - g_chip = chip; - platform_set_drvdata(pdev, card); - audio_info("bcm2835 ALSA card created with %u channels\n", numchans); - - return 0; - -err_free: - snd_card_free(card); - - return err; -} - -static int snd_bcm2835_alsa_remove(struct platform_device *pdev) -{ - int idx; - void *drv_data; - - drv_data = platform_get_drvdata(pdev); - - if (drv_data == (void *)g_card) { - /* This is the card device */ - snd_card_free((struct snd_card *)drv_data); - g_card = NULL; - g_chip = NULL; - } else { - idx = (int)(long)drv_data; - if (g_card) { - BUG_ON(!g_chip); - /* We pass chip device numbers in audio ipc devices - * other than the one we registered our card with - */ - idx = (int)(long)drv_data; - BUG_ON(!idx || idx > MAX_SUBSTREAMS); - g_chip->avail_substreams &= ~(1 << idx); - /* There should be atleast one substream registered - * after we are done here, as it wil be removed when - * the *remove* is called for the card device - */ - BUG_ON(!g_chip->avail_substreams); - } - } - - platform_set_drvdata(pdev, NULL); - - return 0; -} - -#ifdef CONFIG_PM - -static int snd_bcm2835_alsa_suspend(struct platform_device *pdev, - pm_message_t state) -{ - return 0; -} - -static int snd_bcm2835_alsa_resume(struct platform_device *pdev) -{ - return 0; -} - -#endif - -static const struct of_device_id snd_bcm2835_of_match_table[] = { - { .compatible = "brcm,bcm2835-audio",}, - {}, -}; -MODULE_DEVICE_TABLE(of, snd_bcm2835_of_match_table); - -static struct platform_driver bcm2835_alsa0_driver = { - .probe = snd_bcm2835_alsa_probe_dt, - .remove = snd_bcm2835_alsa_remove, -#ifdef CONFIG_PM - .suspend = snd_bcm2835_alsa_suspend, - .resume = snd_bcm2835_alsa_resume, -#endif - .driver = { - .name = "bcm2835_AUD0", - .owner = THIS_MODULE, - .of_match_table = snd_bcm2835_of_match_table, - }, -}; - -static int bcm2835_alsa_device_init(void) -{ - int retval; - - retval = platform_driver_register(&bcm2835_alsa0_driver); - if (retval) - pr_err("Error registering bcm2835_alsa0_driver %d .\n", retval); - - return retval; -} - -static void bcm2835_alsa_device_exit(void) -{ - platform_driver_unregister(&bcm2835_alsa0_driver); -} - -late_initcall(bcm2835_alsa_device_init); -module_exit(bcm2835_alsa_device_exit); - -MODULE_AUTHOR("Dom Cobley"); -MODULE_DESCRIPTION("Alsa driver for BCM2835 chip"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/bcm2835-audio/bcm2835.h b/drivers/staging/bcm2835-audio/bcm2835.h deleted file mode 100644 index 36e3ef8..0000000 --- a/drivers/staging/bcm2835-audio/bcm2835.h +++ /dev/null @@ -1,167 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#ifndef __SOUND_ARM_BCM2835_H -#define __SOUND_ARM_BCM2835_H - -#include <linux/device.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/wait.h> -#include <sound/core.h> -#include <sound/initval.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/pcm-indirect.h> -#include <linux/workqueue.h> - -/* -#define AUDIO_DEBUG_ENABLE -#define AUDIO_VERBOSE_DEBUG_ENABLE - */ - -/* Debug macros */ - -#ifdef AUDIO_DEBUG_ENABLE -#ifdef AUDIO_VERBOSE_DEBUG_ENABLE - -#define audio_debug(fmt, arg...) \ - printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) - -#define audio_info(fmt, arg...) \ - printk(KERN_INFO"%s:%d " fmt, __func__, __LINE__, ##arg) - -#else - -#define audio_debug(fmt, arg...) - -#define audio_info(fmt, arg...) - -#endif /* AUDIO_VERBOSE_DEBUG_ENABLE */ - -#else - -#define audio_debug(fmt, arg...) - -#define audio_info(fmt, arg...) - -#endif /* AUDIO_DEBUG_ENABLE */ - -#define audio_error(fmt, arg...) \ - printk(KERN_ERR"%s:%d " fmt, __func__, __LINE__, ##arg) - -#define audio_warning(fmt, arg...) \ - printk(KERN_WARNING"%s:%d " fmt, __func__, __LINE__, ##arg) - -#define audio_alert(fmt, arg...) \ - printk(KERN_ALERT"%s:%d " fmt, __func__, __LINE__, ##arg) - -#define MAX_SUBSTREAMS (8) -#define AVAIL_SUBSTREAMS_MASK (0xff) - -enum { - CTRL_VOL_MUTE, - CTRL_VOL_UNMUTE -}; - -/* macros for alsa2chip and chip2alsa, instead of functions */ - -#define alsa2chip(vol) (uint)(-((vol << 8) / 100)) /* convert alsa to chip volume (defined as macro rather than function call) */ -#define chip2alsa(vol) -((vol * 100) >> 8) /* convert chip to alsa volume */ - -/* Some constants for values .. */ -enum snd_bcm2835_route { - AUDIO_DEST_AUTO = 0, - AUDIO_DEST_HEADPHONES = 1, - AUDIO_DEST_HDMI = 2, - AUDIO_DEST_MAX, -}; - -enum snd_bcm2835_ctrl { - PCM_PLAYBACK_VOLUME, - PCM_PLAYBACK_MUTE, - PCM_PLAYBACK_DEVICE, -}; - -/* definition of the chip-specific record */ -struct bcm2835_chip { - struct snd_card *card; - struct snd_pcm *pcm; - struct snd_pcm *pcm_spdif; - /* Bitmat for valid reg_base and irq numbers */ - unsigned int avail_substreams; - struct platform_device *pdev[MAX_SUBSTREAMS]; - struct bcm2835_alsa_stream *alsa_stream[MAX_SUBSTREAMS]; - - int volume; - int old_volume; /* stores the volume value whist muted */ - int dest; - int mute; - - unsigned int opened; - unsigned int spdif_status; - struct mutex audio_mutex; -}; - -struct bcm2835_alsa_stream { - struct bcm2835_chip *chip; - struct snd_pcm_substream *substream; - struct snd_pcm_indirect pcm_indirect; - - struct semaphore buffers_update_sem; - struct semaphore control_sem; - spinlock_t lock; - volatile unsigned int control; - volatile unsigned int status; - - int open; - int running; - int draining; - - int channels; - int params_rate; - int pcm_format_width; - - unsigned int pos; - unsigned int buffer_size; - unsigned int period_size; - - atomic_t retrieved; - struct bcm2835_audio_instance *instance; - struct workqueue_struct *my_wq; - int idx; -}; - -int snd_bcm2835_new_ctl(struct bcm2835_chip *chip); -int snd_bcm2835_new_pcm(struct bcm2835_chip *chip); -int snd_bcm2835_new_spdif_pcm(struct bcm2835_chip *chip); - -int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream); -int bcm2835_audio_close(struct bcm2835_alsa_stream *alsa_stream); -int bcm2835_audio_set_params(struct bcm2835_alsa_stream *alsa_stream, - unsigned int channels, unsigned int samplerate, - unsigned int bps); -int bcm2835_audio_setup(struct bcm2835_alsa_stream *alsa_stream); -int bcm2835_audio_start(struct bcm2835_alsa_stream *alsa_stream); -int bcm2835_audio_stop(struct bcm2835_alsa_stream *alsa_stream); -int bcm2835_audio_set_ctls(struct bcm2835_chip *chip); -int bcm2835_audio_write(struct bcm2835_alsa_stream *alsa_stream, - unsigned int count, - void *src); -void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream); -unsigned int bcm2835_audio_retrieve_buffers(struct bcm2835_alsa_stream *alsa_stream); -void bcm2835_audio_flush_buffers(struct bcm2835_alsa_stream *alsa_stream); -void bcm2835_audio_flush_playback_buffers(struct bcm2835_alsa_stream *alsa_stream); - -#endif /* __SOUND_ARM_BCM2835_H */ diff --git a/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h b/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h deleted file mode 100644 index da96f1b..0000000 --- a/drivers/staging/bcm2835-audio/vc_vchi_audioserv_defs.h +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************** - * Copyright 2011 Broadcom Corporation. All rights reserved. - * - * Unless you and Broadcom execute a separate written software license - * agreement governing use of this software, this software is licensed to you - * under the terms of the GNU General Public License version 2, available at - * http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). - * - * Notwithstanding the above, under no circumstances may you combine this - * software in any way with any other Broadcom software provided under a - * license other than the GPL, without Broadcom's express prior written - * consent. - *****************************************************************************/ - -#ifndef _VC_AUDIO_DEFS_H_ -#define _VC_AUDIO_DEFS_H_ - -#define VC_AUDIOSERV_MIN_VER 1 -#define VC_AUDIOSERV_VER 2 - -/* FourCC code used for VCHI connection */ -#define VC_AUDIO_SERVER_NAME MAKE_FOURCC("AUDS") - -/* - * List of screens that are currently supported - * All message types supported for HOST->VC direction - */ - -enum vc_audio_msg_type { - VC_AUDIO_MSG_TYPE_RESULT, // Generic result - VC_AUDIO_MSG_TYPE_COMPLETE, // Generic result - VC_AUDIO_MSG_TYPE_CONFIG, // Configure audio - VC_AUDIO_MSG_TYPE_CONTROL, // Configure audio - VC_AUDIO_MSG_TYPE_OPEN, // Configure audio - VC_AUDIO_MSG_TYPE_CLOSE, // Configure audio - VC_AUDIO_MSG_TYPE_START, // Configure audio - VC_AUDIO_MSG_TYPE_STOP, // Configure audio - VC_AUDIO_MSG_TYPE_WRITE, // Configure audio - VC_AUDIO_MSG_TYPE_MAX -}; - -/* configure the audio */ - -struct vc_audio_config { - u32 channels; - u32 samplerate; - u32 bps; -}; - -struct vc_audio_control { - u32 volume; - u32 dest; -}; - -struct vc_audio_open { - u32 dummy; -}; - -struct vc_audio_close { - u32 dummy; -}; - -struct vc_audio_start { - u32 dummy; -}; - -struct vc_audio_stop { - u32 draining; -}; - -/* configure the write audio samples */ -struct vc_audio_write { - u32 count; // in bytes - u32 cookie1; - u32 cookie2; - s16 silence; - s16 max_packet; -}; - -/* Generic result for a request (VC->HOST) */ -struct vc_audio_result { - s32 success; // Success value -}; - -/* Generic result for a request (VC->HOST) */ -struct vc_audio_complete { - s32 count; // Success value - u32 cookie1; - u32 cookie2; -}; - -/* Message header for all messages in HOST->VC direction */ -struct vc_audio_msg { - s32 type; /* Message type (VC_AUDIO_MSG_TYPE) */ - union { - struct vc_audio_config config; - struct vc_audio_control control; - struct vc_audio_open open; - struct vc_audio_close close; - struct vc_audio_start start; - struct vc_audio_stop stop; - struct vc_audio_write write; - struct vc_audio_result result; - struct vc_audio_complete complete; - } u; -}; - -#endif /* _VC_AUDIO_DEFS_H_ */ |