diff options
Diffstat (limited to 'sound')
486 files changed, 15227 insertions, 17115 deletions
diff --git a/sound/aoa/codecs/Kconfig b/sound/aoa/codecs/Kconfig index 808eb11ebac..0c68e32834c 100644 --- a/sound/aoa/codecs/Kconfig +++ b/sound/aoa/codecs/Kconfig @@ -7,14 +7,6 @@ config SND_AOA_ONYX codec chip found in the latest Apple machines (most of those with digital audio output). -#config SND_AOA_TOPAZ -# tristate "support Topaz chips" -# ---help--- -# This option enables support for the Topaz (CS84xx) -# codec chips found in the latest Apple machines, -# these chips do the digital input and output on -# some PowerMacs. - config SND_AOA_TAS tristate "support TAS chips" select I2C diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index e518d38b1c7..b37b702a3a6 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c @@ -1097,6 +1097,8 @@ static struct amba_id aaci_ids[] = { { 0, 0 }, }; +MODULE_DEVICE_TABLE(amba, aaci_ids); + static struct amba_driver aaci_driver = { .drv = { .name = DRIVER_NAME, diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 5d9411839cd..3a39626a82d 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -251,18 +251,7 @@ static struct platform_driver pxa2xx_ac97_driver = { }, }; -static int __init pxa2xx_ac97_init(void) -{ - return platform_driver_register(&pxa2xx_ac97_driver); -} - -static void __exit pxa2xx_ac97_exit(void) -{ - platform_driver_unregister(&pxa2xx_ac97_driver); -} - -module_init(pxa2xx_ac97_init); -module_exit(pxa2xx_ac97_exit); +module_platform_driver(pxa2xx_ac97_driver); MODULE_AUTHOR("Nicolas Pitre"); MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 6e5addeb236..73516f69ac7 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -899,6 +899,10 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip) /* AC97 v2.2 specifications says minimum 1 us. */ udelay(2); gpio_set_value(chip->reset_pin, 1); + } else { + ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA); + udelay(2); + ac97c_writel(chip, MR, AC97C_MR_ENA); } } diff --git a/sound/core/Kconfig b/sound/core/Kconfig index 475455c7661..ad409381f8c 100644 --- a/sound/core/Kconfig +++ b/sound/core/Kconfig @@ -5,7 +5,6 @@ config SND_TIMER config SND_PCM tristate select SND_TIMER - select GCD config SND_HWDEP tristate @@ -155,6 +154,16 @@ config SND_DYNAMIC_MINORS If you are unsure about this, say N here. +config SND_COMPRESS_OFFLOAD + tristate "ALSA Compressed audio offload support" + default n + help + If you want support for offloading compressed audio and have such + a hardware, then you should say Y here and also to the DSP driver + of your platform. + + If you are unsure about this, say N here. + config SND_SUPPORT_OLD_API bool "Support old ALSA API" default y @@ -207,6 +216,9 @@ config SND_PCM_XRUN_DEBUG config SND_VMASTER bool +config SND_KCTL_JACK + bool + config SND_DMA_SGBUF def_bool y depends on X86 diff --git a/sound/core/Makefile b/sound/core/Makefile index 350a08d277f..43d4117428a 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile @@ -7,6 +7,7 @@ snd-y := sound.o init.o memory.o info.o control.o misc.o device.o snd-$(CONFIG_ISA_DMA_API) += isadma.o snd-$(CONFIG_SND_OSSEMUL) += sound_oss.o info_oss.o snd-$(CONFIG_SND_VMASTER) += vmaster.o +snd-$(CONFIG_SND_KCTL_JACK) += ctljack.o snd-$(CONFIG_SND_JACK) += jack.o snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \ @@ -21,6 +22,8 @@ snd-hrtimer-objs := hrtimer.o snd-rtctimer-objs := rtctimer.o snd-hwdep-objs := hwdep.o +snd-compress-objs := compress_offload.o + obj-$(CONFIG_SND) += snd.o obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o obj-$(CONFIG_SND_TIMER) += snd-timer.o @@ -31,3 +34,5 @@ obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o obj-$(CONFIG_SND_OSSEMUL) += oss/ obj-$(CONFIG_SND_SEQUENCER) += seq/ + +obj-$(CONFIG_SND_COMPRESS_OFFLOAD) += snd-compress.o diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c new file mode 100644 index 00000000000..dac3633507c --- /dev/null +++ b/sound/core/compress_offload.c @@ -0,0 +1,765 @@ +/* + * compress_core.c - compress offload core + * + * Copyright (C) 2011 Intel Corporation + * Authors: Vinod Koul <vinod.koul@linux.intel.com> + * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + */ +#define FORMAT(fmt) "%s: %d: " fmt, __func__, __LINE__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " FORMAT(fmt) + +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/list.h> +#include <linux/mm.h> +#include <linux/mutex.h> +#include <linux/poll.h> +#include <linux/slab.h> +#include <linux/sched.h> +#include <linux/uio.h> +#include <linux/uaccess.h> +#include <linux/module.h> +#include <sound/core.h> +#include <sound/initval.h> +#include <sound/compress_params.h> +#include <sound/compress_offload.h> +#include <sound/compress_driver.h> + +/* TODO: + * - add substream support for multiple devices in case of + * SND_DYNAMIC_MINORS is not used + * - Multiple node representation + * driver should be able to register multiple nodes + */ + +static DEFINE_MUTEX(device_mutex); + +struct snd_compr_file { + unsigned long caps; + struct snd_compr_stream stream; +}; + +/* + * a note on stream states used: + * we use follwing states in the compressed core + * SNDRV_PCM_STATE_OPEN: When stream has been opened. + * SNDRV_PCM_STATE_SETUP: When stream has been initialized. This is done by + * calling SNDRV_COMPRESS_SET_PARAMS. running streams will come to this + * state at stop by calling SNDRV_COMPRESS_STOP, or at end of drain. + * SNDRV_PCM_STATE_RUNNING: When stream has been started and is + * decoding/encoding and rendering/capturing data. + * SNDRV_PCM_STATE_DRAINING: When stream is draining current data. This is done + * by calling SNDRV_COMPRESS_DRAIN. + * SNDRV_PCM_STATE_PAUSED: When stream is paused. This is done by calling + * SNDRV_COMPRESS_PAUSE. It can be stopped or resumed by calling + * SNDRV_COMPRESS_STOP or SNDRV_COMPRESS_RESUME respectively. + */ +static int snd_compr_open(struct inode *inode, struct file *f) +{ + struct snd_compr *compr; + struct snd_compr_file *data; + struct snd_compr_runtime *runtime; + enum snd_compr_direction dirn; + int maj = imajor(inode); + int ret; + + if (f->f_flags & O_WRONLY) + dirn = SND_COMPRESS_PLAYBACK; + else if (f->f_flags & O_RDONLY) + dirn = SND_COMPRESS_CAPTURE; + else { + pr_err("invalid direction\n"); + return -EINVAL; + } + + if (maj == snd_major) + compr = snd_lookup_minor_data(iminor(inode), + SNDRV_DEVICE_TYPE_COMPRESS); + else + return -EBADFD; + + if (compr == NULL) { + pr_err("no device data!!!\n"); + return -ENODEV; + } + + if (dirn != compr->direction) { + pr_err("this device doesn't support this direction\n"); + return -EINVAL; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + data->stream.ops = compr->ops; + data->stream.direction = dirn; + data->stream.private_data = compr->private_data; + data->stream.device = compr; + runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + if (!runtime) { + kfree(data); + return -ENOMEM; + } + runtime->state = SNDRV_PCM_STATE_OPEN; + init_waitqueue_head(&runtime->sleep); + data->stream.runtime = runtime; + f->private_data = (void *)data; + mutex_lock(&compr->lock); + ret = compr->ops->open(&data->stream); + mutex_unlock(&compr->lock); + if (ret) { + kfree(runtime); + kfree(data); + } + return ret; +} + +static int snd_compr_free(struct inode *inode, struct file *f) +{ + struct snd_compr_file *data = f->private_data; + data->stream.ops->free(&data->stream); + kfree(data->stream.runtime->buffer); + kfree(data->stream.runtime); + kfree(data); + return 0; +} + +static void snd_compr_update_tstamp(struct snd_compr_stream *stream, + struct snd_compr_tstamp *tstamp) +{ + if (!stream->ops->pointer) + return; + stream->ops->pointer(stream, tstamp); + pr_debug("dsp consumed till %d total %d bytes\n", + tstamp->byte_offset, tstamp->copied_total); + stream->runtime->hw_pointer = tstamp->byte_offset; + stream->runtime->total_bytes_transferred = tstamp->copied_total; +} + +static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, + struct snd_compr_avail *avail) +{ + long avail_calc; /*this needs to be signed variable */ + + snd_compr_update_tstamp(stream, &avail->tstamp); + + /* FIXME: This needs to be different for capture stream, + available is # of compressed data, for playback it's + remainder of buffer */ + + if (stream->runtime->total_bytes_available == 0 && + stream->runtime->state == SNDRV_PCM_STATE_SETUP) { + pr_debug("detected init and someone forgot to do a write\n"); + return stream->runtime->buffer_size; + } + pr_debug("app wrote %lld, DSP consumed %lld\n", + stream->runtime->total_bytes_available, + stream->runtime->total_bytes_transferred); + if (stream->runtime->total_bytes_available == + stream->runtime->total_bytes_transferred) { + pr_debug("both pointers are same, returning full avail\n"); + return stream->runtime->buffer_size; + } + + /* FIXME: this routine isn't consistent, in one test we use + * cumulative values and in the other byte offsets. Do we + * really need the byte offsets if the cumulative values have + * been updated? In the PCM interface app_ptr and hw_ptr are + * already cumulative */ + + avail_calc = stream->runtime->buffer_size - + (stream->runtime->app_pointer - stream->runtime->hw_pointer); + pr_debug("calc avail as %ld, app_ptr %lld, hw+ptr %lld\n", avail_calc, + stream->runtime->app_pointer, + stream->runtime->hw_pointer); + if (avail_calc >= stream->runtime->buffer_size) + avail_calc -= stream->runtime->buffer_size; + pr_debug("ret avail as %ld\n", avail_calc); + avail->avail = avail_calc; + return avail_calc; +} + +static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) +{ + struct snd_compr_avail avail; + + return snd_compr_calc_avail(stream, &avail); +} + +static int +snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg) +{ + struct snd_compr_avail ioctl_avail; + size_t avail; + + avail = snd_compr_calc_avail(stream, &ioctl_avail); + ioctl_avail.avail = avail; + + if (copy_to_user((__u64 __user *)arg, + &ioctl_avail, sizeof(ioctl_avail))) + return -EFAULT; + return 0; +} + +static int snd_compr_write_data(struct snd_compr_stream *stream, + const char __user *buf, size_t count) +{ + void *dstn; + size_t copy; + struct snd_compr_runtime *runtime = stream->runtime; + + dstn = runtime->buffer + runtime->app_pointer; + pr_debug("copying %ld at %lld\n", + (unsigned long)count, runtime->app_pointer); + if (count < runtime->buffer_size - runtime->app_pointer) { + if (copy_from_user(dstn, buf, count)) + return -EFAULT; + runtime->app_pointer += count; + } else { + copy = runtime->buffer_size - runtime->app_pointer; + if (copy_from_user(dstn, buf, copy)) + return -EFAULT; + if (copy_from_user(runtime->buffer, buf + copy, count - copy)) + return -EFAULT; + runtime->app_pointer = count - copy; + } + /* if DSP cares, let it know data has been written */ + if (stream->ops->ack) + stream->ops->ack(stream, count); + return count; +} + +static ssize_t snd_compr_write(struct file *f, const char __user *buf, + size_t count, loff_t *offset) +{ + struct snd_compr_file *data = f->private_data; + struct snd_compr_stream *stream; + size_t avail; + int retval; + + if (snd_BUG_ON(!data)) + return -EFAULT; + + stream = &data->stream; + mutex_lock(&stream->device->lock); + /* write is allowed when stream is running or has been steup */ + if (stream->runtime->state != SNDRV_PCM_STATE_SETUP && + stream->runtime->state != SNDRV_PCM_STATE_RUNNING) { + mutex_unlock(&stream->device->lock); + return -EBADFD; + } + + avail = snd_compr_get_avail(stream); + pr_debug("avail returned %ld\n", (unsigned long)avail); + /* calculate how much we can write to buffer */ + if (avail > count) + avail = count; + + if (stream->ops->copy) + retval = stream->ops->copy(stream, buf, avail); + else + retval = snd_compr_write_data(stream, buf, avail); + if (retval > 0) + stream->runtime->total_bytes_available += retval; + + /* while initiating the stream, write should be called before START + * call, so in setup move state */ + if (stream->runtime->state == SNDRV_PCM_STATE_SETUP) { + stream->runtime->state = SNDRV_PCM_STATE_PREPARED; + pr_debug("stream prepared, Houston we are good to go\n"); + } + + mutex_unlock(&stream->device->lock); + return retval; +} + + +static ssize_t snd_compr_read(struct file *f, char __user *buf, + size_t count, loff_t *offset) +{ + return -ENXIO; +} + +static int snd_compr_mmap(struct file *f, struct vm_area_struct *vma) +{ + return -ENXIO; +} + +static inline int snd_compr_get_poll(struct snd_compr_stream *stream) +{ + if (stream->direction == SND_COMPRESS_PLAYBACK) + return POLLOUT | POLLWRNORM; + else + return POLLIN | POLLRDNORM; +} + +static unsigned int snd_compr_poll(struct file *f, poll_table *wait) +{ + struct snd_compr_file *data = f->private_data; + struct snd_compr_stream *stream; + size_t avail; + int retval = 0; + + if (snd_BUG_ON(!data)) + return -EFAULT; + stream = &data->stream; + if (snd_BUG_ON(!stream)) + return -EFAULT; + + mutex_lock(&stream->device->lock); + if (stream->runtime->state == SNDRV_PCM_STATE_PAUSED || + stream->runtime->state == SNDRV_PCM_STATE_OPEN) { + retval = -EBADFD; + goto out; + } + poll_wait(f, &stream->runtime->sleep, wait); + + avail = snd_compr_get_avail(stream); + pr_debug("avail is %ld\n", (unsigned long)avail); + /* check if we have at least one fragment to fill */ + switch (stream->runtime->state) { + case SNDRV_PCM_STATE_DRAINING: + /* stream has been woken up after drain is complete + * draining done so set stream state to stopped + */ + retval = snd_compr_get_poll(stream); + stream->runtime->state = SNDRV_PCM_STATE_SETUP; + break; + case SNDRV_PCM_STATE_RUNNING: + case SNDRV_PCM_STATE_PREPARED: + case SNDRV_PCM_STATE_PAUSED: + if (avail >= stream->runtime->fragment_size) + retval = snd_compr_get_poll(stream); + break; + default: + if (stream->direction == SND_COMPRESS_PLAYBACK) + retval = POLLOUT | POLLWRNORM | POLLERR; + else + retval = POLLIN | POLLRDNORM | POLLERR; + break; + } +out: + mutex_unlock(&stream->device->lock); + return retval; +} + +static int +snd_compr_get_caps(struct snd_compr_stream *stream, unsigned long arg) +{ + int retval; + struct snd_compr_caps caps; + + if (!stream->ops->get_caps) + return -ENXIO; + + retval = stream->ops->get_caps(stream, &caps); + if (retval) + goto out; + if (copy_to_user((void __user *)arg, &caps, sizeof(caps))) + retval = -EFAULT; +out: + return retval; +} + +static int +snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) +{ + int retval; + struct snd_compr_codec_caps *caps; + + if (!stream->ops->get_codec_caps) + return -ENXIO; + + caps = kmalloc(sizeof(*caps), GFP_KERNEL); + if (!caps) + return -ENOMEM; + + retval = stream->ops->get_codec_caps(stream, caps); + if (retval) + goto out; + if (copy_to_user((void __user *)arg, caps, sizeof(*caps))) + retval = -EFAULT; + +out: + kfree(caps); + return retval; +} + +/* revisit this with snd_pcm_preallocate_xxx */ +static int snd_compr_allocate_buffer(struct snd_compr_stream *stream, + struct snd_compr_params *params) +{ + unsigned int buffer_size; + void *buffer; + + buffer_size = params->buffer.fragment_size * params->buffer.fragments; + if (stream->ops->copy) { + buffer = NULL; + /* if copy is defined the driver will be required to copy + * the data from core + */ + } else { + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + } + stream->runtime->fragment_size = params->buffer.fragment_size; + stream->runtime->fragments = params->buffer.fragments; + stream->runtime->buffer = buffer; + stream->runtime->buffer_size = buffer_size; + return 0; +} + +static int +snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) +{ + struct snd_compr_params *params; + int retval; + + if (stream->runtime->state == SNDRV_PCM_STATE_OPEN) { + /* + * we should allow parameter change only when stream has been + * opened not in other cases + */ + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) + return -ENOMEM; + if (copy_from_user(params, (void __user *)arg, sizeof(*params))) + return -EFAULT; + retval = snd_compr_allocate_buffer(stream, params); + if (retval) { + kfree(params); + return -ENOMEM; + } + retval = stream->ops->set_params(stream, params); + if (retval) + goto out; + stream->runtime->state = SNDRV_PCM_STATE_SETUP; + } else + return -EPERM; +out: + kfree(params); + return retval; +} + +static int +snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) +{ + struct snd_codec *params; + int retval; + + if (!stream->ops->get_params) + return -EBADFD; + + params = kmalloc(sizeof(*params), GFP_KERNEL); + if (!params) + return -ENOMEM; + retval = stream->ops->get_params(stream, params); + if (retval) + goto out; + if (copy_to_user((char __user *)arg, params, sizeof(*params))) + retval = -EFAULT; + +out: + kfree(params); + return retval; +} + +static inline int +snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) +{ + struct snd_compr_tstamp tstamp; + + snd_compr_update_tstamp(stream, &tstamp); + return copy_to_user((struct snd_compr_tstamp __user *)arg, + &tstamp, sizeof(tstamp)) ? -EFAULT : 0; +} + +static int snd_compr_pause(struct snd_compr_stream *stream) +{ + int retval; + + if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) + return -EPERM; + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); + if (!retval) { + stream->runtime->state = SNDRV_PCM_STATE_PAUSED; + wake_up(&stream->runtime->sleep); + } + return retval; +} + +static int snd_compr_resume(struct snd_compr_stream *stream) +{ + int retval; + + if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED) + return -EPERM; + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE); + if (!retval) + stream->runtime->state = SNDRV_PCM_STATE_RUNNING; + return retval; +} + +static int snd_compr_start(struct snd_compr_stream *stream) +{ + int retval; + + if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED) + return -EPERM; + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START); + if (!retval) + stream->runtime->state = SNDRV_PCM_STATE_RUNNING; + return retval; +} + +static int snd_compr_stop(struct snd_compr_stream *stream) +{ + int retval; + + if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED || + stream->runtime->state == SNDRV_PCM_STATE_SETUP) + return -EPERM; + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); + if (!retval) { + stream->runtime->state = SNDRV_PCM_STATE_SETUP; + wake_up(&stream->runtime->sleep); + } + return retval; +} + +static int snd_compr_drain(struct snd_compr_stream *stream) +{ + int retval; + + if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED || + stream->runtime->state == SNDRV_PCM_STATE_SETUP) + return -EPERM; + retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN); + if (!retval) { + stream->runtime->state = SNDRV_PCM_STATE_DRAINING; + wake_up(&stream->runtime->sleep); + } + return retval; +} + +static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + struct snd_compr_file *data = f->private_data; + struct snd_compr_stream *stream; + int retval = -ENOTTY; + + if (snd_BUG_ON(!data)) + return -EFAULT; + stream = &data->stream; + if (snd_BUG_ON(!stream)) + return -EFAULT; + mutex_lock(&stream->device->lock); + switch (_IOC_NR(cmd)) { + case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION): + put_user(SNDRV_COMPRESS_VERSION, + (int __user *)arg) ? -EFAULT : 0; + break; + case _IOC_NR(SNDRV_COMPRESS_GET_CAPS): + retval = snd_compr_get_caps(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS): + retval = snd_compr_get_codec_caps(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS): + retval = snd_compr_set_params(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS): + retval = snd_compr_get_params(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_TSTAMP): + retval = snd_compr_tstamp(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_AVAIL): + retval = snd_compr_ioctl_avail(stream, arg); + break; + case _IOC_NR(SNDRV_COMPRESS_PAUSE): + retval = snd_compr_pause(stream); + break; + case _IOC_NR(SNDRV_COMPRESS_RESUME): + retval = snd_compr_resume(stream); + break; + case _IOC_NR(SNDRV_COMPRESS_START): + retval = snd_compr_start(stream); + break; + case _IOC_NR(SNDRV_COMPRESS_STOP): + retval = snd_compr_stop(stream); + break; + case _IOC_NR(SNDRV_COMPRESS_DRAIN): + retval = snd_compr_drain(stream); + break; + } + mutex_unlock(&stream->device->lock); + return retval; +} + +static const struct file_operations snd_compr_file_ops = { + .owner = THIS_MODULE, + .open = snd_compr_open, + .release = snd_compr_free, + .write = snd_compr_write, + .read = snd_compr_read, + .unlocked_ioctl = snd_compr_ioctl, + .mmap = snd_compr_mmap, + .poll = snd_compr_poll, +}; + +static int snd_compress_dev_register(struct snd_device *device) +{ + int ret = -EINVAL; + char str[16]; + struct snd_compr *compr; + + if (snd_BUG_ON(!device || !device->device_data)) + return -EBADFD; + compr = device->device_data; + + sprintf(str, "comprC%iD%i", compr->card->number, compr->device); + pr_debug("reg %s for device %s, direction %d\n", str, compr->name, + compr->direction); + /* register compressed device */ + ret = snd_register_device(SNDRV_DEVICE_TYPE_COMPRESS, compr->card, + compr->device, &snd_compr_file_ops, compr, str); + if (ret < 0) { + pr_err("snd_register_device failed\n %d", ret); + return ret; + } + return ret; + +} + +static int snd_compress_dev_disconnect(struct snd_device *device) +{ + struct snd_compr *compr; + + compr = device->device_data; + snd_unregister_device(compr->direction, compr->card, compr->device); + return 0; +} + +/* + * snd_compress_new: create new compress device + * @card: sound card pointer + * @device: device number + * @dirn: device direction, should be of type enum snd_compr_direction + * @compr: compress device pointer + */ +int snd_compress_new(struct snd_card *card, int device, + int dirn, struct snd_compr *compr) +{ + static struct snd_device_ops ops = { + .dev_free = NULL, + .dev_register = snd_compress_dev_register, + .dev_disconnect = snd_compress_dev_disconnect, + }; + + compr->card = card; + compr->device = device; + compr->direction = dirn; + return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops); +} +EXPORT_SYMBOL_GPL(snd_compress_new); + +static int snd_compress_add_device(struct snd_compr *device) +{ + int ret; + + if (!device->card) + return -EINVAL; + + /* register the card */ + ret = snd_card_register(device->card); + if (ret) + goto out; + return 0; + +out: + pr_err("failed with %d\n", ret); + return ret; + +} + +static int snd_compress_remove_device(struct snd_compr *device) +{ + return snd_card_free(device->card); +} + +/** + * snd_compress_register - register compressed device + * + * @device: compressed device to register + */ +int snd_compress_register(struct snd_compr *device) +{ + int retval; + + if (device->name == NULL || device->dev == NULL || device->ops == NULL) + return -EINVAL; + + pr_debug("Registering compressed device %s\n", device->name); + if (snd_BUG_ON(!device->ops->open)) + return -EINVAL; + if (snd_BUG_ON(!device->ops->free)) + return -EINVAL; + if (snd_BUG_ON(!device->ops->set_params)) + return -EINVAL; + if (snd_BUG_ON(!device->ops->trigger)) + return -EINVAL; + + mutex_init(&device->lock); + + /* register a compressed card */ + mutex_lock(&device_mutex); + retval = snd_compress_add_device(device); + mutex_unlock(&device_mutex); + return retval; +} +EXPORT_SYMBOL_GPL(snd_compress_register); + +int snd_compress_deregister(struct snd_compr *device) +{ + pr_debug("Removing compressed device %s\n", device->name); + mutex_lock(&device_mutex); + snd_compress_remove_device(device); + mutex_unlock(&device_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(snd_compress_deregister); + +static int __init snd_compress_init(void) +{ + return 0; +} + +static void __exit snd_compress_exit(void) +{ +} + +module_init(snd_compress_init); +module_exit(snd_compress_exit); + +MODULE_DESCRIPTION("ALSA Compressed offload framework"); +MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/core/ctljack.c b/sound/core/ctljack.c new file mode 100644 index 00000000000..e4b38fbe51d --- /dev/null +++ b/sound/core/ctljack.c @@ -0,0 +1,56 @@ +/* + * Helper functions for jack-detection kcontrols + * + * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <linux/kernel.h> +#include <linux/export.h> +#include <sound/core.h> +#include <sound/control.h> + +#define jack_detect_kctl_info snd_ctl_boolean_mono_info + +static int jack_detect_kctl_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = kcontrol->private_value; + return 0; +} + +static struct snd_kcontrol_new jack_detect_kctl = { + /* name is filled later */ + .iface = SNDRV_CTL_ELEM_IFACE_CARD, + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .info = jack_detect_kctl_info, + .get = jack_detect_kctl_get, +}; + +struct snd_kcontrol * +snd_kctl_jack_new(const char *name, int idx, void *private_data) +{ + struct snd_kcontrol *kctl; + kctl = snd_ctl_new1(&jack_detect_kctl, private_data); + if (!kctl) + return NULL; + snprintf(kctl->id.name, sizeof(kctl->id.name), "%s Jack", name); + kctl->id.index = idx; + kctl->private_value = 0; + return kctl; +} +EXPORT_SYMBOL_GPL(snd_kctl_jack_new); + +void snd_kctl_jack_report(struct snd_card *card, + struct snd_kcontrol *kctl, bool status) +{ + if (kctl->private_value == status) + return; + kctl->private_value = status; + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); +} +EXPORT_SYMBOL_GPL(snd_kctl_jack_report); diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 3cc4b86dfb7..08fde0060fd 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -47,7 +47,7 @@ static int dsp_map[SNDRV_CARDS]; static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1}; -static int nonblock_open = 1; +static bool nonblock_open = 1; MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>"); MODULE_DESCRIPTION("PCM OSS emulation for ALSA."); diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index b9b2235d9ab..bbe32d2177d 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -65,7 +65,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("snd-seq-client-" __stringify(SNDRV_SEQ_CLIENT_DUMMY)); static int ports = 1; -static int duplex; +static bool duplex; module_param(ports, int, 0444); MODULE_PARM_DESC(ports, "number of ports to be created"); diff --git a/sound/core/sound.c b/sound/core/sound.c index 828af353ea9..28f35593a75 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -229,6 +229,7 @@ static int snd_kernel_minor(int type, struct snd_card *card, int dev) case SNDRV_DEVICE_TYPE_RAWMIDI: case SNDRV_DEVICE_TYPE_PCM_PLAYBACK: case SNDRV_DEVICE_TYPE_PCM_CAPTURE: + case SNDRV_DEVICE_TYPE_COMPRESS: if (snd_BUG_ON(!card)) return -EINVAL; minor = SNDRV_MINOR(card->number, type + dev); diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 5dbab38d04a..130cfe677d6 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -52,6 +52,7 @@ struct link_slave { struct link_ctl_info info; int vals[2]; /* current values */ unsigned int flags; + struct snd_kcontrol *kctl; /* original kcontrol pointer */ struct snd_kcontrol slave; /* the copy of original control entry */ }; @@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, slave->count * sizeof(*slave->vd), GFP_KERNEL); if (!srec) return -ENOMEM; + srec->kctl = slave; srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; @@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, static void master_free(struct snd_kcontrol *kcontrol) { struct link_master *master = snd_kcontrol_chip(kcontrol); - struct link_slave *slave; - - list_for_each_entry(slave, &master->slaves, list) - slave->master = NULL; + struct link_slave *slave, *n; + + /* free all slave links and retore the original slave kctls */ + list_for_each_entry_safe(slave, n, &master->slaves, list) { + struct snd_kcontrol *sctl = slave->kctl; + struct list_head olist = sctl->list; + memcpy(sctl, &slave->slave, sizeof(*sctl)); + memcpy(sctl->vd, slave->slave.vd, + sctl->count * sizeof(*sctl->vd)); + sctl->list = olist; /* keep the current linked-list */ + kfree(slave); + } kfree(master); } diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index d83bafc5d8b..ad079b63b8b 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -51,7 +51,7 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Loopback soundcard}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; +static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; static int pcm_notify[SNDRV_CARDS]; diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 97f1f93ed27..ad9434fd637 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -60,15 +60,15 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; +static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; static char *model[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = NULL}; static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; //static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; #ifdef CONFIG_HIGH_RES_TIMERS -static int hrtimer = 1; +static bool hrtimer = 1; #endif -static int fake_buffer = 1; +static bool fake_buffer = 1; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for dummy soundcard."); diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index 2ee82c5d9ee..6c83b1aed28 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -73,7 +73,7 @@ MODULE_SUPPORTED_DEVICE("{{Xilinx,ML403 AC97 Controller Reference}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for ML403 AC97 Controller Reference."); @@ -1341,15 +1341,4 @@ static struct platform_driver snd_ml403_ac97cr_driver = { }, }; -static int __init alsa_card_ml403_ac97cr_init(void) -{ - return platform_driver_register(&snd_ml403_ac97cr_driver); -} - -static void __exit alsa_card_ml403_ac97cr_exit(void) -{ - platform_driver_unregister(&snd_ml403_ac97cr_driver); -} - -module_init(alsa_card_ml403_ac97cr_init) -module_exit(alsa_card_ml403_ac97cr_exit) +module_platform_driver(snd_ml403_ac97cr_driver); diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 257569014f2..86f5fbc2da7 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c @@ -35,13 +35,13 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* exclude the first card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ #ifdef CONFIG_PNP -static int pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool pnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* MPU-401 port number */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* MPU-401 IRQ */ -static int uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool uart_enter[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for MPU-401 device."); diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index f24bf9a06cf..621e60e2029 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -36,7 +36,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static struct platform_device *platform_devices[SNDRV_CARDS]; static int device_count; diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c index 7d722a025d0..2bfe4bcb7a7 100644 --- a/sound/drivers/opl3/opl3_midi.c +++ b/sound/drivers/opl3/opl3_midi.c @@ -27,7 +27,7 @@ extern char snd_opl3_regmap[MAX_OPL2_VOICES][4]; -extern int use_internal_drums; +extern bool use_internal_drums; static void snd_opl3_note_off_unsafe(void *p, int note, int vel, struct snd_midi_channel *chan); diff --git a/sound/drivers/opl3/opl3_seq.c b/sound/drivers/opl3/opl3_seq.c index 723562e34fc..68399538e43 100644 --- a/sound/drivers/opl3/opl3_seq.c +++ b/sound/drivers/opl3/opl3_seq.c @@ -32,7 +32,7 @@ MODULE_AUTHOR("Uros Bizjak <uros@kss-loka.si>"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("ALSA driver for OPL3 FM synth"); -int use_internal_drums = 0; +bool use_internal_drums = 0; module_param(use_internal_drums, bool, 0444); MODULE_PARM_DESC(use_internal_drums, "Enable internal OPL2/3 drums."); diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 946a0cb996a..99704e6a2e2 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c @@ -25,8 +25,8 @@ MODULE_ALIAS("platform:pcspkr"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ -static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ -static int nopcm; /* Disable PCM capability of the driver */ +static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ +static bool nopcm; /* Disable PCM capability of the driver */ module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for pcsp soundcard."); diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index ce9e7d170c0..434981dd4a6 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -14,7 +14,7 @@ #include <asm/io.h> #include "pcsp.h" -static int nforce_wa; +static bool nforce_wa; module_param(nforce_wa, bool, 0444); MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " "(expect bad sound)"); diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index f664823a963..3e32bd3d95d 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c @@ -55,7 +55,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static struct platform_device *platform_devices[SNDRV_CARDS]; static int device_count; diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index 85aad43f0b1..b2d0e8e49be 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c @@ -69,7 +69,7 @@ static char *adaptor_names[] = { static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x3f8,0x2f8,0x3e8,0x2e8 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,4,5,7,9,10,11,14,15 */ static int speed[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 38400}; /* 9600,19200,38400,57600,115200 */ @@ -77,7 +77,7 @@ static int base[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 115200}; /* baud bas static int outs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */ static int ins[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; /* 1 to 16 */ static int adaptor[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = SNDRV_SERIAL_SOUNDCANVAS}; -static int droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF }; +static bool droponfull[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS -1)] = SNDRV_SERIAL_NORMALBUFF }; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Serial MIDI."); diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c index d79d6edc0f5..9d97478a18b 100644 --- a/sound/drivers/virmidi.c +++ b/sound/drivers/virmidi.c @@ -63,7 +63,7 @@ MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual rawmidi device}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; +static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0}; static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; module_param_array(index, int, NULL, 0444); diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index cd44c74207d..94b83b6e46a 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c @@ -44,7 +44,7 @@ MODULE_SUPPORTED_DEVICE("{{Highscreen,Sound-Boostar 16 3D}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c index 34ab69bdffc..2af77faefbb 100644 --- a/sound/isa/ad1848/ad1848.c +++ b/sound/isa/ad1848/ad1848.c @@ -43,11 +43,11 @@ MODULE_SUPPORTED_DEVICE("{{Analog Devices,AD1848}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ -static int thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ +static bool thinkpad[SNDRV_CARDS]; /* Thinkpad special case */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c index 7465ae036e0..4d50c69f329 100644 --- a/sound/isa/adlib.c +++ b/sound/isa/adlib.c @@ -18,7 +18,7 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; module_param_array(index, int, NULL, 0444); diff --git a/sound/isa/als100.c b/sound/isa/als100.c index fc5b38fd265..d1f4351fb6e 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index e55f3ebe87b..6a2c78ef1d8 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c @@ -55,7 +55,7 @@ MODULE_SUPPORTED_DEVICE("{{Aztech Systems,PRO16V}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long wss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index c94578d40b1..7bd5e337ee9 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c @@ -69,9 +69,9 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long sbport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; static int sbirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index 6d81fa75c33..99dda45e82f 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c @@ -41,7 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{Crystal Semiconductors,CS4231}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index f5a94b6e624..740c51a1ed7 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c @@ -74,9 +74,9 @@ MODULE_ALIAS("snd_cs4232"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static long cport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 9a1a6f2c448..b036e60f62d 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c @@ -51,9 +51,9 @@ MODULE_ALIAS("snd_es968"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; +static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; #endif -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */ static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 98e3ac1cfa0..c20baafd9b7 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -1964,9 +1964,9 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1868 PnP AudioDrive}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; +static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ #ifndef CONFIG_PNP diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c index e51d3244742..55e20782858 100644 --- a/sound/isa/galaxy/galaxy.c +++ b/sound/isa/galaxy/galaxy.c @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard."); diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c index d7296500bce..bf633367161 100644 --- a/sound/isa/gus/gusclassic.c +++ b/sound/isa/gus/gusclassic.c @@ -42,7 +42,7 @@ MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Classic}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 3,5,9,11,12,15 */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 597accdb15d..bc10cc26e5f 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c @@ -46,7 +46,7 @@ MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound Extreme}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static long gf1_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x210,0x220,0x230,0x240,0x250,0x260,0x270 */ static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS) - 1] = -1}; /* 0x300,0x310,0x320 */ diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index 933cb0f4c54..41c3f448745 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c @@ -40,7 +40,7 @@ MODULE_SUPPORTED_DEVICE("{{Gravis,UltraSound MAX}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x230,0x240,0x250,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,3,5,9,11,12,15 */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3,5,6,7 */ diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index 8e7e19484da..a76bc8d27c1 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c @@ -55,9 +55,9 @@ MODULE_SUPPORTED_DEVICE("{{AMD,InterWave STB with TEA6330T}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x210,0x220,0x230,0x240,0x250,0x260 */ #ifdef SNDRV_STB diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 0961e2cf20c..29cc8e162b0 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c @@ -785,7 +785,7 @@ static int write_ndelay[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = 1 }; static int calibrate_signal; #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(isapnp, bool, NULL, 0444); MODULE_PARM_DESC(isapnp, "ISA PnP detection for specified soundcard."); #define has_isapnp(x) isapnp[x] diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 64a9a2177f4..f6cc0b917ef 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -46,9 +46,9 @@ MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF719E-S}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0xf86,0x370,0x100 */ static long sb_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 3785b7a784c..c24594c866f 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c @@ -61,7 +61,7 @@ static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ static int wss; static int ide; #ifdef CONFIG_PNP -static int isapnp = 1; /* Enable ISA PnP detection */ +static bool isapnp = 1; /* Enable ISA PnP detection */ #endif module_param(index, int, 0444); diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index 97871bebea9..babaedd242f 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c @@ -63,7 +63,7 @@ MODULE_SUPPORTED_DEVICE("{{OPTi,82C924 (AD1848)}," static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ -//static int enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ +//static bool enable = SNDRV_DEFAULT_ENABLE1; /* Enable this card */ #ifdef CONFIG_PNP static int isapnp = 1; /* Enable ISA PnP detection */ #endif diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c index 54e3c2c1806..410758c6809 100644 --- a/sound/isa/sb/jazz16.c +++ b/sound/isa/sb/jazz16.c @@ -36,7 +36,7 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 115c7748204..39b8eca1521 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c @@ -68,9 +68,9 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB AWE 32}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x330,0x300 */ diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c index 453ef283491..ab5cebea52e 100644 --- a/sound/isa/sb/sb8.c +++ b/sound/isa/sb/sb8.c @@ -36,7 +36,7 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB 1.0/SB 2.0/SB Pro}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3 */ diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 207c161f100..d97d0f38181 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c @@ -48,7 +48,7 @@ MODULE_SUPPORTED_DEVICE("{{Gallant, SC-6000}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220, 0x240 */ static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5, 7, 9, 10, 11 */ static long mss_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x530, 0xe80 */ diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 150b96b3ea1..e0a73271cb9 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c @@ -38,9 +38,9 @@ MODULE_SUPPORTED_DEVICE("{{Turtle Beach,Maui/Tropez/Tropez+}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ #ifdef CONFIG_PNP -static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; #endif static long cs4232_pcm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int cs4232_pcm_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,11,12,15 */ @@ -51,7 +51,7 @@ static int ics2115_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 2,9,11,12,15 */ static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */ static int dma1[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ static int dma2[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 0,1,3,5,6,7 */ -static int use_cs4232_midi[SNDRV_CARDS]; +static bool use_cs4232_midi[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for WaveFront soundcard."); diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 2e6c85894e0..5f88d1f09ff 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -935,15 +935,4 @@ static struct platform_driver hal2_driver = { } }; -static int __init alsa_card_hal2_init(void) -{ - return platform_driver_register(&hal2_driver); -} - -static void __exit alsa_card_hal2_exit(void) -{ - platform_driver_unregister(&hal2_driver); -} - -module_init(alsa_card_hal2_init); -module_exit(alsa_card_hal2_exit); +module_platform_driver(hal2_driver); diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 69425d4c91f..ceaa593ea4e 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -976,15 +976,4 @@ static struct platform_driver sgio2audio_driver = { } }; -static int __init alsa_card_sgio2audio_init(void) -{ - return platform_driver_register(&sgio2audio_driver); -} - -static void __exit alsa_card_sgio2audio_exit(void) -{ - platform_driver_unregister(&sgio2audio_driver); -} - -module_init(alsa_card_sgio2audio_init) -module_exit(alsa_card_sgio2audio_exit) +module_platform_driver(sgio2audio_driver); diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 6c9e8e8f45f..5849b129e50 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -521,7 +521,7 @@ config SC6600_CDROMBASE config SOUND_VIDC tristate "VIDC 16-bit sound" - depends on ARM && (ARCH_ACORN || ARCH_CLPS7500) + depends on ARM && ARCH_ACORN help 16-bit support for the VIDC onboard sound hardware found on Acorn machines. diff --git a/sound/oss/ad1848.c b/sound/oss/ad1848.c index 8a197fd3c57..98d23bdcaf2 100644 --- a/sound/oss/ad1848.c +++ b/sound/oss/ad1848.c @@ -119,9 +119,9 @@ ad1848_port_info; static struct address_info cfg; static int nr_ad1848_devs; -static int deskpro_xl; -static int deskpro_m; -static int soundpro; +static bool deskpro_xl; +static bool deskpro_m; +static bool soundpro; static volatile signed char irq2dev[17] = { -1, -1, -1, -1, -1, -1, -1, -1, @@ -177,7 +177,7 @@ static struct { #ifdef CONFIG_PNP static int isapnp = 1; static int isapnpjump; -static int reverse; +static bool reverse; static int audio_activated; #else diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index 7b5c77b32a9..eba734560f6 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c @@ -1701,7 +1701,7 @@ static int joystick_io __initdata = CONFIG_MSNDPIN_JOYSTICK_IO; #ifndef CONFIG_MSNDPIN_DIGITAL # define CONFIG_MSNDPIN_DIGITAL 0 #endif -static int digital __initdata = CONFIG_MSNDPIN_DIGITAL; +static bool digital __initdata = CONFIG_MSNDPIN_DIGITAL; #endif /* MSND_CLASSIC */ diff --git a/sound/oss/pas2_card.c b/sound/oss/pas2_card.c index 7f377ec3486..dabf8a871dc 100644 --- a/sound/oss/pas2_card.c +++ b/sound/oss/pas2_card.c @@ -41,19 +41,19 @@ static int pas_irq; static int pas_sb_base; DEFINE_SPINLOCK(pas_lock); #ifndef CONFIG_PAS_JOYSTICK -static int joystick; +static bool joystick; #else -static int joystick = 1; +static bool joystick = 1; #endif #ifdef SYMPHONY_PAS -static int symphony = 1; +static bool symphony = 1; #else -static int symphony; +static bool symphony; #endif #ifdef BROKEN_BUS_CLOCK -static int broken_bus_clock = 1; +static bool broken_bus_clock = 1; #else -static int broken_bus_clock; +static bool broken_bus_clock; #endif static struct address_info cfg; diff --git a/sound/oss/pss.c b/sound/oss/pss.c index 2fc0624024b..0f32a561f15 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c @@ -117,9 +117,9 @@ /* If compiled into kernel, it enable or disable pss mixer */ #ifdef CONFIG_PSS_MIXER -static int pss_mixer = 1; +static bool pss_mixer = 1; #else -static int pss_mixer; +static bool pss_mixer; #endif @@ -147,7 +147,7 @@ static DEFINE_SPINLOCK(lock); static int pss_initialized; static int nonstandard_microcode; static int pss_cdrom_port = -1; /* Parameter for the PSS cdrom port */ -static int pss_enable_joystick; /* Parameter for enabling the joystick */ +static bool pss_enable_joystick; /* Parameter for enabling the joystick */ static coproc_operations pss_coproc_operations; static void pss_write(pss_confdata *devc, int data) @@ -1133,8 +1133,8 @@ static int mss_irq __initdata = -1; static int mss_dma __initdata = -1; static int mpu_io __initdata = -1; static int mpu_irq __initdata = -1; -static int pss_no_sound = 0; /* Just configure non-sound components */ -static int pss_keep_settings = 1; /* Keep hardware settings at module exit */ +static bool pss_no_sound = 0; /* Just configure non-sound components */ +static bool pss_keep_settings = 1; /* Keep hardware settings at module exit */ static char *pss_firmware = "/etc/sound/pss_synth"; module_param(pss_io, int, 0); diff --git a/sound/oss/trix.c b/sound/oss/trix.c index e04169e8e3f..944e0c01548 100644 --- a/sound/oss/trix.c +++ b/sound/oss/trix.c @@ -31,7 +31,7 @@ static int mpu; -static int joystick; +static bool joystick; static unsigned char trix_read(int addr) { diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index fac51eef272..9473fca9681 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -42,7 +42,7 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); MODULE_LICENSE("GPL"); -static int enable_loopback; +static bool enable_loopback; module_param(enable_loopback, bool, 0444); MODULE_PARM_DESC(enable_loopback, "Enable AC97 ADC/DAC Loopback Control"); diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 6e311184bb1..9d91d61902b 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -66,7 +66,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for the AD1889 soundcard."); -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable AD1889 soundcard."); diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index ef85ac5d900..bdd6164e9c7 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -48,7 +48,7 @@ MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int pcm_channels = 32; -static int spdif; +static bool spdif; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio."); @@ -60,7 +60,7 @@ module_param(spdif, bool, 0444); MODULE_PARM_DESC(spdif, "Support SPDIF I/O"); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 8dc77a0a5d8..8196e229b2d 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -115,7 +115,14 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS300},{Avance Logic,ALS300+}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for ALS300 sound card."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for ALS300 sound card."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable ALS300 sound card."); struct snd_als300 { unsigned long port; diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 28ef40e01cc..3269b8011ea 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -90,7 +90,7 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ #ifdef SUPPORT_JOYSTICK static int joystick_port[SNDRV_CARDS]; #endif diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index f4b9e2b7ae8..e8de831f98b 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -23,8 +23,11 @@ */ #include "hpi_internal.h" +#include "hpi_version.h" #include "hpimsginit.h" #include "hpioctl.h" +#include "hpicmn.h" + #include <linux/pci.h> #include <linux/init.h> @@ -44,7 +47,8 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); -MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); +MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx " + HPI_VER_STRING); #if defined CONFIG_SND_DEBUG_VERBOSE /** @@ -63,8 +67,8 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; -static int enable_hpi_hwdep = 1; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable_hpi_hwdep = 1; module_param_array(index, int, NULL, S_IRUGO); MODULE_PARM_DESC(index, "ALSA index value for AudioScience soundcard."); @@ -119,12 +123,7 @@ struct clk_cache { struct snd_card_asihpi { struct snd_card *card; struct pci_dev *pci; - u16 adapter_index; - u32 serial_number; - u16 type; - u16 version; - u16 num_outstreams; - u16 num_instreams; + struct hpi_adapter *hpi; u32 h_mixer; struct clk_cache cc; @@ -135,6 +134,8 @@ struct snd_card_asihpi { u16 update_interval_frames; u16 in_max_chans; u16 out_max_chans; + u16 in_min_chans; + u16 out_min_chans; }; /* Per stream data */ @@ -495,6 +496,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, snd_printdd("stream_host_buffer_attach status 0x%x\n", dpcm->hpi_buffer_attached); + } bytes_per_sec = params_rate(params) * params_channels(params); width = snd_pcm_format_width(params_format(params)); @@ -757,8 +759,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; if (state == HPI_STATE_STOPPED) { - if ((bytes_avail == 0) && - (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { + if (bytes_avail == 0) { hpi_handle_error(hpi_stream_start(ds->h_stream)); snd_printdd("P%d start\n", s->number); ds->drained_count = 0; @@ -767,7 +768,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) snd_printd(KERN_WARNING "P%d drained\n", s->number); ds->drained_count++; - if (ds->drained_count > 2) { + if (ds->drained_count > 20) { snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); continue; } @@ -888,8 +889,8 @@ static void snd_card_asihpi_timer_function(unsigned long data) pd, xfer2)); } } - ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; - ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; + ds->pcm_buf_host_rw_ofs += xfercount; + ds->pcm_buf_elapsed_dma_ofs += xfercount; snd_pcm_period_elapsed(s); } } @@ -902,7 +903,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { - snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd); + char name[16]; + snd_pcm_debug_name(substream, name, sizeof(name)); + snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd); return snd_pcm_lib_ioctl(substream, cmd, arg); } @@ -927,21 +930,23 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data; snd_pcm_uframes_t ptr; + char name[16]; + snd_pcm_debug_name(substream, name, sizeof(name)); ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr); + snd_printddd("%s pointer = 0x%04lx\n", name, (unsigned long)ptr); return ptr; } -static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, - u32 h_stream, - struct snd_pcm_hardware *pcmhw) +static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi, + u32 h_stream) { struct hpi_format hpi_format; u16 format; u16 err; u32 h_control; u32 sample_rate = 48000; + u64 formats = 0; /* on cards without SRC, must query at valid rate, * maybe set by external sync @@ -956,41 +961,29 @@ static void snd_card_asihpi_playback_format(struct snd_card_asihpi *asihpi, for (format = HPI_FORMAT_PCM8_UNSIGNED; format <= HPI_FORMAT_PCM24_SIGNED; format++) { - err = hpi_format_create(&hpi_format, - 2, format, sample_rate, 128000, 0); + err = hpi_format_create(&hpi_format, asihpi->out_max_chans, + format, sample_rate, 128000, 0); if (!err) - err = hpi_outstream_query_format(h_stream, - &hpi_format); + err = hpi_outstream_query_format(h_stream, &hpi_format); if (!err && (hpi_to_alsa_formats[format] != -1)) - pcmhw->formats |= - (1ULL << hpi_to_alsa_formats[format]); + formats |= (1ULL << hpi_to_alsa_formats[format]); } + return formats; } -static struct snd_pcm_hardware snd_card_asihpi_playback = { - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = BUFFER_BYTES_MAX, - .period_bytes_min = PERIOD_BYTES_MIN, - .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN, - .periods_min = PERIODS_MIN, - .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, - .fifo_size = 0, -}; - static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm; struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); + struct snd_pcm_hardware snd_card_asihpi_playback; int err; dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); if (dpcm == NULL) return -ENOMEM; - err = - hpi_outstream_open(card->adapter_index, + err = hpi_outstream_open(card->hpi->adapter->index, substream->number, &dpcm->h_stream); hpi_handle_error(err); if (err) @@ -1012,12 +1005,19 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) runtime->private_data = dpcm; runtime->private_free = snd_card_asihpi_runtime_free; - snd_card_asihpi_playback.channels_max = card->out_max_chans; + memset(&snd_card_asihpi_playback, 0, sizeof(snd_card_asihpi_playback)); + snd_card_asihpi_playback.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_playback.period_bytes_min = PERIOD_BYTES_MIN; /*?snd_card_asihpi_playback.period_bytes_min = card->out_max_chans * 4096; */ - - snd_card_asihpi_playback_format(card, dpcm->h_stream, - &snd_card_asihpi_playback); + snd_card_asihpi_playback.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_playback.periods_min = PERIODS_MIN; + snd_card_asihpi_playback.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + /* snd_card_asihpi_playback.fifo_size = 0; */ + snd_card_asihpi_playback.channels_max = card->out_max_chans; + snd_card_asihpi_playback.channels_min = card->out_min_chans; + snd_card_asihpi_playback.formats = + snd_card_asihpi_playback_formats(card, dpcm->h_stream); snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_playback); @@ -1029,8 +1029,10 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID; - if (card->support_grouping) + if (card->support_grouping) { snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; + snd_pcm_set_sync(substream); + } /* struct is copied, so can create initializer dynamically */ runtime->hw = snd_card_asihpi_playback; @@ -1047,8 +1049,6 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, card->update_interval_frames * 2, UINT_MAX); - snd_pcm_set_sync(substream); - snd_printdd("playback open\n"); return 0; @@ -1114,15 +1114,15 @@ static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) -static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, - u32 h_stream, - struct snd_pcm_hardware *pcmhw) +static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, + u32 h_stream) { struct hpi_format hpi_format; u16 format; u16 err; u32 h_control; u32 sample_rate = 48000; + u64 formats = 0; /* on cards without SRC, must query at valid rate, maybe set by external sync */ @@ -1137,34 +1137,22 @@ static void snd_card_asihpi_capture_format(struct snd_card_asihpi *asihpi, for (format = HPI_FORMAT_PCM8_UNSIGNED; format <= HPI_FORMAT_PCM24_SIGNED; format++) { - err = hpi_format_create(&hpi_format, 2, format, - sample_rate, 128000, 0); + err = hpi_format_create(&hpi_format, asihpi->in_max_chans, + format, sample_rate, 128000, 0); if (!err) - err = hpi_instream_query_format(h_stream, - &hpi_format); + err = hpi_instream_query_format(h_stream, &hpi_format); if (!err) - pcmhw->formats |= - (1ULL << hpi_to_alsa_formats[format]); + formats |= (1ULL << hpi_to_alsa_formats[format]); } + return formats; } - -static struct snd_pcm_hardware snd_card_asihpi_capture = { - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = BUFFER_BYTES_MAX, - .period_bytes_min = PERIOD_BYTES_MIN, - .period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN, - .periods_min = PERIODS_MIN, - .periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN, - .fifo_size = 0, -}; - static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); struct snd_card_asihpi_pcm *dpcm; + struct snd_pcm_hardware snd_card_asihpi_capture; int err; dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); @@ -1172,10 +1160,10 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) return -ENOMEM; snd_printdd("capture open adapter %d stream %d\n", - card->adapter_index, substream->number); + card->hpi->adapter->index, substream->number); err = hpi_handle_error( - hpi_instream_open(card->adapter_index, + hpi_instream_open(card->hpi->adapter->index, substream->number, &dpcm->h_stream)); if (err) kfree(dpcm); @@ -1184,7 +1172,6 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) if (err) return -EIO; - init_timer(&dpcm->timer); dpcm->timer.data = (unsigned long) dpcm; dpcm->timer.function = snd_card_asihpi_timer_function; @@ -1192,9 +1179,17 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) runtime->private_data = dpcm; runtime->private_free = snd_card_asihpi_runtime_free; + memset(&snd_card_asihpi_capture, 0, sizeof(snd_card_asihpi_capture)); + snd_card_asihpi_capture.buffer_bytes_max = BUFFER_BYTES_MAX; + snd_card_asihpi_capture.period_bytes_min = PERIOD_BYTES_MIN; + snd_card_asihpi_capture.period_bytes_max = BUFFER_BYTES_MAX / PERIODS_MIN; + snd_card_asihpi_capture.periods_min = PERIODS_MIN; + snd_card_asihpi_capture.periods_max = BUFFER_BYTES_MAX / PERIOD_BYTES_MIN; + /* snd_card_asihpi_capture.fifo_size = 0; */ snd_card_asihpi_capture.channels_max = card->in_max_chans; - snd_card_asihpi_capture_format(card, dpcm->h_stream, - &snd_card_asihpi_capture); + snd_card_asihpi_capture.channels_min = card->in_min_chans; + snd_card_asihpi_capture.formats = + snd_card_asihpi_capture_formats(card, dpcm->h_stream); snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP | @@ -1240,15 +1235,20 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { .pointer = snd_card_asihpi_capture_pointer, }; -static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, - int device, int substreams) +static int __devinit snd_card_asihpi_pcm_new( + struct snd_card_asihpi *asihpi, int device) { struct snd_pcm *pcm; int err; + u16 num_instreams, num_outstreams, x16; + u32 x32; + + err = hpi_adapter_get_info(asihpi->hpi->adapter->index, + &num_outstreams, &num_instreams, + &x16, &x32, &x16); err = snd_pcm_new(asihpi->card, "Asihpi PCM", device, - asihpi->num_outstreams, asihpi->num_instreams, - &pcm); + num_outstreams, num_instreams, &pcm); if (err < 0) return err; /* pointer to ops struct is stored, dont change ops afterwards! */ @@ -1314,7 +1314,7 @@ static const char * const asihpi_src_names[] = { "Analog", "Adapter", "RTP", - "GPI", + "Internal" }; compile_time_assert( @@ -1332,7 +1332,6 @@ static const char * const asihpi_dst_names[] = { "Net", "Analog", "RTP", - "GPO", }; compile_time_assert( @@ -1410,6 +1409,7 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { u32 h_control = kcontrol->private_value; + u32 count; u16 err; /* native gains are in millibels */ short min_gain_mB; @@ -1424,8 +1424,12 @@ static int snd_asihpi_volume_info(struct snd_kcontrol *kcontrol, step_gain_mB = VOL_STEP_mB; } + err = hpi_meter_query_channels(h_control, &count); + if (err) + count = HPI_MAX_CHANNELS; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; + uinfo->count = count; uinfo->value.integer.min = min_gain_mB / VOL_STEP_mB; uinfo->value.integer.max = max_gain_mB / VOL_STEP_mB; uinfo->value.integer.step = step_gain_mB / VOL_STEP_mB; @@ -2033,8 +2037,15 @@ static int __devinit snd_asihpi_tuner_add(struct snd_card_asihpi *asihpi, static int snd_asihpi_meter_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { + u32 h_control = kcontrol->private_value; + u32 count; + u16 err; + err = hpi_meter_query_channels(h_control, &count); + if (err) + count = HPI_MAX_CHANNELS; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = HPI_MAX_CHANNELS; + uinfo->count = count; uinfo->value.integer.min = 0; uinfo->value.integer.max = 0x7FFFFFFF; return 0; @@ -2248,6 +2259,9 @@ static int snd_asihpi_cmode_info(struct snd_kcontrol *kcontrol, valid_modes++; } + if (!valid_modes) + return -EINVAL; + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = valid_modes; @@ -2547,7 +2561,7 @@ static int __devinit snd_card_asihpi_mixer_new(struct snd_card_asihpi *asihpi) strcpy(card->mixername, "Asihpi Mixer"); err = - hpi_mixer_open(asihpi->adapter_index, + hpi_mixer_open(asihpi->hpi->adapter->index, &asihpi->h_mixer); hpi_handle_error(err); if (err) @@ -2665,24 +2679,33 @@ snd_asihpi_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_card_asihpi *asihpi = entry->private_data; - u16 version; u32 h_control; u32 rate = 0; u16 source = 0; + + u16 num_outstreams; + u16 num_instreams; + u16 version; + u32 serial_number; + u16 type; + int err; snd_iprintf(buffer, "ASIHPI driver proc file\n"); + + hpi_handle_error(hpi_adapter_get_info(asihpi->hpi->adapter->index, + &num_outstreams, &num_instreams, + &version, &serial_number, &type)); + snd_iprintf(buffer, - "adapter ID=%4X\n_index=%d\n" - "num_outstreams=%d\n_num_instreams=%d\n", - asihpi->type, asihpi->adapter_index, - asihpi->num_outstreams, asihpi->num_instreams); + "Adapter type ASI%4X\nHardware Index %d\n" + "%d outstreams\n%d instreams\n", + type, asihpi->hpi->adapter->index, + num_outstreams, num_instreams); - version = asihpi->version; snd_iprintf(buffer, - "serial#=%d\n_hw version %c%d\nDSP code version %03d\n", - asihpi->serial_number, ((version >> 3) & 0xf) + 'A', - version & 0x7, + "Serial#%d\nHardware version %c%d\nDSP code version %03d\n", + serial_number, ((version >> 3) & 0xf) + 'A', version & 0x7, ((version >> 13) * 100) + ((version >> 7) & 0x3f)); err = hpi_mixer_get_control(asihpi->h_mixer, @@ -2690,18 +2713,15 @@ snd_asihpi_proc_read(struct snd_info_entry *entry, HPI_CONTROL_SAMPLECLOCK, &h_control); if (!err) { - err = hpi_sample_clock_get_sample_rate( - h_control, &rate); + err = hpi_sample_clock_get_sample_rate(h_control, &rate); err += hpi_sample_clock_get_source(h_control, &source); if (!err) - snd_iprintf(buffer, "sample_clock=%d_hz, source %s\n", + snd_iprintf(buffer, "Sample Clock %dHz, source %s\n", rate, sampleclock_sources[source]); } - } - static void __devinit snd_asihpi_proc_init(struct snd_card_asihpi *asihpi) { struct snd_info_entry *entry; @@ -2773,35 +2793,34 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { int err; - - u16 version; - int pcm_substreams; - - struct hpi_adapter *hpi_card; + struct hpi_adapter *hpi; struct snd_card *card; struct snd_card_asihpi *asihpi; u32 h_control; u32 h_stream; + u32 adapter_index; static int dev; if (dev >= SNDRV_CARDS) return -ENODEV; - /* Should this be enable[hpi_card->index] ? */ + /* Should this be enable[hpi->index] ? */ if (!enable[dev]) { dev++; return -ENOENT; } + /* Initialise low-level HPI driver */ err = asihpi_adapter_probe(pci_dev, pci_id); if (err < 0) return err; - hpi_card = pci_get_drvdata(pci_dev); + hpi = pci_get_drvdata(pci_dev); + adapter_index = hpi->adapter->index; /* first try to give the card the same index as its hardware index */ - err = snd_card_create(hpi_card->index, - id[hpi_card->index], THIS_MODULE, + err = snd_card_create(adapter_index, + id[adapter_index], THIS_MODULE, sizeof(struct snd_card_asihpi), &card); if (err < 0) { @@ -2815,50 +2834,32 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, return err; snd_printk(KERN_WARNING "**** WARNING **** Adapter index %d->ALSA index %d\n", - hpi_card->index, card->number); + adapter_index, card->number); } snd_card_set_dev(card, &pci_dev->dev); - asihpi = (struct snd_card_asihpi *) card->private_data; + asihpi = card->private_data; asihpi->card = card; asihpi->pci = pci_dev; - asihpi->adapter_index = hpi_card->index; - hpi_handle_error(hpi_adapter_get_info( - asihpi->adapter_index, - &asihpi->num_outstreams, - &asihpi->num_instreams, - &asihpi->version, - &asihpi->serial_number, &asihpi->type)); - - version = asihpi->version; - snd_printk(KERN_INFO "adapter ID=%4X index=%d num_outstreams=%d " - "num_instreams=%d S/N=%d\n" - "Hw Version %c%d DSP code version %03d\n", - asihpi->type, asihpi->adapter_index, - asihpi->num_outstreams, - asihpi->num_instreams, asihpi->serial_number, - ((version >> 3) & 0xf) + 'A', - version & 0x7, - ((version >> 13) * 100) + ((version >> 7) & 0x3f)); - - pcm_substreams = asihpi->num_outstreams; - if (pcm_substreams < asihpi->num_instreams) - pcm_substreams = asihpi->num_instreams; - - err = hpi_adapter_get_property(asihpi->adapter_index, + asihpi->hpi = hpi; + + snd_printk(KERN_INFO "adapter ID=%4X index=%d\n", + asihpi->hpi->adapter->type, adapter_index); + + err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_CAPS1, NULL, &asihpi->support_grouping); if (err) asihpi->support_grouping = 0; - err = hpi_adapter_get_property(asihpi->adapter_index, + err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_CAPS2, &asihpi->support_mrx, NULL); if (err) asihpi->support_mrx = 0; - err = hpi_adapter_get_property(asihpi->adapter_index, + err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_INTERVAL, NULL, &asihpi->update_interval_frames); if (err) @@ -2867,7 +2868,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, if (!asihpi->can_dma) asihpi->update_interval_frames *= 2; - hpi_handle_error(hpi_instream_open(asihpi->adapter_index, + hpi_handle_error(hpi_instream_open(adapter_index, 0, &h_stream)); err = hpi_instream_host_buffer_free(h_stream); @@ -2875,7 +2876,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, hpi_handle_error(hpi_instream_close(h_stream)); - err = hpi_adapter_get_property(asihpi->adapter_index, + err = hpi_adapter_get_property(adapter_index, HPI_ADAPTER_PROPERTY_CURCHANNELS, &asihpi->in_max_chans, &asihpi->out_max_chans); if (err) { @@ -2883,13 +2884,22 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->out_max_chans = 2; } - snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n", + if (asihpi->out_max_chans > 2) { /* assume LL mode */ + asihpi->out_min_chans = asihpi->out_max_chans; + asihpi->in_min_chans = asihpi->in_max_chans; + asihpi->support_grouping = 0; + } else { + asihpi->out_min_chans = 1; + asihpi->in_min_chans = 1; + } + + snd_printk(KERN_INFO "Has dma:%d, grouping:%d, mrx:%d\n", asihpi->can_dma, asihpi->support_grouping, asihpi->support_mrx ); - err = snd_card_asihpi_pcm_new(asihpi, 0, pcm_substreams); + err = snd_card_asihpi_pcm_new(asihpi, 0); if (err < 0) { snd_printk(KERN_ERR "pcm_new failed\n"); goto __nodev; @@ -2916,13 +2926,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, strcpy(card->driver, "ASIHPI"); - sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); + sprintf(card->shortname, "AudioScience ASI%4X", + asihpi->hpi->adapter->type); sprintf(card->longname, "%s %i", - card->shortname, asihpi->adapter_index); + card->shortname, adapter_index); err = snd_card_register(card); if (!err) { - hpi_card->snd_card_asihpi = card; + hpi->snd_card = card; dev++; return 0; } @@ -2935,10 +2946,9 @@ __nodev: static void __devexit snd_asihpi_remove(struct pci_dev *pci_dev) { - struct hpi_adapter *hpi_card = pci_get_drvdata(pci_dev); - - snd_card_free(hpi_card->snd_card_asihpi); - hpi_card->snd_card_asihpi = NULL; + struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); + snd_card_free(hpi->snd_card); + hpi->snd_card = NULL; asihpi_adapter_remove(pci_dev); } diff --git a/sound/pci/asihpi/hpi.h b/sound/pci/asihpi/hpi.h index f2072728899..20887241a3a 100644 --- a/sound/pci/asihpi/hpi.h +++ b/sound/pci/asihpi/hpi.h @@ -30,26 +30,8 @@ #ifndef _HPI_H_ #define _HPI_H_ -/* HPI Version -If HPI_VER_MINOR is odd then its a development release not intended for the -public. If HPI_VER_MINOR is even then is a release version -i.e 3.05.02 is a development version -*/ -#define HPI_VERSION_CONSTRUCTOR(maj, min, rel) \ - ((maj << 16) + (min << 8) + rel) - -#define HPI_VER_MAJOR(v) ((int)(v >> 16)) -#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF)) -#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) - -#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0) -#define HPI_VER_STRING "4.08.00" - -/* Library version as documented in hpi-api-versions.txt */ -#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0) #include <linux/types.h> -#define HPI_BUILD_EXCLUDE_DEPRECATED #define HPI_BUILD_KERNEL_MODE /******************************************************************************/ @@ -213,7 +195,7 @@ enum HPI_SOURCENODES { /** RTP stream input node - This node is a destination for packets of RTP audio samples from other devices. */ HPI_SOURCENODE_RTP_DESTINATION = 112, - HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */ + HPI_SOURCENODE_INTERNAL = 113, /**< node internal to the device. */ /* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */ HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */ /* AX6 max sourcenode types = 15 */ @@ -242,9 +224,8 @@ enum HPI_DESTNODES { /** RTP stream output node - This node is a source for packets of RTP audio samples that are sent to other devices. */ HPI_DESTNODE_RTP_SOURCE = 208, - HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */ /* !!!Update this AND hpidebug.h if you add a new destnode type!!! */ - HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */ + HPI_DESTNODE_LAST_INDEX = 208 /**< largest ID */ /* AX6 max destnode types = 15 */ }; @@ -450,7 +431,19 @@ Indicates that the adapter in it's current mode supports interrupts across the host bus. Note, this does not imply that interrupts are enabled. Instead it indicates that they can be enabled. */ - HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272 + HPI_ADAPTER_PROPERTY_SUPPORTS_IRQ = 272, +/** Readonly supports firmware updating. +Indicates that the adapter implements an interface to update firmware +on the adapter. +*/ + HPI_ADAPTER_PROPERTY_SUPPORTS_FW_UPDATE = 273, +/** Readonly Firmware IDs +Identifiy firmware independent of individual adapter type. +May be used as a filter for firmware update images. +Property 1 = Bootloader ID +Property 2 = Main program ID +*/ + HPI_ADAPTER_PROPERTY_FIRMWARE_ID = 274 }; /** Adapter mode commands @@ -638,7 +631,7 @@ enum HPI_MIXER_STORE_COMMAND { HPI_MIXER_STORE_ENABLE = 4, /** Disable auto storage of some control settings. */ HPI_MIXER_STORE_DISABLE = 5, -/** Save the attributes of a single control. */ +/** Unimplemented - save the attributes of a single control. */ HPI_MIXER_STORE_SAVE_SINGLE = 6 }; @@ -941,7 +934,7 @@ enum HPI_ERROR_CODES { HPI_ERROR_BAD_ADAPTER_NUMBER = 202, /** 2 adapters with the same adapter number. */ HPI_ERROR_DUPLICATE_ADAPTER_NUMBER = 203, - /** DSP code failed to bootload. (unused?) */ + /** DSP code failed to bootload. Usually a DSP memory test failure. */ HPI_ERROR_DSP_BOOTLOAD = 204, /** Couldn't find or open the DSP code file. */ HPI_ERROR_DSP_FILE_NOT_FOUND = 206, @@ -978,6 +971,9 @@ enum HPI_ERROR_CODES { HPI_ERROR_FLASH_VERIFY = 225, HPI_ERROR_FLASH_TYPE = 226, HPI_ERROR_FLASH_START = 227, + HPI_ERROR_FLASH_READ = 228, + HPI_ERROR_FLASH_READ_NO_FILE = 229, + HPI_ERROR_FLASH_SIZE = 230, /** Reserved for OEMs. */ HPI_ERROR_RESERVED_1 = 290, @@ -1020,6 +1016,8 @@ enum HPI_ERROR_CODES { HPI_ERROR_NO_INTERDSP_GROUPS = 315, /** Stream wait cancelled before threshold reached. */ HPI_ERROR_WAIT_CANCELLED = 316, + /** A character string is invalid. */ + HPI_ERROR_INVALID_STRING = 317, /** Invalid mixer node for this adapter. */ HPI_ERROR_INVALID_NODE = 400, @@ -1046,11 +1044,15 @@ enum HPI_ERROR_CODES { /** I2C */ HPI_ERROR_I2C_BAD_ADR = 460, - /** Entity errors */ + /** Entity type did not match requested type */ HPI_ERROR_ENTITY_TYPE_MISMATCH = 470, + /** Entity item count did not match requested count */ HPI_ERROR_ENTITY_ITEM_COUNT = 471, + /** Entity type is not one of the valid types */ HPI_ERROR_ENTITY_TYPE_INVALID = 472, + /** Entity role is not one of the valid roles */ HPI_ERROR_ENTITY_ROLE_INVALID = 473, + /** Entity size doesn't match target size */ HPI_ERROR_ENTITY_SIZE_MISMATCH = 474, /* AES18 specific errors were 500..507 */ @@ -1078,8 +1080,7 @@ enum HPI_ERROR_CODES { /** \defgroup maximums HPI maximum values \{ */ -/** Maximum number of adapters per HPI sub-system - WARNING: modifying this value changes the response structure size.*/ +/** Maximum number of PCI HPI adapters */ #define HPI_MAX_ADAPTERS 20 /** Maximum number of in or out streams per adapter */ #define HPI_MAX_STREAMS 16 @@ -1090,6 +1091,9 @@ enum HPI_ERROR_CODES { #define HPI_MAX_ANC_BYTES_PER_FRAME (64) #define HPI_STRING_LEN 16 +/** Networked adapters have index >= 100 */ +#define HPI_MIN_NETWORK_ADAPTER_IDX 100 + /** Velocity units */ #define HPI_OSTREAM_VELOCITY_UNITS 4096 /** OutStream timescale units */ @@ -1111,14 +1115,14 @@ enum HPI_ERROR_CODES { struct hpi_format { u32 sample_rate; /**< 11025, 32000, 44100 ... */ - u32 bit_rate; /**< for MPEG */ + u32 bit_rate; /**< for MPEG */ u32 attributes; /**< Stereo/JointStereo/Mono */ u16 mode_legacy; /**< Legacy ancillary mode or idle bit */ - u16 unused; /**< Unused */ - u16 channels; /**< 1,2..., (or ancillary mode or idle bit */ - u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */ + u16 unused; /**< Unused */ + u16 channels; /**< 1,2..., (or ancillary mode or idle bit */ + u16 format; /**< HPI_FORMAT_PCM16, _MPEG etc. see #HPI_FORMATS. */ }; struct hpi_anc_frame { @@ -1144,9 +1148,6 @@ struct hpi_async_event { } u; }; -/* skip host side function declarations for - DSP compile and documentation extraction */ - #ifndef DISABLE_PRAGMA_PACK1 #pragma pack(pop) #endif @@ -1357,7 +1358,7 @@ u16 hpi_volume_get_mute(u32 h_control, u32 *mute); u16 hpi_volume_query_range(u32 h_control, short *min_gain_01dB, short *max_gain_01dB, short *step_gain_01dB); -u16 hpi_volume_query_channels(const u32 h_volume, u32 *p_channels); +u16 hpi_volume_query_channels(const u32 h_control, u32 *p_channels); u16 hpi_volume_auto_fade(u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms); @@ -1366,6 +1367,9 @@ u16 hpi_volume_auto_fade_profile(u32 h_control, short an_stop_gain0_01dB[HPI_MAX_CHANNELS], u32 duration_ms, u16 profile); +u16 hpi_volume_query_auto_fade_profile(const u32 h_control, const u32 i, + u16 *profile); + /*****************/ /* Level control */ /*****************/ diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 3cc6f11c20a..2414d7a2239 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -231,6 +231,8 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) static void control_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { + struct hpi_hw_obj *phw = pao->priv; + switch (phm->function) { case HPI_CONTROL_GET_STATE: if (pao->has_control_cache) { @@ -248,17 +250,14 @@ static void control_message(struct hpi_adapter_obj *pao, break; } - if (hpi_check_control_cache(((struct hpi_hw_obj *) - pao->priv)->p_cache, phm, - phr)) + if (hpi_check_control_cache(phw->p_cache, phm, phr)) break; } hw_message(pao, phm, phr); break; case HPI_CONTROL_SET_STATE: hw_message(pao, phm, phr); - hpi_cmn_control_cache_sync_to_msg(((struct hpi_hw_obj *)pao-> - priv)->p_cache, phm, phr); + hpi_cmn_control_cache_sync_to_msg(phw->p_cache, phm, phr); break; case HPI_CONTROL_GET_INFO: @@ -451,11 +450,11 @@ static void subsys_create_adapter(struct hpi_message *phm, } for (dsp_index = 0; dsp_index < MAX_DSPS; dsp_index++) { - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; phw->ado[dsp_index].pa_parent_adapter = pao; } - phr->u.s.adapter_type = ao.adapter_type; + phr->u.s.adapter_type = ao.type; phr->u.s.adapter_index = ao.index; phr->error = 0; } @@ -476,7 +475,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, u32 dsp_index = 0; u32 control_cache_size = 0; u32 control_cache_count = 0; - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; /* The PCI2040 has the following address map */ /* BAR0 - 4K = HPI control and status registers on PCI2040 (HPI CSR) */ @@ -559,7 +558,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, if (error) return error; } - pao->adapter_type = hr0.u.ax.info.adapter_type; + pao->type = hr0.u.ax.info.adapter_type; pao->index = hr0.u.ax.info.adapter_index; } @@ -584,9 +583,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, pao->has_control_cache = 1; } - HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", - pao->adapter_type, pao->index); - pao->open = 0; /* upon creation the adapter is closed */ + HPI_DEBUG_LOG(DEBUG, "get adapter info ASI%04X index %d\n", pao->type, + pao->index); if (phw->p_cache) phw->p_cache->adap_idx = pao->index; @@ -596,7 +594,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, static void delete_adapter_obj(struct hpi_adapter_obj *pao) { - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; if (pao->has_control_cache) hpi_free_control_cache(phw->p_cache); @@ -639,7 +637,7 @@ static void adapter_get_asserts(struct hpi_adapter_obj *pao, static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao, u32 *pos_error_code) { - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; short error; u32 timeout; u32 read = 0; @@ -1220,8 +1218,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao, u16 dsp_index, u32 hpi_address, u32 *source, u32 count) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 time_out = PCI_TIMEOUT; int c6711_burst_size = 128; u32 local_hpi_address = hpi_address; @@ -1258,8 +1256,8 @@ static u16 hpi6000_dsp_block_write32(struct hpi_adapter_obj *pao, static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, u16 dsp_index, u32 hpi_address, u32 *dest, u32 count) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 time_out = PCI_TIMEOUT; int c6711_burst_size = 16; u32 local_hpi_address = hpi_address; @@ -1298,7 +1296,7 @@ static u16 hpi6000_dsp_block_read32(struct hpi_adapter_obj *pao, static short hpi6000_message_response_sequence(struct hpi_adapter_obj *pao, u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 timeout; u16 ack; @@ -1414,8 +1412,8 @@ static short hpi6000_send_data_check_adr(u32 address, u32 length_in_dwords) static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 data_sent = 0; u16 ack; u32 length, address; @@ -1487,8 +1485,8 @@ static short hpi6000_send_data(struct hpi_adapter_obj *pao, u16 dsp_index, static short hpi6000_get_data(struct hpi_adapter_obj *pao, u16 dsp_index, struct hpi_message *phm, struct hpi_response *phr) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 data_got = 0; u16 ack; u32 length, address; @@ -1551,8 +1549,8 @@ static void hpi6000_send_dsp_interrupt(struct dsp_obj *pdo) static short hpi6000_send_host_command(struct hpi_adapter_obj *pao, u16 dsp_index, u32 host_cmd) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 timeout = TIMEOUT; /* set command */ @@ -1577,7 +1575,7 @@ static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao, { u32 hPI_error; - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; /* read the error bits from the PCI2040 */ hPI_error = ioread32(phw->dw2040_HPICSR + HPI_ERROR_REPORT); @@ -1597,8 +1595,8 @@ static short hpi6000_check_PCI2040_error_flag(struct hpi_adapter_obj *pao, static short hpi6000_wait_dsp_ack(struct hpi_adapter_obj *pao, u16 dsp_index, u32 ack_value) { - struct dsp_obj *pdo = - &(*(struct hpi_hw_obj *)pao->priv).ado[dsp_index]; + struct hpi_hw_obj *phw = pao->priv; + struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 ack = 0L; u32 timeout; u32 hPIC = 0L; @@ -1640,7 +1638,7 @@ static short hpi6000_update_control_cache(struct hpi_adapter_obj *pao, struct hpi_message *phm) { const u16 dsp_index = 0; - struct hpi_hw_obj *phw = (struct hpi_hw_obj *)pao->priv; + struct hpi_hw_obj *phw = pao->priv; struct dsp_obj *pdo = &phw->ado[dsp_index]; u32 timeout; u32 cache_dirty_flag; @@ -1740,7 +1738,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, { u16 error = 0; u16 dsp_index = 0; - u16 num_dsp = ((struct hpi_hw_obj *)pao->priv)->num_dsp; + struct hpi_hw_obj *phw = pao->priv; + u16 num_dsp = phw->num_dsp; if (num_dsp < 2) dsp_index = 0; diff --git a/sound/pci/asihpi/hpi6000.h b/sound/pci/asihpi/hpi6000.h index 4c7d507c0ec..7e0deeff5e7 100644 --- a/sound/pci/asihpi/hpi6000.h +++ b/sound/pci/asihpi/hpi6000.h @@ -1,7 +1,7 @@ /***************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index e041a6ae1c5..4f2873880b1 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -45,18 +45,21 @@ #define HPI6205_ERROR_MSG_RESP_TIMEOUT 1016 /* initialization/bootload errors */ -#define HPI6205_ERROR_6205_NO_IRQ 1002 -#define HPI6205_ERROR_6205_INIT_FAILED 1003 -#define HPI6205_ERROR_6205_REG 1006 -#define HPI6205_ERROR_6205_DSPPAGE 1007 -#define HPI6205_ERROR_C6713_HPIC 1009 -#define HPI6205_ERROR_C6713_HPIA 1010 -#define HPI6205_ERROR_C6713_PLL 1011 -#define HPI6205_ERROR_DSP_INTMEM 1012 -#define HPI6205_ERROR_DSP_EXTMEM 1013 -#define HPI6205_ERROR_DSP_PLD 1014 -#define HPI6205_ERROR_6205_EEPROM 1017 -#define HPI6205_ERROR_DSP_EMIF 1018 +#define HPI6205_ERROR_6205_NO_IRQ 1002 +#define HPI6205_ERROR_6205_INIT_FAILED 1003 +#define HPI6205_ERROR_6205_REG 1006 +#define HPI6205_ERROR_6205_DSPPAGE 1007 +#define HPI6205_ERROR_C6713_HPIC 1009 +#define HPI6205_ERROR_C6713_HPIA 1010 +#define HPI6205_ERROR_C6713_PLL 1011 +#define HPI6205_ERROR_DSP_INTMEM 1012 +#define HPI6205_ERROR_DSP_EXTMEM 1013 +#define HPI6205_ERROR_DSP_PLD 1014 +#define HPI6205_ERROR_6205_EEPROM 1017 +#define HPI6205_ERROR_DSP_EMIF1 1018 +#define HPI6205_ERROR_DSP_EMIF2 1019 +#define HPI6205_ERROR_DSP_EMIF3 1020 +#define HPI6205_ERROR_DSP_EMIF4 1021 /*****************************************************************************/ /* for C6205 PCI i/f */ @@ -488,7 +491,7 @@ static void subsys_create_adapter(struct hpi_message *phm, return; } - phr->u.s.adapter_type = ao.adapter_type; + phr->u.s.adapter_type = ao.type; phr->u.s.adapter_index = ao.index; phr->error = 0; } @@ -503,7 +506,7 @@ static void adapter_delete(struct hpi_adapter_obj *pao, phr->error = HPI_ERROR_INVALID_OBJ_INDEX; return; } - phw = (struct hpi_hw_obj *)pao->priv; + phw = pao->priv; /* reset adapter h/w */ /* Reset C6713 #1 */ boot_loader_write_mem32(pao, 0, C6205_BAR0_TIMER1_CTL, 0); @@ -652,7 +655,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, if (hr.error) return hr.error; - pao->adapter_type = hr.u.ax.info.adapter_type; + pao->type = hr.u.ax.info.adapter_type; pao->index = hr.u.ax.info.adapter_index; max_streams = @@ -665,8 +668,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, hr.u.ax.info.serial_number); } - pao->open = 0; /* upon creation the adapter is closed */ - if (phw->p_cache) phw->p_cache->adap_idx = pao->index; @@ -803,8 +804,8 @@ static void outstream_host_buffer_allocate(struct hpi_adapter_obj *pao, obj_index]; status->samples_processed = 0; status->stream_state = HPI_STATE_STOPPED; - status->dSP_index = 0; - status->host_index = status->dSP_index; + status->dsp_index = 0; + status->host_index = status->dsp_index; status->size_in_bytes = phm->u.d.u.buffer.buffer_size; status->auxiliary_data_available = 0; @@ -878,7 +879,7 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) { return status->size_in_bytes - (status->host_index - - status->dSP_index); + status->dsp_index); } static void outstream_write(struct hpi_adapter_obj *pao, @@ -1080,8 +1081,8 @@ static void instream_host_buffer_allocate(struct hpi_adapter_obj *pao, obj_index]; status->samples_processed = 0; status->stream_state = HPI_STATE_STOPPED; - status->dSP_index = 0; - status->host_index = status->dSP_index; + status->dsp_index = 0; + status->host_index = status->dsp_index; status->size_in_bytes = phm->u.d.u.buffer.buffer_size; status->auxiliary_data_available = 0; @@ -1162,7 +1163,7 @@ static void instream_start(struct hpi_adapter_obj *pao, static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) { - return status->dSP_index - status->host_index; + return status->dsp_index - status->host_index; } static void instream_read(struct hpi_adapter_obj *pao, @@ -1614,7 +1615,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800008, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800008)) - return HPI6205_ERROR_DSP_EMIF; + return HPI6205_ERROR_DSP_EMIF1; /* EMIF CE1 setup - 32 bit async. This is 6713 #1 HPI, */ /* which occupies D15..0. 6713 starts at 27MHz, so need */ @@ -1627,7 +1628,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800004, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800004)) - return HPI6205_ERROR_DSP_EMIF; + return HPI6205_ERROR_DSP_EMIF2; /* EMIF CE2 setup - 32 bit async. This is 6713 #2 HPI, */ /* which occupies D15..0. 6713 starts at 27MHz, so need */ @@ -1639,7 +1640,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800010, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800010)) - return HPI6205_ERROR_DSP_EMIF; + return HPI6205_ERROR_DSP_EMIF3; /* EMIF CE3 setup - 32 bit async. */ /* This is the PLD on the ASI5000 cards only */ @@ -1650,7 +1651,7 @@ static u16 boot_loader_config_emif(struct hpi_adapter_obj *pao, int dsp_index) boot_loader_write_mem32(pao, dsp_index, 0x01800014, setting); if (setting != boot_loader_read_mem32(pao, dsp_index, 0x01800014)) - return HPI6205_ERROR_DSP_EMIF; + return HPI6205_ERROR_DSP_EMIF4; /* set EMIF SDRAM control for 2Mx32 SDRAM (512x32x4 bank) */ /* need to use this else DSP code crashes? */ diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index d497030c160..4cc315daeda 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h @@ -25,6 +25,7 @@ HPI internal definitions #define _HPI_INTERNAL_H_ #include "hpi.h" + /** maximum number of memory regions mapped to an adapter */ #define HPI_MAX_ADAPTER_MEM_SPACES (2) @@ -220,8 +221,6 @@ enum HPI_CONTROL_ATTRIBUTES { HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1), HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2), - /*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */ - /*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */ HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5), HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6), HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7), @@ -241,7 +240,9 @@ enum HPI_CONTROL_ATTRIBUTES { HPI_PAD_PROGRAM_TYPE = HPI_CTL_ATTR(PAD, 5), HPI_PAD_PROGRAM_ID = HPI_CTL_ATTR(PAD, 6), HPI_PAD_TA_SUPPORT = HPI_CTL_ATTR(PAD, 7), - HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8) + HPI_PAD_TA_ACTIVE = HPI_CTL_ATTR(PAD, 8), + + HPI_UNIVERSAL_ENTITY = HPI_CTL_ATTR(UNIVERSAL, 1) }; #define HPI_POLARITY_POSITIVE 0 @@ -393,14 +394,10 @@ enum HPI_FUNCTION_IDS { HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), - /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */ HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), - /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */ HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), - /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */ - /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */ HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), @@ -430,7 +427,10 @@ enum HPI_FUNCTION_IDS { HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21), -#define HPI_ADAPTER_FUNCTION_COUNT 21 + HPI_ADAPTER_READ_FLASH = HPI_FUNC_ID(ADAPTER, 22), + HPI_ADAPTER_END_FLASH = HPI_FUNC_ID(ADAPTER, 23), + HPI_ADAPTER_FILESTORE_DELETE_ALL = HPI_FUNC_ID(ADAPTER, 24), +#define HPI_ADAPTER_FUNCTION_COUNT 24 HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), @@ -495,7 +495,9 @@ enum HPI_FUNCTION_IDS { HPI_MIXER_GET_CONTROL_MULTIPLE_VALUES = HPI_FUNC_ID(MIXER, 10), HPI_MIXER_STORE = HPI_FUNC_ID(MIXER, 11), HPI_MIXER_GET_CACHE_INFO = HPI_FUNC_ID(MIXER, 12), -#define HPI_MIXER_FUNCTION_COUNT 12 + HPI_MIXER_GET_BLOCK_HANDLE = HPI_FUNC_ID(MIXER, 13), + HPI_MIXER_GET_PARAMETER_HANDLE = HPI_FUNC_ID(MIXER, 14), +#define HPI_MIXER_FUNCTION_COUNT 14 HPI_CONTROL_GET_INFO = HPI_FUNC_ID(CONTROL, 1), HPI_CONTROL_GET_STATE = HPI_FUNC_ID(CONTROL, 2), @@ -618,7 +620,7 @@ struct hpi_hostbuffer_status { u32 auxiliary_data_available; u32 stream_state; /* DSP index in to the host bus master buffer. */ - u32 dSP_index; + u32 dsp_index; /* Host index in to the host bus master buffer. */ u32 host_index; u32 size_in_bytes; @@ -661,13 +663,6 @@ union hpi_adapterx_msg { u16 index; } module_info; struct { - u32 checksum; - u16 sequence; - u16 length; - u16 offset; /**< offset from start of msg to data */ - u16 unused; - } program_flash; - struct { u16 index; u16 what; u16 property_index; @@ -678,25 +673,18 @@ union hpi_adapterx_msg { u16 parameter2; } property_set; struct { - u32 offset; - } query_flash; - struct { u32 pad32; u16 key1; u16 key2; } restart; struct { - u32 offset; - u32 length; - u32 key; - } start_flash; - struct { u32 pad32; u16 value; } test_assert; struct { u32 yes; } irq_query; + u32 pad[3]; }; struct hpi_adapter_res { @@ -724,18 +712,10 @@ union hpi_adapterx_res { u32 adapter_mode; } mode; struct { - u16 sequence; - } program_flash; - struct { u16 parameter1; u16 parameter2; } property_get; struct { - u32 checksum; - u32 length; - u32 version; - } query_flash; - struct { u32 yes; } irq_query; }; @@ -1150,74 +1130,9 @@ struct hpi_res_adapter_get_info { struct hpi_adapter_res p; }; -/* padding is so these are same size as v0 hpi_message */ -struct hpi_msg_adapter_query_flash { - struct hpi_message_header h; - u32 offset; - u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */ - sizeof(struct hpi_message_header) - 1 * sizeof(u32)]; -}; - -/* padding is so these are same size as v0 hpi_response */ -struct hpi_res_adapter_query_flash { - struct hpi_response_header h; - u32 checksum; - u32 length; - u32 version; - u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */ - sizeof(struct hpi_response_header) - 3 * sizeof(u32)]; -}; - -struct hpi_msg_adapter_start_flash { - struct hpi_message_header h; - u32 offset; - u32 length; - u32 key; - u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 res */ - sizeof(struct hpi_message_header) - 3 * sizeof(u32)]; -}; - -struct hpi_res_adapter_start_flash { - struct hpi_response_header h; - u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */ - sizeof(struct hpi_response_header)]; -}; - -struct hpi_msg_adapter_program_flash_payload { - u32 checksum; - u16 sequence; - u16 length; - u16 offset; /**< offset from start of msg to data */ - u16 unused; - /* ensure sizeof(header + payload) == sizeof(hpi_message_V0) - because old firmware expects data after message of this size */ - u8 pad_to_version0_size[sizeof(struct hpi_message) - /* V0 message */ - sizeof(struct hpi_message_header) - sizeof(u32) - - 4 * sizeof(u16)]; -}; - -struct hpi_msg_adapter_program_flash { - struct hpi_message_header h; - struct hpi_msg_adapter_program_flash_payload p; - u32 data[256]; -}; - -struct hpi_res_adapter_program_flash { - struct hpi_response_header h; - u16 sequence; - u8 pad_to_version0_size[sizeof(struct hpi_response) - /* V0 res */ - sizeof(struct hpi_response_header) - sizeof(u16)]; -}; - -struct hpi_msg_adapter_debug_read { - struct hpi_message_header h; - u32 dsp_address; - u32 count_bytes; -}; - struct hpi_res_adapter_debug_read { struct hpi_response_header h; - u8 bytes[256]; + u8 bytes[1024]; }; struct hpi_msg_cobranet_hmi { @@ -1461,7 +1376,7 @@ struct hpi_control_cache_pad { /* 2^N sized FIFO buffer (internal to HPI<->DSP interaction) */ struct hpi_fifo_buffer { u32 size; - u32 dSP_index; + u32 dsp_index; u32 host_index; }; diff --git a/sound/pci/asihpi/hpi_version.h b/sound/pci/asihpi/hpi_version.h new file mode 100644 index 00000000000..e9146e53bd5 --- /dev/null +++ b/sound/pci/asihpi/hpi_version.h @@ -0,0 +1,32 @@ +/** HPI Version Definitions +Development releases have odd minor version. +Production releases have even minor version. + +\file hpi_version.h +*/ + +#ifndef _HPI_VERSION_H +#define _HPI_VERSION_H + +/* Use single digits for versions less that 10 to avoid octal. */ +/* *** HPI_VER is the only edit required to update version *** */ +/** HPI version */ +#define HPI_VER HPI_VERSION_CONSTRUCTOR(4, 10, 1) + +/** HPI version string in dotted decimal format */ +#define HPI_VER_STRING "4.10.01" + +/** Library version as documented in hpi-api-versions.txt */ +#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 2, 0) + +/** Construct hpi version number from major, minor, release numbers */ +#define HPI_VERSION_CONSTRUCTOR(maj, min, r) ((maj << 16) + (min << 8) + r) + +/** Extract major version from hpi version number */ +#define HPI_VER_MAJOR(v) ((int)(v >> 16)) +/** Extract minor version from hpi version number */ +#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF)) +/** Extract release from hpi version number */ +#define HPI_VER_RELEASE(v) ((int)(v & 0xFF)) + +#endif diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index bd47521b24e..7ed5c26c373 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -68,7 +68,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr) u16 hpi_add_adapter(struct hpi_adapter_obj *pao) { u16 retval = 0; - /*HPI_ASSERT(pao->wAdapterType); */ + /*HPI_ASSERT(pao->type); */ hpios_alistlock_lock(&adapters); @@ -77,13 +77,13 @@ u16 hpi_add_adapter(struct hpi_adapter_obj *pao) goto unlock; } - if (adapters.adapter[pao->index].adapter_type) { + if (adapters.adapter[pao->index].type) { int a; for (a = HPI_MAX_ADAPTERS - 1; a >= 0; a--) { - if (!adapters.adapter[a].adapter_type) { + if (!adapters.adapter[a].type) { HPI_DEBUG_LOG(WARNING, "ASI%X duplicate index %d moved to %d\n", - pao->adapter_type, pao->index, a); + pao->type, pao->index, a); pao->index = a; break; } @@ -104,13 +104,13 @@ unlock: void hpi_delete_adapter(struct hpi_adapter_obj *pao) { - if (!pao->adapter_type) { + if (!pao->type) { HPI_DEBUG_LOG(ERROR, "removing null adapter?\n"); return; } hpios_alistlock_lock(&adapters); - if (adapters.adapter[pao->index].adapter_type) + if (adapters.adapter[pao->index].type) adapters.gw_num_adapters--; memset(&adapters.adapter[pao->index], 0, sizeof(adapters.adapter[0])); hpios_alistlock_unlock(&adapters); @@ -132,7 +132,7 @@ struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index) } pao = &adapters.adapter[adapter_index]; - if (pao->adapter_type != 0) { + if (pao->type != 0) { /* HPI_DEBUG_LOG(VERBOSE, "Found adapter index %d\n", wAdapterIndex); @@ -165,7 +165,7 @@ static void subsys_get_adapter(struct hpi_message *phm, /* find the nCount'th nonzero adapter in array */ for (index = 0; index < HPI_MAX_ADAPTERS; index++) { - if (adapters.adapter[index].adapter_type) { + if (adapters.adapter[index].type) { if (!count) break; count--; @@ -174,11 +174,11 @@ static void subsys_get_adapter(struct hpi_message *phm, if (index < HPI_MAX_ADAPTERS) { phr->u.s.adapter_index = adapters.adapter[index].index; - phr->u.s.adapter_type = adapters.adapter[index].adapter_type; + phr->u.s.adapter_type = adapters.adapter[index].type; } else { phr->u.s.adapter_index = 0; phr->u.s.adapter_type = 0; - phr->error = HPI_ERROR_BAD_ADAPTER_NUMBER; + phr->error = HPI_ERROR_INVALID_OBJ_INDEX; } } @@ -324,6 +324,8 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, } phr->error = 0; + phr->specific_error = 0; + phr->version = 0; /* set the default response size */ response_size = @@ -531,8 +533,12 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache, found ? "Cached" : "Uncached", phm->adapter_index, pI->control_index, pI->control_type, phm->u.c.attribute); - if (found) + if (found) { phr->size = (u16)response_size; + phr->type = HPI_TYPE_RESPONSE; + phr->object = phm->object; + phr->function = phm->function; + } return found; } @@ -631,7 +637,7 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, if (!p_cache) return NULL; - p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count, + p_cache->p_info = kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL); if (!p_cache->p_info) { kfree(p_cache); diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index d53cdf6e535..e4412128304 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h @@ -1,7 +1,7 @@ /** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -18,12 +18,15 @@ */ +struct hpi_adapter_obj; + +/* a function that takes an adapter obj and returns an int */ +typedef int adapter_int_func(struct hpi_adapter_obj *pao); + struct hpi_adapter_obj { struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */ - u16 adapter_type; /* ASI6701 etc */ - u16 index; /* */ - u16 open; /* =1 when adapter open */ - u16 mixer_open; + u16 type; /* 0x6644 == ASI6644 etc */ + u16 index; struct hpios_spinlock dsp_lock; diff --git a/sound/pci/asihpi/hpidebug.c b/sound/pci/asihpi/hpidebug.c index b52baf62791..ac86a1f1d3b 100644 --- a/sound/pci/asihpi/hpidebug.c +++ b/sound/pci/asihpi/hpidebug.c @@ -1,7 +1,7 @@ /************************************************************************ AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpidebug.h b/sound/pci/asihpi/hpidebug.h index 940f54c3c53..2c9af2329d3 100644 --- a/sound/pci/asihpi/hpidebug.h +++ b/sound/pci/asihpi/hpidebug.h @@ -1,7 +1,7 @@ /***************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c index 71d32c868c9..456a758f04f 100644 --- a/sound/pci/asihpi/hpidspcd.c +++ b/sound/pci/asihpi/hpidspcd.c @@ -25,6 +25,7 @@ hotplug firmware loader from individual dsp code files #define SOURCEFILE_NAME "hpidspcd.c" #include "hpidspcd.h" #include "hpidebug.h" +#include "hpi_version.h" struct dsp_code_private { /** Firmware descriptor */ @@ -32,9 +33,6 @@ struct dsp_code_private { struct pci_dev *dev; }; -#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ - HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) - /*-------------------------------------------------------------------*/ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, u32 *os_error_code) @@ -66,22 +64,25 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, if ((header.type != 0x45444F43) || /* "CODE" */ (header.adapter != adapter) || (header.size != firmware->size)) { - dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n"); + dev_printk(KERN_ERR, &dev->dev, + "Invalid firmware header size %d != file %zd\n", + header.size, firmware->size); goto error2; } - if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) { + if ((header.version >> 9) != (HPI_VER >> 9)) { + /* Consider even and subsequent odd minor versions to be compatible */ dev_printk(KERN_ERR, &dev->dev, "Incompatible firmware version " - "DSP image %d != Driver %d\n", header.version, - HPI_VER_DECIMAL); + "DSP image %X != Driver %X\n", header.version, + HPI_VER); goto error2; } - if (header.version != HPI_VER_DECIMAL) { - dev_printk(KERN_WARNING, &dev->dev, - "Firmware: release version mismatch DSP image %d != Driver %d\n", - header.version, HPI_VER_DECIMAL); + if (header.version != HPI_VER) { + dev_printk(KERN_INFO, &dev->dev, + "Firmware: release version mismatch DSP image %X != Driver %X\n", + header.version, HPI_VER); } HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); @@ -108,11 +109,8 @@ error1: /*-------------------------------------------------------------------*/ void hpi_dsp_code_close(struct dsp_code *dsp_code) { - if (dsp_code->pvt->firmware) { - HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); - release_firmware(dsp_code->pvt->firmware); - dsp_code->pvt->firmware = NULL; - } + HPI_DEBUG_LOG(DEBUG, "dsp code closed\n"); + release_firmware(dsp_code->pvt->firmware); kfree(dsp_code->pvt); } diff --git a/sound/pci/asihpi/hpidspcd.h b/sound/pci/asihpi/hpidspcd.h index b22881122f1..659d19ca6d4 100644 --- a/sound/pci/asihpi/hpidspcd.h +++ b/sound/pci/asihpi/hpidspcd.h @@ -27,10 +27,6 @@ Functions for reading DSP code to load into DSP #include "hpi_internal.h" -/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */ -#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \ -HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER))) - /** Header structure for dsp firmware file This structure must match that used in s2bin.c for generation of asidsp.bin */ diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index ebb568d695f..510e56cffd3 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c @@ -2826,6 +2826,16 @@ u16 hpi_volume_auto_fade(u32 h_control, duration_ms, HPI_VOLUME_AUTOFADE_LOG); } +u16 hpi_volume_query_auto_fade_profile(const u32 h_volume, const u32 i, + u16 *profile) +{ + u16 e; + u32 u; + e = hpi_control_query(h_volume, HPI_VOLUME_AUTOFADE, i, 0, &u); + *profile = (u16)u; + return e; +} + u16 hpi_vox_set_threshold(u32 h_control, short an_gain0_01dB) { struct hpi_message hm; diff --git a/sound/pci/asihpi/hpimsginit.c b/sound/pci/asihpi/hpimsginit.c index 52400a6b5f1..032d563e370 100644 --- a/sound/pci/asihpi/hpimsginit.c +++ b/sound/pci/asihpi/hpimsginit.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpimsginit.h b/sound/pci/asihpi/hpimsginit.h index bfd330d78b5..5b48708c7d1 100644 --- a/sound/pci/asihpi/hpimsginit.h +++ b/sound/pci/asihpi/hpimsginit.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index 2e779421a61..d4790ddc225 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -22,6 +22,7 @@ Extended Message Function With Response Caching *****************************************************************************/ #define SOURCEFILE_NAME "hpimsgx.c" #include "hpi_internal.h" +#include "hpi_version.h" #include "hpimsginit.h" #include "hpicmn.h" #include "hpimsgx.h" diff --git a/sound/pci/asihpi/hpimsgx.h b/sound/pci/asihpi/hpimsgx.h index fd49e7542a8..37f3efd95a7 100644 --- a/sound/pci/asihpi/hpimsgx.h +++ b/sound/pci/asihpi/hpimsgx.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index f6b9517b469..60915620556 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -21,6 +21,7 @@ Common Linux HPI ioctl and module probe/remove functions #define SOURCEFILE_NAME "hpioctl.c" #include "hpi_internal.h" +#include "hpi_version.h" #include "hpimsginit.h" #include "hpidebug.h" #include "hpimsgx.h" @@ -65,9 +66,7 @@ static struct hpi_adapter adapters[HPI_MAX_ADAPTERS]; static void hpi_send_recv_f(struct hpi_message *phm, struct hpi_response *phr, struct file *file) { - int adapter = phm->adapter_index; - - if ((adapter >= HPI_MAX_ADAPTERS || adapter < 0) + if ((phm->adapter_index >= HPI_MAX_ADAPTERS) && (phm->object != HPI_OBJ_SUBSYSTEM)) phr->error = HPI_ERROR_INVALID_OBJ_INDEX; else @@ -178,19 +177,14 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } else { u16 __user *ptr = NULL; u32 size = 0; - u32 adapter_present; /* -1=no data 0=read from user mem, 1=write to user mem */ int wrflag = -1; - struct hpi_adapter *pa; + struct hpi_adapter *pa = NULL; - if (hm->h.adapter_index < HPI_MAX_ADAPTERS) { + if (hm->h.adapter_index < ARRAY_SIZE(adapters)) pa = &adapters[hm->h.adapter_index]; - adapter_present = pa->type; - } else { - adapter_present = 0; - } - if (!adapter_present) { + if (!pa || !pa->adapter || !pa->adapter->type) { hpi_init_response(&hr->r0, hm->h.object, hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER); @@ -317,6 +311,7 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { int idx, nm; + int adapter_index; unsigned int memlen; struct hpi_message hm; struct hpi_response hr; @@ -345,8 +340,6 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, hm.adapter_index = HPI_ADAPTER_INDEX_INVALID; - adapter.pci = pci_dev; - nm = HPI_MAX_ADAPTER_MEM_SPACES; for (idx = 0; idx < nm; idx++) { @@ -355,18 +348,16 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { memlen = pci_resource_len(pci_dev, idx); - adapter.ap_remapped_mem_base[idx] = + pci.ap_mem_base[idx] = ioremap(pci_resource_start(pci_dev, idx), memlen); - if (!adapter.ap_remapped_mem_base[idx]) { + if (!pci.ap_mem_base[idx]) { HPI_DEBUG_LOG(ERROR, "ioremap failed, aborting\n"); /* unmap previously mapped pci mem space */ goto err; } } - - pci.ap_mem_base[idx] = adapter.ap_remapped_mem_base[idx]; } pci.pci_dev = pci_dev; @@ -378,6 +369,9 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, if (hr.error) goto err; + adapter_index = hr.u.s.adapter_index; + adapter.adapter = hpi_find_adapter(adapter_index); + if (prealloc_stream_buf) { adapter.p_buffer = vmalloc(prealloc_stream_buf); if (!adapter.p_buffer) { @@ -389,36 +383,32 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, } } - adapter.index = hr.u.s.adapter_index; - adapter.type = hr.u.s.adapter_type; - hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, HPI_ADAPTER_OPEN); - hm.adapter_index = adapter.index; + hm.adapter_index = adapter.adapter->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); if (hr.error) goto err; - adapter.snd_card_asihpi = NULL; /* WARNING can't init mutex in 'adapter' * and then copy it to adapters[] ?!?! */ - adapters[adapter.index] = adapter; - mutex_init(&adapters[adapter.index].mutex); - pci_set_drvdata(pci_dev, &adapters[adapter.index]); + adapters[adapter_index] = adapter; + mutex_init(&adapters[adapter_index].mutex); + pci_set_drvdata(pci_dev, &adapters[adapter_index]); dev_printk(KERN_INFO, &pci_dev->dev, - "probe succeeded for ASI%04X HPI index %d\n", adapter.type, - adapter.index); + "probe succeeded for ASI%04X HPI index %d\n", + adapter.adapter->type, adapter_index); return 0; err: for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { - if (adapter.ap_remapped_mem_base[idx]) { - iounmap(adapter.ap_remapped_mem_base[idx]); - adapter.ap_remapped_mem_base[idx] = NULL; + if (pci.ap_mem_base[idx]) { + iounmap(pci.ap_mem_base[idx]); + pci.ap_mem_base[idx] = NULL; } } @@ -437,19 +427,20 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) struct hpi_message hm; struct hpi_response hr; struct hpi_adapter *pa; + struct hpi_pci pci; + pa = pci_get_drvdata(pci_dev); + pci = pa->adapter->pci; hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, HPI_ADAPTER_DELETE); - hm.adapter_index = pa->index; + hm.adapter_index = pa->adapter->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); /* unmap PCI memory space, mapped during device init. */ for (idx = 0; idx < HPI_MAX_ADAPTER_MEM_SPACES; idx++) { - if (pa->ap_remapped_mem_base[idx]) { - iounmap(pa->ap_remapped_mem_base[idx]); - pa->ap_remapped_mem_base[idx] = NULL; - } + if (pci.ap_mem_base[idx]) + iounmap(pci.ap_mem_base[idx]); } if (pa->p_buffer) @@ -461,7 +452,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) "remove %04x:%04x,%04x:%04x,%04x," " HPI index %d.\n", pci_dev->vendor, pci_dev->device, pci_dev->subsystem_vendor, pci_dev->subsystem_device, - pci_dev->devfn, pa->index); + pci_dev->devfn, pa->adapter->index); memset(pa, 0, sizeof(*pa)); } diff --git a/sound/pci/asihpi/hpioctl.h b/sound/pci/asihpi/hpioctl.h index 847f72f03fe..2614aff672e 100644 --- a/sound/pci/asihpi/hpioctl.h +++ b/sound/pci/asihpi/hpioctl.h @@ -1,7 +1,7 @@ /******************************************************************************* AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpios.c b/sound/pci/asihpi/hpios.c index ff2a19b544f..2d7d1c2e1d0 100644 --- a/sound/pci/asihpi/hpios.c +++ b/sound/pci/asihpi/hpios.c @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/asihpi/hpios.h b/sound/pci/asihpi/hpios.h index 2f605e34bad..c5cef113c20 100644 --- a/sound/pci/asihpi/hpios.h +++ b/sound/pci/asihpi/hpios.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as @@ -149,20 +149,18 @@ static inline void cond_unlock(struct hpios_spinlock *l) #define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock)) #define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock)) +struct snd_card; + +/** pci drvdata points to an instance of this struct */ struct hpi_adapter { + struct hpi_adapter_obj *adapter; + struct snd_card *snd_card; + /* mutex prevents contention for one card between multiple user programs (via ioctl) */ struct mutex mutex; - u16 index; - u16 type; - - /* ALSA card structure */ - void *snd_card_asihpi; - char *p_buffer; size_t buffer_size; - struct pci_dev *pci; - void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES]; }; #endif diff --git a/sound/pci/asihpi/hpipcida.h b/sound/pci/asihpi/hpipcida.h index bb30868ce1a..db570ddf64b 100644 --- a/sound/pci/asihpi/hpipcida.h +++ b/sound/pci/asihpi/hpipcida.h @@ -1,7 +1,7 @@ /****************************************************************************** AudioScience HPI driver - Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com> + Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com> This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 15e4e5ee388..590682f115e 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -43,7 +43,7 @@ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int ac97_clock = 48000; static char *ac97_quirk; -static int spdif_aclink = 1; +static bool spdif_aclink = 1; static int ac97_codec = -1; module_param(index, int, 0444); @@ -60,7 +60,7 @@ module_param(spdif_aclink, bool, 0444); MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 57bf8f4bc7a..524d35f3123 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -51,7 +51,7 @@ module_param(ac97_clock, int, 0444); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index dc326be58c4..762bb108c51 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -26,7 +26,7 @@ // module parameters (see "Module Parameters") static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static int pcifix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 255 }; module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 489150380ea..6933a27a5d7 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -805,7 +805,7 @@ static void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en) } static void -vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority, +vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int stereo, int priority, int empty, int valid, int f) { int temp, lifeboat = 0; @@ -837,7 +837,7 @@ vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority, #else temp = (this_4 & 0x3f) << 0xc; #endif - temp = (temp & 0xfffffffd) | ((b & 1) << 1); + temp = (temp & 0xfffffffd) | ((stereo & 1) << 1); temp = (temp & 0xfffffff3) | ((priority & 3) << 2); temp = (temp & 0xffffffef) | ((valid & 1) << 4); temp |= FIFO_U1; @@ -1148,11 +1148,11 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, - int fmt, int d, u32 offset) + int fmt, int stereo, u32 offset) { stream_t *dma = &vortex->dma_adb[adbdma]; - dma->dma_unknown = d; + dma->dma_unknown = stereo; dma->dma_ctrl = ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK)); /* Enable PCMOUT interrupts. */ @@ -1336,7 +1336,6 @@ static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma) dma->fifo_status = FIFO_PAUSE; } -#if 0 // Using pause instead static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma) { stream_t *dma = &vortex->dma_adb[adbdma]; @@ -1351,7 +1350,6 @@ static void vortex_adbdma_stopfifo(vortex_t * vortex, int adbdma) dma->fifo_enabled = 0; } -#endif /* WTDMA */ #ifndef CHIP_AU8810 diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index c5f7ae46afe..0488633ea87 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -307,8 +307,8 @@ static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream) fmt = vortex_alsafmt_aspfmt(runtime->format); spin_lock_irq(&chip->lock); if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { - vortex_adbdma_setmode(chip, dma, 1, dir, fmt, 0 /*? */ , - 0); + vortex_adbdma_setmode(chip, dma, 1, dir, fmt, + runtime->channels == 1 ? 0 : 1, 0); vortex_adbdma_setstartbuffer(chip, dma, 0); if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF) vortex_adb_setsrc(chip, dma, runtime->rate, dir); @@ -353,8 +353,7 @@ static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd) //printk(KERN_INFO "vortex: stop %d\n", dma); stream->fifo_enabled = 0; if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) - vortex_adbdma_pausefifo(chip, dma); - //vortex_adbdma_stopfifo(chip, dma); + vortex_adbdma_stopfifo(chip, dma); #ifndef CHIP_AU8810 else { printk(KERN_INFO "vortex: wt stop %d\n", dma); diff --git a/sound/pci/au88x0/au88x0_xtalk.c b/sound/pci/au88x0/au88x0_xtalk.c index b4151e208b7..b278e285fd4 100644 --- a/sound/pci/au88x0/au88x0_xtalk.c +++ b/sound/pci/au88x0/au88x0_xtalk.c @@ -48,43 +48,61 @@ static unsigned short const wXtalkNarrowLeftDelay = 0x7; static unsigned short const wXtalkNarrowRightDelay = 0x7; static xtalk_gains_t const asXtalkGainsDefault = { - 0x4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000, 0x4000, 4000, - 0x4000 + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000, + 0x4000, 0x4000, 0x4000, 0x4000, 0x4000 }; static xtalk_gains_t const asXtalkGainsTest = { - 0x8000, 0x7FFF, 0, 0xFFFF, 0x0001, 0xC000, 0x4000, 0xFFFE, 0x0002, - 0 + 0x7fff, 0x8000, 0x0000, 0x0000, 0x0001, + 0xffff, 0x4000, 0xc000, 0x0002, 0xfffe }; + static xtalk_gains_t const asXtalkGains1Chan = { - 0x7FFF, 0, 0, 0, 0x7FFF, 0, 0, 0, 0, 0 + 0x7FFF, 0, 0, 0, 0, + 0x7FFF, 0, 0, 0, 0, }; // Input gain for 4 A3D slices. One possible input pair is left zero. static xtalk_gains_t const asXtalkGainsAllChan = { - 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, - 0 - //0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff,0x7FFF,0x7FFF,0x7FFF,0x7FFF,0x7fff + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0, + 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0 +}; + +static xtalk_gains_t const asXtalkGainsZeros = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static xtalk_gains_t const asXtalkGainsZeros; -static xtalk_dline_t const alXtalkDlineZeros; +static xtalk_dline_t const alXtalkDlineZeros = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; static xtalk_dline_t const alXtalkDlineTest = { - 0xFC18, 0x03E8FFFF, 0x186A0, 0x7960FFFE, 1, 0xFFFFFFFF, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0x0000fc18, 0xfff03e8, 0x000186a0, 0xfffe7960, 1, 0xffffffff, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static xtalk_instate_t const asXtalkInStateZeros = { 0, 0, 0, 0 }; -static xtalk_instate_t const asXtalkInStateZeros; -static xtalk_instate_t const asXtalkInStateTest = - { 0xFF80, 0x0080, 0xFFFF, 0x0001 }; -static xtalk_state_t const asXtalkOutStateZeros; +static xtalk_instate_t const asXtalkInStateTest = { + 0x0080, 0xff80, 0x0001, 0xffff +}; + +static xtalk_state_t const asXtalkOutStateZeros = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; static short const sDiamondKLeftEq = 0x401d; static short const sDiamondKRightEq = 0x401d; static short const sDiamondKLeftXt = 0xF90E; static short const sDiamondKRightXt = 0xF90E; -static short const sDiamondShiftLeftEq = 1; /* 0xF90E Is this a bug ??? */ +static short const sDiamondShiftLeftEq = 1; static short const sDiamondShiftRightEq = 1; static short const sDiamondShiftLeftXt = 0; static short const sDiamondShiftRightXt = 0; @@ -94,29 +112,29 @@ static unsigned short const wDiamondRightDelay = 0xb; static xtalk_coefs_t const asXtalkWideCoefsLeftEq = { {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0}, {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0}, - {0x340B, 0xf504, 0x6CE8, 0x0D23, 0x00E4}, - {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA}, + {0x340B, 0xe8f5, 0x236c, 0xe40d, 0}, + {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0}, {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0} }; static xtalk_coefs_t const asXtalkWideCoefsRightEq = { {0xEC4C, 0xDCE9, 0xFDC2, 0xFEEC, 0}, {0x5F60, 0xCBCB, 0xFC26, 0x0305, 0}, - {0x340B, 0xF504, 0x6CE8, 0x0D23, 0x00E4}, - {0xD500, 0x8D76, 0xACC7, 0x5B05, 0x00FA}, + {0x340B, 0xe8f5, 0x236c, 0xe40d, 0}, + {0x76d5, 0xc78d, 0x05ac, 0xfa5b, 0}, {0x7F04, 0xC0FA, 0x0263, 0xFDA2, 0} }; static xtalk_coefs_t const asXtalkWideCoefsLeftXt = { - {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047}, - {0x6000, 0x206A, 0xC6CA, 0x40FF, 0}, - {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001}, - {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0}, + {0x55c6, 0xc97b, 0x005b, 0x0047, 0}, + {0x6a60, 0xca20, 0xffc6, 0x0040, 0}, + {0x6411, 0xd711, 0xfca1, 0x0190, 0}, + {0x77dc, 0xc79e, 0xffb8, 0x000a, 0}, {0, 0, 0, 0, 0} }; static xtalk_coefs_t const asXtalkWideCoefsRightXt = { - {0x86C3, 0x7B55, 0x89C3, 0x005B, 0x0047}, - {0x6000, 0x206A, 0xC6CA, 0x40FF, 0}, - {0x1100, 0x1164, 0xA1D7, 0x90FC, 0x0001}, - {0xDC00, 0x9E77, 0xB8C7, 0x0AFF, 0}, + {0x55c6, 0xc97b, 0x005b, 0x0047, 0}, + {0x6a60, 0xca20, 0xffc6, 0x0040, 0}, + {0x6411, 0xd711, 0xfca1, 0x0190, 0}, + {0x77dc, 0xc79e, 0xffb8, 0x000a, 0}, {0, 0, 0, 0, 0} }; static xtalk_coefs_t const asXtalkNarrowCoefsLeftEq = { @@ -151,7 +169,14 @@ static xtalk_coefs_t const asXtalkNarrowCoefsRightXt = { {0, 0, 0, 0, 0} }; -static xtalk_coefs_t const asXtalkCoefsZeros; +static xtalk_coefs_t const asXtalkCoefsZeros = { + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0} +}; + static xtalk_coefs_t const asXtalkCoefsPipe = { {0, 0, 0x0FA0, 0, 0}, {0, 0, 0x0FA0, 0, 0}, @@ -186,7 +211,7 @@ static xtalk_coefs_t const asXtalkCoefsDenTest = { static xtalk_state_t const asXtalkOutStateTest = { {0x7FFF, 0x0004, 0xFFFC, 0}, {0xFE00, 0x0008, 0xFFF8, 0x4000}, - {0x200, 0x0010, 0xFFF0, 0xC000}, + {0x0200, 0x0010, 0xFFF0, 0xC000}, {0x8000, 0x0020, 0xFFE0, 0}, {0, 0, 0, 0} }; @@ -306,10 +331,10 @@ vortex_XtalkHw_SetLeftEQStates(vortex_t * vortex, hwwrite(vortex->mmio, 0x2421C + i * 0x24, coefs[i][2]); hwwrite(vortex->mmio, 0x24220 + i * 0x24, coefs[i][3]); } - hwwrite(vortex->mmio, 0x244F8 + i * 0x24, arg_0[0]); - hwwrite(vortex->mmio, 0x244FC + i * 0x24, arg_0[1]); - hwwrite(vortex->mmio, 0x24500 + i * 0x24, arg_0[2]); - hwwrite(vortex->mmio, 0x24504 + i * 0x24, arg_0[3]); + hwwrite(vortex->mmio, 0x244F8, arg_0[0]); + hwwrite(vortex->mmio, 0x244FC, arg_0[1]); + hwwrite(vortex->mmio, 0x24500, arg_0[2]); + hwwrite(vortex->mmio, 0x24504, arg_0[3]); } static void @@ -325,10 +350,10 @@ vortex_XtalkHw_SetRightEQStates(vortex_t * vortex, hwwrite(vortex->mmio, 0x242D0 + i * 0x24, coefs[i][2]); hwwrite(vortex->mmio, 0x244D4 + i * 0x24, coefs[i][3]); } - hwwrite(vortex->mmio, 0x24508 + i * 0x24, arg_0[0]); - hwwrite(vortex->mmio, 0x2450C + i * 0x24, arg_0[1]); - hwwrite(vortex->mmio, 0x24510 + i * 0x24, arg_0[2]); - hwwrite(vortex->mmio, 0x24514 + i * 0x24, arg_0[3]); + hwwrite(vortex->mmio, 0x24508, arg_0[0]); + hwwrite(vortex->mmio, 0x2450C, arg_0[1]); + hwwrite(vortex->mmio, 0x24510, arg_0[2]); + hwwrite(vortex->mmio, 0x24514, arg_0[3]); } static void @@ -344,10 +369,10 @@ vortex_XtalkHw_SetLeftXTStates(vortex_t * vortex, hwwrite(vortex->mmio, 0x24384 + i * 0x24, coefs[i][2]); hwwrite(vortex->mmio, 0x24388 + i * 0x24, coefs[i][3]); } - hwwrite(vortex->mmio, 0x24518 + i * 0x24, arg_0[0]); - hwwrite(vortex->mmio, 0x2451C + i * 0x24, arg_0[1]); - hwwrite(vortex->mmio, 0x24520 + i * 0x24, arg_0[2]); - hwwrite(vortex->mmio, 0x24524 + i * 0x24, arg_0[3]); + hwwrite(vortex->mmio, 0x24518, arg_0[0]); + hwwrite(vortex->mmio, 0x2451C, arg_0[1]); + hwwrite(vortex->mmio, 0x24520, arg_0[2]); + hwwrite(vortex->mmio, 0x24524, arg_0[3]); } static void @@ -363,10 +388,10 @@ vortex_XtalkHw_SetRightXTStates(vortex_t * vortex, hwwrite(vortex->mmio, 0x24438 + i * 0x24, coefs[i][2]); hwwrite(vortex->mmio, 0x2443C + i * 0x24, coefs[i][3]); } - hwwrite(vortex->mmio, 0x24528 + i * 0x24, arg_0[0]); - hwwrite(vortex->mmio, 0x2452C + i * 0x24, arg_0[1]); - hwwrite(vortex->mmio, 0x24530 + i * 0x24, arg_0[2]); - hwwrite(vortex->mmio, 0x24534 + i * 0x24, arg_0[3]); + hwwrite(vortex->mmio, 0x24528, arg_0[0]); + hwwrite(vortex->mmio, 0x2452C, arg_0[1]); + hwwrite(vortex->mmio, 0x24530, arg_0[2]); + hwwrite(vortex->mmio, 0x24534, arg_0[3]); } #if 0 @@ -450,10 +475,10 @@ vortex_XtalkHw_GetLeftEQStates(vortex_t * vortex, xtalk_instate_t arg_0, coefs[i][2] = hwread(vortex->mmio, 0x2421C + i * 0x24); coefs[i][3] = hwread(vortex->mmio, 0x24220 + i * 0x24); } - arg_0[0] = hwread(vortex->mmio, 0x244F8 + i * 0x24); - arg_0[1] = hwread(vortex->mmio, 0x244FC + i * 0x24); - arg_0[2] = hwread(vortex->mmio, 0x24500 + i * 0x24); - arg_0[3] = hwread(vortex->mmio, 0x24504 + i * 0x24); + arg_0[0] = hwread(vortex->mmio, 0x244F8); + arg_0[1] = hwread(vortex->mmio, 0x244FC); + arg_0[2] = hwread(vortex->mmio, 0x24500); + arg_0[3] = hwread(vortex->mmio, 0x24504); } static void @@ -468,10 +493,10 @@ vortex_XtalkHw_GetRightEQStates(vortex_t * vortex, xtalk_instate_t arg_0, coefs[i][2] = hwread(vortex->mmio, 0x242D0 + i * 0x24); coefs[i][3] = hwread(vortex->mmio, 0x242D4 + i * 0x24); } - arg_0[0] = hwread(vortex->mmio, 0x24508 + i * 0x24); - arg_0[1] = hwread(vortex->mmio, 0x2450C + i * 0x24); - arg_0[2] = hwread(vortex->mmio, 0x24510 + i * 0x24); - arg_0[3] = hwread(vortex->mmio, 0x24514 + i * 0x24); + arg_0[0] = hwread(vortex->mmio, 0x24508); + arg_0[1] = hwread(vortex->mmio, 0x2450C); + arg_0[2] = hwread(vortex->mmio, 0x24510); + arg_0[3] = hwread(vortex->mmio, 0x24514); } static void @@ -486,10 +511,10 @@ vortex_XtalkHw_GetLeftXTStates(vortex_t * vortex, xtalk_instate_t arg_0, coefs[i][2] = hwread(vortex->mmio, 0x24384 + i * 0x24); coefs[i][3] = hwread(vortex->mmio, 0x24388 + i * 0x24); } - arg_0[0] = hwread(vortex->mmio, 0x24518 + i * 0x24); - arg_0[1] = hwread(vortex->mmio, 0x2451C + i * 0x24); - arg_0[2] = hwread(vortex->mmio, 0x24520 + i * 0x24); - arg_0[3] = hwread(vortex->mmio, 0x24524 + i * 0x24); + arg_0[0] = hwread(vortex->mmio, 0x24518); + arg_0[1] = hwread(vortex->mmio, 0x2451C); + arg_0[2] = hwread(vortex->mmio, 0x24520); + arg_0[3] = hwread(vortex->mmio, 0x24524); } static void @@ -504,10 +529,10 @@ vortex_XtalkHw_GetRightXTStates(vortex_t * vortex, xtalk_instate_t arg_0, coefs[i][2] = hwread(vortex->mmio, 0x24438 + i * 0x24); coefs[i][3] = hwread(vortex->mmio, 0x2443C + i * 0x24); } - arg_0[0] = hwread(vortex->mmio, 0x24528 + i * 0x24); - arg_0[1] = hwread(vortex->mmio, 0x2452C + i * 0x24); - arg_0[2] = hwread(vortex->mmio, 0x24530 + i * 0x24); - arg_0[3] = hwread(vortex->mmio, 0x24534 + i * 0x24); + arg_0[0] = hwread(vortex->mmio, 0x24528); + arg_0[1] = hwread(vortex->mmio, 0x2452C); + arg_0[2] = hwread(vortex->mmio, 0x24530); + arg_0[3] = hwread(vortex->mmio, 0x24534); } #endif diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 7a581151db0..1c523193146 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -153,7 +153,7 @@ static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol, ********************************/ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard."); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index bc1e6830b50..95ffa6a9db6 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -301,7 +301,7 @@ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ module_param_array(id, charp, NULL, 0444); MODULE_PARM_DESC(id, "ID string for AZF3328 soundcard."); -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "Enable AZF3328 soundcard."); diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index c1c2d0c1c7f..62d6163fc9d 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -42,9 +42,9 @@ MODULE_SUPPORTED_DEVICE("{{Brooktree,Bt878}," static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int digital_rate[SNDRV_CARDS]; /* digital input rate */ -static int load_all; /* allow to load the non-whitelisted cards */ +static bool load_all; /* allow to load the non-whitelisted cards */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Bt87x soundcard"); diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index fe99fdeaf15..08d6ebfe5a6 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -156,7 +156,7 @@ MODULE_SUPPORTED_DEVICE("{{Creative,SB CA0106 chip}}"); // module parameters (see "Module Parameters") static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 954c9934748..19b06269adc 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -54,10 +54,10 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static long mpu_port[SNDRV_CARDS]; static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; -static int soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; +static bool soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1}; #ifdef SUPPORT_JOYSTICK static int joystick_port[SNDRV_CARDS]; #endif diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index a6c6c5c53af..a9f368f60df 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -44,8 +44,8 @@ MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,CS4281}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ -static int dual_codec[SNDRV_CARDS]; /* dual codec */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool dual_codec[SNDRV_CARDS]; /* dual codec */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for CS4281 soundcard."); diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index a4ecb40f850..819d79d0586 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -46,10 +46,10 @@ MODULE_SUPPORTED_DEVICE("{{Cirrus Logic,Sound Fusion (CS4280)}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static int external_amp[SNDRV_CARDS]; -static int thinkpad[SNDRV_CARDS]; -static int mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool external_amp[SNDRV_CARDS]; +static bool thinkpad[SNDRV_CARDS]; +static bool mmap_valid[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the CS46xx soundcard."); diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index 958f4949e97..c47cabff2bf 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c @@ -50,7 +50,14 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for CS5530 Audio driver."); +module_param_array(id, charp, NULL, 0444); +MODULE_PARM_DESC(id, "ID string for CS5530 Audio driver."); +module_param_array(enable, bool, NULL, 0444); +MODULE_PARM_DESC(enable, "Enable CS5530 Audio driver."); struct snd_cs5530 { struct snd_card *card; diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index b8959d2c804..a2fb2173e98 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c @@ -57,7 +57,7 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " DRIVER_NAME); diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index e083122ca55..dbf94b189e7 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, struct cs5535audio_dma_desc *desc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; desc->addr = cpu_to_le32(addr); - desc->size = cpu_to_le32(period_bytes); + desc->size = cpu_to_le16(period_bytes); desc->ctlreserved = cpu_to_le16(PRD_EOP); desc_addr += sizeof(struct cs5535audio_dma_desc); addr += period_bytes; diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index e134b3a5780..6e77e86307c 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -437,7 +437,7 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc) /* Allocate mem for master src resource */ if (MEMRD == desc->mode) - src = kzalloc(sizeof(*src)*desc->multi, GFP_KERNEL); + src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL); else src = kzalloc(sizeof(*src), GFP_KERNEL); diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index 93b0aedc36d..03fb909085a 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c @@ -15,8 +15,8 @@ #include "cthardware.h" #include "cttimer.h" -static int use_system_timer; -MODULE_PARM_DESC(use_system_timer, "Foce to use system-timer"); +static bool use_system_timer; +MODULE_PARM_DESC(use_system_timer, "Force to use system-timer"); module_param(use_system_timer, bool, S_IRUGO); struct ct_timer_ops { diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c index 33931ef5e12..15d95d2bace 100644 --- a/sound/pci/ctxfi/xfi.c +++ b/sound/pci/ctxfi/xfi.c @@ -32,7 +32,7 @@ module_param(multiple, uint, S_IRUGO); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static unsigned int subsystem[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 9fd694c6186..595c11f904b 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -26,7 +26,7 @@ MODULE_DEVICE_TABLE(pci, snd_echo_ids); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " ECHOCARD_NAME " soundcard."); diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index eaa198e122c..790c65d980c 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c @@ -44,13 +44,13 @@ MODULE_SUPPORTED_DEVICE("{{Creative Labs,SB Live!/PCI512/E-mu APS}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int extin[SNDRV_CARDS]; static int extout[SNDRV_CARDS]; static int seq_ports[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4}; static int max_synth_voices[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 64}; static int max_buffer_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 128}; -static int enable_ir[SNDRV_CARDS]; +static bool enable_ir[SNDRV_CARDS]; static uint subsystem[SNDRV_CARDS]; /* Force card subsystem model */ static uint delay_pcm_irq[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 6a3e5677f59..754924081d0 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -1480,6 +1480,18 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spdif_bug = 1, .invert_shared_spdif = 1, /* digital/analog switch swapped */ .ac97_chip = 1} , + /* 0x20051102 also has SB0350 written on it, treated as Audigy 2 ZS by + Creative's Windows driver */ + {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20051102, + .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350a]", + .id = "Audigy2", + .emu10k2_chip = 1, + .ca0102_chip = 1, + .ca0151_chip = 1, + .spk71 = 1, + .spdif_bug = 1, + .invert_shared_spdif = 1, /* digital/analog switch swapped */ + .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]", .id = "Audigy2", diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 2228be9f30e..47a651cb6e8 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -50,7 +50,7 @@ MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}"); // module parameters (see "Module Parameters") static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the EMU10K1X soundcard."); diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index d085ad03efe..47a245e8419 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -83,12 +83,12 @@ MODULE_SUPPORTED_DEVICE("{{Ensoniq,AudioPCI ES1371/73}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ #ifdef SUPPORT_JOYSTICK #ifdef CHIP1371 static int joystick_port[SNDRV_CARDS]; #else -static int joystick[SNDRV_CARDS]; +static bool joystick[SNDRV_CARDS]; #endif #endif #ifdef CHIP1371 diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 04cc21f5d01..53eb76b4110 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -79,7 +79,7 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES1938}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for ESS Solo-1 soundcard."); diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 297a151bdba..cb557c603a8 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -132,7 +132,7 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro 2e}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 1-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int total_bufsize[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1024 }; static int pcm_substreams_p[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 4 }; static int pcm_substreams_c[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1 }; @@ -140,7 +140,7 @@ static int clock[SNDRV_CARDS]; static int use_pm[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; #ifdef SUPPORT_JOYSTICK -static int joystick[SNDRV_CARDS]; +static bool joystick[SNDRV_CARDS]; #endif module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index ec05ef5a5ab..9597ef1eccc 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c @@ -48,7 +48,7 @@ MODULE_SUPPORTED_DEVICE("{{ForteMedia,FM801}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ /* * Enable TEA575x tuner * 1 = MediaForte 256-PCS diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index bb7e102d672..163b6b5de3e 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig @@ -2,6 +2,7 @@ menuconfig SND_HDA_INTEL tristate "Intel HD Audio" select SND_PCM select SND_VMASTER + select SND_KCTL_JACK help Say Y here to include support for Intel "High Definition Audio" (Azalia) and its compatible devices. diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index f928d663472..ace157cc3d1 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,6 +1,6 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-y := hda_codec.o +snd-hda-codec-y := hda_codec.o hda_jack.o snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c deleted file mode 100644 index 7894b2b5aac..00000000000 --- a/sound/pci/hda/alc262_quirks.c +++ /dev/null @@ -1,875 +0,0 @@ -/* - * ALC262 quirk models - * included by patch_realtek.c - */ - -/* ALC262 models */ -enum { - ALC262_AUTO, - ALC262_BASIC, - ALC262_HIPPO, - ALC262_HIPPO_1, - ALC262_FUJITSU, - ALC262_BENQ_ED8, - ALC262_BENQ_T31, - ALC262_ULTRA, - ALC262_LENOVO_3000, - ALC262_NEC, - ALC262_TOSHIBA_S06, - ALC262_TOSHIBA_RX1, - ALC262_TYAN, - ALC262_MODEL_LAST /* last tag */ -}; - -#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID -#define ALC262_DIGIN_NID ALC880_DIGIN_NID - -#define alc262_dac_nids alc260_dac_nids -#define alc262_adc_nids alc882_adc_nids -#define alc262_adc_nids_alt alc882_adc_nids_alt -#define alc262_capsrc_nids alc882_capsrc_nids -#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt - -#define alc262_modes alc260_modes -#define alc262_capture_source alc882_capture_source - -static const hda_nid_t alc262_dmic_adc_nids[1] = { - /* ADC0 */ - 0x09 -}; - -static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; - -static const struct snd_kcontrol_new alc262_base_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -/* bind hp and internal speaker mute (with plug check) as master switch */ - -static int alc262_hippo_master_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - *ucontrol->value.integer.value = !spec->master_mute; - return 0; -} - -static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - int val = !*ucontrol->value.integer.value; - - if (val == spec->master_mute) - return 0; - spec->master_mute = val; - update_outputs(codec); - return 1; -} - -#define ALC262_HIPPO_MASTER_SWITCH \ - { \ - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = "Master Playback Switch", \ - .info = snd_ctl_boolean_mono_info, \ - .get = alc262_hippo_master_sw_get, \ - .put = alc262_hippo_master_sw_put, \ - }, \ - { \ - .iface = NID_MAPPING, \ - .name = "Master Playback Switch", \ - .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \ - (SUBDEV_SPEAKER(0) << 16), \ - } - -#define alc262_hp_master_sw_get alc262_hippo_master_sw_get -#define alc262_hp_master_sw_put alc262_hippo_master_sw_put - -static const struct snd_kcontrol_new alc262_hippo_mixer[] = { - ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc262_hippo1_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - { } /* end */ -}; - -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_hippo_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc262_hippo1_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - - -static const struct snd_kcontrol_new alc262_sony_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc262_tyan_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_verb alc262_tyan_verbs[] = { - /* Headphone automute */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* P11 AUX_IN, white 4-pin connector */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1}, - {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93}, - {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19}, - - {} -}; - -/* unsolicited event for HP jack sensing */ -static void alc262_tyan_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - - -#define alc262_capture_mixer alc882_capture_mixer -#define alc262_capture_alt_mixer alc882_capture_alt_mixer - -/* - * generic initialization of ADC, input mixers and output mixers - */ -static const struct hda_verb alc262_init_verbs[] = { - /* - * Unmute ADC0-2 and set the default input to mic-in - */ - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - - /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback - * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for - * front panel mic (mic 2) - */ - /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - - /* - * Set up output mixers (0x0c - 0x0e) - */ - /* set vol=0 to output mixers */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* set up input amps for analog loopback */ - /* Amp Indices: DAC = 0, mixer = 1 */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, - - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, - /* Input mixer3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, - - { } -}; - -static const struct hda_verb alc262_eapd_verbs[] = { - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - -static const struct hda_verb alc262_hippo1_unsol_verbs[] = { - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static const struct hda_verb alc262_sony_unsol_verbs[] = { - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic - - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_verb alc262_toshiba_s06_verbs[] = { - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {} -}; - -static void alc262_toshiba_s06_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->ext_mic_pin = 0x18; - spec->int_mic_pin = 0x12; - spec->auto_mic = 1; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_PIN); -} - -/* - * nec model - * 0x15 = headphone - * 0x16 = internal speaker - * 0x18 = external mic - */ - -static const struct snd_kcontrol_new alc262_nec_mixer[] = { - HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - { } /* end */ -}; - -static const struct hda_verb alc262_nec_verbs[] = { - /* Unmute Speaker */ - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - /* Headphone */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - /* External mic to headphone */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* External mic to speaker */ - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {} -}; - -/* - * fujitsu model - * 0x14 = headphone/spdif-out, 0x15 = internal speaker, - * 0x1b = port replicator headphone out - */ - -static const struct hda_verb alc262_fujitsu_unsol_verbs[] = { - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static const struct hda_verb alc262_lenovo_3000_init_verbs[] = { - /* Front Mic pin: input vref at 50% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {} -}; - -static const struct hda_input_mux alc262_fujitsu_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - { "CD", 0x4 }, - }, -}; - -static void alc262_fujitsu_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.hp_pins[1] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -/* bind volumes of both NID 0x0c and 0x0d */ -static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { - .ops = &snd_hda_bind_vol, - .values = { - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), - HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT), - 0 - }, -}; - -static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = { - HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, - .info = snd_ctl_boolean_mono_info, - .get = alc262_hp_master_sw_get, - .put = alc262_hp_master_sw_put, - }, - { - .iface = NID_MAPPING, - .name = "Master Playback Switch", - .private_value = 0x1b, - }, - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static void alc262_lenovo_3000_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { - HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, - .info = snd_ctl_boolean_mono_info, - .get = alc262_hp_master_sw_get, - .put = alc262_hp_master_sw_put, - }, - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { - HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), - ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - { } /* end */ -}; - -/* additional init verbs for Benq laptops */ -static const struct hda_verb alc262_EAPD_verbs[] = { - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, - {} -}; - -static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, - - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, - {} -}; - -/* Samsung Q1 Ultra Vista model setup */ -static const struct snd_kcontrol_new alc262_ultra_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_verb alc262_ultra_verbs[] = { - /* output mixer */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* speaker */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* HP */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - /* internal mic */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* ADC, choose mic */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)}, - {} -}; - -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_ultra_automute(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - unsigned int mute; - - mute = 0; - /* auto-mute only when HP is used as HP */ - if (!spec->cur_mux[0]) { - spec->hp_jack_present = snd_hda_jack_detect(codec, 0x15); - if (spec->hp_jack_present) - mute = HDA_AMP_MUTE; - } - /* mute/unmute internal speaker */ - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); - /* mute/unmute HP */ - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE); -} - -/* unsolicited event for HP jack sensing */ -static void alc262_ultra_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC_HP_EVENT) - return; - alc262_ultra_automute(codec); -} - -static const struct hda_input_mux alc262_ultra_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x1 }, - { "Headphone", 0x7 }, - }, -}; - -static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - int ret; - - ret = alc_mux_enum_put(kcontrol, ucontrol); - if (!ret) - return 0; - /* reprogram the HP pin as mic or HP according to the input source */ - snd_hda_codec_write_cache(codec, 0x15, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - spec->cur_mux[0] ? PIN_VREF80 : PIN_HP); - alc262_ultra_automute(codec); /* mute/unmute HP */ - return ret; -} - -static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { - HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc262_ultra_mux_enum_put, - }, - { - .iface = NID_MAPPING, - .name = "Capture Source", - .private_value = 0x15, - }, - { } /* end */ -}; - -static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, - - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, - - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {} -}; - -/* - * configuration and preset - */ -static const char * const alc262_models[ALC262_MODEL_LAST] = { - [ALC262_BASIC] = "basic", - [ALC262_HIPPO] = "hippo", - [ALC262_HIPPO_1] = "hippo_1", - [ALC262_FUJITSU] = "fujitsu", - [ALC262_BENQ_ED8] = "benq", - [ALC262_BENQ_T31] = "benq-t31", - [ALC262_TOSHIBA_S06] = "toshiba-s06", - [ALC262_TOSHIBA_RX1] = "toshiba-rx1", - [ALC262_ULTRA] = "ultra", - [ALC262_LENOVO_3000] = "lenovo-3000", - [ALC262_NEC] = "nec", - [ALC262_TYAN] = "tyan", - [ALC262_AUTO] = "auto", -}; - -static const struct snd_pci_quirk alc262_cfg_tbl[] = { - SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), - SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), - SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", - ALC262_TOSHIBA_RX1), - SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), - SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), - SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), - SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN), - SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1", - ALC262_ULTRA), - SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), - SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), - SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), - SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), - SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1), - {} -}; - -static const struct alc_config_preset alc262_presets[] = { - [ALC262_BASIC] = { - .mixers = { alc262_base_mixer }, - .init_verbs = { alc262_init_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - }, - [ALC262_HIPPO] = { - .mixers = { alc262_hippo_mixer }, - .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs}, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_hippo_setup, - .init_hook = alc_inithook, - }, - [ALC262_HIPPO_1] = { - .mixers = { alc262_hippo1_mixer }, - .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs}, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x02, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_hippo1_setup, - .init_hook = alc_inithook, - }, - [ALC262_FUJITSU] = { - .mixers = { alc262_fujitsu_mixer }, - .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, - alc262_fujitsu_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_fujitsu_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_fujitsu_setup, - .init_hook = alc_inithook, - }, - [ALC262_BENQ_ED8] = { - .mixers = { alc262_base_mixer }, - .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - }, - [ALC262_BENQ_T31] = { - .mixers = { alc262_benq_t31_mixer }, - .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, - alc_hp15_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_hippo_setup, - .init_hook = alc_inithook, - }, - [ALC262_ULTRA] = { - .mixers = { alc262_ultra_mixer }, - .cap_mixer = alc262_ultra_capture_mixer, - .init_verbs = { alc262_ultra_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_ultra_capture_source, - .adc_nids = alc262_adc_nids, /* ADC0 */ - .capsrc_nids = alc262_capsrc_nids, - .num_adc_nids = 1, /* single ADC */ - .unsol_event = alc262_ultra_unsol_event, - .init_hook = alc262_ultra_automute, - }, - [ALC262_LENOVO_3000] = { - .mixers = { alc262_lenovo_3000_mixer }, - .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs, - alc262_lenovo_3000_unsol_verbs, - alc262_lenovo_3000_init_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_fujitsu_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_lenovo_3000_setup, - .init_hook = alc_inithook, - }, - [ALC262_NEC] = { - .mixers = { alc262_nec_mixer }, - .init_verbs = { alc262_nec_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - }, - [ALC262_TOSHIBA_S06] = { - .mixers = { alc262_toshiba_s06_mixer }, - .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, - alc262_eapd_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .capsrc_nids = alc262_dmic_capsrc_nids, - .dac_nids = alc262_dac_nids, - .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ - .num_adc_nids = 1, /* single ADC */ - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_toshiba_s06_setup, - .init_hook = alc_inithook, - }, - [ALC262_TOSHIBA_RX1] = { - .mixers = { alc262_toshiba_rx1_mixer }, - .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_hippo_setup, - .init_hook = alc_inithook, - }, - [ALC262_TYAN] = { - .mixers = { alc262_tyan_mixer }, - .init_verbs = { alc262_init_verbs, alc262_tyan_verbs}, - .num_dacs = ARRAY_SIZE(alc262_dac_nids), - .dac_nids = alc262_dac_nids, - .hp_nid = 0x02, - .dig_out_nid = ALC262_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc262_modes), - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc262_tyan_setup, - .init_hook = alc_hp_automute, - }, -}; - diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index bea22edcfd8..5b68435d195 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c @@ -26,8 +26,6 @@ enum { ALC880_CLEVO, ALC880_TCL_S700, ALC880_LG, - ALC880_LG_LW, - ALC880_MEDION_RIM, #ifdef CONFIG_SND_DEBUG ALC880_TEST, #endif @@ -1052,163 +1050,6 @@ static void alc880_lg_setup(struct hda_codec *codec) alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); } -/* - * LG LW20 - * - * Pin assignment: - * Speaker-out: 0x14 - * Mic-In: 0x18 - * Built-in Mic-In: 0x19 - * Line-In: 0x1b - * HP-Out: 0x1a - * SPDIF-Out: 0x1e - */ - -static const struct hda_input_mux alc880_lg_lw_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - { "Line In", 0x2 }, - }, -}; - -#define alc880_lg_lw_modes alc880_threestack_modes - -static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Channel Mode", - .info = alc_ch_mode_info, - .get = alc_ch_mode_get, - .put = alc_ch_mode_put, - }, - { } /* end */ -}; - -static const struct hda_verb alc880_lg_lw_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ - - /* set capture source to mic-in */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, - /* speaker-out */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* HP-out */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* mic-in to input */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* built-in mic */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* jack sense */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc880_lg_lw_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_input_mux alc880_medion_rim_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - }, -}; - -static const struct hda_verb alc880_medion_rim_init_verbs[] = { - {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - /* Mic1 (rear panel) pin widget for input and vref at 80% */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Mic2 (as headphone out) for HP output */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Internal Speaker */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - { } -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc880_medion_rim_automute(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - alc_hp_automute(codec); - /* toggle EAPD */ - if (spec->hp_jack_present) - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); - else - snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); -} - -static void alc880_medion_rim_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - /* Looks like the unsol event is incompatible with the standard - * definition. 4bit tag is placed at 28 bit! - */ - if ((res >> 28) == ALC_HP_EVENT) - alc880_medion_rim_automute(codec); -} - -static void alc880_medion_rim_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x1b; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - #ifdef CONFIG_SND_HDA_POWER_SAVE static const struct hda_amp_list alc880_lg_loopbacks[] = { { 0x0b, HDA_INPUT, 1 }, @@ -1505,8 +1346,6 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = { [ALC880_FUJITSU] = "fujitsu", [ALC880_F1734] = "F1734", [ALC880_LG] = "lg", - [ALC880_LG_LW] = "lg-lw", - [ALC880_MEDION_RIM] = "medion", #ifdef CONFIG_SND_DEBUG [ALC880_TEST] = "test", #endif @@ -1557,18 +1396,15 @@ static const struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), - SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM), SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), - SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), - SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), @@ -1848,35 +1684,6 @@ static const struct alc_config_preset alc880_presets[] = { .loopbacks = alc880_lg_loopbacks, #endif }, - [ALC880_LG_LW] = { - .mixers = { alc880_lg_lw_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_lg_lw_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_dac_nids), - .dac_nids = alc880_dac_nids, - .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), - .channel_mode = alc880_lg_lw_modes, - .input_mux = &alc880_lg_lw_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc880_lg_lw_setup, - .init_hook = alc_hp_automute, - }, - [ALC880_MEDION_RIM] = { - .mixers = { alc880_medion_rim_mixer }, - .init_verbs = { alc880_volume_init_verbs, - alc880_medion_rim_init_verbs, - alc_gpio2_init_verbs }, - .num_dacs = ARRAY_SIZE(alc880_dac_nids), - .dac_nids = alc880_dac_nids, - .dig_out_nid = ALC880_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), - .channel_mode = alc880_2_jack_modes, - .input_mux = &alc880_medion_rim_capture_source, - .unsol_event = alc880_medion_rim_unsol_event, - .setup = alc880_medion_rim_setup, - .init_hook = alc880_medion_rim_automute, - }, #ifdef CONFIG_SND_DEBUG [ALC880_TEST] = { .mixers = { alc880_test_mixer }, diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c index e251514a26a..bdf0ed4ab3e 100644 --- a/sound/pci/hda/alc882_quirks.c +++ b/sound/pci/hda/alc882_quirks.c @@ -6,509 +6,15 @@ /* ALC882 models */ enum { ALC882_AUTO, - ALC882_3ST_DIG, - ALC882_6ST_DIG, - ALC882_ARIMA, - ALC882_W2JC, - ALC882_TARGA, - ALC882_ASUS_A7J, - ALC882_ASUS_A7M, - ALC885_MACPRO, ALC885_MBA21, ALC885_MBP3, ALC885_MB5, ALC885_MACMINI3, - ALC885_IMAC24, ALC885_IMAC91, - ALC883_3ST_2ch_DIG, - ALC883_3ST_6ch_DIG, - ALC883_3ST_6ch, - ALC883_6ST_DIG, - ALC883_TARGA_DIG, - ALC883_TARGA_2ch_DIG, - ALC883_TARGA_8ch_DIG, - ALC883_ACER, - ALC883_ACER_ASPIRE, - ALC888_ACER_ASPIRE_4930G, - ALC888_ACER_ASPIRE_6530G, - ALC888_ACER_ASPIRE_8930G, - ALC888_ACER_ASPIRE_7730G, - ALC883_MEDION, - ALC883_MEDION_WIM2160, - ALC883_LAPTOP_EAPD, - ALC883_LENOVO_101E_2ch, - ALC883_LENOVO_NB0763, - ALC888_LENOVO_MS7195_DIG, - ALC888_LENOVO_SKY, - ALC883_HAIER_W66, - ALC888_3ST_HP, - ALC888_6ST_DELL, - ALC883_MITAC, - ALC883_CLEVO_M540R, - ALC883_CLEVO_M720, - ALC883_FUJITSU_PI2515, - ALC888_FUJITSU_XA3530, - ALC883_3ST_6ch_INTEL, - ALC889A_INTEL, - ALC889_INTEL, - ALC888_ASUS_M90V, - ALC888_ASUS_EEE1601, ALC889A_MB31, - ALC1200_ASUS_P5Q, - ALC883_SONY_VAIO_TT, ALC882_MODEL_LAST, }; -/* - * 2ch mode - */ -static const struct hda_verb alc888_4ST_ch2_intel_init[] = { -/* Mic-in jack as mic in */ - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, -/* Line-in jack as Line in */ - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, -/* Line-Out as Front */ - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc888_4ST_ch4_intel_init[] = { -/* Mic-in jack as mic in */ - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, -/* Line-in jack as Surround */ - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -/* Line-Out as Front */ - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc888_4ST_ch6_intel_init[] = { -/* Mic-in jack as CLFE */ - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -/* Line-in jack as Surround */ - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */ - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, - { } /* end */ -}; - -/* - * 8ch mode - */ -static const struct hda_verb alc888_4ST_ch8_intel_init[] = { -/* Mic-in jack as CLFE */ - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -/* Line-in jack as Surround */ - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -/* Line-Out as Side */ - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, - { } /* end */ -}; - -static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { - { 2, alc888_4ST_ch2_intel_init }, - { 4, alc888_4ST_ch4_intel_init }, - { 6, alc888_4ST_ch6_intel_init }, - { 8, alc888_4ST_ch8_intel_init }, -}; - -/* - * ALC888 Fujitsu Siemens Amillo xa3530 - */ - -static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = { -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Connect Internal HP to Front */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Connect Bass HP to Front */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Connect Line-Out side jack (SPDIF) to Side */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, -/* Connect Mic jack to CLFE */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, -/* Connect Line-in jack to Surround */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, -/* Connect HP out jack to Front */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Enable unsolicited event for HP jack and Line-out jack */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {} -}; - -static void alc889_automute_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x17; - spec->autocfg.speaker_pins[3] = 0x19; - spec->autocfg.speaker_pins[4] = 0x1a; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc889_intel_init_hook(struct hda_codec *codec) -{ - alc889_coef_init(codec); - alc_hp_automute(codec); -} - -static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x17; /* line-out */ - spec->autocfg.hp_pins[1] = 0x1b; /* hp */ - spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ - spec->autocfg.speaker_pins[1] = 0x15; /* bass */ - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -/* - * ALC888 Acer Aspire 4930G model - */ - -static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = { -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Unselect Front Mic by default in input mixer 3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, -/* Enable unsolicited event for HP jack */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, -/* Connect Internal HP to front */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Connect HP out to front */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - -/* - * ALC888 Acer Aspire 6530G model - */ - -static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = { -/* Route to built-in subwoofer as well as speakers */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, -/* Bias voltage on for external mic port */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Unselect Front Mic by default in input mixer 3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, -/* Enable unsolicited event for HP jack */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, -/* Enable speaker output */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, -/* Enable headphone output */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - -/* - *ALC888 Acer Aspire 7730G model - */ - -static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = { -/* Bias voltage on for external mic port */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Unselect Front Mic by default in input mixer 3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, -/* Enable unsolicited event for HP jack */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, -/* Enable speaker output */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, -/* Enable headphone output */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, -/*Enable internal subwoofer */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, - {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - -/* - * ALC889 Acer Aspire 8930G model - */ - -static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = { -/* Front Mic: set to PIN_IN (empty by default) */ - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -/* Unselect Front Mic by default in input mixer 3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, -/* Enable unsolicited event for HP jack */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, -/* Connect Internal Front to Front */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Connect Internal Rear to Rear */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, -/* Connect Internal CLFE to CLFE */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, -/* Connect HP out to Front */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, -/* Enable all DACs */ -/* DAC DISABLE/MUTE 1? */ -/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x03}, - {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, -/* DAC DISABLE/MUTE 2? */ -/* some bit here disables the other DACs. Init=0x4900 */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, - {0x20, AC_VERB_SET_PROC_COEF, 0x0000}, -/* DMIC fix - * This laptop has a stereo digital microphone. The mics are only 1cm apart - * which makes the stereo useless. However, either the mic or the ALC889 - * makes the signal become a difference/sum signal instead of standard - * stereo, which is annoying. So instead we flip this bit which makes the - * codec replicate the sum signal to both channels, turning it into a - * normal mono mic. - */ -/* DMIC_CONTROL? Init value = 0x0001 */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, - {0x20, AC_VERB_SET_PROC_COEF, 0x0003}, - { } -}; - -static const struct hda_input_mux alc888_2_capture_sources[2] = { - /* Front mic only available on one ADC */ - { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Front Mic", 0xb }, - }, - }, - { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - }, - } -}; - -static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { - /* Interal mic only available on one ADC */ - { - .num_items = 5, - .items = { - { "Mic", 0x0 }, - { "Line In", 0x2 }, - { "CD", 0x4 }, - { "Input Mix", 0xa }, - { "Internal Mic", 0xb }, - }, - }, - { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line In", 0x2 }, - { "CD", 0x4 }, - { "Input Mix", 0xa }, - }, - } -}; - -static const struct hda_input_mux alc889_capture_sources[3] = { - /* Digital mic only available on first "ADC" */ - { - .num_items = 5, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Front Mic", 0xb }, - { "Input Mix", 0xa }, - }, - }, - { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Input Mix", 0xa }, - }, - }, - { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - { "Input Mix", 0xa }, - }, - } -}; - -static const struct snd_kcontrol_new alc888_base_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, - HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, - HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, - HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - - -static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x1b; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - #define ALC882_DIGOUT_NID 0x06 #define ALC882_DIGIN_NID 0x0a #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID @@ -531,15 +37,9 @@ static const hda_nid_t alc882_dac_nids[4] = { #define alc882_adc_nids alc880_adc_nids #define alc882_adc_nids_alt alc880_adc_nids_alt #define alc883_adc_nids alc882_adc_nids_alt -static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; -static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; -#define alc889_adc_nids alc880_adc_nids -static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; #define alc883_capsrc_nids alc882_capsrc_nids_alt -static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; -#define alc889_capsrc_nids alc882_capsrc_nids /* input MUX */ /* FIXME: should be a matrix-type input source selection */ @@ -556,15 +56,6 @@ static const struct hda_input_mux alc882_capture_source = { #define alc883_capture_source alc882_capture_source -static const struct hda_input_mux alc889_capture_source = { - .num_items = 3, - .items = { - { "Front Mic", 0x0 }, - { "Mic", 0x3 }, - { "Line", 0x2 }, - }, -}; - static const struct hda_input_mux mb5_capture_source = { .num_items = 3, .items = { @@ -592,49 +83,6 @@ static const struct hda_input_mux alc883_3stack_6ch_intel = { }, }; -static const struct hda_input_mux alc883_lenovo_101e_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x1 }, - { "Line", 0x2 }, - }, -}; - -static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = { - .num_items = 4, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - { "Line", 0x2 }, - { "CD", 0x4 }, - }, -}; - -static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x0 }, - { "Internal Mic", 0x1 }, - }, -}; - -static const struct hda_input_mux alc883_lenovo_sky_capture_source = { - .num_items = 3, - .items = { - { "Mic", 0x0 }, - { "Front Mic", 0x1 }, - { "Line", 0x4 }, - }, -}; - -static const struct hda_input_mux alc883_asus_eee1601_capture_source = { - .num_items = 2, - .items = { - { "Mic", 0x0 }, - { "Line", 0x2 }, - }, -}; - static const struct hda_input_mux alc889A_mb31_capture_source = { .num_items = 2, .items = { @@ -654,131 +102,6 @@ static const struct hda_input_mux alc889A_imac91_capture_source = { }, }; -/* - * 2ch mode - */ -static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = { - { 2, NULL } -}; - -/* - * 2ch mode - */ -static const struct hda_verb alc882_3ST_ch2_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc882_3ST_ch4_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc882_3ST_ch6_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = { - { 2, alc882_3ST_ch2_init }, - { 4, alc882_3ST_ch4_init }, - { 6, alc882_3ST_ch6_init }, -}; - -#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes - -/* - * 2ch mode - */ -static const struct hda_verb alc883_3ST_ch2_clevo_init[] = { - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc883_3ST_ch4_clevo_init[] = { - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc883_3ST_ch6_clevo_init[] = { - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { - { 2, alc883_3ST_ch2_clevo_init }, - { 4, alc883_3ST_ch4_clevo_init }, - { 6, alc883_3ST_ch6_clevo_init }, -}; - - -/* - * 6ch mode - */ -static const struct hda_verb alc882_sixstack_ch6_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { } /* end */ -}; - -/* - * 8ch mode - */ -static const struct hda_verb alc882_sixstack_ch8_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { } /* end */ -}; - -static const struct hda_channel_mode alc882_sixstack_modes[2] = { - { 6, alc882_sixstack_ch6_init }, - { 8, alc882_sixstack_ch8_init }, -}; - - /* Macbook Air 2,1 */ static const struct hda_channel_mode alc885_mba21_ch_modes[1] = { @@ -847,216 +170,6 @@ static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = { #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes -/* - * 2ch mode - */ -static const struct hda_verb alc883_4ST_ch2_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc883_4ST_ch4_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc883_4ST_ch6_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 8ch mode - */ -static const struct hda_verb alc883_4ST_ch8_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = { - { 2, alc883_4ST_ch2_init }, - { 4, alc883_4ST_ch4_init }, - { 6, alc883_4ST_ch6_init }, - { 8, alc883_4ST_ch8_init }, -}; - - -/* - * 2ch mode - */ -static const struct hda_verb alc883_3ST_ch2_intel_init[] = { - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc883_3ST_ch4_intel_init[] = { - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc883_3ST_ch6_intel_init[] = { - { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { - { 2, alc883_3ST_ch2_intel_init }, - { 4, alc883_3ST_ch4_intel_init }, - { 6, alc883_3ST_ch6_intel_init }, -}; - -/* - * 2ch mode - */ -static const struct hda_verb alc889_ch2_intel_init[] = { - { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc889_ch6_intel_init[] = { - { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 8ch mode - */ -static const struct hda_verb alc889_ch8_intel_init[] = { - { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, - { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, - { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 }, - { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { } /* end */ -}; - -static const struct hda_channel_mode alc889_8ch_intel_modes[3] = { - { 2, alc889_ch2_intel_init }, - { 6, alc889_ch6_intel_init }, - { 8, alc889_ch8_intel_init }, -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc883_sixstack_ch6_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { } /* end */ -}; - -/* - * 8ch mode - */ -static const struct hda_verb alc883_sixstack_ch8_init[] = { - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { } /* end */ -}; - -static const struct hda_channel_mode alc883_sixstack_modes[2] = { - { 6, alc883_sixstack_ch6_init }, - { 8, alc883_sixstack_ch8_init }, -}; - - -/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 - * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b - */ -static const struct snd_kcontrol_new alc882_base_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - /* Macbook Air 2,1 same control for HP and internal Speaker */ static const struct snd_kcontrol_new alc885_mba21_mixer[] = { @@ -1121,70 +234,6 @@ static const struct snd_kcontrol_new alc885_imac91_mixer[] = { }; -static const struct snd_kcontrol_new alc882_w2jc_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc882_targa_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - { } /* end */ -}; - -/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? - * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c - */ -static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - static const struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1258,179 +307,8 @@ static const struct hda_verb alc882_base_init_verbs[] = { { } }; -static const struct hda_verb alc882_adc1_init_verbs[] = { - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* ADC1: mute amp left and right */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - { } -}; - -static const struct hda_verb alc882_eapd_verbs[] = { - /* change to EAPD mode */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, - { } -}; - -static const struct hda_verb alc889_eapd_verbs[] = { - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; - -static const struct hda_verb alc_hp15_unsol_verbs[] = { - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} -}; - -static const struct hda_verb alc885_init_verbs[] = { - /* Front mixer: unmute input/output amp left and right (volume = 0) */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Rear mixer */ - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* CLFE mixer */ - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* Side mixer */ - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - /* Front HP Pin: output 0 (0x0c) */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Front Pin: output 0 (0x0c) */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Rear Pin: output 1 (0x0d) */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x19, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* CLFE Pin: output 2 (0x0e) */ - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, - /* Side Pin: output 3 (0x0f) */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, - /* Mic (rear) pin: input vref at 80% */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Front Mic pin: input vref at 80% */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Line In pin: input */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - - /* Mixer elements: 0x18, , 0x1a, 0x1b */ - /* Input mixer1 */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* Input mixer3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - /* ADC2: mute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* ADC3: mute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - - { } -}; - -static const struct hda_verb alc885_init_input_verbs[] = { - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - { } -}; - - -/* Unmute Selector 24h and set the default input to front mic */ -static const struct hda_verb alc889_init_input_verbs[] = { - {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - { } -}; - - #define alc883_init_verbs alc882_base_init_verbs -/* Mac Pro test */ -static const struct snd_kcontrol_new alc882_macpro_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), - /* FIXME: this looks suspicious... - HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT), - */ - { } /* end */ -}; - -static const struct hda_verb alc882_macpro_init_verbs[] = { - /* Front mixer: unmute input/output amp left and right (volume = 0) */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - /* Front Pin: output 0 (0x0c) */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Front Mic pin: input vref at 80% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Speaker: output */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04}, - /* Headphone output (output 0 - 0x0c) */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Input mixer2 */ - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Input mixer3 */ - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* ADC1: mute amp left and right */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* ADC2: mute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* ADC3: mute amp left and right */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, - - { } -}; - /* Macbook 5,1 */ static const struct hda_verb alc885_mb5_init_verbs[] = { /* DACs */ @@ -1669,34 +547,6 @@ static const struct hda_verb alc885_imac91_init_verbs[] = { { } }; -/* iMac 24 mixer. */ -static const struct snd_kcontrol_new alc885_imac24_mixer[] = { - HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), - HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), - { } /* end */ -}; - -/* iMac 24 init verbs. */ -static const struct hda_verb alc885_imac24_init_verbs[] = { - /* Internal speakers: output 0 (0x0c) */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Internal speakers: output 0 (0x0c) */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Headphone: output 0 (0x0c) */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - /* Front Mic: input vref at 80% */ - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - { } -}; - /* Toggle speaker-output according to the hp-jack state */ static void alc885_imac24_setup(struct hda_codec *codec) { @@ -1742,127 +592,6 @@ static void alc885_imac91_setup(struct hda_codec *codec) alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); } -static const struct hda_verb alc882_targa_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc882_targa_automute(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - alc_hp_automute(codec); - snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, - spec->hp_jack_present ? 1 : 3); -} - -static void alc882_targa_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x1b; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) == ALC_HP_EVENT) - alc882_targa_automute(codec); -} - -static const struct hda_verb alc882_asus_a7j_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ - - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - { } /* end */ -}; - -static const struct hda_verb alc882_asus_a7m_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ - - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ - { } /* end */ -}; - -static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) -{ - unsigned int gpiostate, gpiomask, gpiodir; - - gpiostate = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_DATA, 0); - - if (!muted) - gpiostate |= (1 << pin); - else - gpiostate &= ~(1 << pin); - - gpiomask = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_MASK, 0); - gpiomask |= (1 << pin); - - gpiodir = snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_GET_GPIO_DIRECTION, 0); - gpiodir |= (1 << pin); - - - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_MASK, gpiomask); - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DIRECTION, gpiodir); - - msleep(1); - - snd_hda_codec_write(codec, codec->afg, 0, - AC_VERB_SET_GPIO_DATA, gpiostate); -} - -/* set up GPIO at initialization */ -static void alc885_macpro_init_hook(struct hda_codec *codec) -{ - alc882_gpio_mute(codec, 0, 0); - alc882_gpio_mute(codec, 1, 0); -} - -/* set up GPIO and update auto-muting at initialization */ -static void alc885_imac24_init_hook(struct hda_codec *codec) -{ - alc885_macpro_init_hook(codec); - alc_hp_automute(codec); -} - /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ static const struct hda_verb alc889A_mb31_ch2_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ @@ -1906,77 +635,6 @@ static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { { 6, alc889A_mb31_ch6_init }, }; -static const struct hda_verb alc883_medion_eapd_verbs[] = { - /* eanable EAPD on medion laptop */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, - { } -}; - -#define alc883_base_mixer alc882_base_mixer - -static const struct snd_kcontrol_new alc883_mitac_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -2000,235 +658,6 @@ static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { { } /* end */ }; -static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, - HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, - HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_fivestack_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_targa_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_verb alc883_medion_wim2160_verbs[] = { - /* Unmute front mixer */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - /* Set speaker pin to front mixer */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - - /* Init headphone pin */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - - { } /* end */ -}; - -/* toggle speaker-output according to the hp-jack state */ -static void alc883_medion_wim2160_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1a; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), - HDA_CODEC_VOLUME_MONO("Center Playback Volume", - 0x0d, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { /* Output mixers */ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), @@ -2255,61 +684,6 @@ static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { { } /* end */ }; -static const struct snd_kcontrol_new alc883_vaiott_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - { } /* end */ -}; - -static const struct hda_bind_ctls alc883_bind_cap_vol = { - .ops = &snd_hda_bind_vol, - .values = { - HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), - HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), - 0 - }, -}; - -static const struct hda_bind_ctls alc883_bind_cap_switch = { - .ops = &snd_hda_bind_sw, - .values = { - HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), - HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), - 0 - }, -}; - -static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - { } /* end */ -}; - -static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { - HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), - HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - /* .name = "Capture Source", */ - .name = "Input Source", - .count = 1, - .info = alc_mux_enum_info, - .get = alc_mux_enum_get, - .put = alc_mux_enum_put, - }, - { } /* end */ -}; - static const struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -2321,423 +695,6 @@ static const struct snd_kcontrol_new alc883_chmode_mixer[] = { { } /* end */ }; -/* toggle speaker-output according to the hp-jack state */ -static void alc883_mitac_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct hda_verb alc883_mitac_verbs[] = { - /* HP */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - /* Subwoofer */ - {0x17, AC_VERB_SET_CONNECT_SEL, 0x02}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - /* enable unsolicited event */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, */ - - { } /* end */ -}; - -static const struct hda_verb alc883_clevo_m540r_verbs[] = { - /* HP */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - /* Int speaker */ - /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/ - - /* enable unsolicited event */ - /* - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, - */ - - { } /* end */ -}; - -static const struct hda_verb alc883_clevo_m720_verbs[] = { - /* HP */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - /* Int speaker */ - {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - /* enable unsolicited event */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, - - { } /* end */ -}; - -static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { - /* HP */ - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - /* Subwoofer */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - /* enable unsolicited event */ - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - - { } /* end */ -}; - -static const struct hda_verb alc883_targa_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - -/* Connect Line-Out side jack (SPDIF) to Side */ - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, -/* Connect Mic jack to CLFE */ - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, -/* Connect Line-in jack to Surround */ - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, -/* Connect HP out jack to Front */ - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - - { } /* end */ -}; - -static const struct hda_verb alc883_lenovo_101e_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT|AC_USRSP_EN}, - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT|AC_USRSP_EN}, - { } /* end */ -}; - -static const struct hda_verb alc883_lenovo_nb0763_verbs[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - { } /* end */ -}; - -static const struct hda_verb alc888_lenovo_ms7195_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT | AC_USRSP_EN}, - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -static const struct hda_verb alc883_haier_w66_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - - {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - { } /* end */ -}; - -static const struct hda_verb alc888_lenovo_sky_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -static const struct hda_verb alc888_6st_dell_verbs[] = { - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } -}; - -static const struct hda_verb alc883_vaiott_verbs[] = { - /* HP */ - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - - /* enable unsolicited event */ - {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - - { } /* end */ -}; - -static void alc888_3st_hp_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x16; - spec->autocfg.speaker_pins[2] = 0x18; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct hda_verb alc888_3st_hp_verbs[] = { - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ - {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -/* - * 2ch mode - */ -static const struct hda_verb alc888_3st_hp_2ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { } /* end */ -}; - -/* - * 4ch mode - */ -static const struct hda_verb alc888_3st_hp_4ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -/* - * 6ch mode - */ -static const struct hda_verb alc888_3st_hp_6ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, - { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, - { } /* end */ -}; - -static const struct hda_channel_mode alc888_3st_hp_modes[3] = { - { 2, alc888_3st_hp_2ch_init }, - { 4, alc888_3st_hp_4ch_init }, - { 6, alc888_3st_hp_6ch_init }, -}; - -static void alc888_lenovo_ms7195_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.line_out_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -/* toggle speaker-output according to the hp-jack state */ -static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -/* toggle speaker-output according to the hp-jack state */ -#define alc883_targa_init_hook alc882_targa_init_hook -#define alc883_targa_unsol_event alc882_targa_unsol_event - -static void alc883_clevo_m720_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc883_clevo_m720_init_hook(struct hda_codec *codec) -{ - alc_hp_automute(codec); - alc88x_simple_mic_automute(codec); -} - -static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC_MIC_EVENT: - alc88x_simple_mic_automute(codec); - break; - default: - alc_sku_unsol_event(codec, res); - break; - } -} - -/* toggle speaker-output according to the hp-jack state */ -static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc883_haier_w66_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc883_lenovo_101e_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.line_out_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x15; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -/* toggle speaker-output according to the hp-jack state */ -static void alc883_acer_aspire_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x15; - spec->autocfg.speaker_pins[1] = 0x16; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct hda_verb alc883_acer_eapd_verbs[] = { - /* HP Pin: output 0 (0x0c) */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* Front Pin: output 0 (0x0c) */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, - /* eanable EAPD on medion laptop */ - {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, - {0x20, AC_VERB_SET_PROC_COEF, 0x3050}, - /* enable unsolicited event */ - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } -}; - -static void alc888_6st_dell_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x15; - spec->autocfg.speaker_pins[2] = 0x16; - spec->autocfg.speaker_pins[3] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc888_lenovo_sky_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x15; - spec->autocfg.speaker_pins[2] = 0x16; - spec->autocfg.speaker_pins[3] = 0x17; - spec->autocfg.speaker_pins[4] = 0x1a; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static void alc883_vaiott_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x15; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x17; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct hda_verb alc888_asus_m90v_verbs[] = { - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - /* enable unsolicited event */ - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -static void alc883_mode2_setup(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x1b; - spec->autocfg.speaker_pins[0] = 0x14; - spec->autocfg.speaker_pins[1] = 0x15; - spec->autocfg.speaker_pins[2] = 0x16; - spec->ext_mic_pin = 0x18; - spec->int_mic_pin = 0x19; - spec->auto_mic = 1; - alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); -} - -static const struct hda_verb alc888_asus_eee1601_verbs[] = { - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, - {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, - /* enable unsolicited event */ - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - -static void alc883_eee1601_inithook(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - - spec->autocfg.hp_pins[0] = 0x14; - spec->autocfg.speaker_pins[0] = 0x1b; - alc_hp_automute(codec); -} - static const struct hda_verb alc889A_mb31_verbs[] = { /* Init rear pin (used as headphone output) */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ @@ -2773,211 +730,30 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) alc889A_mb31_automute(codec); } -static const hda_nid_t alc883_slave_dig_outs[] = { - ALC1200_DIGOUT_NID, 0, -}; - -static const hda_nid_t alc1200_slave_dig_outs[] = { - ALC883_DIGOUT_NID, 0, -}; - /* * configuration and preset */ static const char * const alc882_models[ALC882_MODEL_LAST] = { - [ALC882_3ST_DIG] = "3stack-dig", - [ALC882_6ST_DIG] = "6stack-dig", - [ALC882_ARIMA] = "arima", - [ALC882_W2JC] = "w2jc", - [ALC882_TARGA] = "targa", - [ALC882_ASUS_A7J] = "asus-a7j", - [ALC882_ASUS_A7M] = "asus-a7m", - [ALC885_MACPRO] = "macpro", [ALC885_MB5] = "mb5", [ALC885_MACMINI3] = "macmini3", [ALC885_MBA21] = "mba21", [ALC885_MBP3] = "mbp3", - [ALC885_IMAC24] = "imac24", [ALC885_IMAC91] = "imac91", - [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig", - [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", - [ALC883_3ST_6ch] = "3stack-6ch", - [ALC883_6ST_DIG] = "alc883-6stack-dig", - [ALC883_TARGA_DIG] = "targa-dig", - [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", - [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", - [ALC883_ACER] = "acer", - [ALC883_ACER_ASPIRE] = "acer-aspire", - [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", - [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", - [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", - [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", - [ALC883_MEDION] = "medion", - [ALC883_MEDION_WIM2160] = "medion-wim2160", - [ALC883_LAPTOP_EAPD] = "laptop-eapd", - [ALC883_LENOVO_101E_2ch] = "lenovo-101e", - [ALC883_LENOVO_NB0763] = "lenovo-nb0763", - [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", - [ALC888_LENOVO_SKY] = "lenovo-sky", - [ALC883_HAIER_W66] = "haier-w66", - [ALC888_3ST_HP] = "3stack-hp", - [ALC888_6ST_DELL] = "6stack-dell", - [ALC883_MITAC] = "mitac", - [ALC883_CLEVO_M540R] = "clevo-m540r", - [ALC883_CLEVO_M720] = "clevo-m720", - [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", - [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", - [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", - [ALC889A_INTEL] = "intel-alc889a", - [ALC889_INTEL] = "intel-x58", - [ALC1200_ASUS_P5Q] = "asus-p5q", [ALC889A_MB31] = "mb31", - [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", [ALC882_AUTO] = "auto", }; -static const struct snd_pci_quirk alc882_cfg_tbl[] = { - SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), - - SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", - ALC888_ACER_ASPIRE_4930G), - SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", - ALC888_ACER_ASPIRE_4930G), - SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", - ALC888_ACER_ASPIRE_8930G), - SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", - ALC888_ACER_ASPIRE_8930G), - SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO), - SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO), - SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", - ALC888_ACER_ASPIRE_6530G), - SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", - ALC888_ACER_ASPIRE_6530G), - SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", - ALC888_ACER_ASPIRE_7730G), - /* default Acer -- disabled as it causes more problems. - * model=auto should work fine now - */ - /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ - - SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), - - SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), - - SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J), - SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J), - SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M), - SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), - SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), - SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), - SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), - - SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT), - SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), - SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), - SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), - SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), - SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), - - SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */ - SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO), - SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG), - SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG), - SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), - SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), - - SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), - SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), - SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), - SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), - SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), - /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */ - SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), - SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", - ALC883_FUJITSU_PI2515), - SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx", - ALC888_FUJITSU_XA3530), - SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), - SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), - SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), - SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), - SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), - SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), - SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), - SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), - - SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), - SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), - SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), - SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL), - SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL), - SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL), - SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG), - - {} -}; - /* codec SSID table for Intel Mac */ static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), - SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO), - SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24), - SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24), SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), - SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M), SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), - SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24), SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), @@ -2991,53 +767,6 @@ static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { }; static const struct alc_config_preset alc882_presets[] = { - [ALC882_3ST_DIG] = { - .mixers = { alc882_base_mixer }, - .init_verbs = { alc882_base_init_verbs, - alc882_adc1_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .need_dac_fix = 1, - .input_mux = &alc882_capture_source, - }, - [ALC882_6ST_DIG] = { - .mixers = { alc882_base_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, - alc882_adc1_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), - .channel_mode = alc882_sixstack_modes, - .input_mux = &alc882_capture_source, - }, - [ALC882_ARIMA] = { - .mixers = { alc882_base_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, - alc882_eapd_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes), - .channel_mode = alc882_sixstack_modes, - .input_mux = &alc882_capture_source, - }, - [ALC882_W2JC] = { - .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, - alc882_eapd_verbs, alc880_gpio1_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), - .channel_mode = alc880_threestack_modes, - .need_dac_fix = 1, - .input_mux = &alc882_capture_source, - .dig_out_nid = ALC882_DIGOUT_NID, - }, [ALC885_MBA21] = { .mixers = { alc885_mba21_mixer }, .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, @@ -3096,32 +825,6 @@ static const struct alc_config_preset alc882_presets[] = { .setup = alc885_macmini3_setup, .init_hook = alc_hp_automute, }, - [ALC885_MACPRO] = { - .mixers = { alc882_macpro_mixer }, - .init_verbs = { alc882_macpro_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .input_mux = &alc882_capture_source, - .init_hook = alc885_macpro_init_hook, - }, - [ALC885_IMAC24] = { - .mixers = { alc885_imac24_mixer }, - .init_verbs = { alc885_imac24_init_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .dig_in_nid = ALC882_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), - .channel_mode = alc882_ch_modes, - .input_mux = &alc882_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc885_imac24_setup, - .init_hook = alc885_imac24_init_hook, - }, [ALC885_IMAC91] = { .mixers = {alc885_imac91_mixer}, .init_verbs = { alc885_imac91_init_verbs, @@ -3137,564 +840,6 @@ static const struct alc_config_preset alc882_presets[] = { .setup = alc885_imac91_setup, .init_hook = alc_hp_automute, }, - [ALC882_TARGA] = { - .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, - alc880_gpio3_init_verbs, alc882_targa_verbs}, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), - .adc_nids = alc882_adc_nids, - .capsrc_nids = alc882_capsrc_nids, - .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), - .channel_mode = alc882_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc882_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc882_targa_setup, - .init_hook = alc882_targa_automute, - }, - [ALC882_ASUS_A7J] = { - .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, - alc882_asus_a7j_verbs}, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc882_adc_nids), - .adc_nids = alc882_adc_nids, - .capsrc_nids = alc882_capsrc_nids, - .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes), - .channel_mode = alc882_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc882_capture_source, - }, - [ALC882_ASUS_A7M] = { - .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, - .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs, - alc882_eapd_verbs, alc880_gpio1_init_verbs, - alc882_asus_a7m_verbs }, - .num_dacs = ARRAY_SIZE(alc882_dac_nids), - .dac_nids = alc882_dac_nids, - .dig_out_nid = ALC882_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), - .channel_mode = alc880_threestack_modes, - .need_dac_fix = 1, - .input_mux = &alc882_capture_source, - }, - [ALC883_3ST_2ch_DIG] = { - .mixers = { alc883_3ST_2ch_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_3ST_6ch_DIG] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - }, - [ALC883_3ST_6ch] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - }, - [ALC883_3ST_6ch_INTEL] = { - .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .slave_dig_outs = alc883_slave_dig_outs, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), - .channel_mode = alc883_3ST_6ch_intel_modes, - .need_dac_fix = 1, - .input_mux = &alc883_3stack_6ch_intel, - }, - [ALC889A_INTEL] = { - .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, - .init_verbs = { alc885_init_verbs, alc885_init_input_verbs, - alc_hp15_unsol_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), - .adc_nids = alc889_adc_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .slave_dig_outs = alc883_slave_dig_outs, - .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), - .channel_mode = alc889_8ch_intel_modes, - .capsrc_nids = alc889_capsrc_nids, - .input_mux = &alc889_capture_source, - .setup = alc889_automute_setup, - .init_hook = alc_hp_automute, - .unsol_event = alc_sku_unsol_event, - .need_dac_fix = 1, - }, - [ALC889_INTEL] = { - .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer }, - .init_verbs = { alc885_init_verbs, alc889_init_input_verbs, - alc889_eapd_verbs, alc_hp15_unsol_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), - .adc_nids = alc889_adc_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .slave_dig_outs = alc883_slave_dig_outs, - .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes), - .channel_mode = alc889_8ch_intel_modes, - .capsrc_nids = alc889_capsrc_nids, - .input_mux = &alc889_capture_source, - .setup = alc889_automute_setup, - .init_hook = alc889_intel_init_hook, - .unsol_event = alc_sku_unsol_event, - .need_dac_fix = 1, - }, - [ALC883_6ST_DIG] = { - .mixers = { alc883_base_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_TARGA_DIG] = { - .mixers = { alc883_targa_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, - alc883_targa_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - .unsol_event = alc883_targa_unsol_event, - .setup = alc882_targa_setup, - .init_hook = alc882_targa_automute, - }, - [ALC883_TARGA_2ch_DIG] = { - .mixers = { alc883_targa_2ch_mixer}, - .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, - alc883_targa_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .adc_nids = alc883_adc_nids_alt, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), - .capsrc_nids = alc883_capsrc_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc883_targa_unsol_event, - .setup = alc882_targa_setup, - .init_hook = alc882_targa_automute, - }, - [ALC883_TARGA_8ch_DIG] = { - .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs, - alc883_targa_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), - .adc_nids = alc883_adc_nids_rev, - .capsrc_nids = alc883_capsrc_nids_rev, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes), - .channel_mode = alc883_4ST_8ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - .unsol_event = alc883_targa_unsol_event, - .setup = alc882_targa_setup, - .init_hook = alc882_targa_automute, - }, - [ALC883_ACER] = { - .mixers = { alc883_base_mixer }, - /* On TravelMate laptops, GPIO 0 enables the internal speaker - * and the headphone jack. Turn this on and rely on the - * standard mute methods whenever the user wants to turn - * these outputs off. - */ - .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_ACER_ASPIRE] = { - .mixers = { alc883_acer_aspire_mixer }, - .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_acer_aspire_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_ACER_ASPIRE_4930G] = { - .mixers = { alc888_acer_aspire_4930g_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc888_acer_aspire_4930g_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), - .adc_nids = alc883_adc_nids_rev, - .capsrc_nids = alc883_capsrc_nids_rev, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .const_channel_count = 6, - .num_mux_defs = - ARRAY_SIZE(alc888_2_capture_sources), - .input_mux = alc888_2_capture_sources, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_acer_aspire_4930g_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_ACER_ASPIRE_6530G] = { - .mixers = { alc888_acer_aspire_6530_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc888_acer_aspire_6530g_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), - .adc_nids = alc883_adc_nids_rev, - .capsrc_nids = alc883_capsrc_nids_rev, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .num_mux_defs = - ARRAY_SIZE(alc888_2_capture_sources), - .input_mux = alc888_acer_aspire_6530_sources, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_acer_aspire_6530g_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_ACER_ASPIRE_8930G] = { - .mixers = { alc889_acer_aspire_8930g_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc889_acer_aspire_8930g_verbs, - alc889_eapd_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), - .adc_nids = alc889_adc_nids, - .capsrc_nids = alc889_capsrc_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .const_channel_count = 6, - .num_mux_defs = - ARRAY_SIZE(alc889_capture_sources), - .input_mux = alc889_capture_sources, - .unsol_event = alc_sku_unsol_event, - .setup = alc889_acer_aspire_8930g_setup, - .init_hook = alc_hp_automute, -#ifdef CONFIG_SND_HDA_POWER_SAVE - .power_hook = alc_power_eapd, -#endif - }, - [ALC888_ACER_ASPIRE_7730G] = { - .mixers = { alc883_3ST_6ch_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs, - alc888_acer_aspire_7730G_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), - .adc_nids = alc883_adc_nids_rev, - .capsrc_nids = alc883_capsrc_nids_rev, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .const_channel_count = 6, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_acer_aspire_7730g_setup, - .init_hook = alc_hp_automute, - }, - [ALC883_MEDION] = { - .mixers = { alc883_fivestack_mixer, - alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, - alc883_medion_eapd_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .adc_nids = alc883_adc_nids_alt, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), - .capsrc_nids = alc883_capsrc_nids, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_MEDION_WIM2160] = { - .mixers = { alc883_medion_wim2160_mixer }, - .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), - .adc_nids = alc883_adc_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_medion_wim2160_setup, - .init_hook = alc_hp_automute, - }, - [ALC883_LAPTOP_EAPD] = { - .mixers = { alc883_base_mixer }, - .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - }, - [ALC883_CLEVO_M540R] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes), - .channel_mode = alc883_3ST_6ch_clevo_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - /* This machine has the hardware HP auto-muting, thus - * we need no software mute via unsol event - */ - }, - [ALC883_CLEVO_M720] = { - .mixers = { alc883_clevo_m720_mixer }, - .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc883_clevo_m720_unsol_event, - .setup = alc883_clevo_m720_setup, - .init_hook = alc883_clevo_m720_init_hook, - }, - [ALC883_LENOVO_101E_2ch] = { - .mixers = { alc883_lenovo_101e_2ch_mixer}, - .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .adc_nids = alc883_adc_nids_alt, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt), - .capsrc_nids = alc883_capsrc_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_lenovo_101e_capture_source, - .setup = alc883_lenovo_101e_setup, - .unsol_event = alc_sku_unsol_event, - .init_hook = alc_inithook, - }, - [ALC883_LENOVO_NB0763] = { - .mixers = { alc883_lenovo_nb0763_mixer }, - .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_lenovo_nb0763_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_lenovo_nb0763_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_LENOVO_MS7195_DIG] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_lenovo_ms7195_setup, - .init_hook = alc_inithook, - }, - [ALC883_HAIER_W66] = { - .mixers = { alc883_targa_2ch_mixer}, - .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_haier_w66_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_3ST_HP] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes), - .channel_mode = alc888_3st_hp_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_3st_hp_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_6ST_DELL] = { - .mixers = { alc883_base_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_6st_dell_setup, - .init_hook = alc_hp_automute, - }, - [ALC883_MITAC] = { - .mixers = { alc883_mitac_mixer }, - .init_verbs = { alc883_init_verbs, alc883_mitac_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_mitac_setup, - .init_hook = alc_hp_automute, - }, - [ALC883_FUJITSU_PI2515] = { - .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, - .init_verbs = { alc883_init_verbs, - alc883_2ch_fujitsu_pi2515_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_fujitsu_pi2515_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_2ch_fujitsu_pi2515_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_FUJITSU_XA3530] = { - .mixers = { alc888_base_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, - alc888_fujitsu_xa3530_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev), - .adc_nids = alc883_adc_nids_rev, - .capsrc_nids = alc883_capsrc_nids_rev, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes), - .channel_mode = alc888_4ST_8ch_intel_modes, - .num_mux_defs = - ARRAY_SIZE(alc888_2_capture_sources), - .input_mux = alc888_2_capture_sources, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_fujitsu_xa3530_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_LENOVO_SKY] = { - .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .need_dac_fix = 1, - .input_mux = &alc883_lenovo_sky_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc888_lenovo_sky_setup, - .init_hook = alc_hp_automute, - }, - [ALC888_ASUS_M90V] = { - .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), - .channel_mode = alc883_3ST_6ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_fujitsu_pi2515_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_mode2_setup, - .init_hook = alc_inithook, - }, - [ALC888_ASUS_EEE1601] = { - .mixers = { alc883_asus_eee1601_mixer }, - .cap_mixer = alc883_asus_eee1601_cap_mixer, - .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .need_dac_fix = 1, - .input_mux = &alc883_asus_eee1601_capture_source, - .unsol_event = alc_sku_unsol_event, - .init_hook = alc883_eee1601_inithook, - }, - [ALC1200_ASUS_P5Q] = { - .mixers = { alc883_base_mixer, alc883_chmode_mixer }, - .init_verbs = { alc883_init_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC1200_DIGOUT_NID, - .dig_in_nid = ALC883_DIGIN_NID, - .slave_dig_outs = alc1200_slave_dig_outs, - .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), - .channel_mode = alc883_sixstack_modes, - .input_mux = &alc883_capture_source, - }, [ALC889A_MB31] = { .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, @@ -3711,18 +856,6 @@ static const struct alc_config_preset alc882_presets[] = { .unsol_event = alc889A_mb31_unsol_event, .init_hook = alc889A_mb31_automute, }, - [ALC883_SONY_VAIO_TT] = { - .mixers = { alc883_vaiott_mixer }, - .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs }, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_sku_unsol_event, - .setup = alc883_vaiott_setup, - .init_hook = alc_hp_automute, - }, }; diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 916a1863af7..4df72c0e8c3 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -33,6 +33,7 @@ #include <sound/jack.h> #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" #include <sound/hda_hwdep.h> #define CREATE_TRACE_POINTS @@ -1723,43 +1724,6 @@ int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, } EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); -/** - * snd_hda_pin_sense - execute pin sense measurement - * @codec: the CODEC to sense - * @nid: the pin NID to sense - * - * Execute necessary pin sense measurement and return its Presence Detect, - * Impedance, ELD Valid etc. status bits. - */ -u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) -{ - u32 pincap; - - if (!codec->no_trigger_sense) { - pincap = snd_hda_query_pin_caps(codec, nid); - if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ - snd_hda_codec_read(codec, nid, 0, - AC_VERB_SET_PIN_SENSE, 0); - } - return snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_SENSE, 0); -} -EXPORT_SYMBOL_HDA(snd_hda_pin_sense); - -/** - * snd_hda_jack_detect - query pin Presence Detect status - * @codec: the CODEC to sense - * @nid: the pin NID to sense - * - * Query and return the pin's Presence Detect status. - */ -int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) -{ - u32 sense = snd_hda_pin_sense(codec, nid); - return !!(sense & AC_PINSENSE_PRESENCE); -} -EXPORT_SYMBOL_HDA(snd_hda_jack_detect); - /* * read the current volume to info * if the cache exists, read the cache value. @@ -2308,6 +2272,7 @@ int snd_hda_codec_reset(struct hda_codec *codec) } if (codec->patch_ops.free) codec->patch_ops.free(codec); + snd_hda_jack_tbl_clear(codec); codec->proc_widget_hook = NULL; codec->spec = NULL; free_hda_cache(&codec->amp_cache); @@ -2331,6 +2296,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) return 0; } +typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); + +/* apply the function to all matching slave ctls in the mixer list */ +static int map_slaves(struct hda_codec *codec, const char * const *slaves, + map_slave_func_t func, void *data) +{ + struct hda_nid_item *items; + const char * const *s; + int i, err; + + items = codec->mixers.list; + for (i = 0; i < codec->mixers.used; i++) { + struct snd_kcontrol *sctl = items[i].kctl; + if (!sctl || !sctl->id.name || + sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) + continue; + for (s = slaves; *s; s++) { + if (!strcmp(sctl->id.name, *s)) { + err = func(data, sctl); + if (err) + return err; + break; + } + } + } + return 0; +} + +static int check_slave_present(void *data, struct snd_kcontrol *sctl) +{ + return 1; +} + /** * snd_hda_add_vmaster - create a virtual master control and add slaves * @codec: HD-audio codec @@ -2351,12 +2349,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *slaves) { struct snd_kcontrol *kctl; - const char * const *s; int err; - for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) - ; - if (!*s) { + err = map_slaves(codec, slaves, check_slave_present, NULL); + if (err != 1) { snd_printdd("No slave found for %s\n", name); return 0; } @@ -2367,23 +2363,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, if (err < 0) return err; - for (s = slaves; *s; s++) { - struct snd_kcontrol *sctl; - int i = 0; - for (;;) { - sctl = _snd_hda_find_mixer_ctl(codec, *s, i); - if (!sctl) { - if (!i) - snd_printdd("Cannot find slave %s, " - "skipped\n", *s); - break; - } - err = snd_ctl_add_slave(kctl, sctl); - if (err < 0) - return err; - i++; - } - } + err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, + kctl); + if (err < 0) + return err; return 0; } EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); @@ -3346,6 +3329,7 @@ static void hda_call_codec_resume(struct hda_codec *codec) restore_pincfgs(codec); /* restore all current pin configs */ restore_shutup_pins(codec); hda_exec_init_verbs(codec); + snd_hda_jack_set_dirty_all(codec); if (codec->patch_ops.resume) codec->patch_ops.resume(codec); else { @@ -3832,6 +3816,12 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type) if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) return audio_idx[type][i]; + /* non-fixed slots starting from 10 */ + for (i = 10; i < 32; i++) { + if (!test_and_set_bit(i, bus->pcm_dev_bits)) + return i; + } + snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); return -EAGAIN; @@ -4028,9 +4018,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, /* Search for codec ID */ for (q = tbl; q->subvendor; q++) { - unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); - - if (vendorid == codec->subsystem_id) + unsigned int mask = 0xffff0000 | q->subdevice_mask; + unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask; + if ((codec->subsystem_id & mask) == id) break; } @@ -4752,6 +4742,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0; + codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); @@ -4767,6 +4758,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue; def_conf = snd_hda_codec_get_pincfg(codec, nid); + if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & + AC_DEFCFG_MISC_NO_PRESENCE)) + codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; @@ -4982,8 +4976,8 @@ EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); * "Rear", "Internal". */ -const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, - int check_location) +static const char *hda_get_input_pin_label(struct hda_codec *codec, + hda_nid_t pin, bool check_location) { unsigned int def_conf; static const char * const mic_names[] = { @@ -5022,7 +5016,6 @@ const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, return "Misc"; } } -EXPORT_SYMBOL_HDA(hda_get_input_pin_label); /* Check whether the location prefix needs to be added to the label. * If all mic-jacks are in the same location (e.g. rear panel), we don't @@ -5079,6 +5072,149 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); +/* return the position of NID in the list, or -1 if not found */ +static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) +{ + int i; + for (i = 0; i < nums; i++) + if (list[i] == nid) + return i; + return -1; +} + +/* get a unique suffix or an index number */ +static const char *check_output_sfx(hda_nid_t nid, const hda_nid_t *pins, + int num_pins, int *indexp) +{ + static const char * const channel_sfx[] = { + " Front", " Surround", " CLFE", " Side" + }; + int i; + + i = find_idx_in_nid_list(nid, pins, num_pins); + if (i < 0) + return NULL; + if (num_pins == 1) + return ""; + if (num_pins > ARRAY_SIZE(channel_sfx)) { + if (indexp) + *indexp = i; + return ""; + } + return channel_sfx[i]; +} + +static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg, + const char *name, char *label, int maxlen, + int *indexp) +{ + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); + int attr = snd_hda_get_input_pin_attr(def_conf); + const char *pfx = "", *sfx = ""; + + /* handle as a speaker if it's a fixed line-out */ + if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) + name = "Speaker"; + /* check the location */ + switch (attr) { + case INPUT_PIN_ATTR_DOCK: + pfx = "Dock "; + break; + case INPUT_PIN_ATTR_FRONT: + pfx = "Front "; + break; + } + if (cfg) { + /* try to give a unique suffix if needed */ + sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs, + indexp); + if (!sfx) + sfx = check_output_sfx(nid, cfg->speaker_pins, cfg->speaker_outs, + indexp); + if (!sfx) { + /* don't add channel suffix for Headphone controls */ + int idx = find_idx_in_nid_list(nid, cfg->hp_pins, + cfg->hp_outs); + if (idx >= 0) + *indexp = idx; + sfx = ""; + } + } + snprintf(label, maxlen, "%s%s%s", pfx, name, sfx); + return 1; +} + +/** + * snd_hda_get_pin_label - Get a label for the given I/O pin + * + * Get a label for the given pin. This function works for both input and + * output pins. When @cfg is given as non-NULL, the function tries to get + * an optimized label using hda_get_autocfg_input_label(). + * + * This function tries to give a unique label string for the pin as much as + * possible. For example, when the multiple line-outs are present, it adds + * the channel suffix like "Front", "Surround", etc (only when @cfg is given). + * If no unique name with a suffix is available and @indexp is non-NULL, the + * index number is stored in the pointer. + */ +int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg, + char *label, int maxlen, int *indexp) +{ + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); + const char *name = NULL; + int i; + + if (indexp) + *indexp = 0; + if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) + return 0; + + switch (get_defcfg_device(def_conf)) { + case AC_JACK_LINE_OUT: + return fill_audio_out_name(codec, nid, cfg, "Line-Out", + label, maxlen, indexp); + case AC_JACK_SPEAKER: + return fill_audio_out_name(codec, nid, cfg, "Speaker", + label, maxlen, indexp); + case AC_JACK_HP_OUT: + return fill_audio_out_name(codec, nid, cfg, "Headphone", + label, maxlen, indexp); + case AC_JACK_SPDIF_OUT: + case AC_JACK_DIG_OTHER_OUT: + if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) + name = "HDMI"; + else + name = "SPDIF"; + if (cfg && indexp) { + i = find_idx_in_nid_list(nid, cfg->dig_out_pins, + cfg->dig_outs); + if (i >= 0) + *indexp = i; + } + break; + default: + if (cfg) { + for (i = 0; i < cfg->num_inputs; i++) { + if (cfg->inputs[i].pin != nid) + continue; + name = hda_get_autocfg_input_label(codec, cfg, i); + if (name) + break; + } + } + if (!name) + name = hda_get_input_pin_label(codec, nid, true); + break; + } + if (!name) + return 0; + strlcpy(label, name, maxlen); + return 1; +} +EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); + /** * snd_hda_add_imux_item - Add an item to input_mux * @@ -5230,113 +5366,5 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen) } EXPORT_SYMBOL_HDA(snd_print_pcm_bits); -#ifdef CONFIG_SND_HDA_INPUT_JACK -/* - * Input-jack notification support - */ -struct hda_jack_item { - hda_nid_t nid; - int type; - struct snd_jack *jack; -}; - -static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, - int type) -{ - switch (type) { - case SND_JACK_HEADPHONE: - return "Headphone"; - case SND_JACK_MICROPHONE: - return "Mic"; - case SND_JACK_LINEOUT: - return "Line-out"; - case SND_JACK_LINEIN: - return "Line-in"; - case SND_JACK_HEADSET: - return "Headset"; - case SND_JACK_VIDEOOUT: - return "HDMI/DP"; - default: - return "Misc"; - } -} - -static void hda_free_jack_priv(struct snd_jack *jack) -{ - struct hda_jack_item *jacks = jack->private_data; - jacks->nid = 0; - jacks->jack = NULL; -} - -int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, - const char *name) -{ - struct hda_jack_item *jack; - int err; - - snd_array_init(&codec->jacks, sizeof(*jack), 32); - jack = snd_array_new(&codec->jacks); - if (!jack) - return -ENOMEM; - - jack->nid = nid; - jack->type = type; - if (!name) - name = get_jack_default_name(codec, nid, type); - err = snd_jack_new(codec->bus->card, name, type, &jack->jack); - if (err < 0) { - jack->nid = 0; - return err; - } - jack->jack->private_data = jack; - jack->jack->private_free = hda_free_jack_priv; - return 0; -} -EXPORT_SYMBOL_HDA(snd_hda_input_jack_add); - -void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid) -{ - struct hda_jack_item *jacks = codec->jacks.list; - int i; - - if (!jacks) - return; - - for (i = 0; i < codec->jacks.used; i++, jacks++) { - unsigned int pin_ctl; - unsigned int present; - int type; - - if (jacks->nid != nid) - continue; - present = snd_hda_jack_detect(codec, nid); - type = jacks->type; - if (type == (SND_JACK_HEADPHONE | SND_JACK_LINEOUT)) { - pin_ctl = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - type = (pin_ctl & AC_PINCTL_HP_EN) ? - SND_JACK_HEADPHONE : SND_JACK_LINEOUT; - } - snd_jack_report(jacks->jack, present ? type : 0); - } -} -EXPORT_SYMBOL_HDA(snd_hda_input_jack_report); - -/* free jack instances manually when clearing/reconfiguring */ -void snd_hda_input_jack_free(struct hda_codec *codec) -{ - if (!codec->bus->shutdown && codec->jacks.list) { - struct hda_jack_item *jacks = codec->jacks.list; - int i; - for (i = 0; i < codec->jacks.used; i++, jacks++) { - if (jacks->jack) - snd_device_free(codec->bus->card, jacks->jack); - } - } - snd_array_free(&codec->jacks); -} -EXPORT_SYMBOL_HDA(snd_hda_input_jack_free); -#endif /* CONFIG_SND_HDA_INPUT_JACK */ - MODULE_DESCRIPTION("HDA codec core"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 755f2b0f9d8..e9f71dc0d46 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -547,9 +547,6 @@ enum { /* max. codec address */ #define HDA_MAX_CODEC_ADDRESS 0x0f -/* max number of PCM devics per card */ -#define HDA_MAX_PCMS 10 - /* * generic arrays */ @@ -854,6 +851,7 @@ struct hda_codec { unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ + unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ @@ -868,6 +866,9 @@ struct hda_codec { void (*proc_widget_hook)(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid); + /* jack detection */ + struct snd_array jacktbl; + #ifdef CONFIG_SND_HDA_INPUT_JACK /* jack detection */ struct snd_array jacks; diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 1c8ddf547a2..c1da422e085 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -297,10 +297,18 @@ static int hdmi_update_eld(struct hdmi_eld *e, buf + ELD_FIXED_BYTES + mnl + 3 * i); } + /* + * HDMI sink's ELD info cannot always be retrieved for now, e.g. + * in console or for audio devices. Assume the highest speakers + * configuration, to _not_ prohibit multi-channel audio playback. + */ + if (!e->spk_alloc) + e->spk_alloc = 0xffff; + + e->eld_valid = true; return 0; out_fail: - e->eld_ver = 0; return -EINVAL; } @@ -323,9 +331,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, * ELD is valid, actual eld_size is assigned in hdmi_update_eld() */ - if (!eld->eld_valid) - return -ENOENT; - size = snd_hdmi_get_eld_size(codec, nid); if (size == 0) { /* wfg: workaround for ASUS P5E-VM HDMI board */ @@ -342,18 +347,28 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, for (i = 0; i < size; i++) { unsigned int val = hdmi_get_eld_data(codec, nid, i); + /* + * Graphics driver might be writing to ELD buffer right now. + * Just abort. The caller will repoll after a while. + */ if (!(val & AC_ELDD_ELD_VALID)) { - if (!i) { - snd_printd(KERN_INFO - "HDMI: invalid ELD data\n"); - ret = -EINVAL; - goto error; - } snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", i); - val = 0; - } else - val &= AC_ELDD_ELD_DATA; + ret = -EINVAL; + goto error; + } + val &= AC_ELDD_ELD_DATA; + /* + * The first byte cannot be zero. This can happen on some DVI + * connections. Some Intel chips may also need some 250ms delay + * to return non-zero ELD data, even when the graphics driver + * correctly writes ELD content before setting ELD_valid bit. + */ + if (!val && !i) { + snd_printdd(KERN_INFO "HDMI: 0 ELD data\n"); + ret = -EINVAL; + goto error; + } buf[i] = val; } diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 096507d2ca9..0852e204a4c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -58,13 +58,13 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static char *model[SNDRV_CARDS]; static int position_fix[SNDRV_CARDS]; static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; static int probe_only[SNDRV_CARDS]; -static int single_cmd; +static bool single_cmd; static int enable_msi = -1; #ifdef CONFIG_SND_HDA_PATCH_LOADER static char *patch[SNDRV_CARDS]; @@ -116,12 +116,12 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " * this may give more power-saving, but will take longer time to * wake up. */ -static int power_save_controller = 1; +static bool power_save_controller = 1; module_param(power_save_controller, bool, 0644); MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); #endif -static int align_buffer_size = 1; +static bool align_buffer_size = 1; module_param(align_buffer_size, bool, 0644); MODULE_PARM_DESC(align_buffer_size, "Force buffer and period sizes to be multiple of 128 bytes."); @@ -407,6 +407,14 @@ struct azx_rb { u32 res[AZX_MAX_CODECS]; /* last read value */ }; +struct azx_pcm { + struct azx *chip; + struct snd_pcm *pcm; + struct hda_codec *codec; + struct hda_pcm_stream *hinfo[2]; + struct list_head list; +}; + struct azx { struct snd_card *card; struct pci_dev *pci; @@ -434,7 +442,7 @@ struct azx { struct azx_dev *azx_dev; /* PCM */ - struct snd_pcm *pcm[HDA_MAX_PCMS]; + struct list_head pcm_list; /* azx_pcm list */ /* HD codec */ unsigned short codec_mask; @@ -479,6 +487,7 @@ enum { AZX_DRIVER_SCH, AZX_DRIVER_ATI, AZX_DRIVER_ATIHDMI, + AZX_DRIVER_ATIHDMI_NS, AZX_DRIVER_VIA, AZX_DRIVER_SIS, AZX_DRIVER_ULI, @@ -525,6 +534,7 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_SCH] = "HDA Intel MID", [AZX_DRIVER_ATI] = "HDA ATI SB", [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", + [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI", [AZX_DRIVER_VIA] = "HDA VIA VT82xx", [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", @@ -1143,16 +1153,6 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, static void azx_init_pci(struct azx *chip) { - /* force to non-snoop mode for a new VIA controller when BIOS is set */ - if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) { - u8 snoop; - pci_read_config_byte(chip->pci, 0x42, &snoop); - if (!(snoop & 0x80) && chip->pci->revision == 0x30) { - chip->snoop = 0; - snd_printdd(SFX "Force to non-snoop mode\n"); - } - } - /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio @@ -1486,10 +1486,9 @@ static void azx_bus_reset(struct hda_bus *bus) azx_init_chip(chip, 1); #ifdef CONFIG_PM if (chip->initialized) { - int i; - - for (i = 0; i < HDA_MAX_PCMS; i++) - snd_pcm_suspend_all(chip->pcm[i]); + struct azx_pcm *p; + list_for_each_entry(p, &chip->pcm_list, list) + snd_pcm_suspend_all(p->pcm); snd_hda_suspend(chip->bus); snd_hda_resume(chip->bus); } @@ -1667,12 +1666,6 @@ static struct snd_pcm_hardware azx_pcm_hw = { .fifo_size = 0, }; -struct azx_pcm { - struct azx *chip; - struct hda_codec *codec; - struct hda_pcm_stream *hinfo[2]; -}; - static int azx_pcm_open(struct snd_pcm_substream *substream) { struct azx_pcm *apcm = snd_pcm_substream_chip(substream); @@ -2197,7 +2190,7 @@ static void azx_pcm_free(struct snd_pcm *pcm) { struct azx_pcm *apcm = pcm->private_data; if (apcm) { - apcm->chip->pcm[pcm->device] = NULL; + list_del(&apcm->list); kfree(apcm); } } @@ -2215,14 +2208,11 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, unsigned int size; int s, err; - if (pcm_dev >= HDA_MAX_PCMS) { - snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", - pcm_dev); - return -EINVAL; - } - if (chip->pcm[pcm_dev]) { - snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); - return -EBUSY; + list_for_each_entry(apcm, &chip->pcm_list, list) { + if (apcm->pcm->device == pcm_dev) { + snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); + return -EBUSY; + } } err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams, @@ -2235,12 +2225,13 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, if (apcm == NULL) return -ENOMEM; apcm->chip = chip; + apcm->pcm = pcm; apcm->codec = codec; pcm->private_data = apcm; pcm->private_free = azx_pcm_free; if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) pcm->dev_class = SNDRV_PCM_CLASS_MODEM; - chip->pcm[pcm_dev] = pcm; + list_add_tail(&apcm->list, &chip->pcm_list); cpcm->pcm = pcm; for (s = 0; s < 2; s++) { apcm->hinfo[s] = &cpcm->stream[s]; @@ -2370,12 +2361,12 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct azx *chip = card->private_data; - int i; + struct azx_pcm *p; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); azx_clear_irq_pending(chip); - for (i = 0; i < HDA_MAX_PCMS; i++) - snd_pcm_suspend_all(chip->pcm[i]); + list_for_each_entry(p, &chip->pcm_list, list) + snd_pcm_suspend_all(p->pcm); if (chip->initialized) snd_hda_suspend(chip->bus); azx_stop_chip(chip); @@ -2502,13 +2493,11 @@ static int azx_dev_free(struct snd_device *device) static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), - SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", POS_FIX_LPIB), SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), - SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), @@ -2634,6 +2623,35 @@ static void __devinit check_msi(struct azx *chip) } } +/* check the snoop mode availability */ +static void __devinit azx_check_snoop_available(struct azx *chip) +{ + bool snoop = chip->snoop; + + switch (chip->driver_type) { + case AZX_DRIVER_VIA: + /* force to non-snoop mode for a new VIA controller + * when BIOS is set + */ + if (snoop) { + u8 val; + pci_read_config_byte(chip->pci, 0x42, &val); + if (!(val & 0x80) && chip->pci->revision == 0x30) + snoop = false; + } + break; + case AZX_DRIVER_ATIHDMI_NS: + /* new ATI HDMI requires non-snoop */ + snoop = false; + break; + } + + if (snoop != chip->snoop) { + snd_printk(KERN_INFO SFX "Force to %s mode\n", + snoop ? "snoop" : "non-snoop"); + chip->snoop = snoop; + } +} /* * constructor @@ -2672,6 +2690,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, check_msi(chip); chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); + INIT_LIST_HEAD(&chip->pcm_list); chip->position_fix[0] = chip->position_fix[1] = check_position_fix(chip, position_fix[dev]); @@ -2679,6 +2698,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->single_cmd = single_cmd; chip->snoop = hda_snoop; + azx_check_snoop_available(chip); if (bdl_pos_adj[dev] < 0) { switch (chip->driver_type) { @@ -2777,6 +2797,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->capture_streams = ULI_NUM_CAPTURE; break; case AZX_DRIVER_ATIHDMI: + case AZX_DRIVER_ATIHDMI_NS: chip->playback_streams = ATIHDMI_NUM_PLAYBACK; chip->capture_streams = ATIHDMI_NUM_CAPTURE; break; @@ -2971,7 +2992,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE}, + AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */ + { PCI_DEVICE(0x8086, 0x080a), + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | + AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Oaktrail */ + /* ICH */ { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_BUFSIZE }, /* ICH6 */ @@ -3038,6 +3063,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0x9902), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaaa0), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaaa8), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaab0), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, /* VIA VT8251/VT8237A */ { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c new file mode 100644 index 00000000000..d8a35da0803 --- /dev/null +++ b/sound/pci/hda/hda_jack.c @@ -0,0 +1,353 @@ +/* + * Jack-detection handling for HD-audio + * + * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/export.h> +#include <sound/core.h> +#include <sound/control.h> +#include <sound/jack.h> +#include "hda_codec.h" +#include "hda_local.h" +#include "hda_jack.h" + +/* execute pin sense measurement */ +static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) +{ + u32 pincap; + + if (!codec->no_trigger_sense) { + pincap = snd_hda_query_pin_caps(codec, nid); + if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ + snd_hda_codec_read(codec, nid, 0, + AC_VERB_SET_PIN_SENSE, 0); + } + return snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_SENSE, 0); +} + +/** + * snd_hda_jack_tbl_get - query the jack-table entry for the given NID + */ +struct hda_jack_tbl * +snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i; + + if (!nid || !jack) + return NULL; + for (i = 0; i < codec->jacktbl.used; i++, jack++) + if (jack->nid == nid) + return jack; + return NULL; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get); + +/** + * snd_hda_jack_tbl_get_from_tag - query the jack-table entry for the given tag + */ +struct hda_jack_tbl * +snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag) +{ + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i; + + if (!tag || !jack) + return NULL; + for (i = 0; i < codec->jacktbl.used; i++, jack++) + if (jack->tag == tag) + return jack; + return NULL; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_get_from_tag); + +/** + * snd_hda_jack_tbl_new - create a jack-table entry for the given NID + */ +struct hda_jack_tbl * +snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + if (jack) + return jack; + snd_array_init(&codec->jacktbl, sizeof(*jack), 16); + jack = snd_array_new(&codec->jacktbl); + if (!jack) + return NULL; + jack->nid = nid; + jack->jack_dirty = 1; + jack->tag = codec->jacktbl.used; + return jack; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_tbl_new); + +void snd_hda_jack_tbl_clear(struct hda_codec *codec) +{ +#ifdef CONFIG_SND_HDA_INPUT_JACK + /* free jack instances manually when clearing/reconfiguring */ + if (!codec->bus->shutdown && codec->jacktbl.list) { + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i; + for (i = 0; i < codec->jacktbl.used; i++, jack++) { + if (jack->jack) + snd_device_free(codec->bus->card, jack->jack); + } + } +#endif + snd_array_free(&codec->jacktbl); +} + +/* update the cached value and notification flag if needed */ +static void jack_detect_update(struct hda_codec *codec, + struct hda_jack_tbl *jack) +{ + if (jack->jack_dirty || !jack->jack_detect) { + jack->pin_sense = read_pin_sense(codec, jack->nid); + jack->jack_dirty = 0; + } +} + +/** + * snd_hda_set_dirty_all - Mark all the cached as dirty + * + * This function sets the dirty flag to all entries of jack table. + * It's called from the resume path in hda_codec.c. + */ +void snd_hda_jack_set_dirty_all(struct hda_codec *codec) +{ + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i; + + for (i = 0; i < codec->jacktbl.used; i++, jack++) + if (jack->nid) + jack->jack_dirty = 1; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_set_dirty_all); + +/** + * snd_hda_pin_sense - execute pin sense measurement + * @codec: the CODEC to sense + * @nid: the pin NID to sense + * + * Execute necessary pin sense measurement and return its Presence Detect, + * Impedance, ELD Valid etc. status bits. + */ +u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); + if (jack) { + jack_detect_update(codec, jack); + return jack->pin_sense; + } + return read_pin_sense(codec, nid); +} +EXPORT_SYMBOL_HDA(snd_hda_pin_sense); + +#define get_jack_plug_state(sense) !!(sense & AC_PINSENSE_PRESENCE) + +/** + * snd_hda_jack_detect - query pin Presence Detect status + * @codec: the CODEC to sense + * @nid: the pin NID to sense + * + * Query and return the pin's Presence Detect status. + */ +int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) +{ + u32 sense = snd_hda_pin_sense(codec, nid); + return get_jack_plug_state(sense); +} +EXPORT_SYMBOL_HDA(snd_hda_jack_detect); + +/** + * snd_hda_jack_detect_enable - enable the jack-detection + */ +int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, + unsigned char action) +{ + struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid); + if (!jack) + return -ENOMEM; + if (jack->jack_detect) + return 0; /* already registered */ + jack->jack_detect = 1; + if (action) + jack->action = action; + return snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | jack->tag); +} +EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable); + +/** + * snd_hda_jack_report_sync - sync the states of all jacks and report if changed + */ +void snd_hda_jack_report_sync(struct hda_codec *codec) +{ + struct hda_jack_tbl *jack = codec->jacktbl.list; + int i, state; + + for (i = 0; i < codec->jacktbl.used; i++, jack++) + if (jack->nid) { + jack_detect_update(codec, jack); + if (!jack->kctl) + continue; + state = get_jack_plug_state(jack->pin_sense); + snd_kctl_jack_report(codec->bus->card, jack->kctl, state); +#ifdef CONFIG_SND_HDA_INPUT_JACK + if (jack->jack) + snd_jack_report(jack->jack, + state ? jack->type : 0); +#endif + } +} +EXPORT_SYMBOL_HDA(snd_hda_jack_report_sync); + +#ifdef CONFIG_SND_HDA_INPUT_JACK +/* guess the jack type from the pin-config */ +static int get_input_jack_type(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); + switch (get_defcfg_device(def_conf)) { + case AC_JACK_LINE_OUT: + case AC_JACK_SPEAKER: + return SND_JACK_LINEOUT; + case AC_JACK_HP_OUT: + return SND_JACK_HEADPHONE; + case AC_JACK_SPDIF_OUT: + case AC_JACK_DIG_OTHER_OUT: + return SND_JACK_AVOUT; + case AC_JACK_MIC_IN: + return SND_JACK_MICROPHONE; + default: + return SND_JACK_LINEIN; + } +} + +static void hda_free_jack_priv(struct snd_jack *jack) +{ + struct hda_jack_tbl *jacks = jack->private_data; + jacks->nid = 0; + jacks->jack = NULL; +} +#endif + +/** + * snd_hda_jack_add_kctl - Add a kctl for the given pin + * + * This assigns a jack-detection kctl to the given pin. The kcontrol + * will have the given name and index. + */ +int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, + const char *name, int idx) +{ + struct hda_jack_tbl *jack; + struct snd_kcontrol *kctl; + int err, state; + + jack = snd_hda_jack_tbl_new(codec, nid); + if (!jack) + return 0; + if (jack->kctl) + return 0; /* already created */ + kctl = snd_kctl_jack_new(name, idx, codec); + if (!kctl) + return -ENOMEM; + err = snd_hda_ctl_add(codec, nid, kctl); + if (err < 0) + return err; + jack->kctl = kctl; + state = snd_hda_jack_detect(codec, nid); + snd_kctl_jack_report(codec->bus->card, kctl, state); +#ifdef CONFIG_SND_HDA_INPUT_JACK + jack->type = get_input_jack_type(codec, nid); + err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); + if (err < 0) + return err; + jack->jack->private_data = jack; + jack->jack->private_free = hda_free_jack_priv; + snd_jack_report(jack->jack, state ? jack->type : 0); +#endif + return 0; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); + +static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg) +{ + unsigned int def_conf, conn; + char name[44]; + int idx, err; + + if (!nid) + return 0; + if (!is_jack_detectable(codec, nid)) + return 0; + def_conf = snd_hda_codec_get_pincfg(codec, nid); + conn = get_defcfg_connect(def_conf); + if (conn != AC_JACK_PORT_COMPLEX) + return 0; + + snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); + err = snd_hda_jack_add_kctl(codec, nid, name, idx); + if (err < 0) + return err; + return snd_hda_jack_detect_enable(codec, nid, 0); +} + +/** + * snd_hda_jack_add_kctls - Add kctls for all pins included in the given pincfg + */ +int snd_hda_jack_add_kctls(struct hda_codec *codec, + const struct auto_pin_cfg *cfg) +{ + const hda_nid_t *p; + int i, err; + + for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { + err = add_jack_kctl(codec, *p, cfg); + if (err < 0) + return err; + } + for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { + if (*p == *cfg->line_out_pins) /* might be duplicated */ + break; + err = add_jack_kctl(codec, *p, cfg); + if (err < 0) + return err; + } + for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { + if (*p == *cfg->line_out_pins) /* might be duplicated */ + break; + err = add_jack_kctl(codec, *p, cfg); + if (err < 0) + return err; + } + for (i = 0; i < cfg->num_inputs; i++) { + err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); + if (err < 0) + return err; + } + for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { + err = add_jack_kctl(codec, *p, cfg); + if (err < 0) + return err; + } + err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); + if (err < 0) + return err; + err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); + if (err < 0) + return err; + return 0; +} +EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls); diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h new file mode 100644 index 00000000000..f8f97c71c9c --- /dev/null +++ b/sound/pci/hda/hda_jack.h @@ -0,0 +1,86 @@ +/* + * Jack-detection handling for HD-audio + * + * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __SOUND_HDA_JACK_H +#define __SOUND_HDA_JACK_H + +struct hda_jack_tbl { + hda_nid_t nid; + unsigned char action; /* event action (0 = none) */ + unsigned char tag; /* unsol event tag */ + unsigned int private_data; /* arbitrary data */ + /* jack-detection stuff */ + unsigned int pin_sense; /* cached pin-sense value */ + unsigned int jack_detect:1; /* capable of jack-detection? */ + unsigned int jack_dirty:1; /* needs to update? */ + struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ +#ifdef CONFIG_SND_HDA_INPUT_JACK + int type; + struct snd_jack *jack; +#endif +}; + +struct hda_jack_tbl * +snd_hda_jack_tbl_get(struct hda_codec *codec, hda_nid_t nid); +struct hda_jack_tbl * +snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec, unsigned char tag); + +struct hda_jack_tbl * +snd_hda_jack_tbl_new(struct hda_codec *codec, hda_nid_t nid); +void snd_hda_jack_tbl_clear(struct hda_codec *codec); + +/** + * snd_hda_jack_get_action - get jack-tbl entry for the tag + * + * Call this from the unsol event handler to get the assigned action for the + * event. This will mark the dirty flag for the later reporting, too. + */ +static inline unsigned char +snd_hda_jack_get_action(struct hda_codec *codec, unsigned int tag) +{ + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get_from_tag(codec, tag); + if (jack) { + jack->jack_dirty = 1; + return jack->action; + } + return 0; +} + +void snd_hda_jack_set_dirty_all(struct hda_codec *codec); + +int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, + unsigned char action); + +u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); +int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); + +static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) +{ + if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) + return false; + if (!codec->ignore_misc_bit && + (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & + AC_DEFCFG_MISC_NO_PRESENCE)) + return false; + if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) + return false; + return true; +} + +int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, + const char *name, int idx); +int snd_hda_jack_add_kctls(struct hda_codec *codec, + const struct auto_pin_cfg *cfg); + +void snd_hda_jack_report_sync(struct hda_codec *codec); + + +#endif /* __SOUND_HDA_JACK_H */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index dcbea0da0fa..aca8d3193b9 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -394,11 +394,12 @@ struct auto_pin_cfg_item { }; struct auto_pin_cfg; -const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, - int check_location); const char *hda_get_autocfg_input_label(struct hda_codec *codec, const struct auto_pin_cfg *cfg, int input); +int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg, + char *label, int maxlen, int *indexp); int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, int index, int *type_index_ret); @@ -487,7 +488,12 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) } /* get the widget type from widget capability bits */ -#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT) +static inline int get_wcaps_type(unsigned int wcaps) +{ + if (!wcaps) + return -1; /* invalid type */ + return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; +} static inline unsigned int get_wcaps_channels(u32 wcaps) { @@ -505,19 +511,6 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, unsigned int caps); -u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); -int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); - -static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) -{ - return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && - /* disable MISC_NO_PRESENCE check because it may break too - * many devices - */ - /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & - AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ - (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); -} /* flags for hda_nid_item */ #define HDA_NID_ITEM_AMP (1<<0) @@ -651,6 +644,9 @@ struct hdmi_eld { int spk_alloc; int sad_count; struct cea_sad sad[ELD_MAX_SAD]; + /* + * all fields above eld_buffer will be cleared before updating ELD + */ char eld_buffer[ELD_MAX_SIZE]; #ifdef CONFIG_PROC_FS struct snd_info_entry *proc_entry; @@ -683,28 +679,4 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec, #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80 void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); -/* - * Input-jack notification support - */ -#ifdef CONFIG_SND_HDA_INPUT_JACK -int snd_hda_input_jack_add(struct hda_codec *codec, hda_nid_t nid, int type, - const char *name); -void snd_hda_input_jack_report(struct hda_codec *codec, hda_nid_t nid); -void snd_hda_input_jack_free(struct hda_codec *codec); -#else /* CONFIG_SND_HDA_INPUT_JACK */ -static inline int snd_hda_input_jack_add(struct hda_codec *codec, - hda_nid_t nid, int type, - const char *name) -{ - return 0; -} -static inline void snd_hda_input_jack_report(struct hda_codec *codec, - hda_nid_t nid) -{ -} -static inline void snd_hda_input_jack_free(struct hda_codec *codec) -{ -} -#endif /* CONFIG_SND_HDA_INPUT_JACK */ - #endif /* __SOUND_HDA_LOCAL_H */ diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 2c981b55940..254ab520460 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -54,6 +54,8 @@ static const char *get_wid_type_name(unsigned int wid_value) [AC_WID_BEEP] = "Beep Generator Widget", [AC_WID_VENDOR] = "Vendor Defined Widget", }; + if (wid_value == -1) + return "UNKNOWN Widget"; wid_value &= 0xf; if (names[wid_value]) return names[wid_value]; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index bcb3310c394..9cb14b42dff 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -29,6 +29,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" struct ad198x_spec { const struct snd_kcontrol_new *mixers[6]; diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 993757b6573..09ccfabb4a1 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c @@ -41,7 +41,7 @@ struct ca0110_spec { hda_nid_t dig_out; hda_nid_t dig_in; unsigned int num_inputs; - const char *input_labels[AUTO_PIN_LAST]; + char input_labels[AUTO_PIN_LAST][32]; struct hda_pcm pcm_rec[2]; /* PCM information */ }; @@ -476,7 +476,9 @@ static void parse_input(struct hda_codec *codec) if (j >= cfg->num_inputs) continue; spec->input_pins[n] = pin; - spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1); + snd_hda_get_pin_label(codec, pin, cfg, + spec->input_labels[n], + sizeof(spec->input_labels[n]), NULL); spec->adcs[n] = nid; n++; } diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 2a2d8645ba0..0e99357e822 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -26,6 +26,7 @@ #include <sound/core.h> #include "hda_codec.h" #include "hda_local.h" +#include "hda_jack.h" #include <sound/tlv.h> /* @@ -58,6 +59,8 @@ struct cs_spec { unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; + unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ + unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -76,6 +79,8 @@ enum { CS420X_MBP53, CS420X_MBP55, CS420X_IMAC27, + CS420X_IMAC27_122, + CS420X_APPLE, CS420X_AUTO, CS420X_MODELS }; @@ -134,7 +139,7 @@ enum { */ #define CS4210_DAC_NID 0x02 #define CS4210_ADC_NID 0x03 -#define CS421X_VENDOR_NID 0x0B +#define CS4210_VENDOR_NID 0x0B #define CS421X_DMIC_PIN_NID 0x09 /* Port E */ #define CS421X_SPDIF_PIN_NID 0x0A /* Port H */ @@ -145,6 +150,10 @@ enum { #define SPDIF_EVENT 0x04 +/* Cirrus Logic CS4213 is like CS4210 but does not have SPDIF input/output */ +#define CS4213_VENDOR_NID 0x09 + + static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) { struct cs_spec *spec = codec->spec; @@ -237,6 +246,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); } +static void cs_update_input_select(struct hda_codec *codec) +{ + struct cs_spec *spec = codec->spec; + if (spec->cur_adc) + snd_hda_codec_write(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[spec->cur_input]); +} + /* * Analog capture */ @@ -250,6 +268,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_adc = spec->adc_nid[spec->cur_input]; spec->cur_adc_stream_tag = stream_tag; spec->cur_adc_format = format; + cs_update_input_select(codec); snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); return 0; } @@ -689,10 +708,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx, spec->cur_adc_stream_tag, 0, spec->cur_adc_format); } - snd_hda_codec_write(codec, spec->cur_adc, 0, - AC_VERB_SET_CONNECT_SEL, - spec->adc_idx[idx]); spec->cur_input = idx; + cs_update_input_select(codec); return 1; } @@ -710,8 +727,9 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol, if (uinfo->value.enumerated.item >= spec->num_inputs) uinfo->value.enumerated.item = spec->num_inputs - 1; idx = spec->input_idx[uinfo->value.enumerated.item]; - strcpy(uinfo->value.enumerated.name, - hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1)); + snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, cfg, + uinfo->value.enumerated.name, + sizeof(uinfo->value.enumerated.name), NULL); return 0; } @@ -909,27 +927,24 @@ static void cs_automute(struct hda_codec *codec) /* mute speakers if spdif or hp jack is plugged in */ for (i = 0; i < cfg->speaker_outs; i++) { + int pin_ctl = hp_present ? 0 : PIN_OUT; + /* detect on spdif is specific to CS4210 */ + if (spdif_present && (spec->vendor_nid == CS4210_VENDOR_NID)) + pin_ctl = 0; + nid = cfg->speaker_pins[i]; snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - hp_present ? 0 : PIN_OUT); - /* detect on spdif is specific to CS421x */ - if (spec->vendor_nid == CS421X_VENDOR_NID) { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - spdif_present ? 0 : PIN_OUT); - } + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl); } - if (spec->board_config == CS420X_MBP53 || - spec->board_config == CS420X_MBP55 || - spec->board_config == CS420X_IMAC27) { - unsigned int gpio = hp_present ? 0x02 : 0x08; + if (spec->gpio_eapd_hp) { + unsigned int gpio = hp_present ? + spec->gpio_eapd_hp : spec->gpio_eapd_speaker; snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, gpio); } - /* specific to CS421x */ - if (spec->vendor_nid == CS421X_VENDOR_NID) { + /* specific to CS4210 */ + if (spec->vendor_nid == CS4210_VENDOR_NID) { /* mute HPs if spdif jack (SENSE_B) is present */ for (i = 0; i < cfg->hp_outs; i++) { nid = cfg->hp_pins[i]; @@ -966,22 +981,19 @@ static void cs_automic(struct hda_codec *codec) present = snd_hda_jack_detect(codec, nid); /* specific to CS421x, single ADC */ - if (spec->vendor_nid == CS421X_VENDOR_NID) { + if (spec->vendor_nid == CS420X_VENDOR_NID) { + if (present) + change_cur_input(codec, spec->automic_idx, 0); + else + change_cur_input(codec, !spec->automic_idx, 0); + } else { if (present) { spec->last_input = spec->cur_input; spec->cur_input = spec->automic_idx; } else { spec->cur_input = spec->last_input; } - - snd_hda_codec_write_cache(codec, spec->cur_adc, 0, - AC_VERB_SET_CONNECT_SEL, - spec->adc_idx[spec->cur_input]); - } else { - if (present) - change_cur_input(codec, spec->automic_idx, 0); - else - change_cur_input(codec, !spec->automic_idx, 0); + cs_update_input_select(codec); } } @@ -1020,9 +1032,7 @@ static void init_output(struct hda_codec *codec) if (!cfg->speaker_outs) continue; if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | HP_EVENT); + snd_hda_jack_detect_enable(codec, nid, HP_EVENT); spec->hp_detect = 1; } } @@ -1063,21 +1073,10 @@ static void init_input(struct hda_codec *codec) AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(spec->adc_idx[i])); if (spec->mic_detect && spec->automic_idx == i) - snd_hda_codec_write(codec, pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | MIC_EVENT); + snd_hda_jack_detect_enable(codec, pin, MIC_EVENT); } - /* specific to CS421x */ - if (spec->vendor_nid == CS421X_VENDOR_NID) { - if (spec->mic_detect) - cs_automic(codec); - else { - spec->cur_adc = spec->adc_nid[spec->cur_input]; - snd_hda_codec_write(codec, spec->cur_adc, 0, - AC_VERB_SET_CONNECT_SEL, - spec->adc_idx[spec->cur_input]); - } - } else { + /* CS420x has multiple ADC, CS421x has single ADC */ + if (spec->vendor_nid == CS420X_VENDOR_NID) { change_cur_input(codec, spec->cur_input, 1); if (spec->mic_detect) cs_automic(codec); @@ -1091,6 +1090,13 @@ static void init_input(struct hda_codec *codec) * selected in IDX_SPDIF_CTL. */ cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); + } else { + if (spec->mic_detect) + cs_automic(codec); + else { + spec->cur_adc = spec->adc_nid[spec->cur_input]; + cs_update_input_select(codec); + } } } @@ -1195,11 +1201,14 @@ static int cs_init(struct hda_codec *codec) init_output(codec); init_input(codec); init_digital(codec); + snd_hda_jack_report_sync(codec); + return 0; } static int cs_build_controls(struct hda_codec *codec) { + struct cs_spec *spec = codec->spec; int err; err = build_output(codec); @@ -1214,7 +1223,15 @@ static int cs_build_controls(struct hda_codec *codec) err = build_digital_input(codec); if (err < 0) return err; - return cs_init(codec); + err = cs_init(codec); + if (err < 0) + return err; + + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + + return 0; } static void cs_free(struct hda_codec *codec) @@ -1227,7 +1244,7 @@ static void cs_free(struct hda_codec *codec) static void cs_unsol_event(struct hda_codec *codec, unsigned int res) { - switch ((res >> 26) & 0x7f) { + switch (snd_hda_jack_get_action(codec, res >> 26)) { case HP_EVENT: cs_automute(codec); break; @@ -1235,6 +1252,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res) cs_automic(codec); break; } + snd_hda_jack_report_sync(codec); } static const struct hda_codec_ops cs_patch_ops = { @@ -1273,6 +1291,8 @@ static const char * const cs420x_models[CS420X_MODELS] = { [CS420X_MBP53] = "mbp53", [CS420X_MBP55] = "mbp55", [CS420X_IMAC27] = "imac27", + [CS420X_IMAC27_122] = "imac27_122", + [CS420X_APPLE] = "apple", [CS420X_AUTO] = "auto", }; @@ -1282,7 +1302,14 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), - SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), + /* this conflicts with too many other models */ + /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ + {} /* terminator */ +}; + +static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = { + SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122), + SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), {} /* terminator */ }; @@ -1364,6 +1391,10 @@ static int patch_cs420x(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, CS420X_MODELS, cs420x_models, cs420x_cfg_tbl); + if (spec->board_config < 0) + spec->board_config = + snd_hda_check_board_codec_sid_config(codec, + CS420X_MODELS, NULL, cs420x_codec_cfg_tbl); if (spec->board_config >= 0) fix_pincfg(codec, spec->board_config, cs_pincfgs); @@ -1371,10 +1402,17 @@ static int patch_cs420x(struct hda_codec *codec) case CS420X_IMAC27: case CS420X_MBP53: case CS420X_MBP55: - /* GPIO1 = headphones */ - /* GPIO3 = speakers */ - spec->gpio_mask = 0x0a; - spec->gpio_dir = 0x0a; + case CS420X_APPLE: + spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */ + spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ + spec->gpio_mask = spec->gpio_dir = + spec->gpio_eapd_hp | spec->gpio_eapd_speaker; + break; + case CS420X_IMAC27_122: + spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */ + spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ + spec->gpio_mask = spec->gpio_dir = + spec->gpio_eapd_hp | spec->gpio_eapd_speaker; break; } @@ -1540,7 +1578,7 @@ static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = { .tlv = { .p = cs421x_speaker_boost_db_scale }, }; -static void cs421x_pinmux_init(struct hda_codec *codec) +static void cs4210_pinmux_init(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; unsigned int def_conf, coef; @@ -1585,10 +1623,7 @@ static void init_cs421x_digital(struct hda_codec *codec) if (!cfg->speaker_outs) continue; if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { - - snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | SPDIF_EVENT); + snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT); spec->spdif_detect = 1; } } @@ -1598,10 +1633,11 @@ static int cs421x_init(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; - snd_hda_sequence_write(codec, cs421x_coef_init_verbs); - snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes); - - cs421x_pinmux_init(codec); + if (spec->vendor_nid == CS4210_VENDOR_NID) { + snd_hda_sequence_write(codec, cs421x_coef_init_verbs); + snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes); + cs4210_pinmux_init(codec); + } if (spec->gpio_mask) { snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, @@ -1615,6 +1651,7 @@ static int cs421x_init(struct hda_codec *codec) init_output(codec); init_input(codec); init_cs421x_digital(codec); + snd_hda_jack_report_sync(codec); return 0; } @@ -1754,32 +1791,21 @@ static int build_cs421x_output(struct hda_codec *codec) struct auto_pin_cfg *cfg = &spec->autocfg; struct snd_kcontrol *kctl; int err; - char *name = "HP/Speakers"; + char *name = "Master"; fix_volume_caps(codec, dac); - if (!spec->vmaster_sw) { - err = add_vmaster(codec, dac); - if (err < 0) - return err; - } err = add_mute(codec, name, 0, HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); if (err < 0) return err; - err = snd_ctl_add_slave(spec->vmaster_sw, kctl); - if (err < 0) - return err; err = add_volume(codec, name, 0, HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl); if (err < 0) return err; - err = snd_ctl_add_slave(spec->vmaster_vol, kctl); - if (err < 0) - return err; - if (cfg->speaker_outs) { + if (cfg->speaker_outs && (spec->vendor_nid == CS4210_VENDOR_NID)) { err = snd_hda_ctl_add(codec, 0, snd_ctl_new1(&cs421x_speaker_bost_ctl, codec)); if (err < 0) @@ -1790,6 +1816,7 @@ static int build_cs421x_output(struct hda_codec *codec) static int cs421x_build_controls(struct hda_codec *codec) { + struct cs_spec *spec = codec->spec; int err; err = build_cs421x_output(codec); @@ -1801,12 +1828,20 @@ static int cs421x_build_controls(struct hda_codec *codec) err = build_digital_output(codec); if (err < 0) return err; - return cs421x_init(codec); + err = cs421x_init(codec); + if (err < 0) + return err; + + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + + return 0; } static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) { - switch ((res >> 26) & 0x3f) { + switch (snd_hda_jack_get_action(codec, res >> 26)) { case HP_EVENT: case SPDIF_EVENT: cs_automute(codec); @@ -1816,6 +1851,7 @@ static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res) cs_automic(codec); break; } + snd_hda_jack_report_sync(codec); } static int parse_cs421x_input(struct hda_codec *codec) @@ -1866,6 +1902,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec) */ static int cs421x_suspend(struct hda_codec *codec, pm_message_t state) { + struct cs_spec *spec = codec->spec; unsigned int coef; snd_hda_shutup_pins(codec); @@ -1875,15 +1912,17 @@ static int cs421x_suspend(struct hda_codec *codec, pm_message_t state) snd_hda_codec_write(codec, CS4210_ADC_NID, 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG); - coef |= 0x0004; /* PDREF */ - cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef); + if (spec->vendor_nid == CS4210_VENDOR_NID) { + coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG); + coef |= 0x0004; /* PDREF */ + cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef); + } return 0; } #endif -static struct hda_codec_ops cs4210_patch_ops = { +static struct hda_codec_ops cs421x_patch_ops = { .build_controls = cs421x_build_controls, .build_pcms = cs_build_pcms, .init = cs421x_init, @@ -1894,7 +1933,7 @@ static struct hda_codec_ops cs4210_patch_ops = { #endif }; -static int patch_cs421x(struct hda_codec *codec) +static int patch_cs4210(struct hda_codec *codec) { struct cs_spec *spec; int err; @@ -1904,7 +1943,7 @@ static int patch_cs421x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; - spec->vendor_nid = CS421X_VENDOR_NID; + spec->vendor_nid = CS4210_VENDOR_NID; spec->board_config = snd_hda_check_board_config(codec, CS421X_MODELS, @@ -1932,14 +1971,39 @@ static int patch_cs421x(struct hda_codec *codec) is auto-parsed. If GPIO or SENSE_B is forced, DMIC input is disabled. */ - cs421x_pinmux_init(codec); + cs4210_pinmux_init(codec); err = cs421x_parse_auto_config(codec); if (err < 0) goto error; - codec->patch_ops = cs4210_patch_ops; + codec->patch_ops = cs421x_patch_ops; + + return 0; + + error: + kfree(codec->spec); + codec->spec = NULL; + return err; +} + +static int patch_cs4213(struct hda_codec *codec) +{ + struct cs_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + codec->spec = spec; + + spec->vendor_nid = CS4213_VENDOR_NID; + + err = cs421x_parse_auto_config(codec); + if (err < 0) + goto error; + codec->patch_ops = cs421x_patch_ops; return 0; error: @@ -1955,13 +2019,15 @@ static int patch_cs421x(struct hda_codec *codec) static const struct hda_codec_preset snd_hda_preset_cirrus[] = { { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, - { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x }, + { .id = 0x10134210, .name = "CS4210", .patch = patch_cs4210 }, + { .id = 0x10134213, .name = "CS4213", .patch = patch_cs4213 }, {} /* terminator */ }; MODULE_ALIAS("snd-hda-codec-id:10134206"); MODULE_ALIAS("snd-hda-codec-id:10134207"); MODULE_ALIAS("snd-hda-codec-id:10134210"); +MODULE_ALIAS("snd-hda-codec-id:10134213"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 5e706e4d173..8a32a69c83c 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -31,6 +31,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" #define CXT_PIN_DIR_IN 0x00 #define CXT_PIN_DIR_OUT 0x01 @@ -415,40 +416,6 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } -static int conexant_init_jacks(struct hda_codec *codec) -{ -#ifdef CONFIG_SND_HDA_INPUT_JACK - struct conexant_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->num_init_verbs; i++) { - const struct hda_verb *hv; - - hv = spec->init_verbs[i]; - while (hv->nid) { - int err = 0; - switch (hv->param ^ AC_USRSP_EN) { - case CONEXANT_HP_EVENT: - err = snd_hda_input_jack_add(codec, hv->nid, - SND_JACK_HEADPHONE, NULL); - snd_hda_input_jack_report(codec, hv->nid); - break; - case CXT5051_PORTC_EVENT: - case CONEXANT_MIC_EVENT: - err = snd_hda_input_jack_add(codec, hv->nid, - SND_JACK_MICROPHONE, NULL); - snd_hda_input_jack_report(codec, hv->nid); - break; - } - if (err < 0) - return err; - ++hv; - } - } -#endif /* CONFIG_SND_HDA_INPUT_JACK */ - return 0; -} - static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg, unsigned int power_state) { @@ -474,7 +441,6 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { - snd_hda_input_jack_free(codec); snd_hda_detach_beep_device(codec); kfree(codec->spec); } @@ -1120,8 +1086,6 @@ static const char * const cxt5045_models[CXT5045_MODELS] = { static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), - SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", - CXT5045_LAPTOP_HPSENSE), SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), @@ -1750,7 +1714,6 @@ static void cxt5051_hp_automute(struct hda_codec *codec) static void cxt5051_hp_unsol_event(struct hda_codec *codec, unsigned int res) { - int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; switch (res >> 26) { case CONEXANT_HP_EVENT: cxt5051_hp_automute(codec); @@ -1762,7 +1725,6 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } - snd_hda_input_jack_report(codec, nid); } static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { @@ -1901,8 +1863,6 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | event); - snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL); - snd_hda_input_jack_report(codec, nid); } static const struct hda_verb cxt5051_ideapad_init_verbs[] = { @@ -1918,7 +1878,6 @@ static int cxt5051_init(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; conexant_init(codec); - conexant_init_jacks(codec); if (spec->auto_mic & AUTO_MIC_PORTB) cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT); @@ -3062,7 +3021,6 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), - SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5066_LAPTOP), SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), @@ -3451,7 +3409,6 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) hda_nid_t nid = pins[i]; if (!nid || !is_jack_detectable(codec, nid)) break; - snd_hda_input_jack_report(codec, nid); present |= snd_hda_jack_detect(codec, nid); } return present; @@ -3756,8 +3713,7 @@ static void cx_auto_automic(struct hda_codec *codec) static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) { - int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20; - switch (res >> 26) { + switch (snd_hda_jack_get_action(codec, res >> 26)) { case CONEXANT_HP_EVENT: cx_auto_hp_automute(codec); break; @@ -3766,9 +3722,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) break; case CONEXANT_MIC_EVENT: cx_auto_automic(codec); - snd_hda_input_jack_report(codec, nid); break; } + snd_hda_jack_report_sync(codec); } /* check whether the pin config is suitable for auto-mic switching; @@ -3980,13 +3936,11 @@ static void mute_outputs(struct hda_codec *codec, int num_nids, } static void enable_unsol_pins(struct hda_codec *codec, int num_pins, - hda_nid_t *pins, unsigned int tag) + hda_nid_t *pins, unsigned int action) { int i; for (i = 0; i < num_pins; i++) - snd_hda_codec_write(codec, pins[i], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | tag); + snd_hda_jack_detect_enable(codec, pins[i], action); } static void cx_auto_init_output(struct hda_codec *codec) @@ -4061,16 +4015,14 @@ static void cx_auto_init_input(struct hda_codec *codec) if (spec->auto_mic) { if (spec->auto_mic_ext >= 0) { - snd_hda_codec_write(codec, - cfg->inputs[spec->auto_mic_ext].pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | CONEXANT_MIC_EVENT); + snd_hda_jack_detect_enable(codec, + cfg->inputs[spec->auto_mic_ext].pin, + CONEXANT_MIC_EVENT); } if (spec->auto_mic_dock >= 0) { - snd_hda_codec_write(codec, - cfg->inputs[spec->auto_mic_dock].pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | CONEXANT_MIC_EVENT); + snd_hda_jack_detect_enable(codec, + cfg->inputs[spec->auto_mic_dock].pin, + CONEXANT_MIC_EVENT); } cx_auto_automic(codec); } else { @@ -4098,6 +4050,7 @@ static int cx_auto_init(struct hda_codec *codec) cx_auto_init_output(codec); cx_auto_init_input(codec); cx_auto_init_digital(codec); + snd_hda_jack_report_sync(codec); return 0; } @@ -4327,6 +4280,7 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) static int cx_auto_build_controls(struct hda_codec *codec) { + struct conexant_spec *spec = codec->spec; int err; err = cx_auto_build_output_controls(codec); @@ -4335,7 +4289,13 @@ static int cx_auto_build_controls(struct hda_codec *codec) err = cx_auto_build_input_controls(codec); if (err < 0) return err; - return conexant_build_controls(codec); + err = conexant_build_controls(codec); + if (err < 0) + return err; + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + return 0; } static int cx_auto_search_adcs(struct hda_codec *codec) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 81b7b791b3c..1168ebd3fb5 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -36,6 +36,7 @@ #include <sound/jack.h> #include "hda_codec.h" #include "hda_local.h" +#include "hda_jack.h" static bool static_hdmi_pcm; module_param(static_hdmi_pcm, bool, 0644); @@ -48,8 +49,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); * * The HDA correspondence of pipes/ports are converter/pin nodes. */ -#define MAX_HDMI_CVTS 4 -#define MAX_HDMI_PINS 4 +#define MAX_HDMI_CVTS 8 +#define MAX_HDMI_PINS 8 struct hdmi_spec_per_cvt { hda_nid_t cvt_nid; @@ -65,7 +66,11 @@ struct hdmi_spec_per_pin { hda_nid_t pin_nid; int num_mux_nids; hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; + + struct hda_codec *codec; struct hdmi_eld sink_eld; + struct delayed_work work; + int repoll_count; }; struct hdmi_spec { @@ -745,17 +750,23 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, * Unsolicited events */ -static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, - struct hdmi_eld *eld); +static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { struct hdmi_spec *spec = codec->spec; - int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; + int tag = res >> AC_UNSOL_RES_TAG_SHIFT; + int pin_nid; int pd = !!(res & AC_UNSOL_RES_PD); int eldv = !!(res & AC_UNSOL_RES_ELDV); int pin_idx; - struct hdmi_eld *eld; + struct hda_jack_tbl *jack; + + jack = snd_hda_jack_tbl_get_from_tag(codec, tag); + if (!jack) + return; + pin_nid = jack->nid; + jack->jack_dirty = 1; printk(KERN_INFO "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", @@ -764,17 +775,9 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) pin_idx = pin_nid_to_pin_index(spec, pin_nid); if (pin_idx < 0) return; - eld = &spec->pins[pin_idx].sink_eld; - - hdmi_present_sense(codec, pin_nid, eld); - /* - * HDMI sink's ELD info cannot always be retrieved for now, e.g. - * in console or for audio devices. Assume the highest speakers - * configuration, to _not_ prohibit multi-channel audio playback. - */ - if (!eld->spk_alloc) - eld->spk_alloc = 0xffff; + hdmi_present_sense(&spec->pins[pin_idx], 1); + snd_hda_jack_report_sync(codec); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -802,11 +805,10 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) { - struct hdmi_spec *spec = codec->spec; int tag = res >> AC_UNSOL_RES_TAG_SHIFT; int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; - if (pin_nid_to_pin_index(spec, tag) < 0) { + if (!snd_hda_jack_tbl_get_from_tag(codec, tag)) { snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); return; } @@ -968,9 +970,11 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) return 0; } -static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, - struct hdmi_eld *eld) +static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) { + struct hda_codec *codec = per_pin->codec; + struct hdmi_eld *eld = &per_pin->sink_eld; + hda_nid_t pin_nid = per_pin->pin_nid; /* * Always execute a GetPinSense verb here, even when called from * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited @@ -980,24 +984,38 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, * the unsolicited response to avoid custom WARs. */ int present = snd_hda_pin_sense(codec, pin_nid); + bool eld_valid = false; - memset(eld, 0, sizeof(*eld)); + memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer)); eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); if (eld->monitor_present) - eld->eld_valid = !!(present & AC_PINSENSE_ELDV); - else - eld->eld_valid = 0; + eld_valid = !!(present & AC_PINSENSE_ELDV); printk(KERN_INFO "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); + codec->addr, pin_nid, eld->monitor_present, eld_valid); - if (eld->eld_valid) + if (eld_valid) { if (!snd_hdmi_get_eld(eld, codec, pin_nid)) snd_hdmi_show_eld(eld); + else if (repoll) { + queue_delayed_work(codec->bus->workq, + &per_pin->work, + msecs_to_jiffies(300)); + } + } +} + +static void hdmi_repoll_eld(struct work_struct *work) +{ + struct hdmi_spec_per_pin *per_pin = + container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); + + if (per_pin->repoll_count++ > 6) + per_pin->repoll_count = 0; - snd_hda_input_jack_report(codec, pin_nid); + hdmi_present_sense(per_pin, per_pin->repoll_count); } static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) @@ -1115,12 +1133,12 @@ static int hdmi_parse_codec(struct hda_codec *codec) /* */ -static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = { - "HDMI 0", - "HDMI 1", - "HDMI 2", - "HDMI 3", -}; +static char *get_hdmi_pcm_name(int idx) +{ + static char names[MAX_HDMI_PINS][8]; + sprintf(&names[idx][0], "HDMI %d", idx); + return &names[idx][0]; +} /* * HDMI callbacks @@ -1198,7 +1216,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) struct hda_pcm_stream *pstr; info = &spec->pcm_rec[pin_idx]; - info->name = generic_hdmi_pcm_names[pin_idx]; + info->name = get_hdmi_pcm_name(pin_idx); info->pcm_type = HDA_PCM_TYPE_HDMI; pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; @@ -1215,21 +1233,15 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) { - int err; - char hdmi_str[32]; + char hdmi_str[32] = "HDMI/DP"; struct hdmi_spec *spec = codec->spec; struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; int pcmdev = spec->pcm_rec[pin_idx].device; - snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev); - - err = snd_hda_input_jack_add(codec, per_pin->pin_nid, - SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL); - if (err < 0) - return err; + if (pcmdev > 0) + sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); - hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); - return 0; + return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0); } static int generic_hdmi_build_controls(struct hda_codec *codec) @@ -1259,6 +1271,8 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) if (err < 0) return err; + + hdmi_present_sense(per_pin, 0); } return 0; @@ -1275,12 +1289,13 @@ static int generic_hdmi_init(struct hda_codec *codec) struct hdmi_eld *eld = &per_pin->sink_eld; hdmi_init_pin(codec, pin_nid); - snd_hda_codec_write(codec, pin_nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | pin_nid); + snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); + per_pin->codec = codec; + INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); snd_hda_eld_proc_new(codec, eld, pin_idx); } + snd_hda_jack_report_sync(codec); return 0; } @@ -1293,10 +1308,11 @@ static void generic_hdmi_free(struct hda_codec *codec) struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; struct hdmi_eld *eld = &per_pin->sink_eld; + cancel_delayed_work(&per_pin->work); snd_hda_eld_proc_free(codec, eld); } - snd_hda_input_jack_free(codec); + flush_workqueue(codec->bus->workq); kfree(spec); } @@ -1349,7 +1365,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) chans = get_wcaps(codec, spec->cvts[i].cvt_nid); chans = get_wcaps_channels(chans); - info->name = generic_hdmi_pcm_names[i]; + info->name = get_hdmi_pcm_name(i); info->pcm_type = HDA_PCM_TYPE_HDMI; pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; snd_BUG_ON(!spec->pcm_playback); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a24e068a021..5e82acf77c5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -33,6 +33,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" /* unsol event tags */ #define ALC_FRONT_EVENT 0x01 @@ -183,6 +184,8 @@ struct alc_spec { unsigned int single_input_src:1; unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ + unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ + unsigned int use_jack_tbl:1; /* 1 for model=auto */ /* auto-mute control */ int automute_mode; @@ -277,6 +280,14 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) return false; } +static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) +{ + return spec->capsrc_nids ? + spec->capsrc_nids[idx] : spec->adc_nids[idx]; +} + +static void call_update_outputs(struct hda_codec *codec); + /* select the given imux item; either unmute exclusively or select the route */ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, unsigned int idx, bool force) @@ -284,13 +295,15 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, struct alc_spec *spec = codec->spec; const struct hda_input_mux *imux; unsigned int mux_idx; - int i, type; + int i, type, num_conns; hda_nid_t nid; mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; imux = &spec->input_mux[mux_idx]; if (!imux->num_items && mux_idx > 0) imux = &spec->input_mux[0]; + if (!imux->num_items) + return 0; if (idx >= imux->num_items) idx = imux->num_items - 1; @@ -298,25 +311,38 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, return 0; spec->cur_mux[adc_idx] = idx; + /* for shared I/O, change the pin-control accordingly */ + if (spec->shared_mic_hp) { + /* NOTE: this assumes that there are only two inputs, the + * first is the real internal mic and the second is HP jack. + */ + snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + spec->cur_mux[adc_idx] ? + PIN_VREF80 : PIN_HP); + spec->automute_speaker = !spec->cur_mux[adc_idx]; + call_update_outputs(codec); + } + if (spec->dyn_adc_switch) { alc_dyn_adc_pcm_resetup(codec, idx); adc_idx = spec->dyn_adc_idx[idx]; } - nid = spec->capsrc_nids ? - spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; + nid = get_capsrc(spec, adc_idx); /* no selection? */ - if (snd_hda_get_conn_list(codec, nid, NULL) <= 1) + num_conns = snd_hda_get_conn_list(codec, nid, NULL); + if (num_conns <= 1) return 1; type = get_wcaps_type(get_wcaps(codec, nid)); if (type == AC_WID_AUD_MIX) { /* Matrix-mixer style (e.g. ALC882) */ - for (i = 0; i < imux->num_items; i++) { - unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; - snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, - imux->items[i].index, + int active = imux->items[idx].index; + for (i = 0; i < num_conns; i++) { + unsigned int v = (i == active) ? 0 : HDA_AMP_MUTE; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, i, HDA_AMP_MUTE, v); } } else { @@ -442,46 +468,6 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, } /* - * Jack-reporting via input-jack layer - */ - -/* initialization of jacks; currently checks only a few known pins */ -static int alc_init_jacks(struct hda_codec *codec) -{ -#ifdef CONFIG_SND_HDA_INPUT_JACK - struct alc_spec *spec = codec->spec; - int err; - unsigned int hp_nid = spec->autocfg.hp_pins[0]; - unsigned int mic_nid = spec->ext_mic_pin; - unsigned int dock_nid = spec->dock_mic_pin; - - if (hp_nid) { - err = snd_hda_input_jack_add(codec, hp_nid, - SND_JACK_HEADPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, hp_nid); - } - - if (mic_nid) { - err = snd_hda_input_jack_add(codec, mic_nid, - SND_JACK_MICROPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, mic_nid); - } - if (dock_nid) { - err = snd_hda_input_jack_add(codec, dock_nid, - SND_JACK_MICROPHONE, NULL); - if (err < 0) - return err; - snd_hda_input_jack_report(codec, dock_nid); - } -#endif /* CONFIG_SND_HDA_INPUT_JACK */ - return 0; -} - -/* * Jack detections for HP auto-mute and mic-switch */ @@ -494,7 +480,6 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) hda_nid_t nid = pins[i]; if (!nid) break; - snd_hda_input_jack_report(codec, nid); present |= snd_hda_jack_detect(codec, nid); } return present; @@ -546,7 +531,8 @@ static void update_outputs(struct hda_codec *codec) * in general, HP pins/amps control should be enabled in all cases, * but currently set only for master_mute, just to be safe */ - do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), + if (!spec->shared_mic_hp) /* don't change HP-pin when shared with mic */ + do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), spec->autocfg.hp_pins, spec->master_mute, true); if (!spec->automute_speaker) @@ -633,19 +619,18 @@ static void alc_mic_automute(struct hda_codec *codec) alc_mux_select(codec, 0, spec->dock_mic_idx, false); else alc_mux_select(codec, 0, spec->int_mic_idx, false); - - snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]); - if (spec->dock_mic_idx >= 0) - snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]); } /* unsolicited event for HP jack sensing */ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) { + struct alc_spec *spec = codec->spec; if (codec->vendor_id == 0x10ec0880) res >>= 28; else res >>= 26; + if (spec->use_jack_tbl) + res = snd_hda_jack_get_action(codec, res); switch (res) { case ALC_HP_EVENT: alc_hp_automute(codec); @@ -657,6 +642,7 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) alc_mic_automute(codec); break; } + snd_hda_jack_report_sync(codec); } /* call init functions of standard auto-mute helpers */ @@ -946,9 +932,7 @@ static void alc_init_automute(struct hda_codec *codec) continue; snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", nid); - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_HP_EVENT); + snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT); spec->detect_hp = 1; } @@ -960,9 +944,8 @@ static void alc_init_automute(struct hda_codec *codec) continue; snd_printdd("realtek: Enable Line-Out " "auto-muting on NID 0x%x\n", nid); - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_FRONT_EVENT); + snd_hda_jack_detect_enable(codec, nid, + ALC_FRONT_EVENT); spec->detect_lo = 1; } spec->automute_lo_possible = spec->detect_hp; @@ -1053,8 +1036,19 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) spec->imux_pins[2] = spec->dock_mic_pin; for (i = 0; i < 3; i++) { strcpy(imux->items[i].label, texts[i]); - if (spec->imux_pins[i]) + if (spec->imux_pins[i]) { + hda_nid_t pin = spec->imux_pins[i]; + int c; + for (c = 0; c < spec->num_adc_nids; c++) { + hda_nid_t cap = get_capsrc(spec, c); + int idx = get_connection_index(codec, cap, pin); + if (idx >= 0) { + imux->items[i].index = idx; + break; + } + } imux->num_items = i + 1; + } } spec->num_mux_defs = 1; spec->input_mux = imux; @@ -1090,13 +1084,10 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec) return false; /* no corresponding imux */ } - snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_MIC_EVENT); + snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT); if (spec->dock_mic_pin) - snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ALC_MIC_EVENT); + snd_hda_jack_detect_enable(codec, spec->dock_mic_pin, + ALC_MIC_EVENT); spec->auto_mic_valid_imux = 1; spec->auto_mic = 1; @@ -1114,6 +1105,9 @@ static void alc_init_auto_mic(struct hda_codec *codec) hda_nid_t fixed, ext, dock; int i; + if (spec->shared_mic_hp) + return; /* no auto-mic for the shared I/O */ + spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1; fixed = ext = dock = 0; @@ -1451,7 +1445,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) switch (fix->type) { case ALC_FIXUP_SKU: if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku) - break;; + break; snd_printdd(KERN_INFO "hda_codec: %s: " "Apply sku override for %s\n", codec->chip_name, modelname); @@ -1505,6 +1499,7 @@ static void alc_pick_fixup(struct hda_codec *codec, const struct alc_fixup *fixlist) { struct alc_spec *spec = codec->spec; + const struct snd_pci_quirk *q; int id = -1; const char *name = NULL; @@ -1519,14 +1514,27 @@ static void alc_pick_fixup(struct hda_codec *codec, } } if (id < 0) { - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (quirk) { - id = quirk->value; + q = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (q) { + id = q->value; #ifdef CONFIG_SND_DEBUG_VERBOSE - name = quirk->name; + name = q->name; #endif } } + if (id < 0) { + for (q = quirk; q->subvendor; q++) { + unsigned int vendorid = + q->subdevice | (q->subvendor << 16); + if (vendorid == codec->subsystem_id) { + id = q->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + name = q->name; +#endif + break; + } + } + } spec->fixup_id = id; if (id >= 0) { @@ -1956,10 +1964,8 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - const hda_nid_t *nids = spec->capsrc_nids; - if (!nids) - nids = spec->adc_nids; - err = snd_hda_add_nid(codec, kctl, i, nids[i]); + err = snd_hda_add_nid(codec, kctl, i, + get_capsrc(spec, i)); if (err < 0) return err; } @@ -2023,6 +2029,10 @@ static int alc_build_controls(struct hda_codec *codec) alc_free_kctls(codec); /* no longer needed */ + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + return 0; } @@ -2050,6 +2060,8 @@ static int alc_init(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); + snd_hda_jack_report_sync(codec); + hda_call_check_power_status(codec, 0x01); return 0; } @@ -2433,7 +2445,6 @@ static void alc_free(struct hda_codec *codec) return; alc_shutup(codec); - snd_hda_input_jack_free(codec); alc_free_kctls(codec); alc_free_bind_ctls(codec); kfree(spec); @@ -2614,6 +2625,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, case AUTO_PIN_SPEAKER_OUT: if (cfg->line_outs == 1) return "Speaker"; + if (cfg->line_outs == 2) + return ch ? "Bass Speaker" : "Speaker"; break; case AUTO_PIN_HP_OUT: /* for multi-io case, only the primary out */ @@ -2666,6 +2679,9 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec) int max_nums = ARRAY_SIZE(spec->private_adc_nids); int i, nums = 0; + if (spec->shared_mic_hp) + max_nums = 1; /* no multi streams with the shared HP/mic */ + nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) { hda_nid_t src; @@ -2728,6 +2744,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) continue; label = hda_get_autocfg_input_label(codec, cfg, i); + if (spec->shared_mic_hp && !strcmp(label, "Misc")) + label = "Headphone Mic"; if (prev_label && !strcmp(label, prev_label)) type_idx++; else @@ -2746,8 +2764,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) } for (c = 0; c < num_adcs; c++) { - hda_nid_t cap = spec->capsrc_nids ? - spec->capsrc_nids[c] : spec->adc_nids[c]; + hda_nid_t cap = get_capsrc(spec, c); idx = get_connection_index(codec, cap, pin); if (idx >= 0) { spec->imux_pins[imux->num_items] = pin; @@ -2763,6 +2780,39 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) return 0; } +/* create a shared input with the headphone out */ +static int alc_auto_create_shared_input(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + unsigned int defcfg; + hda_nid_t nid; + + /* only one internal input pin? */ + if (cfg->num_inputs != 1) + return 0; + defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin); + if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) + return 0; + + if (cfg->hp_outs == 1 && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) + nid = cfg->hp_pins[0]; /* OK, we have a single HP-out */ + else if (cfg->line_outs == 1 && cfg->line_out_type == AUTO_PIN_HP_OUT) + nid = cfg->line_out_pins[0]; /* OK, we have a single line-out */ + else + return 0; /* both not available */ + + if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN)) + return 0; /* no input */ + + cfg->inputs[1].pin = nid; + cfg->inputs[1].type = AUTO_PIN_MIC; + cfg->num_inputs = 2; + spec->shared_mic_hp = 1; + snd_printdd("realtek: Enable shared I/O jack on NID 0x%x\n", nid); + return 0; +} + static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, unsigned int pin_type) { @@ -2888,7 +2938,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) if (!nid) continue; if (found_in_nid_list(nid, spec->multiout.dac_nids, - spec->multiout.num_dacs)) + ARRAY_SIZE(spec->private_dac_nids))) continue; if (found_in_nid_list(nid, spec->multiout.hp_out_nid, ARRAY_SIZE(spec->multiout.hp_out_nid))) @@ -2901,6 +2951,23 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) return 0; } +/* check whether the DAC is reachable from the pin */ +static bool alc_auto_is_dac_reachable(struct hda_codec *codec, + hda_nid_t pin, hda_nid_t dac) +{ + hda_nid_t srcs[5]; + int i, num; + + pin = alc_go_down_to_selector(codec, pin); + num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); + for (i = 0; i < num; i++) { + hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); + if (nid == dac) + return true; + } + return false; +} + static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) { hda_nid_t sel = alc_go_down_to_selector(codec, pin); @@ -2909,6 +2976,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) return 0; } +/* return 0 if no possible DAC is found, 1 if one or more found */ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, const hda_nid_t *pins, hda_nid_t *dacs) { @@ -2926,17 +2994,21 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, if (!dacs[i]) dacs[i] = alc_auto_look_for_dac(codec, pins[i]); } - return 0; + return 1; } static int alc_auto_fill_multi_ios(struct hda_codec *codec, - unsigned int location); + unsigned int location, int offset); +static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, + hda_nid_t pin, hda_nid_t dac); /* fill in the dac_nids table from the parsed pin configuration */ static int alc_auto_fill_dac_nids(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - const struct auto_pin_cfg *cfg = &spec->autocfg; + struct auto_pin_cfg *cfg = &spec->autocfg; + unsigned int location, defcfg; + int num_pins; bool redone = false; int i; @@ -2947,6 +3019,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) spec->multiout.extra_out_nid[0] = 0; memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); spec->multiout.dac_nids = spec->private_dac_nids; + spec->multi_ios = 0; /* fill hard-wired DACs first */ if (!redone) { @@ -2980,21 +3053,20 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) { if (spec->private_dac_nids[i]) spec->multiout.num_dacs++; - else + else { memmove(spec->private_dac_nids + i, spec->private_dac_nids + i + 1, sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); + spec->private_dac_nids[cfg->line_outs - 1] = 0; + } } if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { /* try to fill multi-io first */ - unsigned int location, defcfg; - int num_pins; - defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); location = get_defcfg_location(defcfg); - num_pins = alc_auto_fill_multi_ios(codec, location); + num_pins = alc_auto_fill_multi_ios(codec, location, 0); if (num_pins > 0) { spec->multi_ios = num_pins; spec->ext_channel_count = 2; @@ -3005,10 +3077,48 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) if (cfg->line_out_type != AUTO_PIN_HP_OUT) alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, spec->multiout.hp_out_nid); - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) - alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, - spec->multiout.extra_out_nid); + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { + int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, + cfg->speaker_pins, + spec->multiout.extra_out_nid); + /* if no speaker volume is assigned, try again as the primary + * output + */ + if (!err && cfg->speaker_outs > 0 && + cfg->line_out_type == AUTO_PIN_HP_OUT) { + cfg->hp_outs = cfg->line_outs; + memcpy(cfg->hp_pins, cfg->line_out_pins, + sizeof(cfg->hp_pins)); + cfg->line_outs = cfg->speaker_outs; + memcpy(cfg->line_out_pins, cfg->speaker_pins, + sizeof(cfg->speaker_pins)); + cfg->speaker_outs = 0; + memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); + cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; + redone = false; + goto again; + } + } + + if (!spec->multi_ios && + cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && + cfg->hp_outs) { + /* try multi-ios with HP + inputs */ + defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]); + location = get_defcfg_location(defcfg); + num_pins = alc_auto_fill_multi_ios(codec, location, 1); + if (num_pins > 0) { + spec->multi_ios = num_pins; + spec->ext_channel_count = 2; + spec->multiout.num_dacs = num_pins + 1; + } + } + + if (cfg->line_out_pins[0]) + spec->vmaster_nid = + alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], + spec->multiout.dac_nids[0]); return 0; } @@ -3040,8 +3150,15 @@ static int alc_auto_add_vol_ctl(struct hda_codec *codec, val); } -#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ - alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3) +static int alc_auto_add_stereo_vol(struct hda_codec *codec, + const char *pfx, int cidx, + hda_nid_t nid) +{ + int chs = 1; + if (get_wcaps(codec, nid) & AC_WCAP_STEREO) + chs = 3; + return alc_auto_add_vol_ctl(codec, pfx, cidx, nid, chs); +} /* create a mute-switch for the given mixer widget; * if it has multiple sources (e.g. DAC and loopback), create a bind-mute @@ -3073,8 +3190,14 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec, return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); } -#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ - alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) +static int alc_auto_add_stereo_sw(struct hda_codec *codec, const char *pfx, + int cidx, hda_nid_t nid) +{ + int chs = 1; + if (get_wcaps(codec, nid) & AC_WCAP_STEREO) + chs = 3; + return alc_auto_add_sw_ctl(codec, pfx, cidx, nid, chs); +} static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) @@ -3157,7 +3280,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, } static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, - hda_nid_t dac, const char *pfx) + hda_nid_t dac, const char *pfx, + int cidx) { struct alc_spec *spec = codec->spec; hda_nid_t sw, vol; @@ -3173,15 +3297,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, if (is_ctl_used(spec->sw_ctls, val)) return 0; /* already created */ mark_ctl_usage(spec->sw_ctls, val); - return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); + return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); } sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); - err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); + err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); if (err < 0) return err; - err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); + err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); if (err < 0) return err; return 0; @@ -3222,16 +3346,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, hda_nid_t dac = *dacs; if (!dac) dac = spec->multiout.dac_nids[0]; - return alc_auto_create_extra_out(codec, *pins, dac, pfx); + return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); } if (dacs[num_pins - 1]) { /* OK, we have a multi-output system with individual volumes */ for (i = 0; i < num_pins; i++) { - snprintf(name, sizeof(name), "%s %s", - pfx, channel_name[i]); - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - name); + if (num_pins >= 3) { + snprintf(name, sizeof(name), "%s %s", + pfx, channel_name[i]); + err = alc_auto_create_extra_out(codec, pins[i], dacs[i], + name, 0); + } else { + err = alc_auto_create_extra_out(codec, pins[i], dacs[i], + pfx, i); + } if (err < 0) return err; } @@ -3394,17 +3523,19 @@ static void alc_auto_init_extra_out(struct hda_codec *codec) * multi-io helper */ static int alc_auto_fill_multi_ios(struct hda_codec *codec, - unsigned int location) + unsigned int location, + int offset) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t prime_dac = spec->private_dac_nids[0]; - int type, i, num_pins = 0; + int type, i, dacs, num_pins = 0; + dacs = spec->multiout.num_dacs; for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; - hda_nid_t dac; + hda_nid_t dac = 0; unsigned int defcfg, caps; if (cfg->inputs[i].type != type) continue; @@ -3416,7 +3547,13 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, caps = snd_hda_query_pin_caps(codec, nid); if (!(caps & AC_PINCAP_OUT)) continue; - dac = alc_auto_look_for_dac(codec, nid); + if (offset && offset + num_pins < dacs) { + dac = spec->private_dac_nids[offset + num_pins]; + if (!alc_auto_is_dac_reachable(codec, nid, dac)) + dac = 0; + } + if (!dac) + dac = alc_auto_look_for_dac(codec, nid); if (!dac) continue; spec->multi_io[num_pins].pin = nid; @@ -3425,11 +3562,11 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } } - spec->multiout.num_dacs = 1; + spec->multiout.num_dacs = dacs; if (num_pins < 2) { /* clear up again */ - memset(spec->private_dac_nids, 0, - sizeof(spec->private_dac_nids)); + memset(spec->private_dac_nids + dacs, 0, + sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); spec->private_dac_nids[0] = prime_dac; return 0; } @@ -3653,6 +3790,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) char boost_label[32]; label = hda_get_autocfg_input_label(codec, cfg, i); + if (spec->shared_mic_hp && !strcmp(label, "Misc")) + label = "Headphone Mic"; if (prev_label && !strcmp(label, prev_label)) type_idx++; else @@ -3693,8 +3832,7 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) if (!pin) return 0; for (i = 0; i < spec->num_adc_nids; i++) { - hda_nid_t cap = spec->capsrc_nids ? - spec->capsrc_nids[i] : spec->adc_nids[i]; + hda_nid_t cap = get_capsrc(spec, i); int idx; idx = get_connection_index(codec, cap, pin); @@ -3766,6 +3904,7 @@ static void set_capture_mixer(struct hda_codec *codec) static void alc_auto_init_std(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->use_jack_tbl = 1; alc_auto_init_multi_out(codec); alc_auto_init_extra_out(codec); alc_auto_init_analog_input(codec); @@ -3858,6 +3997,9 @@ static int alc_parse_auto_config(struct hda_codec *codec, err = alc_auto_create_speaker_out(codec); if (err < 0) return err; + err = alc_auto_create_shared_input(codec); + if (err < 0) + return err; err = alc_auto_create_input_ctls(codec); if (err < 0) return err; @@ -3905,6 +4047,37 @@ static const struct hda_amp_list alc880_loopbacks[] = { #endif /* + * ALC880 fix-ups + */ +enum { + ALC880_FIXUP_GPIO2, + ALC880_FIXUP_MEDION_RIM, +}; + +static const struct alc_fixup alc880_fixups[] = { + [ALC880_FIXUP_GPIO2] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = alc_gpio2_init_verbs, + }, + [ALC880_FIXUP_MEDION_RIM] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, + { } + }, + .chained = true, + .chain_id = ALC880_FIXUP_GPIO2, + }, +}; + +static const struct snd_pci_quirk alc880_fixup_tbl[] = { + SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), + {} +}; + + +/* * board setups */ #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS @@ -3950,6 +4123,11 @@ static int patch_alc880(struct hda_codec *codec) } if (board_config == ALC_MODEL_AUTO) { + alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); + } + + if (board_config == ALC_MODEL_AUTO) { /* automatic parse from the BIOS config */ err = alc880_parse_auto_config(codec); if (err < 0) @@ -3964,8 +4142,10 @@ static int patch_alc880(struct hda_codec *codec) #endif } - if (board_config != ALC_MODEL_AUTO) + if (board_config != ALC_MODEL_AUTO) { + spec->vmaster_nid = 0x0c; setup_preset(codec, &alc880_presets[board_config]); + } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -3983,7 +4163,7 @@ static int patch_alc880(struct hda_codec *codec) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); } - spec->vmaster_nid = 0x0c; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) @@ -4091,8 +4271,10 @@ static int patch_alc260(struct hda_codec *codec) #endif } - if (board_config != ALC_MODEL_AUTO) + if (board_config != ALC_MODEL_AUTO) { setup_preset(codec, &alc260_presets[board_config]); + spec->vmaster_nid = 0x08; + } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4112,8 +4294,6 @@ static int patch_alc260(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); - spec->vmaster_nid = 0x08; - codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; @@ -4150,15 +4330,78 @@ static int patch_alc260(struct hda_codec *codec) * Pin config fixes */ enum { - PINFIX_ABIT_AW9D_MAX, - PINFIX_LENOVO_Y530, - PINFIX_PB_M5210, - PINFIX_ACER_ASPIRE_7736, - PINFIX_ASUS_W90V, + ALC882_FIXUP_ABIT_AW9D_MAX, + ALC882_FIXUP_LENOVO_Y530, + ALC882_FIXUP_PB_M5210, + ALC882_FIXUP_ACER_ASPIRE_7736, + ALC882_FIXUP_ASUS_W90V, + ALC889_FIXUP_VAIO_TT, + ALC888_FIXUP_EEE1601, + ALC882_FIXUP_EAPD, + ALC883_FIXUP_EAPD, + ALC883_FIXUP_ACER_EAPD, + ALC882_FIXUP_GPIO3, + ALC889_FIXUP_COEF, + ALC882_FIXUP_ASUS_W2JC, + ALC882_FIXUP_ACER_ASPIRE_4930G, + ALC882_FIXUP_ACER_ASPIRE_8930G, + ALC882_FIXUP_ASPIRE_8930G_VERBS, + ALC885_FIXUP_MACPRO_GPIO, }; +static void alc889_fixup_coef(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + if (action != ALC_FIXUP_ACT_INIT) + return; + alc889_coef_init(codec); +} + +/* toggle speaker-output according to the hp-jack state */ +static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) +{ + unsigned int gpiostate, gpiomask, gpiodir; + + gpiostate = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0); + + if (!muted) + gpiostate |= (1 << pin); + else + gpiostate &= ~(1 << pin); + + gpiomask = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_MASK, 0); + gpiomask |= (1 << pin); + + gpiodir = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DIRECTION, 0); + gpiodir |= (1 << pin); + + + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_MASK, gpiomask); + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DIRECTION, gpiodir); + + msleep(1); + + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_DATA, gpiostate); +} + +/* set up GPIO at initialization */ +static void alc885_fixup_macpro_gpio(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + if (action != ALC_FIXUP_ACT_INIT) + return; + alc882_gpio_mute(codec, 0, 0); + alc882_gpio_mute(codec, 1, 0); +} + static const struct alc_fixup alc882_fixups[] = { - [PINFIX_ABIT_AW9D_MAX] = { + [ALC882_FIXUP_ABIT_AW9D_MAX] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x01080104 }, /* side */ @@ -4167,7 +4410,7 @@ static const struct alc_fixup alc882_fixups[] = { { } } }, - [PINFIX_LENOVO_Y530] = { + [ALC882_FIXUP_LENOVO_Y530] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x15, 0x99130112 }, /* rear int speakers */ @@ -4175,32 +4418,180 @@ static const struct alc_fixup alc882_fixups[] = { { } } }, - [PINFIX_PB_M5210] = { + [ALC882_FIXUP_PB_M5210] = { .type = ALC_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, {} } }, - [PINFIX_ACER_ASPIRE_7736] = { + [ALC882_FIXUP_ACER_ASPIRE_7736] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, - [PINFIX_ASUS_W90V] = { + [ALC882_FIXUP_ASUS_W90V] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130110 }, /* fix sequence for CLFE */ { } } }, + [ALC889_FIXUP_VAIO_TT] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x17, 0x90170111 }, /* hidden surround speaker */ + { } + } + }, + [ALC888_FIXUP_EEE1601] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, + { } + } + }, + [ALC882_FIXUP_EAPD] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* change to EAPD mode */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, + { } + } + }, + [ALC883_FIXUP_EAPD] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* change to EAPD mode */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, + { } + } + }, + [ALC883_FIXUP_ACER_EAPD] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* eanable EAPD on Acer laptops */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, + { } + } + }, + [ALC882_FIXUP_GPIO3] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = alc_gpio3_init_verbs, + }, + [ALC882_FIXUP_ASUS_W2JC] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = alc_gpio1_init_verbs, + .chained = true, + .chain_id = ALC882_FIXUP_EAPD, + }, + [ALC889_FIXUP_COEF] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc889_fixup_coef, + }, + [ALC882_FIXUP_ACER_ASPIRE_4930G] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x16, 0x99130111 }, /* CLFE speaker */ + { 0x17, 0x99130112 }, /* surround speaker */ + { } + } + }, + [ALC882_FIXUP_ACER_ASPIRE_8930G] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x16, 0x99130111 }, /* CLFE speaker */ + { 0x1b, 0x99130112 }, /* surround speaker */ + { } + }, + .chained = true, + .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, + }, + [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { + /* additional init verbs for Acer Aspire 8930G */ + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + /* Enable all DACs */ + /* DAC DISABLE/MUTE 1? */ + /* setting bits 1-5 disables DAC nids 0x02-0x06 + * apparently. Init=0x38 */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, + /* DAC DISABLE/MUTE 2? */ + /* some bit here disables the other DACs. + * Init=0x4900 */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, + /* DMIC fix + * This laptop has a stereo digital microphone. + * The mics are only 1cm apart which makes the stereo + * useless. However, either the mic or the ALC889 + * makes the signal become a difference/sum signal + * instead of standard stereo, which is annoying. + * So instead we flip this bit which makes the + * codec replicate the sum signal to both channels, + * turning it into a normal mono mic. + */ + /* DMIC_CONTROL? Init value = 0x0001 */ + { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, + { } + } + }, + [ALC885_FIXUP_MACPRO_GPIO] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc885_fixup_macpro_gpio, + }, }; static const struct snd_pci_quirk alc882_fixup_tbl[] = { - SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), - SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V), - SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), - SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), - SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), + SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), + SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", + ALC882_FIXUP_ACER_ASPIRE_8930G), + SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", + ALC882_FIXUP_ACER_ASPIRE_8930G), + SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", + ALC882_FIXUP_ACER_ASPIRE_4930G), + SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), + SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), + SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), + SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), + SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), + SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), + + /* All Apple entries are in codec SSIDs */ + SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), + SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), + + SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), + SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), + SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), + SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), + SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), + SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), {} }; @@ -4249,8 +4640,7 @@ static int patch_alc882(struct hda_codec *codec) goto error; board_config = alc_board_config(codec, ALC882_MODEL_LAST, - alc882_models, alc882_cfg_tbl); - + alc882_models, NULL); if (board_config < 0) board_config = alc_board_codec_sid_config(codec, ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); @@ -4273,18 +4663,12 @@ static int patch_alc882(struct hda_codec *codec) err = alc882_parse_auto_config(codec); if (err < 0) goto error; -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS - else if (!err) { - printk(KERN_INFO - "hda_codec: Cannot set up configuration " - "from BIOS. Using base mode...\n"); - board_config = ALC882_3ST_DIG; - } -#endif } - if (board_config != ALC_MODEL_AUTO) + if (board_config != ALC_MODEL_AUTO) { setup_preset(codec, &alc882_presets[board_config]); + spec->vmaster_nid = 0x0c; + } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4304,13 +4688,10 @@ static int patch_alc882(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); - spec->vmaster_nid = 0x0c; - codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc882_loopbacks; @@ -4338,12 +4719,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) * Pin config fixes */ enum { - PINFIX_FSC_H270, - PINFIX_HP_Z200, + ALC262_FIXUP_FSC_H270, + ALC262_FIXUP_HP_Z200, + ALC262_FIXUP_TYAN, + ALC262_FIXUP_TOSHIBA_RX1, + ALC262_FIXUP_LENOVO_3000, + ALC262_FIXUP_BENQ, + ALC262_FIXUP_BENQ_T31, }; static const struct alc_fixup alc262_fixups[] = { - [PINFIX_FSC_H270] = { + [ALC262_FIXUP_FSC_H270] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x14, 0x99130110 }, /* speaker */ @@ -4352,18 +4738,68 @@ static const struct alc_fixup alc262_fixups[] = { { } } }, - [PINFIX_HP_Z200] = { + [ALC262_FIXUP_HP_Z200] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x16, 0x99130120 }, /* internal speaker */ { } } }, + [ALC262_FIXUP_TYAN] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x1993e1f0 }, /* int AUX */ + { } + } + }, + [ALC262_FIXUP_TOSHIBA_RX1] = { + .type = ALC_FIXUP_PINS, + .v.pins = (const struct alc_pincfg[]) { + { 0x14, 0x90170110 }, /* speaker */ + { 0x15, 0x0421101f }, /* HP */ + { 0x1a, 0x40f000f0 }, /* N/A */ + { 0x1b, 0x40f000f0 }, /* N/A */ + { 0x1e, 0x40f000f0 }, /* N/A */ + } + }, + [ALC262_FIXUP_LENOVO_3000] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, + {} + }, + .chained = true, + .chain_id = ALC262_FIXUP_BENQ, + }, + [ALC262_FIXUP_BENQ] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, + {} + } + }, + [ALC262_FIXUP_BENQ_T31] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, + { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, + {} + } + }, }; static const struct snd_pci_quirk alc262_fixup_tbl[] = { - SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200), - SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), + SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), + SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), + SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), + SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), + SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", + ALC262_FIXUP_TOSHIBA_RX1), + SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), + SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), + SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), + SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), {} }; @@ -4374,14 +4810,9 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { /* */ -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS -#include "alc262_quirks.c" -#endif - static int patch_alc262(struct hda_codec *codec) { struct alc_spec *spec; - int board_config; int err; spec = kzalloc(sizeof(*spec), GFP_KERNEL); @@ -4408,37 +4839,13 @@ static int patch_alc262(struct hda_codec *codec) alc_fix_pll_init(codec, 0x20, 0x0a, 10); - board_config = alc_board_config(codec, ALC262_MODEL_LAST, - alc262_models, alc262_cfg_tbl); - - if (board_config < 0) { - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", - codec->chip_name); - board_config = ALC_MODEL_AUTO; - } - - if (board_config == ALC_MODEL_AUTO) { - alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); - alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - } - - if (board_config == ALC_MODEL_AUTO) { - /* automatic parse from the BIOS config */ - err = alc262_parse_auto_config(codec); - if (err < 0) - goto error; -#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS - else if (!err) { - printk(KERN_INFO - "hda_codec: Cannot set up configuration " - "from BIOS. Using base mode...\n"); - board_config = ALC262_BASIC; - } -#endif - } + alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); + alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); - if (board_config != ALC_MODEL_AUTO) - setup_preset(codec, &alc262_presets[board_config]); + /* automatic parse from the BIOS config */ + err = alc262_parse_auto_config(codec); + if (err < 0) + goto error; if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4458,14 +4865,10 @@ static int patch_alc262(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); - spec->vmaster_nid = 0x0c; - codec->patch_ops = alc_patch_ops; - if (board_config == ALC_MODEL_AUTO) - spec->init_hook = alc_auto_init_std; + spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc262_loopbacks; @@ -4572,14 +4975,10 @@ static int patch_alc268(struct hda_codec *codec) if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); - spec->vmaster_nid = 0x02; - codec->patch_ops = alc_patch_ops; spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); - return 0; error: @@ -4921,7 +5320,7 @@ static const struct alc_fixup alc269_fixups[] = { { } }, }, - [ALC269_FIXUP_DMIC] = { + [ALC269VB_FIXUP_DMIC] = { .type = ALC_FIXUP_PINS, .v.pins = (const struct alc_pincfg[]) { { 0x12, 0x99a3092f }, /* int-mic */ @@ -5128,8 +5527,6 @@ static int patch_alc269(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); - spec->vmaster_nid = 0x02; - codec->patch_ops = alc_patch_ops; #ifdef CONFIG_PM codec->patch_ops.resume = alc269_resume; @@ -5137,7 +5534,6 @@ static int patch_alc269(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc269_shutup; - alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; @@ -5234,8 +5630,6 @@ static int patch_alc861(struct hda_codec *codec) set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); } - spec->vmaster_nid = 0x03; - alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -5360,8 +5754,6 @@ static int patch_alc861vd(struct hda_codec *codec) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); } - spec->vmaster_nid = 0x02; - alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -5744,7 +6136,6 @@ static int patch_alc662(struct hda_codec *codec) break; } } - spec->vmaster_nid = 0x02; alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); @@ -5752,8 +6143,6 @@ static int patch_alc662(struct hda_codec *codec) spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; - alc_init_jacks(codec); - #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc662_loopbacks; @@ -5800,8 +6189,6 @@ static int patch_alc680(struct hda_codec *codec) if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); - spec->vmaster_nid = 0x02; - codec->patch_ops = alc_patch_ops; spec->init_hook = alc_auto_init_std; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4e715fefebe..87e684fa830 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -37,6 +37,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_beep.h" +#include "hda_jack.h" enum { STAC_VREF_EVENT = 1, @@ -95,7 +96,7 @@ enum { STAC_92HD83XXX_REF, STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, - STAC_92HD83XXX_HP, + STAC_DELL_VOSTRO_3500, STAC_92HD83XXX_HP_cNB11_INTQUAD, STAC_HP_DV7_4000, STAC_92HD83XXX_MODELS @@ -175,13 +176,6 @@ enum { STAC_9872_MODELS }; -struct sigmatel_event { - hda_nid_t nid; - unsigned char type; - unsigned char tag; - int data; -}; - struct sigmatel_mic_route { hda_nid_t pin; signed char mux_idx; @@ -214,6 +208,7 @@ struct sigmatel_spec { unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; + unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ unsigned int vref_led; /* stream */ @@ -226,13 +221,9 @@ struct sigmatel_spec { /* power management */ unsigned int num_pwrs; - const unsigned int *pwr_mapping; const hda_nid_t *pwr_nids; const hda_nid_t *dac_list; - /* events */ - struct snd_array events; - /* playback */ struct hda_input_mux *mono_mux; unsigned int cur_mmux; @@ -373,18 +364,15 @@ static const unsigned long stac92hd73xx_capvols[] = { #define STAC92HD83_DAC_COUNT 3 -static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { - 0xa, 0xb, 0xd, 0xe, +static const hda_nid_t stac92hd83xxx_pwr_nids[7] = { + 0x0a, 0x0b, 0x0c, 0xd, 0x0e, + 0x0f, 0x10 }; static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 0x1e, 0, }; -static const unsigned int stac92hd83xxx_pwr_mapping[4] = { - 0x03, 0x0c, 0x20, 0x40, -}; - static const hda_nid_t stac92hd83xxx_dmic_nids[] = { 0x11, 0x20, }; @@ -1096,13 +1084,10 @@ static const char * const slave_sws[] = { }; static void stac92xx_free_kctls(struct hda_codec *codec); -static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type); static int stac92xx_build_controls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - hda_nid_t nid; int err; int i; @@ -1188,31 +1173,9 @@ static int stac92xx_build_controls(struct hda_codec *codec) stac92xx_free_kctls(codec); /* no longer needed */ - /* create jack input elements */ - if (spec->hp_detect) { - for (i = 0; i < cfg->hp_outs; i++) { - int type = SND_JACK_HEADPHONE; - nid = cfg->hp_pins[i]; - /* jack detection */ - if (cfg->hp_outs == i) - type |= SND_JACK_LINEOUT; - err = stac92xx_add_jack(codec, nid, type); - if (err < 0) - return err; - } - } - for (i = 0; i < cfg->line_outs; i++) { - err = stac92xx_add_jack(codec, cfg->line_out_pins[i], - SND_JACK_LINEOUT); - if (err < 0) - return err; - } - for (i = 0; i < cfg->num_inputs; i++) { - nid = cfg->inputs[i].pin; - err = stac92xx_add_jack(codec, nid, SND_JACK_MICROPHONE); - if (err < 0) - return err; - } + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; return 0; } @@ -1644,6 +1607,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, "Alienware M17x", STAC_ALIENWARE_M17X), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, + "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; @@ -1659,6 +1624,12 @@ static const unsigned int dell_s14_pin_configs[10] = { 0x40f000f0, 0x40f000f0, }; +static const unsigned int dell_vostro_3500_pin_configs[10] = { + 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110, + 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160, + 0x400000f4, 0x400000f5, +}; + static const unsigned int hp_dv7_4000_pin_configs[10] = { 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, @@ -1675,6 +1646,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, [STAC_DELL_S14] = dell_s14_pin_configs, + [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, }; @@ -1684,7 +1656,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = "ref", [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", - [STAC_92HD83XXX_HP] = "hp", + [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", [STAC_HP_DV7_4000] = "hp-dv7-4000", }; @@ -1697,8 +1669,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD83XXX_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, "unknown Dell", STAC_DELL_S14), - SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, - "HP", STAC_92HD83XXX_HP), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, + "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, @@ -2865,7 +2837,8 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, } if (control) { - strcpy(name, hda_get_input_pin_label(codec, nid, 1)); + snd_hda_get_pin_label(codec, nid, &spec->autocfg, + name, sizeof(name), NULL); return stac92xx_add_control(codec->spec, control, strcat(name, " Jack Mode"), nid); } @@ -3543,7 +3516,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, for (i = 0; i < spec->num_dmics; i++) { hda_nid_t nid; int index, type_idx; - const char *label; + char label[32]; nid = spec->dmic_nids[i]; if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) @@ -3556,7 +3529,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (index < 0) continue; - label = hda_get_input_pin_label(codec, nid, 1); + snd_hda_get_pin_label(codec, nid, &spec->autocfg, + label, sizeof(label), NULL); snd_hda_add_imux_item(dimux, label, index, &type_idx); if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) snd_hda_add_imux_item(imux, label, index, &type_idx); @@ -4154,65 +4128,18 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } -static int stac92xx_add_jack(struct hda_codec *codec, - hda_nid_t nid, int type) -{ -#ifdef CONFIG_SND_HDA_INPUT_JACK - int def_conf = snd_hda_codec_get_pincfg(codec, nid); - int connectivity = get_defcfg_connect(def_conf); - - if (connectivity && connectivity != AC_JACK_PORT_FIXED) - return 0; - - return snd_hda_input_jack_add(codec, nid, type, NULL); -#else - return 0; -#endif /* CONFIG_SND_HDA_INPUT_JACK */ -} - -static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, +static int stac_add_event(struct hda_codec *codec, hda_nid_t nid, unsigned char type, int data) { - struct sigmatel_event *event; + struct hda_jack_tbl *event; - snd_array_init(&spec->events, sizeof(*event), 32); - event = snd_array_new(&spec->events); + event = snd_hda_jack_tbl_new(codec, nid); if (!event) return -ENOMEM; - event->nid = nid; - event->type = type; - event->tag = spec->events.used; - event->data = data; - - return event->tag; -} - -static struct sigmatel_event *stac_get_event(struct hda_codec *codec, - hda_nid_t nid) -{ - struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event = spec->events.list; - int i; - - for (i = 0; i < spec->events.used; i++, event++) { - if (event->nid == nid) - return event; - } - return NULL; -} - -static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, - unsigned char tag) -{ - struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event = spec->events.list; - int i; + event->action = type; + event->private_data = data; - for (i = 0; i < spec->events.used; i++, event++) { - if (event->tag == tag) - return event; - } - return NULL; + return 0; } /* check if given nid is a valid pin and no other events are assigned @@ -4222,24 +4149,17 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, unsigned int type) { - struct sigmatel_event *event; - int tag; + struct hda_jack_tbl *event; if (!is_jack_detectable(codec, nid)) return 0; - event = stac_get_event(codec, nid); - if (event) { - if (event->type != type) - return 0; - tag = event->tag; - } else { - tag = stac_add_event(codec->spec, nid, type, 0); - if (tag < 0) - return 0; - } - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | tag); + event = snd_hda_jack_tbl_new(codec, nid); + if (!event) + return -ENOMEM; + if (event->action && event->action != type) + return 0; + event->action = type; + snd_hda_jack_detect_enable(codec, nid, 0); return 1; } @@ -4309,15 +4229,34 @@ static void stac_store_hints(struct hda_codec *codec) spec->eapd_switch = val; get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { - if (spec->gpio_led <= 8) { - spec->gpio_mask |= spec->gpio_led; - spec->gpio_dir |= spec->gpio_led; - if (spec->gpio_led_polarity) - spec->gpio_data |= spec->gpio_led; - } + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + if (spec->gpio_led_polarity) + spec->gpio_data |= spec->gpio_led; } } +static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins, + const hda_nid_t *pins) +{ + while (num_pins--) + stac_issue_unsol_event(codec, *pins++); +} + +/* fake event to set up pins */ +static void stac_fake_hp_events(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + + if (spec->autocfg.hp_outs) + stac_issue_unsol_events(codec, spec->autocfg.hp_outs, + spec->autocfg.hp_pins); + if (spec->autocfg.line_outs && + spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0]) + stac_issue_unsol_events(codec, spec->autocfg.line_outs, + spec->autocfg.line_out_pins); +} + static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -4368,10 +4307,7 @@ static int stac92xx_init(struct hda_codec *codec) stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], AC_PINCTL_OUT_EN); /* fake event to set up pins */ - if (cfg->hp_pins[0]) - stac_issue_unsol_event(codec, cfg->hp_pins[0]); - else if (cfg->line_out_pins[0]) - stac_issue_unsol_event(codec, cfg->line_out_pins[0]); + stac_fake_hp_events(codec); } else { stac92xx_auto_init_multi_out(codec); stac92xx_auto_init_hp_out(codec); @@ -4432,7 +4368,9 @@ static int stac92xx_init(struct hda_codec *codec) int pinctl, def_conf; /* power on when no jack detection is available */ - if (!spec->hp_detect) { + /* or when the VREF is used for controlling LED */ + if (!spec->hp_detect || + spec->vref_mute_led_nid == nid) { stac_toggle_power_map(codec, nid, 1); continue; } @@ -4459,10 +4397,16 @@ static int stac92xx_init(struct hda_codec *codec) stac_toggle_power_map(codec, nid, 1); continue; } - if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) + if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) { stac_issue_unsol_event(codec, nid); + continue; + } + /* none of the above, turn the port OFF */ + stac_toggle_power_map(codec, nid, 0); } + snd_hda_jack_report_sync(codec); + /* sync mute LED */ if (spec->gpio_led) hda_call_check_power_status(codec, 0x01); @@ -4519,8 +4463,6 @@ static void stac92xx_free(struct hda_codec *codec) return; stac92xx_shutup(codec); - snd_hda_input_jack_free(codec); - snd_array_free(&spec->events); kfree(spec); snd_hda_detach_beep_device(codec); @@ -4716,11 +4658,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, if (idx >= spec->num_pwrs) return; - /* several codecs have two power down bits */ - if (spec->pwr_mapping) - idx = spec->pwr_mapping[idx]; - else - idx = 1 << idx; + idx = 1 << idx; val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff; if (enable) @@ -4788,26 +4726,13 @@ static void stac92xx_mic_detect(struct hda_codec *codec) mic->mux_idx); } -static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) -{ - struct sigmatel_event *event = stac_get_event(codec, nid); - if (!event) - return; - codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); -} - -static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +static void handle_unsol_event(struct hda_codec *codec, + struct hda_jack_tbl *event) { struct sigmatel_spec *spec = codec->spec; - struct sigmatel_event *event; - int tag, data; - - tag = (res >> 26) & 0x7f; - event = stac_get_event_from_tag(codec, tag); - if (!event) - return; + int data; - switch (event->type) { + switch (event->action) { case STAC_HP_EVENT: case STAC_LO_EVENT: stac92xx_hp_detect(codec); @@ -4817,7 +4742,7 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) break; } - switch (event->type) { + switch (event->action) { case STAC_HP_EVENT: case STAC_LO_EVENT: case STAC_MIC_EVENT: @@ -4825,7 +4750,6 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) case STAC_PWR_EVENT: if (spec->num_pwrs > 0) stac92xx_pin_sense(codec, event->nid); - snd_hda_input_jack_report(codec, event->nid); switch (codec->subsystem_id) { case 0x103c308f: @@ -4850,11 +4774,33 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) AC_VERB_GET_GPIO_DATA, 0); /* toggle VREF state based on GPIOx status */ snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, - !!(data & (1 << event->data))); + !!(data & (1 << event->private_data))); break; } } +static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid) +{ + struct hda_jack_tbl *event = snd_hda_jack_tbl_get(codec, nid); + if (!event) + return; + handle_unsol_event(codec, event); +} + +static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) +{ + struct hda_jack_tbl *event; + int tag; + + tag = (res >> 26) & 0x7f; + event = snd_hda_jack_tbl_get_from_tag(codec, tag); + if (!event) + return; + event->jack_dirty = 1; + handle_unsol_event(codec, event); + snd_hda_jack_report_sync(codec); +} + static int hp_blike_system(u32 subsystem_id); static void set_hp_led_gpio(struct hda_codec *codec) @@ -4893,7 +4839,7 @@ static void set_hp_led_gpio(struct hda_codec *codec) * Need more information on whether it is true across the entire series. * -- kunal */ -static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) +static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) { struct sigmatel_spec *spec = codec->spec; const struct dmi_device *dev = NULL; @@ -4904,8 +4850,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { - if (spec->gpio_led < 4) + unsigned int max_gpio; + max_gpio = snd_hda_param_read(codec, codec->afg, + AC_PAR_GPIO_CAP); + max_gpio &= AC_GPIO_IO_COUNT; + if (spec->gpio_led < max_gpio) spec->gpio_led = 1 << spec->gpio_led; + else + spec->vref_mute_led_nid = spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", @@ -4913,13 +4865,21 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) set_hp_led_gpio(codec); return 1; } + /* BIOS bug: unfilled OEM string */ + if (strstr(dev->name, "HP_Mute_LED_P_G")) { + set_hp_led_gpio(codec); + spec->gpio_led_polarity = 1; + return 1; + } } /* * Fallback case - if we don't find the DMI strings, - * we statically set the GPIO - if not a B-series system. + * we statically set the GPIO - if not a B-series system + * and default polarity is provided */ - if (!hp_blike_system(codec->subsystem_id)) { + if (!hp_blike_system(codec->subsystem_id) && + (default_polarity == 0 || default_polarity == 1)) { set_hp_led_gpio(codec); spec->gpio_led_polarity = default_polarity; return 1; @@ -5006,19 +4966,11 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer, #ifdef CONFIG_PM static int stac92xx_resume(struct hda_codec *codec) { - struct sigmatel_spec *spec = codec->spec; - stac92xx_init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); /* fake event to set up pins again to override cached values */ - if (spec->hp_detect) { - if (spec->autocfg.hp_pins[0]) - stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); - else if (spec->autocfg.line_out_pins[0]) - stac_issue_unsol_event(codec, - spec->autocfg.line_out_pins[0]); - } + stac_fake_hp_events(codec); return 0; } @@ -5034,29 +4986,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; /* sync mute LED */ - if (spec->gpio_led) { - if (spec->gpio_led <= 8) { - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); - } else { - stac_vrefout_set(codec, - spec->gpio_led, spec->vref_led); - } - } - return 0; -} - -static int stac92xx_post_suspend(struct hda_codec *codec) -{ - struct sigmatel_spec *spec = codec->spec; - if (spec->gpio_led > 8) { - /* with vref-out pin used for mute led control - * codec AFG is prevented from D3 state, but on - * system suspend it can (and should) be used - */ - snd_hda_codec_read(codec, codec->afg, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } + if (spec->vref_mute_led_nid) + stac_vrefout_set(codec, spec->vref_mute_led_nid, + spec->vref_led); + else if (spec->gpio_led) + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data); return 0; } @@ -5067,7 +5002,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, struct sigmatel_spec *spec = codec->spec; if (power_state == AC_PWRST_D3) { - if (spec->gpio_led > 8) { + if (spec->vref_mute_led_nid) { /* with vref-out pin used for mute led control * codec AFG is prevented from D3 state */ @@ -5120,7 +5055,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) } } /*polarity defines *not* muted state level*/ - if (spec->gpio_led <= 8) { + if (!spec->vref_mute_led_nid) { if (muted) spec->gpio_data &= ~spec->gpio_led; /* orange */ else @@ -5138,7 +5073,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec) muted_lvl = spec->gpio_led_polarity ? AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; spec->vref_led = muted ? muted_lvl : notmtd_lvl; - stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); + stac_vrefout_set(codec, spec->vref_mute_led_nid, + spec->vref_led); } return 0; } @@ -5618,9 +5554,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e); } - /* reset pin power-down; Windows may leave these bits after reboot */ - snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); - snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); codec->no_trigger_sense = 1; codec->spec = spec; @@ -5630,7 +5563,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; spec->pwr_nids = stac92hd83xxx_pwr_nids; - spec->pwr_mapping = stac92hd83xxx_pwr_mapping; spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); spec->multiout.dac_nids = spec->dac_nids; spec->init = stac92hd83xxx_core_init; @@ -5647,27 +5579,22 @@ again: stac92xx_set_config_regs(codec, stac92hd83xxx_brd_tbl[spec->board_config]); - if (spec->board_config != STAC_92HD83XXX_PWR_REF) - spec->num_pwrs = 0; - codec->patch_ops = stac92xx_patch_ops; - if (find_mute_led_gpio(codec, 0)) + if (find_mute_led_cfg(codec, -1/*no default cfg*/)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (spec->gpio_led <= 8) { + if (!spec->vref_mute_led_nid) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; - codec->patch_ops.post_suspend = - stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = @@ -5842,15 +5769,13 @@ again: switch (spec->board_config) { case STAC_HP_M4: /* Enable VREF power saving on GPIO1 detect */ - err = stac_add_event(spec, codec->afg, + err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x02); if (err < 0) return err; snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | err); + snd_hda_jack_detect_enable(codec, codec->afg, 0); spec->gpio_mask |= 0x02; break; } @@ -5858,8 +5783,6 @@ again: (codec->revision_id & 0xf) == 1) spec->stream_delay = 40; /* 40 milliseconds */ - /* no output amps */ - spec->num_pwrs = 0; /* disable VSW */ spec->init = stac92hd71bxx_core_init; unmute_init++; @@ -5874,8 +5797,6 @@ again: if ((codec->revision_id & 0xf) == 1) spec->stream_delay = 40; /* 40 milliseconds */ - /* no output amps */ - spec->num_pwrs = 0; /* fallthru */ default: spec->init = stac92hd71bxx_core_init; @@ -5971,22 +5892,20 @@ again: } } - if (find_mute_led_gpio(codec, 1)) + if (find_mute_led_cfg(codec, 1)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (spec->gpio_led <= 8) { + if (!spec->vref_mute_led_nid) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; - codec->patch_ops.post_suspend = - stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = @@ -6327,14 +6246,12 @@ static int patch_stac9205(struct hda_codec *codec) snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); /* Enable unsol response for GPIO4/Dock HP connection */ - err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); + err = stac_add_event(codec, codec->afg, STAC_VREF_EVENT, 0x01); if (err < 0) return err; snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | err); + snd_hda_jack_detect_enable(codec, codec->afg, 0); spec->gpio_dir = 0x0b; spec->eapd_mask = 0x01; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 431c0d417ee..03e63fed9ca 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -54,6 +54,7 @@ #include <sound/asoundef.h> #include "hda_codec.h" #include "hda_local.h" +#include "hda_jack.h" /* Pin Widget NID */ #define VT1708_HP_PIN_NID 0x20 @@ -208,6 +209,7 @@ struct via_spec { /* work to check hp jack state */ struct hda_codec *codec; struct delayed_work vt1708_hp_work; + int hp_work_active; int vt1708_jack_detect; int vt1708_hp_present; @@ -305,27 +307,35 @@ enum { static void analog_low_current_mode(struct hda_codec *codec); static bool is_aa_path_mute(struct hda_codec *codec); -static void vt1708_start_hp_work(struct via_spec *spec) +#define hp_detect_with_aa(codec) \ + (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ + !is_aa_path_mute(codec)) + +static void vt1708_stop_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, - !spec->vt1708_jack_detect); - if (!delayed_work_pending(&spec->vt1708_hp_work)) - schedule_delayed_work(&spec->vt1708_hp_work, - msecs_to_jiffies(100)); + if (spec->hp_work_active) { + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1); + cancel_delayed_work_sync(&spec->vt1708_hp_work); + spec->hp_work_active = 0; + } } -static void vt1708_stop_hp_work(struct via_spec *spec) +static void vt1708_update_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 - && !is_aa_path_mute(spec->codec)) - return; - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, - !spec->vt1708_jack_detect); - cancel_delayed_work_sync(&spec->vt1708_hp_work); + if (spec->vt1708_jack_detect && + (spec->active_streams || hp_detect_with_aa(spec->codec))) { + if (!spec->hp_work_active) { + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0); + schedule_delayed_work(&spec->vt1708_hp_work, + msecs_to_jiffies(100)); + spec->hp_work_active = 1; + } + } else if (!hp_detect_with_aa(spec->codec)) + vt1708_stop_hp_work(spec); } static void set_widgets_power_state(struct hda_codec *codec) @@ -343,12 +353,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, set_widgets_power_state(codec); analog_low_current_mode(snd_kcontrol_chip(kcontrol)); - if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { - if (is_aa_path_mute(codec)) - vt1708_start_hp_work(codec->spec); - else - vt1708_stop_hp_work(codec->spec); - } + vt1708_update_hp_work(codec->spec); return change; } @@ -1154,7 +1159,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_dac_stream_tag = stream_tag; spec->cur_dac_format = format; mutex_unlock(&spec->config_mutex); - vt1708_start_hp_work(spec); + vt1708_update_hp_work(spec); return 0; } @@ -1174,7 +1179,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_hp_stream_tag = stream_tag; spec->cur_hp_format = format; mutex_unlock(&spec->config_mutex); - vt1708_start_hp_work(spec); + vt1708_update_hp_work(spec); return 0; } @@ -1188,7 +1193,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); spec->active_streams &= ~STREAM_MULTI_OUT; mutex_unlock(&spec->config_mutex); - vt1708_stop_hp_work(spec); + vt1708_update_hp_work(spec); return 0; } @@ -1203,7 +1208,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); spec->active_streams &= ~STREAM_INDEP_HP; mutex_unlock(&spec->config_mutex); - vt1708_stop_hp_work(spec); + vt1708_update_hp_work(spec); return 0; } @@ -1499,6 +1504,11 @@ static int via_build_controls(struct hda_codec *codec) analog_low_current_mode(codec); via_free_kctls(codec); /* no longer needed */ + + err = snd_hda_jack_add_kctls(codec, &spec->autocfg); + if (err < 0) + return err; + return 0; } @@ -1645,7 +1655,8 @@ static void via_hp_automute(struct hda_codec *codec) int nums; struct via_spec *spec = codec->spec; - if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0]) + if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] && + (spec->codec_type != VT1708 || spec->vt1708_jack_detect)) present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); if (spec->smart51_enabled) @@ -1709,6 +1720,7 @@ static void via_unsol_event(struct hda_codec *codec, unsigned int res) { res >>= 26; + res = snd_hda_jack_get_action(codec, res); if (res & VIA_JACK_EVENT) set_widgets_power_state(codec); @@ -1719,6 +1731,7 @@ static void via_unsol_event(struct hda_codec *codec, via_hp_automute(codec); else if (res == VIA_GPIO_EVENT) via_gpio_control(codec); + snd_hda_jack_report_sync(codec); } #ifdef CONFIG_PM @@ -2195,7 +2208,10 @@ static int via_auto_create_loopback_switch(struct hda_codec *codec) { struct via_spec *spec = codec->spec; - if (!spec->aa_mix_nid || !spec->out_mix_path.depth) + if (!spec->aa_mix_nid) + return 0; /* no loopback switching available */ + if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth || + spec->speaker_path.depth)) return 0; /* no loopback switching available */ if (!via_clone_control(spec, &via_aamix_ctl_enum)) return -ENOMEM; @@ -2612,8 +2628,6 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol, if (spec->codec_type != VT1708) return 0; - spec->vt1708_jack_detect = - !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; return 0; } @@ -2623,18 +2637,22 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct via_spec *spec = codec->spec; - int change; + int val; if (spec->codec_type != VT1708) return 0; - spec->vt1708_jack_detect = ucontrol->value.integer.value[0]; - change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) - == !spec->vt1708_jack_detect; - if (spec->vt1708_jack_detect) { + val = !!ucontrol->value.integer.value[0]; + if (spec->vt1708_jack_detect == val) + return 0; + spec->vt1708_jack_detect = val; + if (spec->vt1708_jack_detect && + snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) { mute_aa_path(codec, 1); notify_aa_path_ctls(codec); } - return change; + via_hp_automute(codec); + vt1708_update_hp_work(spec); + return 1; } static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { @@ -2729,9 +2747,8 @@ static void via_auto_init_unsol_event(struct hda_codec *codec) int i; if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0])) - snd_hda_codec_write(codec, cfg->hp_pins[0], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT); + snd_hda_jack_detect_enable(codec, cfg->hp_pins[0], + VIA_HP_EVENT | VIA_JACK_EVENT); if (cfg->speaker_pins[0]) ev = VIA_LINE_EVENT; @@ -2740,16 +2757,14 @@ static void via_auto_init_unsol_event(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) { if (cfg->line_out_pins[i] && is_jack_detectable(codec, cfg->line_out_pins[i])) - snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | ev | VIA_JACK_EVENT); + snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i], + ev | VIA_JACK_EVENT); } for (i = 0; i < cfg->num_inputs; i++) { if (is_jack_detectable(codec, cfg->inputs[i].pin)) - snd_hda_codec_write(codec, cfg->inputs[i].pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | VIA_JACK_EVENT); + snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin, + VIA_JACK_EVENT); } } @@ -2771,6 +2786,8 @@ static int via_init(struct hda_codec *codec) via_auto_init_unsol_event(codec); via_hp_automute(codec); + vt1708_update_hp_work(spec); + snd_hda_jack_report_sync(codec); return 0; } @@ -2781,13 +2798,16 @@ static void vt1708_update_hp_jack_state(struct work_struct *work) vt1708_hp_work.work); if (spec->codec_type != VT1708) return; + snd_hda_jack_set_dirty_all(spec->codec); /* if jack state toggled */ if (spec->vt1708_hp_present != snd_hda_jack_detect(spec->codec, spec->autocfg.hp_pins[0])) { spec->vt1708_hp_present ^= 1; via_hp_automute(spec->codec); } - vt1708_start_hp_work(spec); + if (spec->vt1708_jack_detect) + schedule_delayed_work(&spec->vt1708_hp_work, + msecs_to_jiffies(100)); } static int get_mux_nids(struct hda_codec *codec) diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index e328cfb7620..e525da2673b 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -68,8 +68,11 @@ static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) { - /* we use pins 39 and 41 of the VT1616 for left and right read outputs */ - snd_ac97_write_cache(ice->ac97, 0x5a, snd_ac97_read(ice->ac97, 0x5a) & ~0x8000); + if (ice->ac97) + /* we use pins 39 and 41 of the VT1616 for left and right + read outputs */ + snd_ac97_write_cache(ice->ac97, 0x5a, + snd_ac97_read(ice->ac97, 0x5a) & ~0x8000); return 0; } diff --git a/sound/pci/ice1712/envy24ht.h b/sound/pci/ice1712/envy24ht.h index a0c5e009bb4..4ca33a800bc 100644 --- a/sound/pci/ice1712/envy24ht.h +++ b/sound/pci/ice1712/envy24ht.h @@ -66,6 +66,7 @@ enum { #define VT1724_CFG_CLOCK384 0x40 /* 16.9344Mhz, 44.1kHz*384 */ #define VT1724_CFG_MPU401 0x20 /* MPU401 UARTs */ #define VT1724_CFG_ADC_MASK 0x0c /* one, two or one and S/PDIF, stereo ADCs */ +#define VT1724_CFG_ADC_NONE 0x0c /* no ADCs */ #define VT1724_CFG_DAC_MASK 0x03 /* one, two, three, four stereo DACs */ #define VT1724_REG_AC97_CFG 0x05 /* byte */ diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 44446f2222d..132a86e09d0 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -84,9 +84,9 @@ MODULE_SUPPORTED_DEVICE("{" static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ static char *model[SNDRV_CARDS]; -static int omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ +static bool omni[SNDRV_CARDS]; /* Delta44 & 66 Omni I/O support */ static int cs8427_timeout[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 500}; /* CS8427 S/PDIF transceiver reset timeout value in msec */ static int dxr_enable[SNDRV_CARDS]; /* DXR enable for DMX6FIRE */ diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 4353e76bf0a..92362973764 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -80,7 +80,7 @@ MODULE_SUPPORTED_DEVICE("{" static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static char *model[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); @@ -1117,14 +1117,21 @@ static struct snd_pcm_ops snd_vt1724_capture_pro_ops = { static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; - int err; + int capt, err; - err = snd_pcm_new(ice->card, "ICE1724", device, 1, 1, &pcm); + if ((ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_ADC_MASK) == + VT1724_CFG_ADC_NONE) + capt = 0; + else + capt = 1; + err = snd_pcm_new(ice->card, "ICE1724", device, 1, capt, &pcm); if (err < 0) return err; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_vt1724_playback_pro_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_vt1724_capture_pro_ops); + if (capt) + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_vt1724_capture_pro_ops); pcm->private_data = ice; pcm->info_flags = 0; @@ -1825,7 +1832,12 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; - uinfo->value.enumerated.items = hw_rates_count + ice->ext_clock_count; + /* internal clocks */ + uinfo->value.enumerated.items = hw_rates_count; + /* external clocks */ + if (ice->force_rdma1 || + (ice->eeprom.data[ICE_EEP2_SPDIF] & VT1724_CFG_SPDIF_IN)) + uinfo->value.enumerated.items += ice->ext_clock_count; /* upper limit - keep at top */ if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; @@ -2173,6 +2185,40 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { static struct snd_ice1712_card_info no_matched __devinitdata; + +/* + ooAoo cards with no controls +*/ +static unsigned char ooaoo_sq210_eeprom[] __devinitdata = { + [ICE_EEP2_SYSCONF] = 0x4c, /* 49MHz crystal, no mpu401, no ADC, + 1xDACs */ + [ICE_EEP2_ACLINK] = 0x80, /* I2S */ + [ICE_EEP2_I2S] = 0x78, /* no volume, 96k, 24bit, 192k */ + [ICE_EEP2_SPDIF] = 0xc1, /* out-en, out-int, out-ext */ + [ICE_EEP2_GPIO_DIR] = 0x00, /* no GPIOs are used */ + [ICE_EEP2_GPIO_DIR1] = 0x00, + [ICE_EEP2_GPIO_DIR2] = 0x00, + [ICE_EEP2_GPIO_MASK] = 0xff, + [ICE_EEP2_GPIO_MASK1] = 0xff, + [ICE_EEP2_GPIO_MASK2] = 0xff, + + [ICE_EEP2_GPIO_STATE] = 0x00, /* inputs */ + [ICE_EEP2_GPIO_STATE1] = 0x00, /* all 1, but GPIO_CPLD_RW + and GPIO15 always zero */ + [ICE_EEP2_GPIO_STATE2] = 0x00, /* inputs */ +}; + + +struct snd_ice1712_card_info snd_vt1724_ooaoo_cards[] __devinitdata = { + { + .name = "ooAoo SQ210a", + .model = "sq210a", + .eeprom_size = sizeof(ooaoo_sq210_eeprom), + .eeprom_data = ooaoo_sq210_eeprom, + }, + { } /* terminator */ +}; + static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_revo_cards, snd_vt1724_amp_cards, @@ -2187,6 +2233,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_wtm_cards, snd_vt1724_se_cards, snd_vt1724_qtet_cards, + snd_vt1724_ooaoo_cards, NULL, }; @@ -2270,7 +2317,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, } } for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->subvendor; c++) { + for (c = *tbl; c->name; c++) { if (modelname && c->model && !strcmp(modelname, c->model)) { printk(KERN_INFO "ice1724: Using board model %s\n", @@ -2579,8 +2626,10 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, ice->ext_clock_count = 0; for (tbl = card_tables; *tbl; tbl++) { - for (c = *tbl; c->subvendor; c++) { - if (c->subvendor == ice->eeprom.subvendor) { + for (c = *tbl; c->name; c++) { + if ((model[dev] && c->model && + !strcmp(model[dev], c->model)) || + (c->subvendor == ice->eeprom.subvendor)) { strcpy(card->shortname, c->name); if (c->driver) /* specific driver? */ strcpy(card->driver, c->driver); diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 29e312597f2..40b181bab93 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -79,9 +79,9 @@ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int ac97_clock; static char *ac97_quirk; -static int buggy_semaphore; +static bool buggy_semaphore; static int buggy_irq = -1; /* auto-check */ -static int xbox; +static bool xbox; static int spdif_aclink = -1; static int inside_vm = -1; @@ -105,7 +105,7 @@ module_param(inside_vm, bool, 0444); MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); static int joystick; module_param(joystick, int, 0444); @@ -1077,6 +1077,13 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs } if (civ != igetbyte(chip, ichdev->reg_offset + ICH_REG_OFF_CIV)) continue; + + /* IO read operation is very expensive inside virtual machine + * as it is emulated. The probability that subsequent PICB read + * will return different result is high enough to loop till + * timeout here. + * Same CIV is strict enough condition to be sure that PICB + * is valid inside VM on emulated card. */ if (chip->inside_vm) break; if (ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) @@ -2930,6 +2937,45 @@ static unsigned int sis_codec_bits[3] = { ICH_PCR, ICH_SCR, ICH_SIS_TCR }; +static int __devinit snd_intel8x0_inside_vm(struct pci_dev *pci) +{ + int result = inside_vm; + char *msg = NULL; + + /* check module parameter first (override detection) */ + if (result >= 0) { + msg = result ? "enable (forced) VM" : "disable (forced) VM"; + goto fini; + } + + /* detect KVM and Parallels virtual environments */ + result = kvm_para_available(); +#ifdef X86_FEATURE_HYPERVISOR + result = result || boot_cpu_has(X86_FEATURE_HYPERVISOR); +#endif + if (!result) + goto fini; + + /* check for known (emulated) devices */ + if (pci->subsystem_vendor == 0x1af4 && + pci->subsystem_device == 0x1100) { + /* KVM emulated sound, PCI SSID: 1af4:1100 */ + msg = "enable KVM"; + } else if (pci->subsystem_vendor == 0x1ab8) { + /* Parallels VM emulated sound, PCI SSID: 1ab8:xxxx */ + msg = "enable Parallels VM"; + } else { + msg = "disable (unknown or VT-d) VM"; + result = 0; + } + +fini: + if (msg != NULL) + printk(KERN_INFO "intel8x0: %s optimization\n", msg); + + return result; +} + static int __devinit snd_intel8x0_create(struct snd_card *card, struct pci_dev *pci, unsigned long device_type, @@ -2997,9 +3043,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, if (xbox) chip->xbox = 1; - chip->inside_vm = inside_vm; - if (inside_vm) - printk(KERN_INFO "intel8x0: enable KVM optimization\n"); + chip->inside_vm = snd_intel8x0_inside_vm(pci); if (pci->vendor == PCI_VENDOR_ID_INTEL && pci->device == PCI_DEVICE_ID_INTEL_440MX) @@ -3243,14 +3287,6 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, buggy_irq = 0; } - if (inside_vm < 0) { - /* detect KVM and Parallels virtual environments */ - inside_vm = kvm_para_available(); -#if defined(__i386__) || defined(__x86_64__) - inside_vm = inside_vm || boot_cpu_has(X86_FEATURE_HYPERVISOR); -#endif - } - if ((err = snd_intel8x0_create(card, pci, pci_id->driver_data, &chip)) < 0) { snd_card_free(card); diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 0f7041ec7dd..d689913a61b 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -68,7 +68,7 @@ module_param(ac97_clock, int, 0444); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); /* diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 841864b6b37..8fea45ab588 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -408,7 +408,7 @@ MODULE_FIRMWARE("korg/k1212.dsp"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Korg 1212 soundcard."); diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c index 924168ef1ed..37598273685 100644 --- a/sound/pci/lola/lola.c +++ b/sound/pci/lola/lola.c @@ -35,7 +35,7 @@ /* Standard options */ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Digigram Lola driver."); diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 04ae84b2a10..d94c0c292bd 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -42,7 +42,7 @@ MODULE_SUPPORTED_DEVICE("{digigram lx6464es{}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Digigram LX6464ES interface."); diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 5c8717e29ee..8c3e7fcefd9 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -78,10 +78,15 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port) return ioread32(address); } -void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len) +static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, + u32 len) { - void __iomem *address = lx_dsp_register(chip, port); - memcpy_fromio(data, address, len*sizeof(u32)); + u32 __iomem *address = lx_dsp_register(chip, port); + int i; + + /* we cannot use memcpy_fromio */ + for (i = 0; i != len; ++i) + data[i] = ioread32(address + i); } @@ -91,11 +96,15 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data) iowrite32(data, address); } -void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, - u32 len) +static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, + const u32 *data, u32 len) { - void __iomem *address = lx_dsp_register(chip, port); - memcpy_toio(address, data, len*sizeof(u32)); + u32 __iomem *address = lx_dsp_register(chip, port); + int i; + + /* we cannot use memcpy_to */ + for (i = 0; i != len; ++i) + iowrite32(data[i], address + i); } diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h index 1dd562980b6..4d7ff797a64 100644 --- a/sound/pci/lx6464es/lx_core.h +++ b/sound/pci/lx6464es/lx_core.h @@ -72,10 +72,7 @@ enum { }; unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); -void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len); void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); -void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, - u32 len); /* plx register access */ enum { diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 863c8bdaecd..78229b0dad2 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -64,8 +64,8 @@ MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */ -static int external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* all enabled */ +static bool external_amp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; static int amp_gpio[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index a0bd1d99793..487837c01c9 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -49,7 +49,7 @@ MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard."); diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index c6c45d979f7..ade2c64bd60 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -57,12 +57,12 @@ static int index = SNDRV_DEFAULT_IDX1; /* Index */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int playback_bufsize = 16; static int capture_bufsize = 16; -static int force_ac97; /* disabled as default */ +static bool force_ac97; /* disabled as default */ static int buffer_top; /* not specified */ -static int use_cache; /* disabled */ -static int vaio_hack; /* disabled */ -static int reset_workaround; -static int reset_workaround_2; +static bool use_cache; /* disabled */ +static bool vaio_hack; /* disabled */ +static bool reset_workaround; +static bool reset_workaround_2; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); @@ -86,7 +86,7 @@ module_param(reset_workaround_2, bool, 0444); MODULE_PARM_DESC(reset_workaround_2, "Enable extended AC97 RESET workaround for some other laptops."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 5f3a13d4369..eab663eef11 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -74,7 +74,7 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}" static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "card index"); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 4149a0cb8b7..3fdee495017 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -32,7 +32,7 @@ MODULE_SUPPORTED_DEVICE("{{Asus,AV66},{Asus,AV100},{Asus,AV200}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "card index"); diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 252719101c4..c8febf4b9bd 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -418,6 +418,7 @@ static const struct oxygen_model model_xonar_d1 = { .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF | AC97_FMIC_SWITCH, .dac_channels_pcm = 8, .dac_channels_mixer = 8, diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c index bc6eb58be38..793bdf03d7e 100644 --- a/sound/pci/oxygen/xonar_dg.c +++ b/sound/pci/oxygen/xonar_dg.c @@ -597,7 +597,8 @@ struct oxygen_model model_xonar_dg = { .model_data_size = sizeof(struct dg), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF, .dac_channels_pcm = 6, .dac_channels_mixer = 0, .function_flags = OXYGEN_FUNCTION_SPI, diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 42d1ab13621..478303e6c2b 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -1274,7 +1274,8 @@ static const struct oxygen_model model_xonar_ds = { .model_data_size = sizeof(struct xonar_wm87x6), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, + CAPTURE_0_FROM_I2S_1 | + CAPTURE_1_FROM_SPDIF, .dac_channels_pcm = 8, .dac_channels_mixer = 8, .dac_volume_min = 255 - 2*60, @@ -1306,7 +1307,8 @@ static const struct oxygen_model model_xonar_hdav_slim = { .model_data_size = sizeof(struct xonar_wm87x6), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, + CAPTURE_0_FROM_I2S_1 | + CAPTURE_1_FROM_SPDIF, .dac_channels_pcm = 8, .dac_channels_mixer = 2, .dac_volume_min = 255 - 2*60, diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 56a52659742..fd1809ab73b 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -52,8 +52,8 @@ MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ -static int mono[SNDRV_CARDS]; /* capture mono only */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static bool mono[SNDRV_CARDS]; /* capture mono only */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard"); diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index dcbedd33a62..0481d94aac9 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -122,7 +122,7 @@ MODULE_FIRMWARE("riptide.hex"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; #ifdef SUPPORT_JOYSTICK static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 }; diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 21bcb47fab5..b4819d5e41d 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -89,8 +89,8 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static int fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1}; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool fullduplex[SNDRV_CARDS]; // = {[0 ... (SNDRV_CARDS - 1)] = 1}; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME Digi32 soundcard."); diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 4585c9729fe..ba894158e76 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -53,7 +53,7 @@ MODULE_SUPPORTED_DEVICE("{{RME,Digi96}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME Digi96 soundcard."); diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index f2a3758dac5..b68cdec03b9 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -45,7 +45,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME Hammerfall DSP interface."); @@ -2640,8 +2640,7 @@ static int snd_hdsp_info_pref_sync_ref(struct snd_kcontrol *kcontrol, struct snd uinfo->value.enumerated.items = 3; break; default: - uinfo->value.enumerated.items = 0; - break; + return -EINVAL; } if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index e760adad952..cc9f6c83d66 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -61,7 +61,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME HDSPM interface."); @@ -941,6 +941,8 @@ struct hdspm { cycles_t last_interrupt; + unsigned int serial; + struct hdspm_peak_rms peak_rms; }; @@ -4694,7 +4696,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n", (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF, - (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF); + hdspm->serial); snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); @@ -6266,8 +6268,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, hdspm_version.card_type = hdspm->io_type; strncpy(hdspm_version.cardname, hdspm->card_name, sizeof(hdspm_version.cardname)); - hdspm_version.serial = (hdspm_read(hdspm, - HDSPM_midiStatusIn0)>>8) & 0xFFFFFF; + hdspm_version.serial = hdspm->serial; hdspm_version.firmware_rev = hdspm->firmware_rev; hdspm_version.addons = 0; if (hdspm->tco) @@ -6518,7 +6519,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, hdspm->io_type = AES32; hdspm->card_name = "RME AES32"; hdspm->midiPorts = 2; - } else if ((hdspm->firmware_rev == 0xd5) || + } else if ((hdspm->firmware_rev == 0xd2) || ((hdspm->firmware_rev >= 0xc8) && (hdspm->firmware_rev <= 0xcf))) { hdspm->io_type = MADI; @@ -6782,6 +6783,25 @@ static int __devinit snd_hdspm_create(struct snd_card *card, tasklet_init(&hdspm->midi_tasklet, hdspm_midi_tasklet, (unsigned long) hdspm); + + if (hdspm->io_type != MADIface) { + hdspm->serial = (hdspm_read(hdspm, + HDSPM_midiStatusIn0)>>8) & 0xFFFFFF; + /* id contains either a user-provided value or the default + * NULL. If it's the default, we're safe to + * fill card->id with the serial number. + * + * If the serial number is 0xFFFFFF, then we're dealing with + * an old PCI revision that comes without a sane number. In + * this case, we don't set card->id to avoid collisions + * when running with multiple cards. + */ + if (NULL == id[hdspm->dev] && hdspm->serial != 0xFFFFFF) { + sprintf(card->id, "HDSPMx%06x", hdspm->serial); + snd_card_set_id(card, card->id); + } + } + snd_printdd("create alsa devices.\n"); err = snd_hdspm_create_alsa_devices(card, hdspm); if (err < 0) @@ -6868,10 +6888,10 @@ static int __devinit snd_hdspm_probe(struct pci_dev *pci, if (hdspm->io_type != MADIface) { sprintf(card->shortname, "%s_%x", hdspm->card_name, - (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF); + hdspm->serial); sprintf(card->longname, "%s S/N 0x%x at 0x%lx, irq %d", hdspm->card_name, - (hdspm_read(hdspm, HDSPM_midiStatusIn0)>>8) & 0xFFFFFF, + hdspm->serial, hdspm->port, hdspm->irq); } else { sprintf(card->shortname, "%s", hdspm->card_name); diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index 732c5e83743..b737d1619cc 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -38,8 +38,8 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static int precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool precise_ptr[SNDRV_CARDS]; /* Enable precise pointer */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for RME Digi9652 (Hammerfall) soundcard."); diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index a391e622a19..ff500a87f76 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c @@ -40,7 +40,8 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ -static int enable = 1; +static bool enable = 1; +static int codecs = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); @@ -48,6 +49,8 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); module_param(enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); +module_param(codecs, int, 0444); +MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, @@ -140,6 +143,9 @@ struct sis7019 { dma_addr_t silence_dma_addr; }; +/* These values are also used by the module param 'codecs' to indicate + * which codecs should be present. + */ #define SIS_PRIMARY_CODEC_PRESENT 0x0001 #define SIS_SECONDARY_CODEC_PRESENT 0x0002 #define SIS_TERTIARY_CODEC_PRESENT 0x0004 @@ -977,7 +983,7 @@ timeout: mutex_unlock(&sis->ac97_mutex); if (!count) { - printk(KERN_ERR "sis7019: ac97 codec %d timeout cmd 0x%08x\n", + dev_err(&sis->pci->dev, "ac97 codec %d timeout cmd 0x%08x\n", codec, cmd); } @@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis) { unsigned long io = sis->ioport; void __iomem *ioaddr = sis->ioaddr; + unsigned long timeout; u16 status; int count; int i; @@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) udelay(1); + /* Command complete, we can let go of the semaphore now. + */ + outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); + if (!count) + return -EIO; + /* Now that we've finished the reset, find out what's attached. + * There are some codec/board combinations that take an extremely + * long time to come up. 350+ ms has been observed in the field, + * so we'll give them up to 500ms. */ - status = inl(io + SIS_AC97_STATUS); - if (status & SIS_AC97_STATUS_CODEC_READY) - sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC2_READY) - sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC3_READY) - sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; - - /* All done, let go of the semaphore, and check for errors + sis->codecs_present = 0; + timeout = msecs_to_jiffies(500) + jiffies; + while (time_before_eq(jiffies, timeout)) { + status = inl(io + SIS_AC97_STATUS); + if (status & SIS_AC97_STATUS_CODEC_READY) + sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC2_READY) + sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC3_READY) + sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; + + if (sis->codecs_present == codecs) + break; + + msleep(1); + } + + /* All done, check for errors. */ - outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); - if (!sis->codecs_present || !count) + if (!sis->codecs_present) { + dev_err(&sis->pci->dev, "could not find any codecs\n"); return -EIO; + } + + if (sis->codecs_present != codecs) { + dev_warn(&sis->pci->dev, "missing codecs, found %0x, expected %0x\n", + sis->codecs_present, codecs); + } /* Let the hardware know that the audio driver is alive, * and enable PCM slots on the AC-link for L/R playback (3 & 4) and @@ -1225,18 +1256,18 @@ static int sis_resume(struct pci_dev *pci) pci_restore_state(pci); if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "sis7019: unable to re-enable device\n"); + dev_err(&pci->dev, "unable to re-enable device\n"); goto error; } if (sis_chip_init(sis)) { - printk(KERN_ERR "sis7019: unable to re-init controller\n"); + dev_err(&pci->dev, "unable to re-init controller\n"); goto error; } if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, sis)) { - printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq); + dev_err(&pci->dev, "unable to regain IRQ %d\n", pci->irq); goto error; } @@ -1304,8 +1335,7 @@ static int __devinit sis_chip_create(struct snd_card *card, goto error_out; if (pci_set_dma_mask(pci, DMA_BIT_MASK(30)) < 0) { - printk(KERN_ERR "sis7019: architecture does not support " - "30-bit PCI busmaster DMA"); + dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA"); goto error_out_enabled; } @@ -1319,20 +1349,20 @@ static int __devinit sis_chip_create(struct snd_card *card, rc = pci_request_regions(pci, "SiS7019"); if (rc) { - printk(KERN_ERR "sis7019: unable request regions\n"); + dev_err(&pci->dev, "unable request regions\n"); goto error_out_enabled; } rc = -EIO; sis->ioaddr = ioremap_nocache(pci_resource_start(pci, 1), 0x4000); if (!sis->ioaddr) { - printk(KERN_ERR "sis7019: unable to remap MMIO, aborting\n"); + dev_err(&pci->dev, "unable to remap MMIO, aborting\n"); goto error_out_cleanup; } rc = sis_alloc_suspend(sis); if (rc < 0) { - printk(KERN_ERR "sis7019: unable to allocate state storage\n"); + dev_err(&pci->dev, "unable to allocate state storage\n"); goto error_out_cleanup; } @@ -1340,9 +1370,9 @@ static int __devinit sis_chip_create(struct snd_card *card, if (rc) goto error_out_cleanup; - if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, - KBUILD_MODNAME, sis)) { - printk(KERN_ERR "unable to allocate irq %d\n", sis->irq); + if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, + sis)) { + dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); goto error_out_cleanup; } @@ -1390,6 +1420,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out; + /* The user can specify which codecs should be present so that we + * can wait for them to show up if they are slow to recover from + * the AC97 cold reset. We default to a single codec, the primary. + * + * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. + */ + codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | + SIS_TERTIARY_CODEC_PRESENT; + if (!codecs) + codecs = SIS_PRIMARY_CODEC_PRESENT; + rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); if (rc < 0) goto error_out; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 31b6ad3ab1d..54cc802050f 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -52,9 +52,9 @@ MODULE_SUPPORTED_DEVICE("{{S3,SonicVibes PCI}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static int reverb[SNDRV_CARDS]; -static int mge[SNDRV_CARDS]; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool reverb[SNDRV_CARDS]; +static bool mge[SNDRV_CARDS]; static unsigned int dmaio = 0x7a00; /* DDMA i/o address */ module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index deb04b92412..5f1def7f45e 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -47,7 +47,7 @@ MODULE_SUPPORTED_DEVICE("{{Trident,4DWave DX}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32}; static int wavetable_size[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8192}; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index ae98d56d05b..75630408c6d 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -80,7 +80,7 @@ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static long mpu_port; #ifdef SUPPORT_JOYSTICK -static int joystick; +static bool joystick; #endif static int ac97_clock = 48000; static char *ac97_quirk; @@ -110,7 +110,7 @@ module_param(nodelay, int, 0444); MODULE_PARM_DESC(nodelay, "Disable 500ms init delay"); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 80a9c2bf330..5efcbcac506 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -66,7 +66,7 @@ module_param(ac97_clock, int, 0444); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); /* just for backward compatibility */ -static int enable; +static bool enable; module_param(enable, bool, 0444); diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c index 6765822fb3b..6a534bfe127 100644 --- a/sound/pci/vx222/vx222.c +++ b/sound/pci/vx222/vx222.c @@ -37,8 +37,8 @@ MODULE_SUPPORTED_DEVICE("{{Digigram," CARD_NAME "}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ -static int mic[SNDRV_CARDS]; /* microphone */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool mic[SNDRV_CARDS]; /* microphone */ static int ibl[SNDRV_CARDS]; /* microphone */ module_param_array(index, int, NULL, 0444); diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index e97ddcac0d3..e57b89e8aa8 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c @@ -41,13 +41,13 @@ MODULE_SUPPORTED_DEVICE("{{Yamaha,YMF724}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static long fm_port[SNDRV_CARDS]; static long mpu_port[SNDRV_CARDS]; #ifdef SUPPORT_JOYSTICK static long joystick_port[SNDRV_CARDS]; #endif -static int rear_switch[SNDRV_CARDS]; +static bool rear_switch[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the Yamaha DS-1 PCI soundcard."); diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 6af41d2d8fc..830839a874b 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -39,7 +39,7 @@ MODULE_SUPPORTED_DEVICE("{{Sound Core," CARD_NAME "}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 9e361c9d5bf..512f0b47237 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -39,7 +39,7 @@ MODULE_SUPPORTED_DEVICE("{{Digigram,VXPocket},{Digigram,VXPocket440}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */ static int ibl[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index 65645693c48..5a4e263b5b0 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c @@ -36,7 +36,7 @@ MODULE_LICENSE("GPL"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ -static int enable_beep = 1; +static bool enable_beep = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for " CHIP_NAME " soundchip."); diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index a3ce1b22620..1aa52eff526 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -876,7 +876,7 @@ static void __devinit snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) (0x0fUL << 12) | (PS3_AUDIO_IOID); - ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); + ret = lv1_gpu_attribute(0x100, 0x007, val); if (ret) pr_info("%s: gpu_attribute failed %d\n", __func__, ret); diff --git a/sound/sh/aica.c b/sound/sh/aica.c index 1120ca49edd..391a38ca58b 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -55,7 +55,7 @@ MODULE_FIRMWARE("aica_firmware.bin"); #define CARD_NAME "AICA" static int index = -1; static char *id; -static int enable = 1; +static bool enable = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); module_param(id, charp, 0444); diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index 56bcb46abf0..b11f82b5718 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -441,15 +441,4 @@ static struct platform_driver driver = { }, }; -static int __init sh_dac_init(void) -{ - return platform_driver_register(&driver); -} - -static void __exit sh_dac_exit(void) -{ - platform_driver_unregister(&driver); -} - -module_init(sh_dac_init); -module_exit(sh_dac_exit); +module_platform_driver(driver); diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 1381db853ef..35e662d270e 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -22,21 +22,6 @@ menuconfig SND_SOC if SND_SOC -config SND_SOC_CACHE_LZO - bool "Support LZO compression for register caches" - select LZO_COMPRESS - select LZO_DECOMPRESS - ---help--- - Select this to enable LZO compression for register caches. - This will allow machine or CODEC drivers to compress register - caches in memory, reducing the memory consumption at the - expense of performance. If this is not present and is used - the system will fall back to uncompressed caches. - - Usually it is safe to disable this option, where cache - compression in used the rbtree option will typically perform - better. - config SND_SOC_AC97_BUS bool diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index bee3c94f58b..72b09cfd3dc 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig @@ -1,6 +1,6 @@ config SND_ATMEL_SOC tristate "SoC Audio for the Atmel System-on-Chip" - depends on ARCH_AT91 || AVR32 + depends on ARCH_AT91 help Say Y or M if you want to add support for codecs attached to the ATMEL SSC interface. You will also need @@ -24,28 +24,9 @@ config SND_AT91_SOC_SAM9G20_WM8731 Say Y if you want to add support for SoC audio on WM8731-based AT91sam9g20 evaluation board. -config SND_AT32_SOC_PLAYPAQ - tristate "SoC Audio support for PlayPaq with WM8510" - depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS - select SND_ATMEL_SOC_SSC - select SND_SOC_WM8510 - help - Say Y or M here if you want to add support for SoC audio - on the LRS PlayPaq. - -config SND_AT32_SOC_PLAYPAQ_SLAVE - bool "Run CODEC on PlayPaq in slave mode" - depends on SND_AT32_SOC_PLAYPAQ - default n - help - Say Y if you want to run with the AT32 SSC generating the BCLK - and FRAME signals on the PlayPaq. Unless you want to play - with the AT32 as the SSC master, you probably want to say N here, - as this will give you better sound quality. - config SND_AT91_SOC_AFEB9260 tristate "SoC Audio support for AFEB9260 board" - depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC + depends on ATMEL_SSC && ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC select SND_ATMEL_SOC_SSC select SND_SOC_TLV320AIC23 help diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index e7ea56bd5f8..a5c0bf19da7 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile @@ -8,9 +8,5 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o # AT91 Machine Support snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o -# AT32 Machine Support -snd-soc-playpaq-objs := playpaq_wm8510.o - obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o -obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index f81d4c3f895..a21ff459e5d 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c @@ -367,7 +367,6 @@ static u64 atmel_pcm_dmamask = 0xffffffff; static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -376,14 +375,14 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = atmel_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { pr_debug("atmel-pcm:" "Allocating PCM capture DMA buffer\n"); ret = atmel_pcm_preallocate_dma_buffer(pcm, @@ -495,17 +494,7 @@ static struct platform_driver atmel_pcm_driver = { .remove = __devexit_p(atmel_soc_platform_remove), }; -static int __init snd_atmel_pcm_init(void) -{ - return platform_driver_register(&atmel_pcm_driver); -} -module_init(snd_atmel_pcm_init); - -static void __exit snd_atmel_pcm_exit(void) -{ - platform_driver_unregister(&atmel_pcm_driver); -} -module_exit(snd_atmel_pcm_exit); +module_platform_driver(atmel_pcm_driver); MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>"); MODULE_DESCRIPTION("Atmel PCM module"); diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index 71225090c49..354341ec0f4 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c @@ -719,7 +719,7 @@ static int atmel_ssc_remove(struct snd_soc_dai *dai) #define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops atmel_ssc_dai_ops = { +static const struct snd_soc_dai_ops atmel_ssc_dai_ops = { .startup = atmel_ssc_startup, .shutdown = atmel_ssc_shutdown, .prepare = atmel_ssc_prepare, @@ -859,17 +859,7 @@ int atmel_ssc_set_audio(int ssc_id) } EXPORT_SYMBOL_GPL(atmel_ssc_set_audio); -static int __init snd_atmel_ssc_init(void) -{ - return platform_driver_register(&asoc_ssc_driver); -} -module_init(snd_atmel_ssc_init); - -static void __exit snd_atmel_ssc_exit(void) -{ - platform_driver_unregister(&asoc_ssc_driver); -} -module_exit(snd_atmel_ssc_exit); +module_platform_driver(asoc_ssc_driver); /* Module information */ MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com"); diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c deleted file mode 100644 index 73ae99ad457..00000000000 --- a/sound/soc/atmel/playpaq_wm8510.c +++ /dev/null @@ -1,473 +0,0 @@ -/* sound/soc/at32/playpaq_wm8510.c - * ASoC machine driver for PlayPaq using WM8510 codec - * - * Copyright (C) 2008 Long Range Systems - * Geoffrey Wossum <gwossum@acm.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c - * - * NOTE: If you don't have the AT32 enhanced portmux configured (which - * isn't currently in the mainline or Atmel patched kernel), you will - * need to set the MCLK pin (PA30) to peripheral A in your board initialization - * code. Something like: - * at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); - * - */ - -/* #define DEBUG */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/clk.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> - -#include <mach/at32ap700x.h> -#include <mach/portmux.h> - -#include "../codecs/wm8510.h" -#include "atmel-pcm.h" -#include "atmel_ssc_dai.h" - - -/*-------------------------------------------------------------------------*\ - * constants -\*-------------------------------------------------------------------------*/ -#define MCLK_PIN GPIO_PIN_PA(30) -#define MCLK_PERIPH GPIO_PERIPH_A - - -/*-------------------------------------------------------------------------*\ - * data types -\*-------------------------------------------------------------------------*/ -/* SSC clocking data */ -struct ssc_clock_data { - /* CMR div */ - unsigned int cmr_div; - - /* Frame period (as needed by xCMR.PERIOD) */ - unsigned int period; - - /* The SSC clock rate these settings where calculated for */ - unsigned long ssc_rate; -}; - - -/*-------------------------------------------------------------------------*\ - * module data -\*-------------------------------------------------------------------------*/ -static struct clk *_gclk0; -static struct clk *_pll0; - -#define CODEC_CLK (_gclk0) - - -/*-------------------------------------------------------------------------*\ - * Sound SOC operations -\*-------------------------------------------------------------------------*/ -#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE -static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); - struct ssc_device *ssc = ssc_p->ssc; - struct ssc_clock_data cd; - unsigned int rate, width_bits, channels; - unsigned int bitrate, ssc_div; - unsigned actual_rate; - - - /* - * Figure out required bitrate - */ - rate = params_rate(params); - channels = params_channels(params); - width_bits = snd_pcm_format_physical_width(params_format(params)); - bitrate = rate * width_bits * channels; - - - /* - * Figure out required SSC divider and period for required bitrate - */ - cd.ssc_rate = clk_get_rate(ssc->clk); - ssc_div = cd.ssc_rate / bitrate; - cd.cmr_div = ssc_div / 2; - if (ssc_div & 1) { - /* round cmr_div up */ - cd.cmr_div++; - } - cd.period = width_bits - 1; - - - /* - * Find actual rate, compare to requested rate - */ - actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1)); - pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n", - rate, actual_rate); - - - return cd; -} -#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ - - - -static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); - struct ssc_device *ssc = ssc_p->ssc; - unsigned int pll_out = 0, bclk = 0, mclk_div = 0; - int ret; - - - /* Due to difficulties with getting the correct clocks from the AT32's - * PLL0, we're going to let the CODEC be in charge of all the clocks - */ -#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE - const unsigned int fmt = (SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); -#else - struct ssc_clock_data cd; - const unsigned int fmt = (SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); -#endif - - if (ssc == NULL) { - pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n"); - return -EINVAL; - } - - - /* - * Figure out PLL and BCLK dividers for WM8510 - */ - switch (params_rate(params)) { - case 48000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_2; - bclk = WM8510_BCLKDIV_8; - break; - - case 44100: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_2; - bclk = WM8510_BCLKDIV_8; - break; - - case 22050: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_4; - bclk = WM8510_BCLKDIV_8; - break; - - case 16000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_6; - bclk = WM8510_BCLKDIV_8; - break; - - case 11025: - pll_out = 22579200; - mclk_div = WM8510_MCLKDIV_8; - bclk = WM8510_BCLKDIV_8; - break; - - case 8000: - pll_out = 24576000; - mclk_div = WM8510_MCLKDIV_12; - bclk = WM8510_BCLKDIV_8; - break; - - default: - pr_warning("playpaq_wm8510: Unsupported sample rate %d\n", - params_rate(params)); - return -EINVAL; - } - - - /* - * set CPU and CODEC DAI configuration - */ - ret = snd_soc_dai_set_fmt(codec_dai, fmt); - if (ret < 0) { - pr_warning("playpaq_wm8510: " - "Failed to set CODEC DAI format (%d)\n", - ret); - return ret; - } - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) { - pr_warning("playpaq_wm8510: " - "Failed to set CPU DAI format (%d)\n", - ret); - return ret; - } - - - /* - * Set CPU clock configuration - */ -#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE - cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai); - pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n", - cd.cmr_div, cd.period); - ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div); - if (ret < 0) { - pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n", - ret); - return ret; - } - ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, - cd.period); - if (ret < 0) { - pr_warning("playpaq_wm8510: " - "Failed to set CPU transmit period (%d)\n", - ret); - return ret; - } -#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ - - - /* - * Set CODEC clock configuration - */ - pr_debug("playpaq_wm8510: " - "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n", - clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div); - - -#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); - if (ret < 0) { - pr_warning - ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n", - ret); - return ret; - } -#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ - - - ret = snd_soc_dai_set_pll(codec_dai, 0, 0, - clk_get_rate(CODEC_CLK), pll_out); - if (ret < 0) { - pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", - ret); - return ret; - } - - - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div); - if (ret < 0) { - pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n", - ret); - return ret; - } - - - return 0; -} - - - -static struct snd_soc_ops playpaq_wm8510_ops = { - .hw_params = playpaq_wm8510_hw_params, -}; - - - -static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { - SND_SOC_DAPM_MIC("Int Mic", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), -}; - - - -static const struct snd_soc_dapm_route intercon[] = { - /* speaker connected to SPKOUT */ - {"Ext Spk", NULL, "SPKOUTP"}, - {"Ext Spk", NULL, "SPKOUTN"}, - - {"Mic Bias", NULL, "Int Mic"}, - {"MICN", NULL, "Mic Bias"}, - {"MICP", NULL, "Mic Bias"}, -}; - - - -static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int i; - - /* - * Add DAPM widgets - */ - for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) - snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); - - - - /* - * Setup audio path interconnects - */ - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - - - /* always connected pins */ - snd_soc_dapm_enable_pin(dapm, "Int Mic"); - snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - - - - /* Make CSB show PLL rate */ - snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV, - WM8510_OPCLKDIV_1 | 4); - - return 0; -} - - - -static struct snd_soc_dai_link playpaq_wm8510_dai = { - .name = "WM8510", - .stream_name = "WM8510 PCM", - .cpu_dai_name= "atmel-ssc-dai.0", - .platform_name = "atmel-pcm-audio", - .codec_name = "wm8510-codec.0-0x1a", - .codec_dai_name = "wm8510-hifi", - .init = playpaq_wm8510_init, - .ops = &playpaq_wm8510_ops, -}; - - - -static struct snd_soc_card snd_soc_playpaq = { - .name = "LRS_PlayPaq_WM8510", - .dai_link = &playpaq_wm8510_dai, - .num_links = 1, -}; - -static struct platform_device *playpaq_snd_device; - - -static int __init playpaq_asoc_init(void) -{ - int ret = 0; - - /* - * Configure MCLK for WM8510 - */ - _gclk0 = clk_get(NULL, "gclk0"); - if (IS_ERR(_gclk0)) { - _gclk0 = NULL; - ret = PTR_ERR(_gclk0); - goto err_gclk0; - } - _pll0 = clk_get(NULL, "pll0"); - if (IS_ERR(_pll0)) { - _pll0 = NULL; - ret = PTR_ERR(_pll0); - goto err_pll0; - } - ret = clk_set_parent(_gclk0, _pll0); - if (ret) { - pr_warning("snd-soc-playpaq: " - "Failed to set PLL0 as parent for DAC clock\n"); - goto err_set_clk; - } - clk_set_rate(CODEC_CLK, 12000000); - clk_enable(CODEC_CLK); - -#if defined CONFIG_AT32_ENHANCED_PORTMUX - at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0); -#endif - - - /* - * Create and register platform device - */ - playpaq_snd_device = platform_device_alloc("soc-audio", 0); - if (playpaq_snd_device == NULL) { - ret = -ENOMEM; - goto err_device_alloc; - } - - platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq); - - ret = platform_device_add(playpaq_snd_device); - if (ret) { - pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n", - ret); - goto err_device_add; - } - - return 0; - - -err_device_add: - if (playpaq_snd_device != NULL) { - platform_device_put(playpaq_snd_device); - playpaq_snd_device = NULL; - } -err_device_alloc: -err_set_clk: - if (_pll0 != NULL) { - clk_put(_pll0); - _pll0 = NULL; - } -err_pll0: - if (_gclk0 != NULL) { - clk_put(_gclk0); - _gclk0 = NULL; - } - return ret; -} - - -static void __exit playpaq_asoc_exit(void) -{ - if (_gclk0 != NULL) { - clk_put(_gclk0); - _gclk0 = NULL; - } - if (_pll0 != NULL) { - clk_put(_pll0); - _pll0 = NULL; - } - -#if defined CONFIG_AT32_ENHANCED_PORTMUX - at32_free_pin(MCLK_PIN); -#endif - - platform_device_unregister(playpaq_snd_device); - playpaq_snd_device = NULL; -} - -module_init(playpaq_asoc_init); -module_exit(playpaq_asoc_exit); - -MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>"); -MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 0377c5451ae..c88351488f4 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -189,6 +189,7 @@ static struct snd_soc_dai_link at91sam9g20ek_dai = { static struct snd_soc_card snd_soc_at91sam9g20ek = { .name = "AT91SAMG20-EK", + .owner = THIS_MODULE, .dai_link = &at91sam9g20ek_dai, .num_links = 1, .set_bias_level = at91sam9g20ek_set_bias_level, diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index d427e9217ce..4ca667d477f 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c @@ -135,6 +135,7 @@ static struct snd_soc_dai_link afeb9260_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_machine_afeb9260 = { .name = "AFEB9260", + .owner = THIS_MODULE, .dai_link = &afeb9260_dai, .num_links = 1, }; diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index 726bd651a10..c5ac2449563 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c @@ -195,7 +195,7 @@ static int alchemy_ac97c_startup(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops alchemy_ac97c_ops = { +static const struct snd_soc_dai_ops alchemy_ac97c_ops = { .startup = alchemy_ac97c_startup, }; @@ -229,35 +229,34 @@ static int __devinit au1xac97c_drvprobe(struct platform_device *pdev) struct resource *iores, *dmares; struct au1xpsc_audio_data *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; mutex_init(&ctx->lock); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iores) { - ret = -ENODEV; - goto out0; - } + if (!iores) + return -ENODEV; - ret = -EBUSY; - if (!request_mem_region(iores->start, resource_size(iores), - pdev->name)) - goto out0; + if (!devm_request_mem_region(&pdev->dev, iores->start, + resource_size(iores), + pdev->name)) + return -EBUSY; - ctx->mmio = ioremap_nocache(iores->start, resource_size(iores)); + ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start, + resource_size(iores)); if (!ctx->mmio) - goto out1; + return -EBUSY; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmares) - goto out2; + return -EBUSY; ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!dmares) - goto out2; + return -EBUSY; ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; /* switch it on */ @@ -271,33 +270,20 @@ static int __devinit au1xac97c_drvprobe(struct platform_device *pdev) ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver); if (ret) - goto out2; + return ret; ac97c_workdata = ctx; return 0; - -out2: - iounmap(ctx->mmio); -out1: - release_mem_region(iores->start, resource_size(iores)); -out0: - kfree(ctx); - return ret; } static int __devexit au1xac97c_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); snd_soc_unregister_dai(&pdev->dev); WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ - iounmap(ctx->mmio); - release_mem_region(r->start, resource_size(r)); - kfree(ctx); - ac97c_workdata = NULL; /* MDEV */ return 0; diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c index 127477a5e0c..511d83c11a9 100644 --- a/sound/soc/au1x/db1000.c +++ b/sound/soc/au1x/db1000.c @@ -29,6 +29,7 @@ static struct snd_soc_dai_link db1000_ac97_dai = { static struct snd_soc_card db1000_ac97 = { .name = "DB1000_AC97", + .owner = THIS_MODULE, .dai_link = &db1000_ac97_dai, .num_links = 1, }; @@ -57,18 +58,7 @@ static struct platform_driver db1000_audio_driver = { .remove = __devexit_p(db1000_audio_remove), }; -static int __init db1000_audio_load(void) -{ - return platform_driver_register(&db1000_audio_driver); -} - -static void __exit db1000_audio_unload(void) -{ - platform_driver_unregister(&db1000_audio_driver); -} - -module_init(db1000_audio_load); -module_exit(db1000_audio_unload); +module_platform_driver(db1000_audio_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio"); diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index 289312c14b9..1c629393df7 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -45,6 +45,7 @@ static struct snd_soc_dai_link db1200_ac97_dai = { static struct snd_soc_card db1200_ac97_machine = { .name = "DB1200_AC97", + .owner = THIS_MODULE, .dai_link = &db1200_ac97_dai, .num_links = 1, }; @@ -94,6 +95,7 @@ static struct snd_soc_dai_link db1200_i2s_dai = { static struct snd_soc_card db1200_i2s_machine = { .name = "DB1200_I2S", + .owner = THIS_MODULE, .dai_link = &db1200_i2s_dai, .num_links = 1, }; @@ -133,18 +135,7 @@ static struct platform_driver db1200_audio_driver = { .remove = __devexit_p(db1200_audio_remove), }; -static int __init db1200_audio_load(void) -{ - return platform_driver_register(&db1200_audio_driver); -} - -static void __exit db1200_audio_unload(void) -{ - platform_driver_unregister(&db1200_audio_driver); -} - -module_init(db1200_audio_load); -module_exit(db1200_audio_unload); +module_platform_driver(db1200_audio_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DB1200 ASoC audio support"); diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index d7d04e26eee..8372cd35f0d 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c @@ -341,7 +341,7 @@ static int au1xpsc_pcm_new(struct snd_soc_pcm_runtime *rtd) } /* au1xpsc audio platform */ -struct snd_soc_platform_driver au1xpsc_soc_platform = { +static struct snd_soc_platform_driver au1xpsc_soc_platform = { .ops = &au1xpsc_pcm_ops, .pcm_new = au1xpsc_pcm_new, .pcm_free = au1xpsc_pcm_free_dma_buffers, @@ -350,27 +350,21 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = { static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) { struct au1xpsc_audio_dmadata *dmadata; - int ret; - dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); + dmadata = devm_kzalloc(&pdev->dev, + 2 * sizeof(struct au1xpsc_audio_dmadata), + GFP_KERNEL); if (!dmadata) return -ENOMEM; platform_set_drvdata(pdev, dmadata); - ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); - if (ret) - kfree(dmadata); - - return ret; + return snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); } static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev) { - struct au1xpsc_audio_dmadata *dmadata = platform_get_drvdata(pdev); - snd_soc_unregister_platform(&pdev->dev); - kfree(dmadata); return 0; } @@ -384,18 +378,7 @@ static struct platform_driver au1xpsc_pcm_driver = { .remove = __devexit_p(au1xpsc_pcm_drvremove), }; -static int __init au1xpsc_audio_dbdma_load(void) -{ - return platform_driver_register(&au1xpsc_pcm_driver); -} - -static void __exit au1xpsc_audio_dbdma_unload(void) -{ - platform_driver_unregister(&au1xpsc_pcm_driver); -} - -module_init(au1xpsc_audio_dbdma_load); -module_exit(au1xpsc_audio_dbdma_unload); +module_platform_driver(au1xpsc_pcm_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index 177f7137a9c..0a91b186a86 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -316,7 +316,7 @@ static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -struct snd_soc_platform_driver alchemy_pcm_soc_platform = { +static struct snd_soc_platform_driver alchemy_pcm_soc_platform = { .ops = &alchemy_pcm_ops, .pcm_new = alchemy_pcm_new, .pcm_free = alchemy_pcm_free_dma_buffers, @@ -325,27 +325,19 @@ struct snd_soc_platform_driver alchemy_pcm_soc_platform = { static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev) { struct alchemy_pcm_ctx *ctx; - int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; platform_set_drvdata(pdev, ctx); - ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform); - if (ret) - kfree(ctx); - - return ret; + return snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform); } static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev) { - struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev); - snd_soc_unregister_platform(&pdev->dev); - kfree(ctx); return 0; } @@ -359,18 +351,7 @@ static struct platform_driver alchemy_pcmdma_driver = { .remove = __devexit_p(alchemy_pcm_drvremove), }; -static int __init alchemy_pcmdma_load(void) -{ - return platform_driver_register(&alchemy_pcmdma_driver); -} - -static void __exit alchemy_pcmdma_unload(void) -{ - platform_driver_unregister(&alchemy_pcmdma_driver); -} - -module_init(alchemy_pcmdma_load); -module_exit(alchemy_pcmdma_unload); +module_platform_driver(alchemy_pcmdma_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver"); diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c index 6bcf48f5884..d4b9e364a47 100644 --- a/sound/soc/au1x/i2sc.c +++ b/sound/soc/au1x/i2sc.c @@ -227,69 +227,50 @@ static struct snd_soc_dai_driver au1xi2s_dai_driver = { static int __devinit au1xi2s_drvprobe(struct platform_device *pdev) { - int ret; struct resource *iores, *dmares; struct au1xpsc_audio_data *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iores) { - ret = -ENODEV; - goto out0; - } + if (!iores) + return -ENODEV; - ret = -EBUSY; - if (!request_mem_region(iores->start, resource_size(iores), - pdev->name)) - goto out0; + if (!devm_request_mem_region(&pdev->dev, iores->start, + resource_size(iores), + pdev->name)) + return -EBUSY; - ctx->mmio = ioremap_nocache(iores->start, resource_size(iores)); + ctx->mmio = devm_ioremap_nocache(&pdev->dev, iores->start, + resource_size(iores)); if (!ctx->mmio) - goto out1; + return -EBUSY; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmares) - goto out2; + return -EBUSY; ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!dmares) - goto out2; + return -EBUSY; ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; platform_set_drvdata(pdev, ctx); - ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); - if (ret) - goto out2; - - return 0; - -out2: - iounmap(ctx->mmio); -out1: - release_mem_region(iores->start, resource_size(iores)); -out0: - kfree(ctx); - return ret; + return snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); } static int __devexit au1xi2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); snd_soc_unregister_dai(&pdev->dev); WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ - iounmap(ctx->mmio); - release_mem_region(r->start, resource_size(r)); - kfree(ctx); - return 0; } @@ -331,18 +312,7 @@ static struct platform_driver au1xi2s_driver = { .remove = __devexit_p(au1xi2s_drvremove), }; -static int __init au1xi2s_load(void) -{ - return platform_driver_register(&au1xi2s_driver); -} - -static void __exit au1xi2s_unload(void) -{ - platform_driver_unregister(&au1xi2s_driver); -} - -module_init(au1xi2s_load); -module_exit(au1xi2s_unload); +module_platform_driver(au1xi2s_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver"); diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index 0c6acd54714..476b79a1c11 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c @@ -337,7 +337,7 @@ static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) return au1xpsc_ac97_workdata ? 0 : -ENODEV; } -static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { +static const struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { .startup = au1xpsc_ac97_startup, .trigger = au1xpsc_ac97_trigger, .hw_params = au1xpsc_ac97_hw_params, @@ -368,35 +368,35 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) unsigned long sel; struct au1xpsc_audio_data *wd; - wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); + wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data), + GFP_KERNEL); if (!wd) return -ENOMEM; mutex_init(&wd->lock); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iores) { - ret = -ENODEV; - goto out0; - } + if (!iores) + return -ENODEV; - ret = -EBUSY; - if (!request_mem_region(iores->start, resource_size(iores), - pdev->name)) - goto out0; + if (!devm_request_mem_region(&pdev->dev, iores->start, + resource_size(iores), + pdev->name)) + return -EBUSY; - wd->mmio = ioremap(iores->start, resource_size(iores)); + wd->mmio = devm_ioremap(&pdev->dev, iores->start, + resource_size(iores)); if (!wd->mmio) - goto out1; + return -EBUSY; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmares) - goto out2; + return -EBUSY; wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!dmares) - goto out2; + return -EBUSY; wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; /* configuration: max dma trigger threshold, enable ac97 */ @@ -421,24 +421,15 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); if (ret) - goto out2; + return ret; au1xpsc_ac97_workdata = wd; return 0; - -out2: - iounmap(wd->mmio); -out1: - release_mem_region(iores->start, resource_size(iores)); -out0: - kfree(wd); - return ret; } static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); snd_soc_unregister_dai(&pdev->dev); @@ -448,10 +439,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); au_sync(); - iounmap(wd->mmio); - release_mem_region(r->start, resource_size(r)); - kfree(wd); - au1xpsc_ac97_workdata = NULL; /* MDEV */ return 0; diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index e03c5ce01b3..0607ba3d925 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c @@ -265,7 +265,7 @@ static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { +static const struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { .startup = au1xpsc_i2s_startup, .trigger = au1xpsc_i2s_trigger, .hw_params = au1xpsc_i2s_hw_params, @@ -295,33 +295,34 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) int ret; struct au1xpsc_audio_data *wd; - wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); + wd = devm_kzalloc(&pdev->dev, sizeof(struct au1xpsc_audio_data), + GFP_KERNEL); if (!wd) return -ENOMEM; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!iores) { - ret = -ENODEV; - goto out0; - } + if (!iores) + return -ENODEV; ret = -EBUSY; - if (!request_mem_region(iores->start, resource_size(iores), - pdev->name)) - goto out0; + if (!devm_request_mem_region(&pdev->dev, iores->start, + resource_size(iores), + pdev->name)) + return -EBUSY; - wd->mmio = ioremap(iores->start, resource_size(iores)); + wd->mmio = devm_ioremap(&pdev->dev, iores->start, + resource_size(iores)); if (!wd->mmio) - goto out1; + return -EBUSY; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmares) - goto out2; + return -EBUSY; wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!dmares) - goto out2; + return -EBUSY; wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; /* preserve PSC clock source set up by platform (dev.platform_data @@ -349,23 +350,12 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) platform_set_drvdata(pdev, wd); - ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); - if (!ret) - return 0; - -out2: - iounmap(wd->mmio); -out1: - release_mem_region(iores->start, resource_size(iores)); -out0: - kfree(wd); - return ret; + return snd_soc_register_dai(&pdev->dev, &wd->dai_drv); } static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) { struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); - struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); snd_soc_unregister_dai(&pdev->dev); @@ -374,10 +364,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd)); au_sync(); - iounmap(wd->mmio); - release_mem_region(r->start, resource_size(r)); - kfree(wd); - return 0; } @@ -435,18 +421,7 @@ static struct platform_driver au1xpsc_i2s_driver = { .remove = __devexit_p(au1xpsc_i2s_drvremove), }; -static int __init au1xpsc_i2s_load(void) -{ - return platform_driver_register(&au1xpsc_i2s_driver); -} - -static void __exit au1xpsc_i2s_unload(void) -{ - platform_driver_unregister(&au1xpsc_i2s_driver); -} - -module_init(au1xpsc_i2s_load); -module_exit(au1xpsc_i2s_unload); +module_platform_driver(au1xpsc_i2s_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver"); diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 56815c1d47b..d7dc9bde097 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c @@ -421,7 +421,6 @@ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -431,14 +430,14 @@ static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -475,17 +474,7 @@ static struct platform_driver bf5xx_pcm_driver = { .remove = __devexit_p(bf5xx_soc_platform_remove), }; -static int __init snd_bf5xx_pcm_init(void) -{ - return platform_driver_register(&bf5xx_pcm_driver); -} -module_init(snd_bf5xx_pcm_init); - -static void __exit snd_bf5xx_pcm_exit(void) -{ - platform_driver_unregister(&bf5xx_pcm_driver); -} -module_exit(snd_bf5xx_pcm_exit); +module_platform_driver(bf5xx_pcm_driver); MODULE_AUTHOR("Cliff Cai"); MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module"); diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c index 6d216259088..f4e9dc4e262 100644 --- a/sound/soc/blackfin/bf5xx-ac97.c +++ b/sound/soc/blackfin/bf5xx-ac97.c @@ -375,18 +375,7 @@ static struct platform_driver asoc_bfin_ac97_driver = { .remove = __devexit_p(asoc_bfin_ac97_remove), }; -static int __init bfin_ac97_init(void) -{ - return platform_driver_register(&asoc_bfin_ac97_driver); -} -module_init(bfin_ac97_init); - -static void __exit bfin_ac97_exit(void) -{ - platform_driver_unregister(&asoc_bfin_ac97_driver); -} -module_exit(bfin_ac97_exit); - +module_platform_driver(asoc_bfin_ac97_driver); MODULE_AUTHOR("Roy Huang"); MODULE_DESCRIPTION("AC97 driver for ADI Blackfin"); diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index f79d1655e03..60962ce6cd4 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -91,6 +91,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { static struct snd_soc_card bf5xx_ad1836 = { .name = "bfin-ad1836", + .owner = THIS_MODULE, .dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index 5956584ea3a..2d8d82dbc15 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -119,6 +119,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = { static struct snd_soc_card bf5xx_ad193x = { .name = "bfin-ad193x", + .owner = THIS_MODULE, .dai_link = &bf5xx_ad193x_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c index 06a84b211b5..b30f88bbd70 100644 --- a/sound/soc/blackfin/bf5xx-ad1980.c +++ b/sound/soc/blackfin/bf5xx-ad1980.c @@ -74,6 +74,7 @@ static struct snd_soc_dai_link bf5xx_board_dai[] = { static struct snd_soc_card bf5xx_board = { .name = "bfin-ad1980", + .owner = THIS_MODULE, .dai_link = &bf5xx_board_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index b94eb7ef7d1..8e49508596d 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -192,6 +192,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { static struct snd_soc_card bf5xx_ad73311 = { .name = "bfin-ad73311", + .owner = THIS_MODULE, .probe = bf5xx_probe, .dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 7565e1576ff..63205d723ea 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c @@ -260,7 +260,6 @@ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -270,14 +269,14 @@ static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -314,17 +313,7 @@ static struct platform_driver bfin_i2s_pcm_driver = { .remove = __devexit_p(bfin_i2s_soc_platform_remove), }; -static int __init snd_bfin_i2s_pcm_init(void) -{ - return platform_driver_register(&bfin_i2s_pcm_driver); -} -module_init(snd_bfin_i2s_pcm_init); - -static void __exit snd_bfin_i2s_pcm_exit(void) -{ - platform_driver_unregister(&bfin_i2s_pcm_driver); -} -module_exit(snd_bfin_i2s_pcm_exit); +module_platform_driver(bfin_i2s_pcm_driver); MODULE_AUTHOR("Cliff Cai"); MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module"); diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 00cc3e00b2f..4dccf0374fe 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -223,7 +223,7 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai) SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { +static const struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { .shutdown = bf5xx_i2s_shutdown, .hw_params = bf5xx_i2s_hw_params, .set_fmt = bf5xx_i2s_set_dai_fmt, @@ -288,18 +288,7 @@ static struct platform_driver bfin_i2s_driver = { }, }; -static int __init bfin_i2s_init(void) -{ - return platform_driver_register(&bfin_i2s_driver); -} - -static void __exit bfin_i2s_exit(void) -{ - platform_driver_unregister(&bfin_i2s_driver); -} - -module_init(bfin_i2s_init); -module_exit(bfin_i2s_exit); +module_platform_driver(bfin_i2s_driver); /* Module information */ MODULE_AUTHOR("Cliff Cai"); diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 767e772a815..03030323804 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -125,6 +125,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { static struct snd_soc_card bf5xx_ssm2602 = { .name = "bfin-ssm2602", + .owner = THIS_MODULE, .dai_link = &bf5xx_ssm2602_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, }; diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c index c95cc03d583..254490cf187 100644 --- a/sound/soc/blackfin/bf5xx-tdm-pcm.c +++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c @@ -286,7 +286,6 @@ static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -295,14 +294,14 @@ static int bf5xx_pcm_tdm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = bf5xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -339,17 +338,7 @@ static struct platform_driver bfin_tdm_driver = { .remove = __devexit_p(bf5xx_soc_platform_remove), }; -static int __init snd_bfin_tdm_init(void) -{ - return platform_driver_register(&bfin_tdm_driver); -} -module_init(snd_bfin_tdm_init); - -static void __exit snd_bfin_tdm_exit(void) -{ - platform_driver_unregister(&bfin_tdm_driver); -} -module_exit(snd_bfin_tdm_exit); +module_platform_driver(bfin_tdm_driver); MODULE_AUTHOR("Barry Song"); MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module"); diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c index a822d1ee138..594f88217c7 100644 --- a/sound/soc/blackfin/bf5xx-tdm.c +++ b/sound/soc/blackfin/bf5xx-tdm.c @@ -226,7 +226,7 @@ static int bf5xx_tdm_resume(struct snd_soc_dai *dai) #define bf5xx_tdm_resume NULL #endif -static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = { +static const struct snd_soc_dai_ops bf5xx_tdm_dai_ops = { .hw_params = bf5xx_tdm_hw_params, .set_fmt = bf5xx_tdm_set_dai_fmt, .shutdown = bf5xx_tdm_shutdown, @@ -314,17 +314,7 @@ static struct platform_driver bfin_tdm_driver = { }, }; -static int __init bfin_tdm_init(void) -{ - return platform_driver_register(&bfin_tdm_driver); -} -module_init(bfin_tdm_init); - -static void __exit bfin_tdm_exit(void) -{ - platform_driver_unregister(&bfin_tdm_driver); -} -module_exit(bfin_tdm_exit); +module_platform_driver(bfin_tdm_driver); /* Module information */ MODULE_AUTHOR("Barry Song"); diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c index 8df2a3b0cb3..26b271c62ef 100644 --- a/sound/soc/blackfin/bfin-eval-adau1373.c +++ b/sound/soc/blackfin/bfin-eval-adau1373.c @@ -147,6 +147,7 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = { static struct snd_soc_card bfin_eval_adau1373 = { .name = "bfin-eval-adau1373", + .owner = THIS_MODULE, .dai_link = &bfin_eval_adau1373_dai, .num_links = 1, @@ -184,17 +185,7 @@ static struct platform_driver bfin_eval_adau1373_driver = { .remove = __devexit_p(bfin_eval_adau1373_remove), }; -static int __init bfin_eval_adau1373_init(void) -{ - return platform_driver_register(&bfin_eval_adau1373_driver); -} -module_init(bfin_eval_adau1373_init); - -static void __exit bfin_eval_adau1373_exit(void) -{ - platform_driver_unregister(&bfin_eval_adau1373_driver); -} -module_exit(bfin_eval_adau1373_exit); +module_platform_driver(bfin_eval_adau1373_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver"); diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c index e5550acba2c..c0064fa1dca 100644 --- a/sound/soc/blackfin/bfin-eval-adau1701.c +++ b/sound/soc/blackfin/bfin-eval-adau1701.c @@ -84,6 +84,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { static struct snd_soc_card bfin_eval_adau1701 = { .name = "bfin-eval-adau1701", + .owner = THIS_MODULE, .dai_link = &bfin_eval_adau1701_dai[CONFIG_SND_BF5XX_SPORT_NUM], .num_links = 1, @@ -121,17 +122,7 @@ static struct platform_driver bfin_eval_adau1701_driver = { .remove = __devexit_p(bfin_eval_adau1701_remove), }; -static int __init bfin_eval_adau1701_init(void) -{ - return platform_driver_register(&bfin_eval_adau1701_driver); -} -module_init(bfin_eval_adau1701_init); - -static void __exit bfin_eval_adau1701_exit(void) -{ - platform_driver_unregister(&bfin_eval_adau1701_driver); -} -module_exit(bfin_eval_adau1701_exit); +module_platform_driver(bfin_eval_adau1701_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("ALSA SoC bfin ADAU1701 driver"); diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c index 897cfa68a2a..4ef079f95e2 100644 --- a/sound/soc/blackfin/bfin-eval-adav80x.c +++ b/sound/soc/blackfin/bfin-eval-adav80x.c @@ -93,6 +93,7 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = { static struct snd_soc_card bfin_eval_adav80x = { .name = "bfin-eval-adav80x", + .owner = THIS_MODULE, .dai_link = bfin_eval_adav80x_dais, .num_links = ARRAY_SIZE(bfin_eval_adav80x_dais), @@ -157,17 +158,7 @@ static struct platform_driver bfin_eval_adav80x_driver = { .id_table = bfin_eval_adav80x_ids, }; -static int __init bfin_eval_adav80x_init(void) -{ - return platform_driver_register(&bfin_eval_adav80x_driver); -} -module_init(bfin_eval_adav80x_init); - -static void __exit bfin_eval_adav80x_exit(void) -{ - platform_driver_unregister(&bfin_eval_adav80x_driver); -} -module_exit(bfin_eval_adav80x_exit); +module_platform_driver(bfin_eval_adav80x_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("ALSA SoC bfin adav80x driver"); diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 5ca122e5118..9fd3b6827bb 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -861,7 +861,7 @@ static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = { PM860X_DAPM_OUTPUT("RSYNC", pm860x_rsync_event), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route pm860x_dapm_routes[] = { /* supply */ {"Left DAC", NULL, "VCODEC"}, {"Right DAC", NULL, "VCODEC"}, @@ -1198,14 +1198,14 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_dai_ops pm860x_pcm_dai_ops = { +static const struct snd_soc_dai_ops pm860x_pcm_dai_ops = { .digital_mute = pm860x_digital_mute, .hw_params = pm860x_pcm_hw_params, .set_fmt = pm860x_pcm_set_dai_fmt, .set_sysclk = pm860x_set_dai_sysclk, }; -static struct snd_soc_dai_ops pm860x_i2s_dai_ops = { +static const struct snd_soc_dai_ops pm860x_i2s_dai_ops = { .digital_mute = pm860x_digital_mute, .hw_params = pm860x_i2s_hw_params, .set_fmt = pm860x_i2s_set_dai_fmt, @@ -1361,7 +1361,6 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect); static int pm860x_probe(struct snd_soc_codec *codec) { struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; int i, ret; pm860x->codec = codec; @@ -1388,11 +1387,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) goto out; } - snd_soc_add_controls(codec, pm860x_snd_controls, - ARRAY_SIZE(pm860x_snd_controls)); - snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets, - ARRAY_SIZE(pm860x_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; out: @@ -1420,6 +1414,13 @@ static struct snd_soc_codec_driver soc_codec_dev_pm860x = { .reg_cache_size = REG_CACHE_SIZE, .reg_word_size = sizeof(u8), .set_bias_level = pm860x_set_bias_level, + + .controls = pm860x_snd_controls, + .num_controls = ARRAY_SIZE(pm860x_snd_controls), + .dapm_widgets = pm860x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(pm860x_dapm_widgets), + .dapm_routes = pm860x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(pm860x_dapm_routes), }; static int __devinit pm860x_codec_probe(struct platform_device *pdev) @@ -1429,7 +1430,8 @@ static int __devinit pm860x_codec_probe(struct platform_device *pdev) struct resource *res; int i, ret; - pm860x = kzalloc(sizeof(struct pm860x_priv), GFP_KERNEL); + pm860x = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_priv), + GFP_KERNEL); if (pm860x == NULL) return -ENOMEM; @@ -1458,17 +1460,13 @@ static int __devinit pm860x_codec_probe(struct platform_device *pdev) out: platform_set_drvdata(pdev, NULL); - kfree(pm860x); return -EINVAL; } static int __devexit pm860x_codec_remove(struct platform_device *pdev) { - struct pm860x_priv *pm860x = platform_get_drvdata(pdev); - snd_soc_unregister_codec(&pdev->dev); platform_set_drvdata(pdev, NULL); - kfree(pm860x); return 0; } @@ -1481,17 +1479,7 @@ static struct platform_driver pm860x_codec_driver = { .remove = __devexit_p(pm860x_codec_remove), }; -static __init int pm860x_init(void) -{ - return platform_driver_register(&pm860x_codec_driver); -} -module_init(pm860x_init); - -static __exit void pm860x_exit(void) -{ - platform_driver_unregister(&pm860x_codec_driver); -} -module_exit(pm860x_exit); +module_platform_driver(pm860x_codec_driver); MODULE_DESCRIPTION("ASoC 88PM860x driver"); MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 4584514d93d..7c205e77d83 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -26,14 +26,16 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4642 if I2C select SND_SOC_AK4671 if I2C select SND_SOC_ALC5623 if I2C + select SND_SOC_ALC5632 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C + select SND_SOC_CS42L73 if I2C select SND_SOC_CS4270 if I2C select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI select SND_SOC_CX20442 select SND_SOC_DA7210 if I2C select SND_SOC_DFBMCS320 - select SND_SOC_JZ4740_CODEC if SOC_JZ4740 + select SND_SOC_JZ4740_CODEC select SND_SOC_LM4857 if I2C select SND_SOC_MAX98088 if I2C select SND_SOC_MAX98095 if I2C @@ -139,7 +141,7 @@ config SND_SOC_AD73311 tristate config SND_SOC_ADAU1701 - select SIGMA + select SND_SOC_SIGMADSP tristate config SND_SOC_ADAU1373 @@ -168,6 +170,8 @@ config SND_SOC_AK4671 config SND_SOC_ALC5623 tristate +config SND_SOC_ALC5632 + tristate config SND_SOC_CQ0093VC tristate @@ -175,6 +179,9 @@ config SND_SOC_CQ0093VC config SND_SOC_CS42L51 tristate +config SND_SOC_CS42L73 + tristate + # Cirrus Logic CS4270 Codec config SND_SOC_CS4270 tristate @@ -227,6 +234,10 @@ config SND_SOC_RT5631 config SND_SOC_SGTL5000 tristate +config SND_SOC_SIGMADSP + tristate + select CRC32 + config SND_SOC_SN95031 tristate @@ -278,6 +289,9 @@ config SND_SOC_WL1273 config SND_SOC_WM1250_EV1 tristate +config SND_SOC_WM2000 + tristate + config SND_SOC_WM5100 tristate @@ -395,6 +409,9 @@ config SND_SOC_WM8996 config SND_SOC_WM9081 tristate +config SND_SOC_WM9090 + tristate + config SND_SOC_WM9705 tristate @@ -413,9 +430,3 @@ config SND_SOC_MAX9877 config SND_SOC_TPA6130A2 tristate - -config SND_SOC_WM2000 - tristate - -config SND_SOC_WM9090 - tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index a2c7842e357..de8078178f8 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -15,13 +15,16 @@ snd-soc-ak4642-objs := ak4642.o snd-soc-ak4671-objs := ak4671.o snd-soc-cq93vc-objs := cq93vc.o snd-soc-cs42l51-objs := cs42l51.o +snd-soc-cs42l73-objs := cs42l73.o snd-soc-cs4270-objs := cs4270.o snd-soc-cs4271-objs := cs4271.o snd-soc-cx20442-objs := cx20442.o snd-soc-da7210-objs := da7210.o snd-soc-dfbmcs320-objs := dfbmcs320.o snd-soc-dmic-objs := dmic.o +snd-soc-jz4740-codec-objs := jz4740.o snd-soc-l3-objs := l3.o +snd-soc-lm4857-objs := lm4857.o snd-soc-max98088-objs := max98088.o snd-soc-max98095-objs := max98095.o snd-soc-max9850-objs := max9850.o @@ -29,6 +32,8 @@ snd-soc-pcm3008-objs := pcm3008.o snd-soc-rt5631-objs := rt5631.o snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-alc5623-objs := alc5623.o +snd-soc-alc5632-objs := alc5632.o +snd-soc-sigmadsp-objs := sigmadsp.o snd-soc-sn95031-objs := sn95031.o snd-soc-spdif-objs := spdif_transciever.o snd-soc-ssm2602-objs := ssm2602.o @@ -45,6 +50,7 @@ snd-soc-uda134x-objs := uda134x.o snd-soc-uda1380-objs := uda1380.o snd-soc-wl1273-objs := wl1273.o snd-soc-wm1250-ev1-objs := wm1250-ev1.o +snd-soc-wm2000-objs := wm2000.o snd-soc-wm5100-objs := wm5100.o wm5100-tables.o snd-soc-wm8350-objs := wm8350.o snd-soc-wm8400-objs := wm8400.o @@ -81,21 +87,18 @@ snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm8991-objs := wm8991.o snd-soc-wm8993-objs := wm8993.o -snd-soc-wm8994-objs := wm8994.o wm8994-tables.o wm8958-dsp2.o +snd-soc-wm8994-objs := wm8994.o wm8958-dsp2.o snd-soc-wm8995-objs := wm8995.o snd-soc-wm9081-objs := wm9081.o +snd-soc-wm9090-objs := wm9090.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o snd-soc-wm-hubs-objs := wm_hubs.o -snd-soc-jz4740-codec-objs := jz4740.o # Amp -snd-soc-lm4857-objs := lm4857.o snd-soc-max9877-objs := max9877.o snd-soc-tpa6130a2-objs := tpa6130a2.o -snd-soc-wm2000-objs := wm2000.o -snd-soc-wm9090-objs := wm9090.o obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o @@ -113,8 +116,10 @@ obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o +obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o +obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o @@ -122,6 +127,7 @@ obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o +obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o @@ -129,6 +135,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o +obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o @@ -145,6 +152,7 @@ obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o +obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o @@ -184,14 +192,12 @@ obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o +obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o # Amp -obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o -obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o -obj-$(CONFIG_SND_SOC_WM9090) += snd-soc-wm9090.o diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index e715186b430..1bbad4c16d2 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c @@ -39,7 +39,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops ac97_dai_ops = { +static const struct snd_soc_dai_ops ac97_dai_ops = { .prepare = ac97_prepare, }; @@ -99,7 +99,7 @@ static int ac97_soc_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int ac97_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg) +static int ac97_soc_suspend(struct snd_soc_codec *codec) { snd_ac97_suspend(codec->ac97); @@ -148,17 +148,7 @@ static struct platform_driver ac97_codec_driver = { .remove = __devexit_p(ac97_remove), }; -static int __init ac97_init(void) -{ - return platform_driver_register(&ac97_codec_driver); -} -module_init(ac97_init); - -static void __exit ac97_exit(void) -{ - platform_driver_unregister(&ac97_codec_driver); -} -module_exit(ac97_exit); +module_platform_driver(ac97_codec_driver); MODULE_DESCRIPTION("Soc Generic AC97 driver"); MODULE_AUTHOR("Liam Girdwood"); diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 4e5c5726366..982d201c2e8 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -189,7 +189,7 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops ad1836_dai_ops = { +static const struct snd_soc_dai_ops ad1836_dai_ops = { .hw_params = ad1836_hw_params, .set_fmt = ad1836_set_dai_fmt, }; @@ -223,7 +223,7 @@ static struct snd_soc_dai_driver ad183x_dais[] = { }; #ifdef CONFIG_PM -static int ad1836_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int ad1836_suspend(struct snd_soc_codec *codec) { /* reset clock control mode */ return snd_soc_update_bits(codec, AD1836_ADC_CTRL2, @@ -341,7 +341,8 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi) struct ad1836_priv *ad1836; int ret; - ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL); + ad1836 = devm_kzalloc(&spi->dev, sizeof(struct ad1836_priv), + GFP_KERNEL); if (ad1836 == NULL) return -ENOMEM; @@ -351,17 +352,15 @@ static int __devinit ad1836_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad1836, &ad183x_dais[ad1836->type], 1); - if (ret < 0) - kfree(ad1836); return ret; } static int __devexit ad1836_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } + static const struct spi_device_id ad1836_ids[] = { { "ad1835", AD1835 }, { "ad1836", AD1836 }, diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h index 444747f0db2..dd7be0dbbc5 100644 --- a/sound/soc/codecs/ad1836.h +++ b/sound/soc/codecs/ad1836.h @@ -34,7 +34,7 @@ #define AD1836_ADC_CTRL2 13 #define AD1836_ADC_WORD_LEN_MASK 0x30 -#define AD1836_ADC_WORD_OFFSET 5 +#define AD1836_ADC_WORD_OFFSET 4 #define AD1836_ADC_SERFMT_MASK (7 << 6) #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index 120602130b5..a4a6bef2c0b 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -30,21 +30,23 @@ struct ad193x_priv { /* * AD193X volume/mute/de-emphasis etc. controls */ -static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; +static const char * const ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; static const struct soc_enum ad193x_deemp_enum = SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); +static const DECLARE_TLV_DB_MINMAX(adau193x_tlv, -9563, 0); + static const struct snd_kcontrol_new ad193x_snd_controls[] = { /* DAC volume control */ - SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL, - AD193X_DAC_R1_VOL, 0, 0xFF, 1), - SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL, - AD193X_DAC_R2_VOL, 0, 0xFF, 1), - SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL, - AD193X_DAC_R3_VOL, 0, 0xFF, 1), - SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL, - AD193X_DAC_R4_VOL, 0, 0xFF, 1), + SOC_DOUBLE_R_TLV("DAC1 Volume", AD193X_DAC_L1_VOL, + AD193X_DAC_R1_VOL, 0, 0xFF, 1, adau193x_tlv), + SOC_DOUBLE_R_TLV("DAC2 Volume", AD193X_DAC_L2_VOL, + AD193X_DAC_R2_VOL, 0, 0xFF, 1, adau193x_tlv), + SOC_DOUBLE_R_TLV("DAC3 Volume", AD193X_DAC_L3_VOL, + AD193X_DAC_R3_VOL, 0, 0xFF, 1, adau193x_tlv), + SOC_DOUBLE_R_TLV("DAC4 Volume", AD193X_DAC_L4_VOL, + AD193X_DAC_R4_VOL, 0, 0xFF, 1, adau193x_tlv), /* ADC switch control */ SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE, @@ -75,6 +77,7 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = { SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0), SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("SYSCLK", AD193X_PLL_CLK_CTRL0, 7, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("DAC1OUT"), SND_SOC_DAPM_OUTPUT("DAC2OUT"), SND_SOC_DAPM_OUTPUT("DAC3OUT"), @@ -84,16 +87,17 @@ static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = { }; static const struct snd_soc_dapm_route audio_paths[] = { - { "DAC", NULL, "PLL_PWR" }, - { "ADC", NULL, "PLL_PWR" }, + { "DAC", NULL, "SYSCLK" }, + { "ADC", NULL, "SYSCLK" }, { "DAC", NULL, "ADC_PWR" }, { "ADC", NULL, "ADC_PWR" }, - { "DAC1OUT", "DAC1 Switch", "DAC" }, - { "DAC2OUT", "DAC2 Switch", "DAC" }, - { "DAC3OUT", "DAC3 Switch", "DAC" }, - { "DAC4OUT", "DAC4 Switch", "DAC" }, - { "ADC", "ADC1 Switch", "ADC1IN" }, - { "ADC", "ADC2 Switch", "ADC2IN" }, + { "DAC1OUT", NULL, "DAC" }, + { "DAC2OUT", NULL, "DAC" }, + { "DAC3OUT", NULL, "DAC" }, + { "DAC4OUT", NULL, "DAC" }, + { "ADC", NULL, "ADC1IN" }, + { "ADC", NULL, "ADC2IN" }, + { "SYSCLK", NULL, "PLL_PWR" }, }; /* @@ -102,14 +106,14 @@ static const struct snd_soc_dapm_route audio_paths[] = { static int ad193x_mute(struct snd_soc_dai *dai, int mute) { - struct snd_soc_codec *codec = dai->codec; + struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec); if (mute) - snd_soc_update_bits(codec, AD193X_DAC_CTRL2, + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2, AD193X_DAC_MASTER_MUTE, AD193X_DAC_MASTER_MUTE); else - snd_soc_update_bits(codec, AD193X_DAC_CTRL2, + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2, AD193X_DAC_MASTER_MUTE, 0); return 0; @@ -118,36 +122,30 @@ static int ad193x_mute(struct snd_soc_dai *dai, int mute) static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, unsigned int rx_mask, int slots, int width) { - struct snd_soc_codec *codec = dai->codec; - int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1); - int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2); - - dac_reg &= ~AD193X_DAC_CHAN_MASK; - adc_reg &= ~AD193X_ADC_CHAN_MASK; + struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(dai->codec); + unsigned int channels; switch (slots) { case 2: - dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT; - adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT; + channels = AD193X_2_CHANNELS; break; case 4: - dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT; - adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT; + channels = AD193X_4_CHANNELS; break; case 8: - dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT; - adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT; + channels = AD193X_8_CHANNELS; break; case 16: - dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT; - adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT; + channels = AD193X_16_CHANNELS; break; default: return -EINVAL; } - snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); - snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg); + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, + AD193X_DAC_CHAN_MASK, channels << AD193X_DAC_CHAN_SHFT); + regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, + AD193X_ADC_CHAN_MASK, channels << AD193X_ADC_CHAN_SHFT); return 0; } @@ -155,24 +153,20 @@ static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { - struct snd_soc_codec *codec = codec_dai->codec; - int adc_reg1, adc_reg2, dac_reg; - - adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1); - adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2); - dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1); + struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec_dai->codec); + unsigned int adc_serfmt = 0; + unsigned int adc_fmt = 0; + unsigned int dac_fmt = 0; /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; - adc_reg1 |= AD193X_ADC_SERFMT_TDM; + adc_serfmt |= AD193X_ADC_SERFMT_TDM; break; case SND_SOC_DAIFMT_DSP_A: - adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; - adc_reg1 |= AD193X_ADC_SERFMT_AUX; + adc_serfmt |= AD193X_ADC_SERFMT_AUX; break; default: return -EINVAL; @@ -180,29 +174,20 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ - adc_reg2 &= ~AD193X_ADC_LEFT_HIGH; - adc_reg2 &= ~AD193X_ADC_BCLK_INV; - dac_reg &= ~AD193X_DAC_LEFT_HIGH; - dac_reg &= ~AD193X_DAC_BCLK_INV; break; case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */ - adc_reg2 |= AD193X_ADC_LEFT_HIGH; - adc_reg2 &= ~AD193X_ADC_BCLK_INV; - dac_reg |= AD193X_DAC_LEFT_HIGH; - dac_reg &= ~AD193X_DAC_BCLK_INV; + adc_fmt |= AD193X_ADC_LEFT_HIGH; + dac_fmt |= AD193X_DAC_LEFT_HIGH; break; case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */ - adc_reg2 &= ~AD193X_ADC_LEFT_HIGH; - adc_reg2 |= AD193X_ADC_BCLK_INV; - dac_reg &= ~AD193X_DAC_LEFT_HIGH; - dac_reg |= AD193X_DAC_BCLK_INV; + adc_fmt |= AD193X_ADC_BCLK_INV; + dac_fmt |= AD193X_DAC_BCLK_INV; break; - case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */ - adc_reg2 |= AD193X_ADC_LEFT_HIGH; - adc_reg2 |= AD193X_ADC_BCLK_INV; - dac_reg |= AD193X_DAC_LEFT_HIGH; - dac_reg |= AD193X_DAC_BCLK_INV; + adc_fmt |= AD193X_ADC_LEFT_HIGH; + adc_fmt |= AD193X_ADC_BCLK_INV; + dac_fmt |= AD193X_DAC_LEFT_HIGH; + dac_fmt |= AD193X_DAC_BCLK_INV; break; default: return -EINVAL; @@ -210,36 +195,31 @@ static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ - adc_reg2 |= AD193X_ADC_LCR_MASTER; - adc_reg2 |= AD193X_ADC_BCLK_MASTER; - dac_reg |= AD193X_DAC_LCR_MASTER; - dac_reg |= AD193X_DAC_BCLK_MASTER; + adc_fmt |= AD193X_ADC_LCR_MASTER; + adc_fmt |= AD193X_ADC_BCLK_MASTER; + dac_fmt |= AD193X_DAC_LCR_MASTER; + dac_fmt |= AD193X_DAC_BCLK_MASTER; break; case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */ - adc_reg2 |= AD193X_ADC_LCR_MASTER; - adc_reg2 &= ~AD193X_ADC_BCLK_MASTER; - dac_reg |= AD193X_DAC_LCR_MASTER; - dac_reg &= ~AD193X_DAC_BCLK_MASTER; + adc_fmt |= AD193X_ADC_LCR_MASTER; + dac_fmt |= AD193X_DAC_LCR_MASTER; break; case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ - adc_reg2 &= ~AD193X_ADC_LCR_MASTER; - adc_reg2 |= AD193X_ADC_BCLK_MASTER; - dac_reg &= ~AD193X_DAC_LCR_MASTER; - dac_reg |= AD193X_DAC_BCLK_MASTER; + adc_fmt |= AD193X_ADC_BCLK_MASTER; + dac_fmt |= AD193X_DAC_BCLK_MASTER; break; case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */ - adc_reg2 &= ~AD193X_ADC_LCR_MASTER; - adc_reg2 &= ~AD193X_ADC_BCLK_MASTER; - dac_reg &= ~AD193X_DAC_LCR_MASTER; - dac_reg &= ~AD193X_DAC_BCLK_MASTER; break; default: return -EINVAL; } - snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1); - snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2); - snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); + regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, + AD193X_ADC_SERFMT_MASK, adc_serfmt); + regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL2, + AD193X_ADC_FMT_MASK, adc_fmt); + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL1, + AD193X_DAC_FMT_MASK, dac_fmt); return 0; } @@ -299,20 +279,20 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, break; } - snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0, + regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0, AD193X_PLL_INPUT_MASK, master_rate); - snd_soc_update_bits(codec, AD193X_DAC_CTRL2, + regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL2, AD193X_DAC_WORD_LEN_MASK, word_len << AD193X_DAC_WORD_LEN_SHFT); - snd_soc_update_bits(codec, AD193X_ADC_CTRL1, + regmap_update_bits(ad193x->regmap, AD193X_ADC_CTRL1, AD193X_ADC_WORD_LEN_MASK, word_len); return 0; } -static struct snd_soc_dai_ops ad193x_dai_ops = { +static const struct snd_soc_dai_ops ad193x_dai_ops = { .hw_params = ad193x_hw_params, .digital_mute = ad193x_mute, .set_tdm_slot = ad193x_set_tdm_slot, @@ -345,7 +325,6 @@ static struct snd_soc_dai_driver ad193x_dai = { static int ad193x_probe(struct snd_soc_codec *codec) { struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; codec->control_data = ad193x->regmap; @@ -358,32 +337,37 @@ static int ad193x_probe(struct snd_soc_codec *codec) /* default setting for ad193x */ /* unmute dac channels */ - snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0); + regmap_write(ad193x->regmap, AD193X_DAC_CHNL_MUTE, 0x0); /* de-emphasis: 48kHz, powedown dac */ - snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A); + regmap_write(ad193x->regmap, AD193X_DAC_CTRL2, 0x1A); /* powerdown dac, dac in tdm mode */ - snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41); + regmap_write(ad193x->regmap, AD193X_DAC_CTRL0, 0x41); /* high-pass filter enable */ - snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3); + regmap_write(ad193x->regmap, AD193X_ADC_CTRL0, 0x3); /* sata delay=1, adc aux mode */ - snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43); + regmap_write(ad193x->regmap, AD193X_ADC_CTRL1, 0x43); /* pll input: mclki/xi */ - snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ - snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04); - - snd_soc_add_controls(codec, ad193x_snd_controls, - ARRAY_SIZE(ad193x_snd_controls)); - snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets, - ARRAY_SIZE(ad193x_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); + regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ + regmap_write(ad193x->regmap, AD193X_PLL_CLK_CTRL1, 0x04); return ret; } static struct snd_soc_codec_driver soc_codec_dev_ad193x = { .probe = ad193x_probe, + .controls = ad193x_snd_controls, + .num_controls = ARRAY_SIZE(ad193x_snd_controls), + .dapm_widgets = ad193x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ad193x_dapm_widgets), + .dapm_routes = audio_paths, + .num_dapm_routes = ARRAY_SIZE(audio_paths), }; +static bool adau193x_reg_volatile(struct device *dev, unsigned int reg) +{ + return false; +} + #if defined(CONFIG_SPI_MASTER) static const struct regmap_config ad193x_spi_regmap_config = { @@ -391,6 +375,9 @@ static const struct regmap_config ad193x_spi_regmap_config = { .reg_bits = 16, .read_flag_mask = 0x09, .write_flag_mask = 0x08, + + .max_register = AD193X_NUM_REGS - 1, + .volatile_reg = adau193x_reg_volatile, }; static int __devinit ad193x_spi_probe(struct spi_device *spi) @@ -398,14 +385,15 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi) struct ad193x_priv *ad193x; int ret; - ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL); + ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv), + GFP_KERNEL); if (ad193x == NULL) return -ENOMEM; ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config); if (IS_ERR(ad193x->regmap)) { ret = PTR_ERR(ad193x->regmap); - goto err_free; + goto err_out; } spi_set_drvdata(spi, ad193x); @@ -419,9 +407,7 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi) err_regmap_exit: regmap_exit(ad193x->regmap); -err_free: - kfree(ad193x); - +err_out: return ret; } @@ -431,7 +417,6 @@ static int __devexit ad193x_spi_remove(struct spi_device *spi) snd_soc_unregister_codec(&spi->dev); regmap_exit(ad193x->regmap); - kfree(ad193x); return 0; } @@ -450,6 +435,9 @@ static struct spi_driver ad193x_spi_driver = { static const struct regmap_config ad193x_i2c_regmap_config = { .val_bits = 8, .reg_bits = 8, + + .max_register = AD193X_NUM_REGS - 1, + .volatile_reg = adau193x_reg_volatile, }; static const struct i2c_device_id ad193x_id[] = { @@ -465,14 +453,15 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, struct ad193x_priv *ad193x; int ret; - ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL); + ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv), + GFP_KERNEL); if (ad193x == NULL) return -ENOMEM; ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config); if (IS_ERR(ad193x->regmap)) { ret = PTR_ERR(ad193x->regmap); - goto err_free; + goto err_out; } i2c_set_clientdata(client, ad193x); @@ -486,8 +475,7 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, err_regmap_exit: regmap_exit(ad193x->regmap); -err_free: - kfree(ad193x); +err_out: return ret; } @@ -497,7 +485,6 @@ static int __devexit ad193x_i2c_remove(struct i2c_client *client) snd_soc_unregister_codec(&client->dev); regmap_exit(ad193x->regmap); - kfree(ad193x); return 0; } diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index 1507eaa425a..47338804999 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h @@ -23,16 +23,14 @@ #define AD193X_DAC_SERFMT_STEREO (0 << 6) #define AD193X_DAC_SERFMT_TDM (1 << 6) #define AD193X_DAC_CTRL1 0x03 -#define AD193X_DAC_2_CHANNELS 0 -#define AD193X_DAC_4_CHANNELS 1 -#define AD193X_DAC_8_CHANNELS 2 -#define AD193X_DAC_16_CHANNELS 3 #define AD193X_DAC_CHAN_SHFT 1 #define AD193X_DAC_CHAN_MASK (3 << AD193X_DAC_CHAN_SHFT) #define AD193X_DAC_LCR_MASTER (1 << 4) #define AD193X_DAC_BCLK_MASTER (1 << 5) #define AD193X_DAC_LEFT_HIGH (1 << 3) #define AD193X_DAC_BCLK_INV (1 << 7) +#define AD193X_DAC_FMT_MASK (AD193X_DAC_LCR_MASTER | \ + AD193X_DAC_BCLK_MASTER | AD193X_DAC_LEFT_HIGH | AD193X_DAC_BCLK_INV) #define AD193X_DAC_CTRL2 0x04 #define AD193X_DAC_WORD_LEN_SHFT 3 #define AD193X_DAC_WORD_LEN_MASK 0x18 @@ -68,16 +66,19 @@ #define AD193X_ADC_SERFMT_AUX (2 << 5) #define AD193X_ADC_WORD_LEN_MASK 0x3 #define AD193X_ADC_CTRL2 0x10 -#define AD193X_ADC_2_CHANNELS 0 -#define AD193X_ADC_4_CHANNELS 1 -#define AD193X_ADC_8_CHANNELS 2 -#define AD193X_ADC_16_CHANNELS 3 #define AD193X_ADC_CHAN_SHFT 4 #define AD193X_ADC_CHAN_MASK (3 << AD193X_ADC_CHAN_SHFT) #define AD193X_ADC_LCR_MASTER (1 << 3) #define AD193X_ADC_BCLK_MASTER (1 << 6) #define AD193X_ADC_LEFT_HIGH (1 << 2) #define AD193X_ADC_BCLK_INV (1 << 1) +#define AD193X_ADC_FMT_MASK (AD193X_ADC_LCR_MASTER | \ + AD193X_ADC_BCLK_MASTER | AD193X_ADC_LEFT_HIGH | AD193X_ADC_BCLK_INV) + +#define AD193X_2_CHANNELS 0 +#define AD193X_4_CHANNELS 1 +#define AD193X_8_CHANNELS 2 +#define AD193X_16_CHANNELS 3 #define AD193X_NUM_REGS 17 diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index e3931cc5e66..9bba7f84946 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -277,17 +277,7 @@ static struct platform_driver ad1980_codec_driver = { .remove = __devexit_p(ad1980_remove), }; -static int __init ad1980_init(void) -{ - return platform_driver_register(&ad1980_codec_driver); -} -module_init(ad1980_init); - -static void __exit ad1980_exit(void) -{ - platform_driver_unregister(&ad1980_codec_driver); -} -module_exit(ad1980_exit); +module_platform_driver(ad1980_codec_driver); MODULE_DESCRIPTION("ASoC ad1980 driver (Obsolete)"); MODULE_AUTHOR("Roy Huang, Cliff Cai"); diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c index 8d793e993e9..ee7a68dcefd 100644 --- a/sound/soc/codecs/ad73311.c +++ b/sound/soc/codecs/ad73311.c @@ -63,17 +63,7 @@ static struct platform_driver ad73311_codec_driver = { .remove = __devexit_p(ad73311_remove), }; -static int __init ad73311_init(void) -{ - return platform_driver_register(&ad73311_codec_driver); -} -module_init(ad73311_init); - -static void __exit ad73311_exit(void) -{ - platform_driver_unregister(&ad73311_codec_driver); -} -module_exit(ad73311_exit); +module_platform_driver(ad73311_codec_driver); MODULE_DESCRIPTION("ASoC ad73311 driver"); MODULE_AUTHOR("Cliff Cai "); diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 1ccf8dd4757..971ba452917 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -245,7 +245,7 @@ static const char *adau1373_bass_hpf_cutoff_text[] = { }; static const unsigned int adau1373_bass_tlv[] = { - TLV_DB_RANGE_HEAD(4), + TLV_DB_RANGE_HEAD(3), 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), @@ -1321,7 +1321,7 @@ static int adau1373_remove(struct snd_soc_codec *codec) return 0; } -static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int adau1373_suspend(struct snd_soc_codec *codec) { return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); } @@ -1360,7 +1360,7 @@ static int __devinit adau1373_i2c_probe(struct i2c_client *client, struct adau1373 *adau1373; int ret; - adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL); + adau1373 = devm_kzalloc(&client->dev, sizeof(*adau1373), GFP_KERNEL); if (!adau1373) return -ENOMEM; @@ -1368,16 +1368,12 @@ static int __devinit adau1373_i2c_probe(struct i2c_client *client, ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver, adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver)); - if (ret < 0) - kfree(adau1373); - return ret; } static int __devexit adau1373_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(dev_get_drvdata(&client->dev)); return 0; } diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 8b7e1c50d6e..6b325ea0386 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -12,13 +12,13 @@ #include <linux/init.h> #include <linux/i2c.h> #include <linux/delay.h> -#include <linux/sigma.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include "sigmadsp.h" #include "adau1701.h" #define ADAU1701_DSPCTRL 0x1c @@ -496,23 +496,19 @@ static __devinit int adau1701_i2c_probe(struct i2c_client *client, struct adau1701 *adau1701; int ret; - adau1701 = kzalloc(sizeof(*adau1701), GFP_KERNEL); + adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); if (!adau1701) return -ENOMEM; i2c_set_clientdata(client, adau1701); ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, &adau1701_dai, 1); - if (ret < 0) - kfree(adau1701); - return ret; } static __devexit int adau1701_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index f9f08948e5e..ebd7b37b902 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -798,7 +798,7 @@ static int adav80x_probe(struct snd_soc_codec *codec) return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); } -static int adav80x_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int adav80x_suspend(struct snd_soc_codec *codec) { return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF); } diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c index 9082e0f729f..8103b938b8c 100644 --- a/sound/soc/codecs/ads117x.c +++ b/sound/soc/codecs/ads117x.c @@ -58,17 +58,7 @@ static struct platform_driver ads117x_codec_driver = { .remove = __devexit_p(ads117x_remove), }; -static int __init ads117x_init(void) -{ - return platform_driver_register(&ads117x_codec_driver); -} -module_init(ads117x_init); - -static void __exit ads117x_exit(void) -{ - platform_driver_unregister(&ads117x_codec_driver); -} -module_exit(ads117x_exit); +module_platform_driver(ads117x_codec_driver); MODULE_DESCRIPTION("ASoC ads117x driver"); MODULE_AUTHOR("Graeme Gregory"); diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index d3b29dce6ed..d27b5e4cce9 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c @@ -170,7 +170,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); } -static struct snd_soc_dai_ops ak4101_dai_ops = { +static const struct snd_soc_dai_ops ak4101_dai_ops = { .hw_params = ak4104_hw_params, .set_fmt = ak4104_set_dai_fmt, }; @@ -261,7 +261,8 @@ static int ak4104_spi_probe(struct spi_device *spi) if (ret < 0) return ret; - ak4104 = kzalloc(sizeof(struct ak4104_private), GFP_KERNEL); + ak4104 = devm_kzalloc(&spi->dev, sizeof(struct ak4104_private), + GFP_KERNEL); if (ak4104 == NULL) return -ENOMEM; @@ -271,15 +272,12 @@ static int ak4104_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_device_ak4104, &ak4104_dai, 1); - if (ret < 0) - kfree(ak4104); return ret; } static int __devexit ak4104_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 95d782d86e7..9e809e05d06 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -331,7 +330,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops ak4535_dai_ops = { +static const struct snd_soc_dai_ops ak4535_dai_ops = { .hw_params = ak4535_hw_params, .set_fmt = ak4535_set_dai_fmt, .digital_mute = ak4535_mute, @@ -355,7 +354,7 @@ static struct snd_soc_dai_driver ak4535_dai = { .ops = &ak4535_dai_ops, }; -static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int ak4535_suspend(struct snd_soc_codec *codec) { ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -417,7 +416,8 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, struct ak4535_priv *ak4535; int ret; - ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL); + ak4535 = devm_kzalloc(&i2c->dev, sizeof(struct ak4535_priv), + GFP_KERNEL); if (ak4535 == NULL) return -ENOMEM; @@ -426,15 +426,12 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4535, &ak4535_dai, 1); - if (ret < 0) - kfree(ak4535); return ret; } static __devexit int ak4535_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 77838586f35..c4d165a4bdd 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -17,7 +17,6 @@ #include <linux/gpio.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -340,6 +339,7 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, { struct snd_soc_codec *codec = codec_dai->codec; u8 btif; + int ret; /* interface format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -359,7 +359,11 @@ static int ak4641_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - return snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif); + ret = snd_soc_update_bits(codec, AK4641_BTIF, (0x3 << 5), btif); + if (ret < 0) + return ret; + + return 0; } static int ak4641_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, @@ -442,14 +446,14 @@ static int ak4641_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000) #define AK4641_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) -static struct snd_soc_dai_ops ak4641_i2s_dai_ops = { +static const struct snd_soc_dai_ops ak4641_i2s_dai_ops = { .hw_params = ak4641_i2s_hw_params, .set_fmt = ak4641_i2s_set_dai_fmt, .digital_mute = ak4641_mute, .set_sysclk = ak4641_set_dai_sysclk, }; -static struct snd_soc_dai_ops ak4641_pcm_dai_ops = { +static const struct snd_soc_dai_ops ak4641_pcm_dai_ops = { .hw_params = NULL, /* rates are controlled by BT chip */ .set_fmt = ak4641_pcm_set_dai_fmt, .digital_mute = ak4641_mute, @@ -499,7 +503,7 @@ static struct snd_soc_dai_driver ak4641_dai[] = { }, }; -static int ak4641_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int ak4641_suspend(struct snd_soc_codec *codec) { ak4641_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -603,7 +607,8 @@ static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, struct ak4641_priv *ak4641; int ret; - ak4641 = kzalloc(sizeof(struct ak4641_priv), GFP_KERNEL); + ak4641 = devm_kzalloc(&i2c->dev, sizeof(struct ak4641_priv), + GFP_KERNEL); if (!ak4641) return -ENOMEM; @@ -611,16 +616,12 @@ static int __devinit ak4641_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ak4641, ak4641_dai, ARRAY_SIZE(ak4641_dai)); - if (ret < 0) - kfree(ak4641); - return ret; } static int __devexit ak4641_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); return 0; } diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 12c1bdef673..5ef70b5d27e 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -18,21 +18,19 @@ * This is very simple driver. * It can use headphone output / stereo input only * - * AK4642 is not tested. + * AK4642 is tested. * AK4643 is tested. + * AK4648 is tested. */ #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/module.h> #include <sound/soc.h> #include <sound/initval.h> #include <sound/tlv.h> -#define AK4642_VERSION "0.0.1" - #define PW_MGMT1 0x00 #define PW_MGMT2 0x01 #define SG_SL1 0x02 @@ -71,8 +69,6 @@ #define HP_MS 0x23 #define SPK_MS 0x24 -#define AK4642_CACHEREGNUM 0x25 - /* PW_MGMT1*/ #define PMVCM (1 << 6) /* VCOM Power Management */ #define PMMIN (1 << 5) /* MIN Input Power Management */ @@ -150,8 +146,52 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, 0, 0xFF, 1, out_tlv), + + SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0), +}; + +static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = { + SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0), +}; + +static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { + SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), +}; + +static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { + + /* Outputs */ + SND_SOC_DAPM_OUTPUT("HPOUTL"), + SND_SOC_DAPM_OUTPUT("HPOUTR"), + SND_SOC_DAPM_OUTPUT("LINEOUT"), + + SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0, + &ak4642_hpout_mixer_controls[0], + ARRAY_SIZE(ak4642_hpout_mixer_controls)), + + SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0, + &ak4642_hpout_mixer_controls[0], + ARRAY_SIZE(ak4642_hpout_mixer_controls)), + + SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, + &ak4642_lout_mixer_controls[0], + ARRAY_SIZE(ak4642_lout_mixer_controls)), + + /* DAC */ + SND_SOC_DAPM_DAC("DAC", "HiFi Playback", PW_MGMT1, 2, 0), }; +static const struct snd_soc_dapm_route ak4642_intercon[] = { + + /* Outputs */ + {"HPOUTL", NULL, "HPOUTL Mixer"}, + {"HPOUTR", NULL, "HPOUTR Mixer"}, + {"LINEOUT", NULL, "LINEOUT Mixer"}, + + {"HPOUTL Mixer", "DACH", "DAC"}, + {"HPOUTR Mixer", "DACH", "DAC"}, + {"LINEOUT Mixer", "DACL", "DAC"}, +}; /* codec private data */ struct ak4642_priv { @@ -162,7 +202,7 @@ struct ak4642_priv { /* * ak4642 register cache */ -static const u8 ak4642_reg[AK4642_CACHEREGNUM] = { +static const u8 ak4642_reg[] = { 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe1, 0xe1, 0x18, 0x00, @@ -175,6 +215,19 @@ static const u8 ak4642_reg[AK4642_CACHEREGNUM] = { 0x00, }; +static const u8 ak4648_reg[] = { + 0x00, 0x00, 0x01, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0xe1, 0xe1, 0x18, 0x00, + 0xe1, 0x18, 0x11, 0xb8, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0x88, 0x08, +}; + static int ak4642_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -192,14 +245,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, * This operation came from example code of * "ASAHI KASEI AK4642" (japanese) manual p97. */ - snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); - snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); snd_soc_write(codec, L_IVC, 0x91); /* volume */ snd_soc_write(codec, R_IVC, 0x91); /* volume */ - snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, - PMVCM | PMMIN | PMDAC); - snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); - snd_soc_update_bits(codec, PW_MGMT2, HPMTN, HPMTN); } else { /* * start stereo input @@ -217,8 +264,7 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, snd_soc_write(codec, SG_SL1, PMMP | MGAIN0); snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); snd_soc_write(codec, ALC_CTL1, ALC | LMTH0); - snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, - PMVCM | PMADL); + snd_soc_update_bits(codec, PW_MGMT1, PMADL, PMADL); snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); } @@ -232,12 +278,6 @@ static void ak4642_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; if (is_play) { - /* stop headphone output */ - snd_soc_update_bits(codec, PW_MGMT2, HPMTN, 0); - snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0); - snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0); - snd_soc_update_bits(codec, MD_CTL3, BST1, 0); - snd_soc_update_bits(codec, MD_CTL4, DACH, 0); } else { /* stop stereo input */ snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0); @@ -376,7 +416,23 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops ak4642_dai_ops = { +static int ak4642_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_OFF: + snd_soc_write(codec, PW_MGMT1, 0x00); + break; + default: + snd_soc_update_bits(codec, PW_MGMT1, PMVCM, PMVCM); + break; + } + codec->dapm.bias_level = level; + + return 0; +} + +static const struct snd_soc_dai_ops ak4642_dai_ops = { .startup = ak4642_dai_startup, .shutdown = ak4642_dai_shutdown, .set_sysclk = ak4642_dai_set_sysclk, @@ -414,8 +470,6 @@ static int ak4642_probe(struct snd_soc_codec *codec) struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); int ret; - dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); - ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); if (ret < 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); @@ -425,15 +479,43 @@ static int ak4642_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ak4642_snd_controls, ARRAY_SIZE(ak4642_snd_controls)); + ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + return 0; +} + +static int ak4642_remove(struct snd_soc_codec *codec) +{ + ak4642_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; } static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { .probe = ak4642_probe, + .remove = ak4642_remove, + .resume = ak4642_resume, + .set_bias_level = ak4642_set_bias_level, + .reg_cache_default = ak4642_reg, /* ak4642 reg */ + .reg_cache_size = ARRAY_SIZE(ak4642_reg), /* ak4642 reg */ + .reg_word_size = sizeof(u8), + .dapm_widgets = ak4642_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), + .dapm_routes = ak4642_intercon, + .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), +}; + +static struct snd_soc_codec_driver soc_codec_dev_ak4648 = { + .probe = ak4642_probe, + .remove = ak4642_remove, .resume = ak4642_resume, - .reg_cache_size = ARRAY_SIZE(ak4642_reg), + .set_bias_level = ak4642_set_bias_level, + .reg_cache_default = ak4648_reg, /* ak4648 reg */ + .reg_cache_size = ARRAY_SIZE(ak4648_reg), /* ak4648 reg */ .reg_word_size = sizeof(u8), - .reg_cache_default = ak4642_reg, + .dapm_widgets = ak4642_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ak4642_dapm_widgets), + .dapm_routes = ak4642_intercon, + .num_dapm_routes = ARRAY_SIZE(ak4642_intercon), }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) @@ -443,7 +525,8 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, struct ak4642_priv *ak4642; int ret; - ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL); + ak4642 = devm_kzalloc(&i2c->dev, sizeof(struct ak4642_priv), + GFP_KERNEL); if (!ak4642) return -ENOMEM; @@ -451,22 +534,21 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, ak4642->control_type = SND_SOC_I2C; ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_ak4642, &ak4642_dai, 1); - if (ret < 0) - kfree(ak4642); + (struct snd_soc_codec_driver *)id->driver_data, + &ak4642_dai, 1); return ret; } static __devexit int ak4642_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } static const struct i2c_device_id ak4642_i2c_id[] = { - { "ak4642", 0 }, - { "ak4643", 0 }, + { "ak4642", (kernel_ulong_t)&soc_codec_dev_ak4642 }, + { "ak4643", (kernel_ulong_t)&soc_codec_dev_ak4642 }, + { "ak4648", (kernel_ulong_t)&soc_codec_dev_ak4648 }, { } }; MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index de9ff66d372..a53b152e6a0 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -594,7 +594,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec, #define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE -static struct snd_soc_dai_ops ak4671_dai_ops = { +static const struct snd_soc_dai_ops ak4671_dai_ops = { .hw_params = ak4671_hw_params, .set_sysclk = ak4671_set_dai_sysclk, .set_fmt = ak4671_set_dai_fmt, @@ -661,7 +661,8 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client, struct ak4671_priv *ak4671; int ret; - ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); + ak4671 = devm_kzalloc(&client->dev, sizeof(struct ak4671_priv), + GFP_KERNEL); if (ak4671 == NULL) return -ENOMEM; @@ -670,15 +671,12 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client, ret = snd_soc_register_codec(&client->dev, &soc_codec_dev_ak4671, &ak4671_dai, 1); - if (ret < 0) - kfree(ak4671); return ret; } static __devexit int ak4671_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 984b14bcb60..3feee569cee 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -22,7 +22,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/slab.h> -#include <linux/platform_device.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -100,7 +99,7 @@ static const unsigned int boost_tlv[] = { }; static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); -static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = { +static const struct snd_kcontrol_new alc5621_vol_snd_controls[] = { SOC_DOUBLE_TLV("Speaker Playback Volume", ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), SOC_DOUBLE("Speaker Playback Switch", @@ -111,7 +110,7 @@ static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = { ALC5623_HP_OUT_VOL, 15, 7, 1, 1), }; -static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = { +static const struct snd_kcontrol_new alc5622_vol_snd_controls[] = { SOC_DOUBLE_TLV("Speaker Playback Volume", ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), SOC_DOUBLE("Speaker Playback Switch", @@ -839,7 +838,7 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec, | SNDRV_PCM_FMTBIT_S24_LE \ | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops alc5623_dai_ops = { +static const struct snd_soc_dai_ops alc5623_dai_ops = { .hw_params = alc5623_pcm_hw_params, .digital_mute = alc5623_mute, .set_fmt = alc5623_set_dai_fmt, @@ -869,7 +868,7 @@ static struct snd_soc_dai_driver alc5623_dai = { .ops = &alc5623_dai_ops, }; -static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg) +static int alc5623_suspend(struct snd_soc_codec *codec) { alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -926,12 +925,12 @@ static int alc5623_probe(struct snd_soc_codec *codec) switch (alc5623->id) { case 0x21: - snd_soc_add_controls(codec, rt5621_vol_snd_controls, - ARRAY_SIZE(rt5621_vol_snd_controls)); + snd_soc_add_controls(codec, alc5621_vol_snd_controls, + ARRAY_SIZE(alc5621_vol_snd_controls)); break; case 0x22: - snd_soc_add_controls(codec, rt5622_vol_snd_controls, - ARRAY_SIZE(rt5622_vol_snd_controls)); + snd_soc_add_controls(codec, alc5622_vol_snd_controls, + ARRAY_SIZE(alc5622_vol_snd_controls)); break; case 0x23: snd_soc_add_controls(codec, alc5623_vol_snd_controls, @@ -1023,7 +1022,8 @@ static int alc5623_i2c_probe(struct i2c_client *client, dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); - alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL); + alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), + GFP_KERNEL); if (alc5623 == NULL) return -ENOMEM; @@ -1045,7 +1045,6 @@ static int alc5623_i2c_probe(struct i2c_client *client, alc5623_dai.name = "alc5623-hifi"; break; default: - kfree(alc5623); return -EINVAL; } @@ -1054,20 +1053,15 @@ static int alc5623_i2c_probe(struct i2c_client *client, ret = snd_soc_register_codec(&client->dev, &soc_codec_device_alc5623, &alc5623_dai, 1); - if (ret != 0) { + if (ret != 0) dev_err(&client->dev, "Failed to register codec: %d\n", ret); - kfree(alc5623); - } return ret; } static int alc5623_i2c_remove(struct i2c_client *client) { - struct alc5623_priv *alc5623 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - kfree(alc5623); return 0; } diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c new file mode 100644 index 00000000000..390e437d7c5 --- /dev/null +++ b/sound/soc/codecs/alc5632.c @@ -0,0 +1,1159 @@ +/* +* alc5632.c -- ALC5632 ALSA SoC Audio Codec +* +* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> +* +* Authors: Leon Romanovsky <leon@leon.nu> +* Andrey Danin <danindrey@mail.ru> +* Ilya Petrov <ilya.muromec@gmail.com> +* Marc Dietrich <marvin24@gmx.de> +* +* Based on alc5623.c by Arnaud Patard +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/regmap.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/tlv.h> +#include <sound/soc.h> +#include <sound/initval.h> + +#include "alc5632.h" + +/* + * ALC5632 register cache + */ +static struct reg_default alc5632_reg_defaults[] = { + { 2, 0x8080 }, /* R2 - Speaker Output Volume */ + { 4, 0x8080 }, /* R4 - Headphone Output Volume */ + { 6, 0x8080 }, /* R6 - AUXOUT Volume */ + { 8, 0xC800 }, /* R8 - Phone Input */ + { 10, 0xE808 }, /* R10 - LINE_IN Volume */ + { 12, 0x1010 }, /* R12 - STEREO DAC Input Volume */ + { 14, 0x0808 }, /* R14 - MIC Input Volume */ + { 16, 0xEE0F }, /* R16 - Stereo DAC and MIC Routing Control */ + { 18, 0xCBCB }, /* R18 - ADC Record Gain */ + { 20, 0x7F7F }, /* R20 - ADC Record Mixer Control */ + { 24, 0xE010 }, /* R24 - Voice DAC Volume */ + { 28, 0x8008 }, /* R28 - Output Mixer Control */ + { 34, 0x0000 }, /* R34 - Microphone Control */ + { 36, 0x00C0 }, /* R36 - Codec Digital MIC/Digital Boost + Control */ + { 46, 0x0000 }, /* R46 - Stereo DAC/Voice DAC/Stereo ADC + Function Select */ + { 52, 0x8000 }, /* R52 - Main Serial Data Port Control + (Stereo I2S) */ + { 54, 0x0000 }, /* R54 - Extend Serial Data Port Control + (VoDAC_I2S/PCM) */ + { 58, 0x0000 }, /* R58 - Power Management Addition 1 */ + { 60, 0x0000 }, /* R60 - Power Management Addition 2 */ + { 62, 0x8000 }, /* R62 - Power Management Addition 3 */ + { 64, 0x0C0A }, /* R64 - General Purpose Control Register 1 */ + { 66, 0x0000 }, /* R66 - General Purpose Control Register 2 */ + { 68, 0x0000 }, /* R68 - PLL1 Control */ + { 70, 0x0000 }, /* R70 - PLL2 Control */ + { 76, 0xBE3E }, /* R76 - GPIO Pin Configuration */ + { 78, 0xBE3E }, /* R78 - GPIO Pin Polarity */ + { 80, 0x0000 }, /* R80 - GPIO Pin Sticky */ + { 82, 0x0000 }, /* R82 - GPIO Pin Wake Up */ + { 86, 0x0000 }, /* R86 - Pin Sharing */ + { 90, 0x0009 }, /* R90 - Soft Volume Control Setting */ + { 92, 0x0000 }, /* R92 - GPIO_Output Pin Control */ + { 94, 0x3000 }, /* R94 - MISC Control */ + { 96, 0x3075 }, /* R96 - Stereo DAC Clock Control_1 */ + { 98, 0x1010 }, /* R98 - Stereo DAC Clock Control_2 */ + { 100, 0x3110 }, /* R100 - VoDAC_PCM Clock Control_1 */ + { 104, 0x0553 }, /* R104 - Pseudo Stereo and Spatial Effect + Block Control */ + { 106, 0x0000 }, /* R106 - Private Register Address */ +}; + +/* codec private data */ +struct alc5632_priv { + struct regmap *regmap; + u8 id; + unsigned int sysclk; +}; + +static bool alc5632_volatile_register(struct device *dev, + unsigned int reg) +{ + switch (reg) { + case ALC5632_RESET: + case ALC5632_PWR_DOWN_CTRL_STATUS: + case ALC5632_GPIO_PIN_STATUS: + case ALC5632_OVER_CURR_STATUS: + case ALC5632_HID_CTRL_DATA: + case ALC5632_EQ_CTRL: + case ALC5632_VENDOR_ID1: + case ALC5632_VENDOR_ID2: + return true; + + default: + break; + } + + return false; +} + +static inline int alc5632_reset(struct regmap *map) +{ + return regmap_write(map, ALC5632_RESET, 0x59B4); +} + +static int amp_mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + /* to power-on/off class-d amp generators/speaker */ + /* need to write to 'index-46h' register : */ + /* so write index num (here 0x46) to reg 0x6a */ + /* and then 0xffff/0 to reg 0x6c */ + snd_soc_write(w->codec, ALC5632_HID_CTRL_INDEX, 0x46); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0xFFFF); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_write(w->codec, ALC5632_HID_CTRL_DATA, 0); + break; + } + + return 0; +} + +/* + * ALC5632 Controls + */ + +/* -34.5db min scale, 1.5db steps, no mute */ +static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0); +/* -46.5db min scale, 1.5db steps, no mute */ +static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); +/* -16.5db min scale, 1.5db steps, no mute */ +static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); +static const unsigned int boost_tlv[] = { + TLV_DB_RANGE_HEAD(3), + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), +}; +/* 0db min scale, 6 db steps, no mute */ +static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); +/* 0db min scalem 0.75db steps, no mute */ +static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); + +static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { + /* left starts at bit 8, right at bit 0 */ + /* 31 steps (5 bit), -46.5db scale */ + SOC_DOUBLE_TLV("Speaker Playback Volume", + ALC5632_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + /* bit 15 mutes left, bit 7 right */ + SOC_DOUBLE("Speaker Playback Switch", + ALC5632_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Headphone Playback Volume", + ALC5632_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Headphone Playback Switch", + ALC5632_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new alc5632_snd_controls[] = { + SOC_DOUBLE_TLV("Auxout Playback Volume", + ALC5632_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Auxout Playback Switch", + ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), + SOC_SINGLE_TLV("Voice DAC Playback Volume", + ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), + SOC_SINGLE_TLV("Phone Capture Volume", + ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("LineIn Capture Volume", + ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("Master Playback Volume", + ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), + SOC_DOUBLE("Master Playback Switch", + ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), + SOC_SINGLE_TLV("Mic1 Capture Volume", + ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), + SOC_SINGLE_TLV("Mic2 Capture Volume", + ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("Rec Capture Volume", + ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), + SOC_SINGLE_TLV("Mic 1 Boost Volume", + ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Mic 2 Boost Volume", + ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Digital Boost Volume", + ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), +}; + +/* + * DAPM Controls + */ +static const struct snd_kcontrol_new alc5632_hp_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5632_LINE_IN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("PHONE2HP Playback Switch", ALC5632_PHONE_IN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 11, 1, 1), +SOC_DAPM_SINGLE("VOICE2HP Playback Switch", ALC5632_VOICE_DAC_VOL, 15, 1, 1), +}; + +static const struct snd_kcontrol_new alc5632_hpl_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5632_ADC_REC_GAIN, 15, 1, 1), +SOC_DAPM_SINGLE("DACL2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 3, 1, 1), +}; + +static const struct snd_kcontrol_new alc5632_hpr_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5632_ADC_REC_GAIN, 7, 1, 1), +SOC_DAPM_SINGLE("DACR2HP Playback Switch", ALC5632_MIC_ROUTING_CTRL, 2, 1, 1), +}; + +static const struct snd_kcontrol_new alc5632_mono_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5632_ADC_REC_GAIN, 14, 1, 1), +SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5632_ADC_REC_GAIN, 6, 1, 1), +SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5632_LINE_IN_VOL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC12MONO Playback Switch", + ALC5632_MIC_ROUTING_CTRL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC22MONO Playback Switch", + ALC5632_MIC_ROUTING_CTRL, 9, 1, 1), +SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5632_MIC_ROUTING_CTRL, 0, 1, 1), +SOC_DAPM_SINGLE("VOICE2MONO Playback Switch", ALC5632_VOICE_DAC_VOL, 13, 1, 1), +}; + +static const struct snd_kcontrol_new alc5632_speaker_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5632_LINE_IN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("PHONE2SPK Playback Switch", ALC5632_PHONE_IN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC12SPK Playback Switch", + ALC5632_MIC_ROUTING_CTRL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC22SPK Playback Switch", + ALC5632_MIC_ROUTING_CTRL, 10, 1, 1), +SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5632_MIC_ROUTING_CTRL, 1, 1, 1), +SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1), +}; + +/* Left Record Mixer */ +static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), +SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), +SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), +SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), +}; + +/* Right Record Mixer */ +static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), +SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), +SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), +SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), +}; + +static const char *alc5632_spk_n_sour_sel[] = { + "RN/-R", "RP/+R", "LN/-R", "Mute"}; +static const char *alc5632_hpl_out_input_sel[] = { + "Vmid", "HP Left Mix"}; +static const char *alc5632_hpr_out_input_sel[] = { + "Vmid", "HP Right Mix"}; +static const char *alc5632_spkout_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; +static const char *alc5632_aux_out_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; + +/* auxout output mux */ +static const struct soc_enum alc5632_aux_out_input_enum = +SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 6, 4, alc5632_aux_out_input_sel); +static const struct snd_kcontrol_new alc5632_auxout_mux_controls = +SOC_DAPM_ENUM("AuxOut Mux", alc5632_aux_out_input_enum); + +/* speaker output mux */ +static const struct soc_enum alc5632_spkout_input_enum = +SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 10, 4, alc5632_spkout_input_sel); +static const struct snd_kcontrol_new alc5632_spkout_mux_controls = +SOC_DAPM_ENUM("SpeakerOut Mux", alc5632_spkout_input_enum); + +/* headphone left output mux */ +static const struct soc_enum alc5632_hpl_out_input_enum = +SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 9, 2, alc5632_hpl_out_input_sel); +static const struct snd_kcontrol_new alc5632_hpl_out_mux_controls = +SOC_DAPM_ENUM("Left Headphone Mux", alc5632_hpl_out_input_enum); + +/* headphone right output mux */ +static const struct soc_enum alc5632_hpr_out_input_enum = +SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 8, 2, alc5632_hpr_out_input_sel); +static const struct snd_kcontrol_new alc5632_hpr_out_mux_controls = +SOC_DAPM_ENUM("Right Headphone Mux", alc5632_hpr_out_input_enum); + +/* speaker output N select */ +static const struct soc_enum alc5632_spk_n_sour_enum = +SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 14, 4, alc5632_spk_n_sour_sel); +static const struct snd_kcontrol_new alc5632_spkoutn_mux_controls = +SOC_DAPM_ENUM("SpeakerOut N Mux", alc5632_spk_n_sour_enum); + +/* speaker amplifier */ +static const char *alc5632_amp_names[] = {"AB Amp", "D Amp"}; +static const struct soc_enum alc5632_amp_enum = + SOC_ENUM_SINGLE(ALC5632_OUTPUT_MIXER_CTRL, 13, 2, alc5632_amp_names); +static const struct snd_kcontrol_new alc5632_amp_mux_controls = + SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); + + +static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { +/* Muxes */ +SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0, + &alc5632_auxout_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0, + &alc5632_spkout_mux_controls), +SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5632_hpl_out_mux_controls), +SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5632_hpr_out_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, + &alc5632_spkoutn_mux_controls), + +/* output mixers */ +SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, + &alc5632_hp_mixer_controls[0], + ARRAY_SIZE(alc5632_hp_mixer_controls)), +SND_SOC_DAPM_MIXER("HPR Mix", ALC5632_PWR_MANAG_ADD2, 4, 0, + &alc5632_hpr_mixer_controls[0], + ARRAY_SIZE(alc5632_hpr_mixer_controls)), +SND_SOC_DAPM_MIXER("HPL Mix", ALC5632_PWR_MANAG_ADD2, 5, 0, + &alc5632_hpl_mixer_controls[0], + ARRAY_SIZE(alc5632_hpl_mixer_controls)), +SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0, + &alc5632_mono_mixer_controls[0], + ARRAY_SIZE(alc5632_mono_mixer_controls)), +SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, + &alc5632_speaker_mixer_controls[0], + ARRAY_SIZE(alc5632_speaker_mixer_controls)), + +/* input mixers */ +SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, + &alc5632_captureL_mixer_controls[0], + ARRAY_SIZE(alc5632_captureL_mixer_controls)), +SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0, + &alc5632_captureR_mixer_controls[0], + ARRAY_SIZE(alc5632_captureR_mixer_controls)), + +SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", + ALC5632_PWR_MANAG_ADD2, 9, 0), +SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", + ALC5632_PWR_MANAG_ADD2, 8, 0), +SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), +SND_SOC_DAPM_MIXER("DAC Right Channel", + ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), +SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", + ALC5632_PWR_MANAG_ADD2, 7, 0), +SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", + ALC5632_PWR_MANAG_ADD2, 6, 0), +SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Speaker", ALC5632_PWR_MANAG_ADD3, 12, 0, NULL, 0), +SND_SOC_DAPM_PGA("Aux Out", ALC5632_PWR_MANAG_ADD3, 14, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left LineIn", ALC5632_PWR_MANAG_ADD3, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right LineIn", ALC5632_PWR_MANAG_ADD3, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("Phone", ALC5632_PWR_MANAG_ADD3, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("Phone ADMix", ALC5632_PWR_MANAG_ADD3, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 PGA", ALC5632_PWR_MANAG_ADD3, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 PGA", ALC5632_PWR_MANAG_ADD3, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5632_PWR_MANAG_ADD3, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5632_PWR_MANAG_ADD3, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS1", ALC5632_PWR_MANAG_ADD1, 3, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS2", ALC5632_PWR_MANAG_ADD1, 2, 0, NULL, 0), + +SND_SOC_DAPM_PGA_E("D Amp", ALC5632_PWR_MANAG_ADD2, 14, 0, NULL, 0, + amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_PGA("AB Amp", ALC5632_PWR_MANAG_ADD2, 15, 0, NULL, 0), +SND_SOC_DAPM_MUX("AB-D Amp Mux", ALC5632_PWR_MANAG_ADD1, 10, 0, + &alc5632_amp_mux_controls), + +SND_SOC_DAPM_OUTPUT("AUXOUT"), +SND_SOC_DAPM_OUTPUT("HPL"), +SND_SOC_DAPM_OUTPUT("HPR"), +SND_SOC_DAPM_OUTPUT("SPKOUT"), +SND_SOC_DAPM_OUTPUT("SPKOUTN"), +SND_SOC_DAPM_INPUT("LINEINL"), +SND_SOC_DAPM_INPUT("LINEINR"), +SND_SOC_DAPM_INPUT("PHONEP"), +SND_SOC_DAPM_INPUT("PHONEN"), +SND_SOC_DAPM_INPUT("MIC1"), +SND_SOC_DAPM_INPUT("MIC2"), +SND_SOC_DAPM_VMID("Vmid"), +}; + + +static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { + /* virtual mixer - mixes left & right channels */ + {"I2S Mix", NULL, "Left DAC"}, + {"I2S Mix", NULL, "Right DAC"}, + {"Line Mix", NULL, "Right LineIn"}, + {"Line Mix", NULL, "Left LineIn"}, + {"Phone Mix", NULL, "Phone"}, + {"Phone Mix", NULL, "Phone ADMix"}, + {"AUXOUT", NULL, "Aux Out"}, + + /* DAC */ + {"DAC Right Channel", NULL, "I2S Mix"}, + {"DAC Left Channel", NULL, "I2S Mix"}, + + /* HP mixer */ + {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"}, + {"HPL Mix", NULL, "HP Mix"}, + {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"}, + {"HPR Mix", NULL, "HP Mix"}, + {"HP Mix", "LI2HP Playback Switch", "Line Mix"}, + {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, + {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, + {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, + + {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, + {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, + + /* speaker mixer */ + {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, + {"Speaker Mix", "PHONE2SPK Playback Switch", "Phone Mix"}, + {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, + {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, + {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, + + + + /* mono mixer */ + {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, + {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, + {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, + {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"}, + {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, + {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, + {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, + + /* Left record mixer */ + {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, + {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, + {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, + {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /*Right record mixer */ + {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, + {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, + {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, + {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /* headphone left mux */ + {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, + {"Left Headphone Mux", "Vmid", "Vmid"}, + + /* headphone right mux */ + {"Right Headphone Mux", "HP Right Mix", "HPR Mix"}, + {"Right Headphone Mux", "Vmid", "Vmid"}, + + /* speaker out mux */ + {"SpeakerOut Mux", "Vmid", "Vmid"}, + {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"}, + {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"}, + {"SpeakerOut Mux", "Mono Mix", "Mono Mix"}, + + /* Mono/Aux Out mux */ + {"AuxOut Mux", "Vmid", "Vmid"}, + {"AuxOut Mux", "HPOut Mix", "HPOut Mix"}, + {"AuxOut Mux", "Speaker Mix", "Speaker Mix"}, + {"AuxOut Mux", "Mono Mix", "Mono Mix"}, + + /* output pga */ + {"HPL", NULL, "Left Headphone"}, + {"Left Headphone", NULL, "Left Headphone Mux"}, + {"HPR", NULL, "Right Headphone"}, + {"Right Headphone", NULL, "Right Headphone Mux"}, + {"Aux Out", NULL, "AuxOut Mux"}, + + /* input pga */ + {"Left LineIn", NULL, "LINEINL"}, + {"Right LineIn", NULL, "LINEINR"}, + {"Phone", NULL, "PHONEP"}, + {"MIC1 Pre Amp", NULL, "MIC1"}, + {"MIC2 Pre Amp", NULL, "MIC2"}, + {"MIC1 PGA", NULL, "MIC1 Pre Amp"}, + {"MIC2 PGA", NULL, "MIC2 Pre Amp"}, + + /* left ADC */ + {"Left ADC", NULL, "Left Capture Mix"}, + + /* right ADC */ + {"Right ADC", NULL, "Right Capture Mix"}, + + {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, + {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, + {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, + {"SpeakerOut N Mux", "Mute", "Vmid"}, + + {"SpeakerOut N Mux", "RN/-R", "Right Speaker"}, + {"SpeakerOut N Mux", "RP/+R", "Right Speaker"}, + {"SpeakerOut N Mux", "LN/-R", "Right Speaker"}, + {"SpeakerOut N Mux", "Mute", "Vmid"}, + + {"AB Amp", NULL, "SpeakerOut Mux"}, + {"D Amp", NULL, "SpeakerOut Mux"}, + {"AB-D Amp Mux", "AB Amp", "AB Amp"}, + {"AB-D Amp Mux", "D Amp", "D Amp"}, + {"Left Speaker", NULL, "AB-D Amp Mux"}, + {"Right Speaker", NULL, "AB-D Amp Mux"}, + + {"SPKOUT", NULL, "Left Speaker"}, + {"SPKOUT", NULL, "Right Speaker"}, + + {"SPKOUTN", NULL, "SpeakerOut N Mux"}, + +}; + +/* PLL divisors */ +struct _pll_div { + u32 pll_in; + u32 pll_out; + u16 regvalue; +}; + +/* Note : pll code from original alc5632 driver. Not sure of how good it is */ +/* usefull only for master mode */ +static const struct _pll_div codec_master_pll_div[] = { + + { 2048000, 8192000, 0x0ea0}, + { 3686400, 8192000, 0x4e27}, + { 12000000, 8192000, 0x456b}, + { 13000000, 8192000, 0x495f}, + { 13100000, 8192000, 0x0320}, + { 2048000, 11289600, 0xf637}, + { 3686400, 11289600, 0x2f22}, + { 12000000, 11289600, 0x3e2f}, + { 13000000, 11289600, 0x4d5b}, + { 13100000, 11289600, 0x363b}, + { 2048000, 16384000, 0x1ea0}, + { 3686400, 16384000, 0x9e27}, + { 12000000, 16384000, 0x452b}, + { 13000000, 16384000, 0x542f}, + { 13100000, 16384000, 0x03a0}, + { 2048000, 16934400, 0xe625}, + { 3686400, 16934400, 0x9126}, + { 12000000, 16934400, 0x4d2c}, + { 13000000, 16934400, 0x742f}, + { 13100000, 16934400, 0x3c27}, + { 2048000, 22579200, 0x2aa0}, + { 3686400, 22579200, 0x2f20}, + { 12000000, 22579200, 0x7e2f}, + { 13000000, 22579200, 0x742f}, + { 13100000, 22579200, 0x3c27}, + { 2048000, 24576000, 0x2ea0}, + { 3686400, 24576000, 0xee27}, + { 12000000, 24576000, 0x2915}, + { 13000000, 24576000, 0x772e}, + { 13100000, 24576000, 0x0d20}, +}; + +/* FOUT = MCLK*(N+2)/((M+2)*(K+2)) + N: bit 15:8 (div 2 .. div 257) + K: bit 6:4 typical 2 + M: bit 3:0 (div 2 .. div 17) + + same as for 5623 - thanks! +*/ + +static const struct _pll_div codec_slave_pll_div[] = { + + { 1024000, 16384000, 0x3ea0}, + { 1411200, 22579200, 0x3ea0}, + { 1536000, 24576000, 0x3ea0}, + { 2048000, 16384000, 0x1ea0}, + { 2822400, 22579200, 0x1ea0}, + { 3072000, 24576000, 0x1ea0}, + +}; + +static int alc5632_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + int i; + struct snd_soc_codec *codec = codec_dai->codec; + int gbl_clk = 0, pll_div = 0; + u16 reg; + + if (pll_id < ALC5632_PLL_FR_MCLK || pll_id > ALC5632_PLL_FR_VBCLK) + return -EINVAL; + + /* Disable PLL power */ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_ADD2_PLL1, + 0); + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_ADD2_PLL2, + 0); + + /* pll is not used in slave mode */ + reg = snd_soc_read(codec, ALC5632_DAI_CONTROL); + if (reg & ALC5632_DAI_SDP_SLAVE_MODE) + return 0; + + if (!freq_in || !freq_out) + return 0; + + switch (pll_id) { + case ALC5632_PLL_FR_MCLK: + for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) { + if (codec_master_pll_div[i].pll_in == freq_in + && codec_master_pll_div[i].pll_out == freq_out) { + /* PLL source from MCLK */ + pll_div = codec_master_pll_div[i].regvalue; + break; + } + } + break; + case ALC5632_PLL_FR_BCLK: + for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { + if (codec_slave_pll_div[i].pll_in == freq_in + && codec_slave_pll_div[i].pll_out == freq_out) { + /* PLL source from Bitclk */ + gbl_clk = ALC5632_PLL_FR_BCLK; + pll_div = codec_slave_pll_div[i].regvalue; + break; + } + } + break; + case ALC5632_PLL_FR_VBCLK: + for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { + if (codec_slave_pll_div[i].pll_in == freq_in + && codec_slave_pll_div[i].pll_out == freq_out) { + /* PLL source from voice clock */ + gbl_clk = ALC5632_PLL_FR_VBCLK; + pll_div = codec_slave_pll_div[i].regvalue; + break; + } + } + break; + default: + return -EINVAL; + } + + if (!pll_div) + return -EINVAL; + + /* choose MCLK/BCLK/VBCLK */ + snd_soc_write(codec, ALC5632_GPCR2, gbl_clk); + /* choose PLL1 clock rate */ + snd_soc_write(codec, ALC5632_PLL1_CTRL, pll_div); + /* enable PLL1 */ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_ADD2_PLL1, + ALC5632_PWR_ADD2_PLL1); + /* enable PLL2 */ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_ADD2_PLL2, + ALC5632_PWR_ADD2_PLL2); + /* use PLL1 as main SYSCLK */ + snd_soc_update_bits(codec, ALC5632_GPCR1, + ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1, + ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1); + + return 0; +} + +struct _coeff_div { + u16 fs; + u16 regvalue; +}; + +/* codec hifi mclk (after PLL) clock divider coefficients */ +/* values inspired from column BCLK=32Fs of Appendix A table */ +static const struct _coeff_div coeff_div[] = { + {512*1, 0x3075}, +}; + +static int get_coeff(struct snd_soc_codec *codec, int rate) +{ + struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].fs * rate == alc5632->sysclk) + return i; + } + return -EINVAL; +} + +/* + * Clock after PLL and dividers + */ +static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); + + switch (freq) { + case 8192000: + case 11289600: + case 12288000: + case 16384000: + case 16934400: + case 18432000: + case 22579200: + case 24576000: + alc5632->sysclk = freq; + return 0; + } + return -EINVAL; +} + +static int alc5632_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iface = ALC5632_DAI_SDP_MASTER_MODE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iface = ALC5632_DAI_SDP_SLAVE_MODE; + break; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= ALC5632_DAI_I2S_DF_I2S; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= ALC5632_DAI_I2S_DF_LEFT; + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= ALC5632_DAI_I2S_DF_PCM_A; + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= ALC5632_DAI_I2S_DF_PCM_B; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_NB_IF: + break; + default: + return -EINVAL; + } + + return snd_soc_write(codec, ALC5632_DAI_CONTROL, iface); +} + +static int alc5632_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + int coeff, rate; + u16 iface; + + iface = snd_soc_read(codec, ALC5632_DAI_CONTROL); + iface &= ~ALC5632_DAI_I2S_DL_MASK; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + iface |= ALC5632_DAI_I2S_DL_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= ALC5632_DAI_I2S_DL_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= ALC5632_DAI_I2S_DL_24; + break; + default: + return -EINVAL; + } + + /* set iface & srate */ + snd_soc_write(codec, ALC5632_DAI_CONTROL, iface); + rate = params_rate(params); + coeff = get_coeff(codec, rate); + if (coeff < 0) + return -EINVAL; + + coeff = coeff_div[coeff].regvalue; + snd_soc_write(codec, ALC5632_DAC_CLK_CTRL1, coeff); + + return 0; +} + +static int alc5632_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 hp_mute = ALC5632_MISC_HP_DEPOP_MUTE_L + |ALC5632_MISC_HP_DEPOP_MUTE_R; + u16 mute_reg = snd_soc_read(codec, ALC5632_MISC_CTRL) & ~hp_mute; + + if (mute) + mute_reg |= hp_mute; + + return snd_soc_write(codec, ALC5632_MISC_CTRL, mute_reg); +} + +#define ALC5632_ADD2_POWER_EN (ALC5632_PWR_ADD2_VREF) + +#define ALC5632_ADD3_POWER_EN (ALC5632_PWR_ADD3_MIC1_BOOST_AD) + +#define ALC5632_ADD1_POWER_EN \ + (ALC5632_PWR_ADD1_DAC_REF \ + | ALC5632_PWR_ADD1_SOFTGEN_EN \ + | ALC5632_PWR_ADD1_HP_OUT_AMP \ + | ALC5632_PWR_ADD1_HP_OUT_ENH_AMP \ + | ALC5632_PWR_ADD1_MAIN_BIAS) + +static void enable_power_depop(struct snd_soc_codec *codec) +{ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1, + ALC5632_PWR_ADD1_SOFTGEN_EN, + ALC5632_PWR_ADD1_SOFTGEN_EN); + + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3, + ALC5632_ADD3_POWER_EN, + ALC5632_ADD3_POWER_EN); + + snd_soc_update_bits(codec, ALC5632_MISC_CTRL, + ALC5632_MISC_HP_DEPOP_MODE2_EN, + ALC5632_MISC_HP_DEPOP_MODE2_EN); + + /* "normal" mode: 0 @ 26 */ + /* set all PR0-7 mixers to 0 */ + snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS, + ALC5632_PWR_DOWN_CTRL_STATUS_MASK, + 0); + + msleep(500); + + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_ADD2_POWER_EN, + ALC5632_ADD2_POWER_EN); + + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1, + ALC5632_ADD1_POWER_EN, + ALC5632_ADD1_POWER_EN); + + /* disable HP Depop2 */ + snd_soc_update_bits(codec, ALC5632_MISC_CTRL, + ALC5632_MISC_HP_DEPOP_MODE2_EN, + 0); + +} + +static int alc5632_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + enable_power_depop(codec); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + /* everything off except vref/vmid, */ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1, + ALC5632_PWR_MANAG_ADD1_MASK, + ALC5632_PWR_ADD1_MAIN_BIAS); + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_MANAG_ADD2_MASK, + ALC5632_PWR_ADD2_VREF); + /* "normal" mode: 0 @ 26 */ + snd_soc_update_bits(codec, ALC5632_PWR_DOWN_CTRL_STATUS, + ALC5632_PWR_DOWN_CTRL_STATUS_MASK, + 0xffff ^ (ALC5632_PWR_VREF_PR3 + | ALC5632_PWR_VREF_PR2)); + break; + case SND_SOC_BIAS_OFF: + /* everything off, dac mute, inactive */ + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD2, + ALC5632_PWR_MANAG_ADD2_MASK, 0); + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD3, + ALC5632_PWR_MANAG_ADD3_MASK, 0); + snd_soc_update_bits(codec, ALC5632_PWR_MANAG_ADD1, + ALC5632_PWR_MANAG_ADD1_MASK, 0); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +#define ALC5632_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +static const struct snd_soc_dai_ops alc5632_dai_ops = { + .hw_params = alc5632_pcm_hw_params, + .digital_mute = alc5632_mute, + .set_fmt = alc5632_set_dai_fmt, + .set_sysclk = alc5632_set_dai_sysclk, + .set_pll = alc5632_set_dai_pll, +}; + +static struct snd_soc_dai_driver alc5632_dai = { + .name = "alc5632-hifi", + .playback = { + .stream_name = "HiFi Playback", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5632_FORMATS,}, + .capture = { + .stream_name = "HiFi Capture", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5632_FORMATS,}, + + .ops = &alc5632_dai_ops, + .symmetric_rates = 1, +}; + +#ifdef CONFIG_PM +static int alc5632_suspend(struct snd_soc_codec *codec) +{ + alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int alc5632_resume(struct snd_soc_codec *codec) +{ + struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); + + regcache_sync(alc5632->regmap); + + alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define alc5632_suspend NULL +#define alc5632_resume NULL +#endif + +static int alc5632_probe(struct snd_soc_codec *codec) +{ + struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); + int ret; + + codec->control_data = alc5632->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + /* power on device */ + alc5632_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + switch (alc5632->id) { + case 0x5c: + snd_soc_add_controls(codec, alc5632_vol_snd_controls, + ARRAY_SIZE(alc5632_vol_snd_controls)); + break; + default: + return -EINVAL; + } + + return ret; +} + +/* power down chip */ +static int alc5632_remove(struct snd_soc_codec *codec) +{ + alc5632_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_device_alc5632 = { + .probe = alc5632_probe, + .remove = alc5632_remove, + .suspend = alc5632_suspend, + .resume = alc5632_resume, + .set_bias_level = alc5632_set_bias_level, + .controls = alc5632_snd_controls, + .num_controls = ARRAY_SIZE(alc5632_snd_controls), + .dapm_widgets = alc5632_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(alc5632_dapm_widgets), + .dapm_routes = alc5632_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(alc5632_dapm_routes), +}; + +static struct regmap_config alc5632_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = ALC5632_MAX_REGISTER, + .reg_defaults = alc5632_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(alc5632_reg_defaults), + .volatile_reg = alc5632_volatile_register, + .cache_type = REGCACHE_RBTREE, +}; + +/* + * alc5632 2 wire address is determined by A1 pin + * state during powerup. + * low = 0x1a + * high = 0x1b + */ +static __devinit int alc5632_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct alc5632_priv *alc5632; + int ret, ret1, ret2; + unsigned int vid1, vid2; + + alc5632 = devm_kzalloc(&client->dev, + sizeof(struct alc5632_priv), GFP_KERNEL); + if (alc5632 == NULL) + return -ENOMEM; + + i2c_set_clientdata(client, alc5632); + + alc5632->regmap = regmap_init_i2c(client, &alc5632_regmap); + if (IS_ERR(alc5632->regmap)) { + ret = PTR_ERR(alc5632->regmap); + dev_err(&client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + ret1 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID1, &vid1); + ret2 = regmap_read(alc5632->regmap, ALC5632_VENDOR_ID2, &vid2); + if (ret1 != 0 || ret2 != 0) { + dev_err(&client->dev, + "Failed to read chip ID: ret1=%d, ret2=%d\n", ret1, ret2); + regmap_exit(alc5632->regmap); + return -EIO; + } + + vid2 >>= 8; + + if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) { + dev_err(&client->dev, + "Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2); + regmap_exit(alc5632->regmap); + return -EINVAL; + } + + ret = alc5632_reset(alc5632->regmap); + if (ret < 0) { + dev_err(&client->dev, "Failed to issue reset\n"); + regmap_exit(alc5632->regmap); + return ret; + } + + alc5632->id = vid2; + switch (alc5632->id) { + case 0x5c: + alc5632_dai.name = "alc5632-hifi"; + break; + default: + return -EINVAL; + } + + ret = snd_soc_register_codec(&client->dev, + &soc_codec_device_alc5632, &alc5632_dai, 1); + + if (ret < 0) { + dev_err(&client->dev, "Failed to register codec: %d\n", ret); + regmap_exit(alc5632->regmap); + return ret; + } + + return ret; +} + +static int alc5632_i2c_remove(struct i2c_client *client) +{ + struct alc5632_priv *alc5632 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); + regmap_exit(alc5632->regmap); + return 0; +} + +static const struct i2c_device_id alc5632_i2c_table[] = { + {"alc5632", 0x5c}, + {} +}; +MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table); + +/* i2c codec control layer */ +static struct i2c_driver alc5632_i2c_driver = { + .driver = { + .name = "alc5632", + .owner = THIS_MODULE, + }, + .probe = alc5632_i2c_probe, + .remove = __devexit_p(alc5632_i2c_remove), + .id_table = alc5632_i2c_table, +}; + +static int __init alc5632_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&alc5632_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "%s: can't add i2c driver", __func__); + return ret; + } + + return ret; +} +module_init(alc5632_modinit); + +static void __exit alc5632_modexit(void) +{ + i2c_del_driver(&alc5632_i2c_driver); +} +module_exit(alc5632_modexit); + +MODULE_DESCRIPTION("ASoC ALC5632 driver"); +MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h new file mode 100644 index 00000000000..357651ec074 --- /dev/null +++ b/sound/soc/codecs/alc5632.h @@ -0,0 +1,251 @@ +/* +* alc5632.h -- ALC5632 ALSA SoC Audio Codec +* +* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> +* +* Authors: Leon Romanovsky <leon@leon.nu> +* Andrey Danin <danindrey@mail.ru> +* Ilya Petrov <ilya.muromec@gmail.com> +* Marc Dietrich <marvin24@gmx.de> +* +* Based on alc5623.h by Arnaud Patard +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#ifndef _ALC5632_H +#define _ALC5632_H + +#define ALC5632_RESET 0x00 +/* speaker output vol 2 2 */ +/* line output vol 4 2 */ +/* HP output vol 4 0 4 */ +#define ALC5632_SPK_OUT_VOL 0x02 /* spe out vol */ +#define ALC5632_SPK_OUT_VOL_STEP 1.5 +#define ALC5632_HP_OUT_VOL 0x04 /* hp out vol */ +#define ALC5632_AUX_OUT_VOL 0x06 /* aux out vol */ +#define ALC5632_PHONE_IN_VOL 0x08 /* phone in vol */ +#define ALC5632_LINE_IN_VOL 0x0A /* line in vol */ +#define ALC5632_STEREO_DAC_IN_VOL 0x0C /* stereo dac in vol */ +#define ALC5632_MIC_VOL 0x0E /* mic in vol */ +/* stero dac/mic routing */ +#define ALC5632_MIC_ROUTING_CTRL 0x10 +#define ALC5632_MIC_ROUTE_MONOMIX (1 << 0) +#define ALC5632_MIC_ROUTE_SPK (1 << 1) +#define ALC5632_MIC_ROUTE_HP (1 << 2) + +#define ALC5632_ADC_REC_GAIN 0x12 /* rec gain */ +#define ALC5632_ADC_REC_GAIN_RANGE 0x1F1F +#define ALC5632_ADC_REC_GAIN_BASE (-16.5) +#define ALC5632_ADC_REC_GAIN_STEP 1.5 + +#define ALC5632_ADC_REC_MIXER 0x14 /* mixer control */ +#define ALC5632_ADC_REC_MIC1 (1 << 6) +#define ALC5632_ADC_REC_MIC2 (1 << 5) +#define ALC5632_ADC_REC_LINE_IN (1 << 4) +#define ALC5632_ADC_REC_AUX (1 << 3) +#define ALC5632_ADC_REC_HP (1 << 2) +#define ALC5632_ADC_REC_SPK (1 << 1) +#define ALC5632_ADC_REC_MONOMIX (1 << 0) + +#define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ +/* ALC5632_OUTPUT_MIXER_CTRL : */ +/* same remark as for reg 2 line vs speaker */ +#define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ +#define ALC5632_OUTPUT_MIXER_RP (1 << 14) +#define ALC5632_OUTPUT_MIXER_WEEK (1 << 12) +#define ALC5632_OUTPUT_MIXER_HP (1 << 10) +#define ALC5632_OUTPUT_MIXER_AUX_SPK (2 << 6) +#define ALC5632_OUTPUT_MIXER_AUX_HP_LR (1 << 6) +#define ALC5632_OUTPUT_MIXER_HP_R (1 << 8) +#define ALC5632_OUTPUT_MIXER_HP_L (1 << 9) + +#define ALC5632_MIC_CTRL 0x22 /* mic phone ctrl */ +#define ALC5632_MIC_BOOST_BYPASS 0 +#define ALC5632_MIC_BOOST_20DB 1 +#define ALC5632_MIC_BOOST_30DB 2 +#define ALC5632_MIC_BOOST_40DB 3 + +#define ALC5632_DIGI_BOOST_CTRL 0x24 /* digi mic / bost ctl */ +#define ALC5632_MIC_BOOST_RANGE 7 +#define ALC5632_MIC_BOOST_STEP 6 +#define ALC5632_PWR_DOWN_CTRL_STATUS 0x26 +#define ALC5632_PWR_DOWN_CTRL_STATUS_MASK 0xEF00 +#define ALC5632_PWR_VREF_PR3 (1 << 11) +#define ALC5632_PWR_VREF_PR2 (1 << 10) +#define ALC5632_PWR_VREF_STATUS (1 << 3) +#define ALC5632_PWR_AMIX_STATUS (1 << 2) +#define ALC5632_PWR_DAC_STATUS (1 << 1) +#define ALC5632_PWR_ADC_STATUS (1 << 0) +/* stereo/voice DAC / stereo adc func ctrl */ +#define ALC5632_DAC_FUNC_SELECT 0x2E + +/* Main serial data port ctrl (i2s) */ +#define ALC5632_DAI_CONTROL 0x34 + +#define ALC5632_DAI_SDP_MASTER_MODE (0 << 15) +#define ALC5632_DAI_SDP_SLAVE_MODE (1 << 15) +#define ALC5632_DAI_SADLRCK_MODE (1 << 14) +/* 0:voice, 1:main */ +#define ALC5632_DAI_MAIN_I2S_SYSCLK_SEL (1 << 8) +#define ALC5632_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7) +/* 0:normal, 1:invert */ +#define ALC5632_DAI_MAIN_I2S_LRCK_INV (1 << 6) +#define ALC5632_DAI_I2S_DL_MASK (3 << 2) +#define ALC5632_DAI_I2S_DL_8 (3 << 2) +#define ALC5632_DAI_I2S_DL_24 (2 << 2) +#define ALC5632_DAI_I2S_DL_20 (1 << 2) +#define ALC5632_DAI_I2S_DL_16 (0 << 2) +#define ALC5632_DAI_I2S_DF_MASK (3 << 0) +#define ALC5632_DAI_I2S_DF_PCM_B (3 << 0) +#define ALC5632_DAI_I2S_DF_PCM_A (2 << 0) +#define ALC5632_DAI_I2S_DF_LEFT (1 << 0) +#define ALC5632_DAI_I2S_DF_I2S (0 << 0) +/* extend serial data port control (VoDAC_i2c/pcm) */ +#define ALC5632_DAI_CONTROL2 0x36 +/* 0:gpio func, 1:voice pcm */ +#define ALC5632_DAI_VOICE_PCM_ENABLE (1 << 15) +/* 0:master, 1:slave */ +#define ALC5632_DAI_VOICE_MODE_SEL (1 << 14) +/* 0:disable, 1:enable */ +#define ALC5632_DAI_HPF_CLK_CTRL (1 << 13) +/* 0:main, 1:voice */ +#define ALC5632_DAI_VOICE_I2S_SYSCLK_SEL (1 << 8) +/* 0:normal, 1:invert */ +#define ALC5632_DAI_VOICE_VBCLK_SYSCLK_SEL (1 << 7) +/* 0:normal, 1:invert */ +#define ALC5632_DAI_VOICE_I2S_LR_INV (1 << 6) +#define ALC5632_DAI_VOICE_DL_MASK (3 << 2) +#define ALC5632_DAI_VOICE_DL_16 (0 << 2) +#define ALC5632_DAI_VOICE_DL_20 (1 << 2) +#define ALC5632_DAI_VOICE_DL_24 (2 << 2) +#define ALC5632_DAI_VOICE_DL_8 (3 << 2) +#define ALC5632_DAI_VOICE_DF_MASK (3 << 0) +#define ALC5632_DAI_VOICE_DF_I2S (0 << 0) +#define ALC5632_DAI_VOICE_DF_LEFT (1 << 0) +#define ALC5632_DAI_VOICE_DF_PCM_A (2 << 0) +#define ALC5632_DAI_VOICE_DF_PCM_B (3 << 0) + +#define ALC5632_PWR_MANAG_ADD1 0x3A +#define ALC5632_PWR_MANAG_ADD1_MASK 0xEFFF +#define ALC5632_PWR_ADD1_DAC_L_EN (1 << 15) +#define ALC5632_PWR_ADD1_DAC_R_EN (1 << 14) +#define ALC5632_PWR_ADD1_ZERO_CROSS (1 << 13) +#define ALC5632_PWR_ADD1_MAIN_I2S_EN (1 << 11) +#define ALC5632_PWR_ADD1_SPK_AMP_EN (1 << 10) +#define ALC5632_PWR_ADD1_HP_OUT_AMP (1 << 9) +#define ALC5632_PWR_ADD1_HP_OUT_ENH_AMP (1 << 8) +#define ALC5632_PWR_ADD1_VOICE_DAC_MIX (1 << 7) +#define ALC5632_PWR_ADD1_SOFTGEN_EN (1 << 6) +#define ALC5632_PWR_ADD1_MIC1_SHORT_CURR (1 << 5) +#define ALC5632_PWR_ADD1_MIC2_SHORT_CURR (1 << 4) +#define ALC5632_PWR_ADD1_MIC1_EN (1 << 3) +#define ALC5632_PWR_ADD1_MIC2_EN (1 << 2) +#define ALC5632_PWR_ADD1_MAIN_BIAS (1 << 1) +#define ALC5632_PWR_ADD1_DAC_REF (1 << 0) + +#define ALC5632_PWR_MANAG_ADD2 0x3C +#define ALC5632_PWR_MANAG_ADD2_MASK 0x7FFF +#define ALC5632_PWR_ADD2_PLL1 (1 << 15) +#define ALC5632_PWR_ADD2_PLL2 (1 << 14) +#define ALC5632_PWR_ADD2_VREF (1 << 13) +#define ALC5632_PWR_ADD2_OVT_DET (1 << 12) +#define ALC5632_PWR_ADD2_VOICE_DAC (1 << 10) +#define ALC5632_PWR_ADD2_L_DAC_CLK (1 << 9) +#define ALC5632_PWR_ADD2_R_DAC_CLK (1 << 8) +#define ALC5632_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7) +#define ALC5632_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6) +#define ALC5632_PWR_ADD2_L_HP_MIXER (1 << 5) +#define ALC5632_PWR_ADD2_R_HP_MIXER (1 << 4) +#define ALC5632_PWR_ADD2_SPK_MIXER (1 << 3) +#define ALC5632_PWR_ADD2_MONO_MIXER (1 << 2) +#define ALC5632_PWR_ADD2_L_ADC_REC_MIXER (1 << 1) +#define ALC5632_PWR_ADD2_R_ADC_REC_MIXER (1 << 0) + +#define ALC5632_PWR_MANAG_ADD3 0x3E +#define ALC5632_PWR_MANAG_ADD3_MASK 0x7CFF +#define ALC5632_PWR_ADD3_AUXOUT_VOL (1 << 14) +#define ALC5632_PWR_ADD3_SPK_L_OUT (1 << 13) +#define ALC5632_PWR_ADD3_SPK_R_OUT (1 << 12) +#define ALC5632_PWR_ADD3_HP_L_OUT_VOL (1 << 11) +#define ALC5632_PWR_ADD3_HP_R_OUT_VOL (1 << 10) +#define ALC5632_PWR_ADD3_LINEIN_L_VOL (1 << 7) +#define ALC5632_PWR_ADD3_LINEIN_R_VOL (1 << 6) +#define ALC5632_PWR_ADD3_AUXIN_VOL (1 << 5) +#define ALC5632_PWR_ADD3_AUXIN_MIX (1 << 4) +#define ALC5632_PWR_ADD3_MIC1_VOL (1 << 3) +#define ALC5632_PWR_ADD3_MIC2_VOL (1 << 2) +#define ALC5632_PWR_ADD3_MIC1_BOOST_AD (1 << 1) +#define ALC5632_PWR_ADD3_MIC2_BOOST_AD (1 << 0) + +#define ALC5632_GPCR1 0x40 +#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_PLL1 (1 << 15) +#define ALC5632_GPCR1_CLK_SYS_SRC_SEL_MCLK (0 << 15) +#define ALC5632_GPCR1_DAC_HI_FLT_EN (1 << 10) +#define ALC5632_GPCR1_SPK_AMP_CTRL (7 << 1) +#define ALC5632_GPCR1_VDD_100 (5 << 1) +#define ALC5632_GPCR1_VDD_125 (4 << 1) +#define ALC5632_GPCR1_VDD_150 (3 << 1) +#define ALC5632_GPCR1_VDD_175 (2 << 1) +#define ALC5632_GPCR1_VDD_200 (1 << 1) +#define ALC5632_GPCR1_VDD_225 (0 << 1) + +#define ALC5632_GPCR2 0x42 +#define ALC5632_GPCR2_PLL1_SOUR_SEL (3 << 12) +#define ALC5632_PLL_FR_MCLK (0 << 12) +#define ALC5632_PLL_FR_BCLK (2 << 12) +#define ALC5632_PLL_FR_VBCLK (3 << 12) +#define ALC5632_GPCR2_CLK_PLL_PRE_DIV1 (0 << 0) + +#define ALC5632_PLL1_CTRL 0x44 +#define ALC5632_PLL1_CTRL_N_VAL(n) (((n) & 0x0f) << 8) +#define ALC5632_PLL1_M_BYPASS (1 << 7) +#define ALC5632_PLL1_CTRL_K_VAL(k) (((k) & 0x07) << 4) +#define ALC5632_PLL1_CTRL_M_VAL(m) (((m) & 0x0f) << 0) + +#define ALC5632_PLL2_CTRL 0x46 +#define ALC5632_PLL2_EN (1 << 15) +#define ALC5632_PLL2_RATIO (0 << 15) + +#define ALC5632_GPIO_PIN_CONFIG 0x4C +#define ALC5632_GPIO_PIN_POLARITY 0x4E +#define ALC5632_GPIO_PIN_STICKY 0x50 +#define ALC5632_GPIO_PIN_WAKEUP 0x52 +#define ALC5632_GPIO_PIN_STATUS 0x54 +#define ALC5632_GPIO_PIN_SHARING 0x56 +#define ALC5632_OVER_CURR_STATUS 0x58 +#define ALC5632_SOFTVOL_CTRL 0x5A +#define ALC5632_GPIO_OUPUT_PIN_CTRL 0x5C + +#define ALC5632_MISC_CTRL 0x5E +#define ALC5632_MISC_DISABLE_FAST_VREG (1 << 15) +#define ALC5632_MISC_AVC_TRGT_SEL (3 << 12) +#define ALC5632_MISC_AVC_TRGT_RIGHT (1 << 12) +#define ALC5632_MISC_AVC_TRGT_LEFT (2 << 12) +#define ALC5632_MISC_AVC_TRGT_BOTH (3 << 12) +#define ALC5632_MISC_HP_DEPOP_MODE1_EN (1 << 9) +#define ALC5632_MISC_HP_DEPOP_MODE2_EN (1 << 8) +#define ALC5632_MISC_HP_DEPOP_MUTE_L (1 << 7) +#define ALC5632_MISC_HP_DEPOP_MUTE_R (1 << 6) +#define ALC5632_MISC_HP_DEPOP_MUTE (1 << 5) +#define ALC5632_MISC_GPIO_WAKEUP_CTRL (1 << 1) +#define ALC5632_MISC_IRQOUT_INV_CTRL (1 << 0) + +#define ALC5632_DAC_CLK_CTRL1 0x60 +#define ALC5632_DAC_CLK_CTRL2 0x62 +#define ALC5632_DAC_CLK_CTRL2_DIV1_2 (1 << 0) +#define ALC5632_VOICE_DAC_PCM_CLK_CTRL1 0x64 +#define ALC5632_PSEUDO_SPATIAL_CTRL 0x68 +#define ALC5632_HID_CTRL_INDEX 0x6A +#define ALC5632_HID_CTRL_DATA 0x6C +#define ALC5632_EQ_CTRL 0x6E + +/* undocumented */ +#define ALC5632_VENDOR_ID1 0x7C +#define ALC5632_VENDOR_ID2 0x7E + +#define ALC5632_MAX_REGISTER 0x7E + +#endif diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 46dbfd067f7..4854b472d5f 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -122,7 +122,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec, #define CQ93VC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000) #define CQ93VC_FORMATS (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE) -static struct snd_soc_dai_ops cq93vc_dai_ops = { +static const struct snd_soc_dai_ops cq93vc_dai_ops = { .digital_mute = cq93vc_mute, .set_sysclk = cq93vc_set_dai_sysclk, }; @@ -206,17 +206,7 @@ static struct platform_driver cq93vc_codec_driver = { .remove = __devexit_p(cq93vc_platform_remove), }; -static int __init cq93vc_init(void) -{ - return platform_driver_register(&cq93vc_codec_driver); -} -module_init(cq93vc_init); - -static void __exit cq93vc_exit(void) -{ - platform_driver_unregister(&cq93vc_codec_driver); -} -module_exit(cq93vc_exit); +module_platform_driver(cq93vc_codec_driver); MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC CQ0093 Voice Codec Driver"); MODULE_AUTHOR("Miguel Aguilar"); diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index f1f237ecec2..055536645da 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -22,7 +22,6 @@ */ #include <linux/module.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/soc.h> @@ -447,7 +446,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { snd_soc_get_volsw, cs4270_soc_put_mute), }; -static struct snd_soc_dai_ops cs4270_dai_ops = { +static const struct snd_soc_dai_ops cs4270_dai_ops = { .hw_params = cs4270_hw_params, .set_sysclk = cs4270_set_dai_sysclk, .set_fmt = cs4270_set_dai_fmt, @@ -579,7 +578,7 @@ static int cs4270_remove(struct snd_soc_codec *codec) * and all registers are written back to the hardware when resuming. */ -static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) +static int cs4270_soc_suspend(struct snd_soc_codec *codec) { struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); int reg, ret; @@ -601,7 +600,6 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) static int cs4270_soc_resume(struct snd_soc_codec *codec) { struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c_client = to_i2c_client(codec->dev); int reg; regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), @@ -612,14 +610,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) ndelay(500); /* first restore the entire register cache ... */ - for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { - u8 val = snd_soc_read(codec, reg); - - if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { - dev_err(codec->dev, "i2c write failed\n"); - return -EIO; - } - } + snd_soc_cache_sync(codec); /* ... then disable the power-down bits */ reg = snd_soc_read(codec, CS4270_PWRCTL); @@ -680,7 +671,8 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, i2c_client->addr); dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); - cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); + cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private), + GFP_KERNEL); if (!cs4270) { dev_err(&i2c_client->dev, "could not allocate codec\n"); return -ENOMEM; @@ -691,8 +683,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_device_cs4270, &cs4270_dai, 1); - if (ret < 0) - kfree(cs4270); return ret; } @@ -705,7 +695,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, static int cs4270_i2c_remove(struct i2c_client *i2c_client) { snd_soc_unregister_codec(&i2c_client->dev); - kfree(i2c_get_clientdata(i2c_client)); return 0; } diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 23d1bd5dadd..f6fe846b6a6 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -402,7 +402,7 @@ static const struct snd_kcontrol_new cs4271_snd_controls[] = { 7, 1, 1), }; -static struct snd_soc_dai_ops cs4271_dai_ops = { +static const struct snd_soc_dai_ops cs4271_dai_ops = { .hw_params = cs4271_hw_params, .set_sysclk = cs4271_set_dai_sysclk, .set_fmt = cs4271_set_dai_fmt, @@ -430,11 +430,12 @@ static struct snd_soc_dai_driver cs4271_dai = { }; #ifdef CONFIG_PM -static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) +static int cs4271_soc_suspend(struct snd_soc_codec *codec) { int ret; /* Set power-down bit */ - ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN); + ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, + CS4271_MODE2_PDN); if (ret < 0) return ret; return 0; @@ -501,8 +502,9 @@ static int cs4271_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, - CS4271_MODE2_PDN | CS4271_MODE2_CPEN); + ret = snd_soc_update_bits(codec, CS4271_MODE2, + CS4271_MODE2_PDN | CS4271_MODE2_CPEN, + CS4271_MODE2_PDN | CS4271_MODE2_CPEN); if (ret < 0) return ret; ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 8c3c8205d19..a8bf588e874 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -22,7 +22,6 @@ */ #include <linux/module.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/soc.h> @@ -175,21 +174,18 @@ static const struct snd_kcontrol_new cs42l51_snd_controls[] = { static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - unsigned long value; - - value = snd_soc_read(w->codec, CS42L51_POWER_CTL1); - value &= ~CS42L51_POWER_CTL1_PDN; - switch (event) { case SND_SOC_DAPM_PRE_PMD: - value |= CS42L51_POWER_CTL1_PDN; + snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, + CS42L51_POWER_CTL1_PDN, + CS42L51_POWER_CTL1_PDN); break; default: case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, + CS42L51_POWER_CTL1_PDN, 0); break; } - snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, - CS42L51_POWER_CTL1_PDN, value); return 0; } @@ -486,7 +482,7 @@ static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute) return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg); } -static struct snd_soc_dai_ops cs42l51_dai_ops = { +static const struct snd_soc_dai_ops cs42l51_dai_ops = { .hw_params = cs42l51_hw_params, .set_sysclk = cs42l51_set_dai_sysclk, .set_fmt = cs42l51_set_dai_fmt, @@ -515,7 +511,6 @@ static struct snd_soc_dai_driver cs42l51_dai = { static int cs42l51_probe(struct snd_soc_codec *codec) { struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, reg; ret = cs42l51_fill_cache(codec); @@ -543,20 +538,20 @@ static int cs42l51_probe(struct snd_soc_codec *codec) if (ret < 0) return ret; - snd_soc_add_controls(codec, cs42l51_snd_controls, - ARRAY_SIZE(cs42l51_snd_controls)); - snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets, - ARRAY_SIZE(cs42l51_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, cs42l51_routes, - ARRAY_SIZE(cs42l51_routes)); - return 0; } static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { - .probe = cs42l51_probe, - .reg_cache_size = CS42L51_NUMREGS, + .probe = cs42l51_probe, + .reg_cache_size = CS42L51_NUMREGS + 1, .reg_word_size = sizeof(u8), + + .controls = cs42l51_snd_controls, + .num_controls = ARRAY_SIZE(cs42l51_snd_controls), + .dapm_widgets = cs42l51_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs42l51_dapm_widgets), + .dapm_routes = cs42l51_routes, + .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), }; static int cs42l51_i2c_probe(struct i2c_client *i2c_client, @@ -582,7 +577,8 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c_client, dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", ret & 7); - cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL); + cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), + GFP_KERNEL); if (!cs42l51) { dev_err(&i2c_client->dev, "could not allocate codec\n"); return -ENOMEM; @@ -593,18 +589,13 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c_client, ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_device_cs42l51, &cs42l51_dai, 1); - if (ret < 0) - kfree(cs42l51); error: return ret; } static int cs42l51_i2c_remove(struct i2c_client *client) { - struct cs42l51_private *cs42l51 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - kfree(cs42l51); return 0; } diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c new file mode 100644 index 00000000000..9d38db8f191 --- /dev/null +++ b/sound/soc/codecs/cs42l73.c @@ -0,0 +1,1453 @@ +/* + * cs42l73.c -- CS42L73 ALSA Soc Audio driver + * + * Copyright 2011 Cirrus Logic, Inc. + * + * Authors: Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com> + * Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/initval.h> +#include <sound/tlv.h> +#include "cs42l73.h" + +struct sp_config { + u8 spc, mmcc, spfs; + u32 srate; +}; +struct cs42l73_private { + struct sp_config config[3]; + struct regmap *regmap; + u32 sysclk; + u8 mclksel; + u32 mclk; +}; + +static const struct reg_default cs42l73_reg_defaults[] = { + { 1, 0x42 }, /* r01 - Device ID A&B */ + { 2, 0xA7 }, /* r02 - Device ID C&D */ + { 3, 0x30 }, /* r03 - Device ID E */ + { 6, 0xF1 }, /* r06 - Power Ctl 1 */ + { 7, 0xDF }, /* r07 - Power Ctl 2 */ + { 8, 0x3F }, /* r08 - Power Ctl 3 */ + { 9, 0x50 }, /* r09 - Charge Pump Freq */ + { 10, 0x53 }, /* r0A - Output Load MicBias Short Detect */ + { 11, 0x00 }, /* r0B - DMIC Master Clock Ctl */ + { 12, 0x00 }, /* r0C - Aux PCM Ctl */ + { 13, 0x15 }, /* r0D - Aux PCM Master Clock Ctl */ + { 14, 0x00 }, /* r0E - Audio PCM Ctl */ + { 15, 0x15 }, /* r0F - Audio PCM Master Clock Ctl */ + { 16, 0x00 }, /* r10 - Voice PCM Ctl */ + { 17, 0x15 }, /* r11 - Voice PCM Master Clock Ctl */ + { 18, 0x00 }, /* r12 - Voice/Aux Sample Rate */ + { 19, 0x06 }, /* r13 - Misc I/O Path Ctl */ + { 20, 0x00 }, /* r14 - ADC Input Path Ctl */ + { 21, 0x00 }, /* r15 - MICA Preamp, PGA Volume */ + { 22, 0x00 }, /* r16 - MICB Preamp, PGA Volume */ + { 23, 0x00 }, /* r17 - Input Path A Digital Volume */ + { 24, 0x00 }, /* r18 - Input Path B Digital Volume */ + { 25, 0x00 }, /* r19 - Playback Digital Ctl */ + { 26, 0x00 }, /* r1A - HP/LO Left Digital Volume */ + { 27, 0x00 }, /* r1B - HP/LO Right Digital Volume */ + { 28, 0x00 }, /* r1C - Speakerphone Digital Volume */ + { 29, 0x00 }, /* r1D - Ear/SPKLO Digital Volume */ + { 30, 0x00 }, /* r1E - HP Left Analog Volume */ + { 31, 0x00 }, /* r1F - HP Right Analog Volume */ + { 32, 0x00 }, /* r20 - LO Left Analog Volume */ + { 33, 0x00 }, /* r21 - LO Right Analog Volume */ + { 34, 0x00 }, /* r22 - Stereo Input Path Advisory Volume */ + { 35, 0x00 }, /* r23 - Aux PCM Input Advisory Volume */ + { 36, 0x00 }, /* r24 - Audio PCM Input Advisory Volume */ + { 37, 0x00 }, /* r25 - Voice PCM Input Advisory Volume */ + { 38, 0x00 }, /* r26 - Limiter Attack Rate HP/LO */ + { 39, 0x7F }, /* r27 - Limter Ctl, Release Rate HP/LO */ + { 40, 0x00 }, /* r28 - Limter Threshold HP/LO */ + { 41, 0x00 }, /* r29 - Limiter Attack Rate Speakerphone */ + { 42, 0x3F }, /* r2A - Limter Ctl, Release Rate Speakerphone */ + { 43, 0x00 }, /* r2B - Limter Threshold Speakerphone */ + { 44, 0x00 }, /* r2C - Limiter Attack Rate Ear/SPKLO */ + { 45, 0x3F }, /* r2D - Limter Ctl, Release Rate Ear/SPKLO */ + { 46, 0x00 }, /* r2E - Limter Threshold Ear/SPKLO */ + { 47, 0x00 }, /* r2F - ALC Enable, Attack Rate Left/Right */ + { 48, 0x3F }, /* r30 - ALC Release Rate Left/Right */ + { 49, 0x00 }, /* r31 - ALC Threshold Left/Right */ + { 50, 0x00 }, /* r32 - Noise Gate Ctl Left/Right */ + { 51, 0x00 }, /* r33 - ALC/NG Misc Ctl */ + { 52, 0x18 }, /* r34 - Mixer Ctl */ + { 53, 0x3F }, /* r35 - HP/LO Left Mixer Input Path Volume */ + { 54, 0x3F }, /* r36 - HP/LO Right Mixer Input Path Volume */ + { 55, 0x3F }, /* r37 - HP/LO Left Mixer Aux PCM Volume */ + { 56, 0x3F }, /* r38 - HP/LO Right Mixer Aux PCM Volume */ + { 57, 0x3F }, /* r39 - HP/LO Left Mixer Audio PCM Volume */ + { 58, 0x3F }, /* r3A - HP/LO Right Mixer Audio PCM Volume */ + { 59, 0x3F }, /* r3B - HP/LO Left Mixer Voice PCM Mono Volume */ + { 60, 0x3F }, /* r3C - HP/LO Right Mixer Voice PCM Mono Volume */ + { 61, 0x3F }, /* r3D - Aux PCM Left Mixer Input Path Volume */ + { 62, 0x3F }, /* r3E - Aux PCM Right Mixer Input Path Volume */ + { 63, 0x3F }, /* r3F - Aux PCM Left Mixer Volume */ + { 64, 0x3F }, /* r40 - Aux PCM Left Mixer Volume */ + { 65, 0x3F }, /* r41 - Aux PCM Left Mixer Audio PCM L Volume */ + { 66, 0x3F }, /* r42 - Aux PCM Right Mixer Audio PCM R Volume */ + { 67, 0x3F }, /* r43 - Aux PCM Left Mixer Voice PCM Volume */ + { 68, 0x3F }, /* r44 - Aux PCM Right Mixer Voice PCM Volume */ + { 69, 0x3F }, /* r45 - Audio PCM Left Input Path Volume */ + { 70, 0x3F }, /* r46 - Audio PCM Right Input Path Volume */ + { 71, 0x3F }, /* r47 - Audio PCM Left Mixer Aux PCM L Volume */ + { 72, 0x3F }, /* r48 - Audio PCM Right Mixer Aux PCM R Volume */ + { 73, 0x3F }, /* r49 - Audio PCM Left Mixer Volume */ + { 74, 0x3F }, /* r4A - Audio PCM Right Mixer Volume */ + { 75, 0x3F }, /* r4B - Audio PCM Left Mixer Voice PCM Volume */ + { 76, 0x3F }, /* r4C - Audio PCM Right Mixer Voice PCM Volume */ + { 77, 0x3F }, /* r4D - Voice PCM Left Input Path Volume */ + { 78, 0x3F }, /* r4E - Voice PCM Right Input Path Volume */ + { 79, 0x3F }, /* r4F - Voice PCM Left Mixer Aux PCM L Volume */ + { 80, 0x3F }, /* r50 - Voice PCM Right Mixer Aux PCM R Volume */ + { 81, 0x3F }, /* r51 - Voice PCM Left Mixer Audio PCM L Volume */ + { 82, 0x3F }, /* r52 - Voice PCM Right Mixer Audio PCM R Volume */ + { 83, 0x3F }, /* r53 - Voice PCM Left Mixer Voice PCM Volume */ + { 84, 0x3F }, /* r54 - Voice PCM Right Mixer Voice PCM Volume */ + { 85, 0xAA }, /* r55 - Mono Mixer Ctl */ + { 86, 0x3F }, /* r56 - SPK Mono Mixer Input Path Volume */ + { 87, 0x3F }, /* r57 - SPK Mono Mixer Aux PCM Mono/L/R Volume */ + { 88, 0x3F }, /* r58 - SPK Mono Mixer Audio PCM Mono/L/R Volume */ + { 89, 0x3F }, /* r59 - SPK Mono Mixer Voice PCM Mono Volume */ + { 90, 0x3F }, /* r5A - SPKLO Mono Mixer Input Path Mono Volume */ + { 91, 0x3F }, /* r5B - SPKLO Mono Mixer Aux Mono/L/R Volume */ + { 92, 0x3F }, /* r5C - SPKLO Mono Mixer Audio Mono/L/R Volume */ + { 93, 0x3F }, /* r5D - SPKLO Mono Mixer Voice Mono Volume */ + { 94, 0x00 }, /* r5E - Interrupt Mask 1 */ + { 95, 0x00 }, /* r5F - Interrupt Mask 2 */ +}; + +static bool cs42l73_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS42L73_IS1: + case CS42L73_IS2: + return true; + default: + return false; + } +} + +static bool cs42l73_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS42L73_DEVID_AB: + case CS42L73_DEVID_CD: + case CS42L73_DEVID_E: + case CS42L73_REVID: + case CS42L73_PWRCTL1: + case CS42L73_PWRCTL2: + case CS42L73_PWRCTL3: + case CS42L73_CPFCHC: + case CS42L73_OLMBMSDC: + case CS42L73_DMMCC: + case CS42L73_XSPC: + case CS42L73_XSPMMCC: + case CS42L73_ASPC: + case CS42L73_ASPMMCC: + case CS42L73_VSPC: + case CS42L73_VSPMMCC: + case CS42L73_VXSPFS: + case CS42L73_MIOPC: + case CS42L73_ADCIPC: + case CS42L73_MICAPREPGAAVOL: + case CS42L73_MICBPREPGABVOL: + case CS42L73_IPADVOL: + case CS42L73_IPBDVOL: + case CS42L73_PBDC: + case CS42L73_HLADVOL: + case CS42L73_HLBDVOL: + case CS42L73_SPKDVOL: + case CS42L73_ESLDVOL: + case CS42L73_HPAAVOL: + case CS42L73_HPBAVOL: + case CS42L73_LOAAVOL: + case CS42L73_LOBAVOL: + case CS42L73_STRINV: + case CS42L73_XSPINV: + case CS42L73_ASPINV: + case CS42L73_VSPINV: + case CS42L73_LIMARATEHL: + case CS42L73_LIMRRATEHL: + case CS42L73_LMAXHL: + case CS42L73_LIMARATESPK: + case CS42L73_LIMRRATESPK: + case CS42L73_LMAXSPK: + case CS42L73_LIMARATEESL: + case CS42L73_LIMRRATEESL: + case CS42L73_LMAXESL: + case CS42L73_ALCARATE: + case CS42L73_ALCRRATE: + case CS42L73_ALCMINMAX: + case CS42L73_NGCAB: + case CS42L73_ALCNGMC: + case CS42L73_MIXERCTL: + case CS42L73_HLAIPAA: + case CS42L73_HLBIPBA: + case CS42L73_HLAXSPAA: + case CS42L73_HLBXSPBA: + case CS42L73_HLAASPAA: + case CS42L73_HLBASPBA: + case CS42L73_HLAVSPMA: + case CS42L73_HLBVSPMA: + case CS42L73_XSPAIPAA: + case CS42L73_XSPBIPBA: + case CS42L73_XSPAXSPAA: + case CS42L73_XSPBXSPBA: + case CS42L73_XSPAASPAA: + case CS42L73_XSPAASPBA: + case CS42L73_XSPAVSPMA: + case CS42L73_XSPBVSPMA: + case CS42L73_ASPAIPAA: + case CS42L73_ASPBIPBA: + case CS42L73_ASPAXSPAA: + case CS42L73_ASPBXSPBA: + case CS42L73_ASPAASPAA: + case CS42L73_ASPBASPBA: + case CS42L73_ASPAVSPMA: + case CS42L73_ASPBVSPMA: + case CS42L73_VSPAIPAA: + case CS42L73_VSPBIPBA: + case CS42L73_VSPAXSPAA: + case CS42L73_VSPBXSPBA: + case CS42L73_VSPAASPAA: + case CS42L73_VSPBASPBA: + case CS42L73_VSPAVSPMA: + case CS42L73_VSPBVSPMA: + case CS42L73_MMIXCTL: + case CS42L73_SPKMIPMA: + case CS42L73_SPKMXSPA: + case CS42L73_SPKMASPA: + case CS42L73_SPKMVSPMA: + case CS42L73_ESLMIPMA: + case CS42L73_ESLMXSPA: + case CS42L73_ESLMASPA: + case CS42L73_ESLMVSPMA: + case CS42L73_IM1: + case CS42L73_IM2: + return true; + default: + return false; + } +} + +static const unsigned int hpaloa_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 13, TLV_DB_SCALE_ITEM(-7600, 200, 0), + 14, 75, TLV_DB_SCALE_ITEM(-4900, 100, 0), +}; + +static DECLARE_TLV_DB_SCALE(adc_boost_tlv, 0, 2500, 0); + +static DECLARE_TLV_DB_SCALE(hl_tlv, -10200, 50, 0); + +static DECLARE_TLV_DB_SCALE(ipd_tlv, -9600, 100, 0); + +static DECLARE_TLV_DB_SCALE(micpga_tlv, -600, 50, 0); + +static const unsigned int limiter_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), + 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0), +}; + +static const DECLARE_TLV_DB_SCALE(attn_tlv, -6300, 100, 1); + +static const char * const cs42l73_pgaa_text[] = { "Line A", "Mic 1" }; +static const char * const cs42l73_pgab_text[] = { "Line B", "Mic 2" }; + +static const struct soc_enum pgaa_enum = + SOC_ENUM_SINGLE(CS42L73_ADCIPC, 3, + ARRAY_SIZE(cs42l73_pgaa_text), cs42l73_pgaa_text); + +static const struct soc_enum pgab_enum = + SOC_ENUM_SINGLE(CS42L73_ADCIPC, 7, + ARRAY_SIZE(cs42l73_pgab_text), cs42l73_pgab_text); + +static const struct snd_kcontrol_new pgaa_mux = + SOC_DAPM_ENUM("Left Analog Input Capture Mux", pgaa_enum); + +static const struct snd_kcontrol_new pgab_mux = + SOC_DAPM_ENUM("Right Analog Input Capture Mux", pgab_enum); + +static const struct snd_kcontrol_new input_left_mixer[] = { + SOC_DAPM_SINGLE("ADC Left Input", CS42L73_PWRCTL1, + 5, 1, 1), + SOC_DAPM_SINGLE("DMIC Left Input", CS42L73_PWRCTL1, + 4, 1, 1), +}; + +static const struct snd_kcontrol_new input_right_mixer[] = { + SOC_DAPM_SINGLE("ADC Right Input", CS42L73_PWRCTL1, + 7, 1, 1), + SOC_DAPM_SINGLE("DMIC Right Input", CS42L73_PWRCTL1, + 6, 1, 1), +}; + +static const char * const cs42l73_ng_delay_text[] = { + "50ms", "100ms", "150ms", "200ms" }; + +static const struct soc_enum ng_delay_enum = + SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, + ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); + +static const char * const charge_pump_freq_text[] = { + "0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", + "10", "11", "12", "13", "14", "15" }; + +static const struct soc_enum charge_pump_enum = + SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4, + ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text); + +static const char * const cs42l73_mono_mix_texts[] = { + "Left", "Right", "Mono Mix"}; + +static const unsigned int cs42l73_mono_mix_values[] = { 0, 1, 2 }; + +static const struct soc_enum spk_asp_enum = + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 6, 1, + ARRAY_SIZE(cs42l73_mono_mix_texts), + cs42l73_mono_mix_texts, + cs42l73_mono_mix_values); + +static const struct snd_kcontrol_new spk_asp_mixer = + SOC_DAPM_ENUM("Route", spk_asp_enum); + +static const struct soc_enum spk_xsp_enum = + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 4, 3, + ARRAY_SIZE(cs42l73_mono_mix_texts), + cs42l73_mono_mix_texts, + cs42l73_mono_mix_values); + +static const struct snd_kcontrol_new spk_xsp_mixer = + SOC_DAPM_ENUM("Route", spk_xsp_enum); + +static const struct soc_enum esl_asp_enum = + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 2, 5, + ARRAY_SIZE(cs42l73_mono_mix_texts), + cs42l73_mono_mix_texts, + cs42l73_mono_mix_values); + +static const struct snd_kcontrol_new esl_asp_mixer = + SOC_DAPM_ENUM("Route", esl_asp_enum); + +static const struct soc_enum esl_xsp_enum = + SOC_VALUE_ENUM_SINGLE(CS42L73_MMIXCTL, 0, 7, + ARRAY_SIZE(cs42l73_mono_mix_texts), + cs42l73_mono_mix_texts, + cs42l73_mono_mix_values); + +static const struct snd_kcontrol_new esl_xsp_mixer = + SOC_DAPM_ENUM("Route", esl_xsp_enum); + +static const char * const cs42l73_ip_swap_text[] = { + "Stereo", "Mono A", "Mono B", "Swap A-B"}; + +static const struct soc_enum ip_swap_enum = + SOC_ENUM_SINGLE(CS42L73_MIOPC, 6, + ARRAY_SIZE(cs42l73_ip_swap_text), cs42l73_ip_swap_text); + +static const char * const cs42l73_spo_mixer_text[] = {"Mono", "Stereo"}; + +static const struct soc_enum vsp_output_mux_enum = + SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 5, + ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); + +static const struct soc_enum xsp_output_mux_enum = + SOC_ENUM_SINGLE(CS42L73_MIXERCTL, 4, + ARRAY_SIZE(cs42l73_spo_mixer_text), cs42l73_spo_mixer_text); + +static const struct snd_kcontrol_new vsp_output_mux = + SOC_DAPM_ENUM("Route", vsp_output_mux_enum); + +static const struct snd_kcontrol_new xsp_output_mux = + SOC_DAPM_ENUM("Route", xsp_output_mux_enum); + +static const struct snd_kcontrol_new hp_amp_ctl = + SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1); + +static const struct snd_kcontrol_new lo_amp_ctl = + SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 1, 1, 1); + +static const struct snd_kcontrol_new spk_amp_ctl = + SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 2, 1, 1); + +static const struct snd_kcontrol_new spklo_amp_ctl = + SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 4, 1, 1); + +static const struct snd_kcontrol_new ear_amp_ctl = + SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 3, 1, 1); + +static const struct snd_kcontrol_new cs42l73_snd_controls[] = { + SOC_DOUBLE_R_SX_TLV("Headphone Analog Playback Volume", + CS42L73_HPAAVOL, CS42L73_HPBAVOL, 7, + 0xffffffC1, 0x0C, hpaloa_tlv), + + SOC_DOUBLE_R_SX_TLV("LineOut Analog Playback Volume", CS42L73_LOAAVOL, + CS42L73_LOBAVOL, 7, 0xffffffC1, 0x0C, hpaloa_tlv), + + SOC_DOUBLE_R_SX_TLV("Input PGA Analog Volume", CS42L73_MICAPREPGAAVOL, + CS42L73_MICBPREPGABVOL, 5, 0xffffff35, + 0x34, micpga_tlv), + + SOC_DOUBLE_R("MIC Preamp Switch", CS42L73_MICAPREPGAAVOL, + CS42L73_MICBPREPGABVOL, 6, 1, 1), + + SOC_DOUBLE_R_SX_TLV("Input Path Digital Volume", CS42L73_IPADVOL, + CS42L73_IPBDVOL, 7, 0xffffffA0, 0xA0, ipd_tlv), + + SOC_DOUBLE_R_SX_TLV("HL Digital Playback Volume", + CS42L73_HLADVOL, CS42L73_HLBDVOL, 7, 0xffffffE5, + 0xE4, hl_tlv), + + SOC_SINGLE_TLV("ADC A Boost Volume", + CS42L73_ADCIPC, 2, 0x01, 1, adc_boost_tlv), + + SOC_SINGLE_TLV("ADC B Boost Volume", + CS42L73_ADCIPC, 6, 0x01, 1, adc_boost_tlv), + + SOC_SINGLE_TLV("Speakerphone Digital Playback Volume", + CS42L73_SPKDVOL, 0, 0xE4, 1, hl_tlv), + + SOC_SINGLE_TLV("Ear Speaker Digital Playback Volume", + CS42L73_ESLDVOL, 0, 0xE4, 1, hl_tlv), + + SOC_DOUBLE_R("Headphone Analog Playback Switch", CS42L73_HPAAVOL, + CS42L73_HPBAVOL, 7, 1, 1), + + SOC_DOUBLE_R("LineOut Analog Playback Switch", CS42L73_LOAAVOL, + CS42L73_LOBAVOL, 7, 1, 1), + SOC_DOUBLE("Input Path Digital Switch", CS42L73_ADCIPC, 0, 4, 1, 1), + SOC_DOUBLE("HL Digital Playback Switch", CS42L73_PBDC, 0, + 1, 1, 1), + SOC_SINGLE("Speakerphone Digital Playback Switch", CS42L73_PBDC, 2, 1, + 1), + SOC_SINGLE("Ear Speaker Digital Playback Switch", CS42L73_PBDC, 3, 1, + 1), + + SOC_SINGLE("PGA Soft-Ramp Switch", CS42L73_MIOPC, 3, 1, 0), + SOC_SINGLE("Analog Zero Cross Switch", CS42L73_MIOPC, 2, 1, 0), + SOC_SINGLE("Digital Soft-Ramp Switch", CS42L73_MIOPC, 1, 1, 0), + SOC_SINGLE("Analog Output Soft-Ramp Switch", CS42L73_MIOPC, 0, 1, 0), + + SOC_DOUBLE("ADC Signal Polarity Switch", CS42L73_ADCIPC, 1, 5, 1, + 0), + + SOC_SINGLE("HL Limiter Attack Rate", CS42L73_LIMARATEHL, 0, 0x3F, + 0), + SOC_SINGLE("HL Limiter Release Rate", CS42L73_LIMRRATEHL, 0, + 0x3F, 0), + + + SOC_SINGLE("HL Limiter Switch", CS42L73_LIMRRATEHL, 7, 1, 0), + SOC_SINGLE("HL Limiter All Channels Switch", CS42L73_LIMRRATEHL, 6, 1, + 0), + + SOC_SINGLE_TLV("HL Limiter Max Threshold Volume", CS42L73_LMAXHL, 5, 7, + 1, limiter_tlv), + + SOC_SINGLE_TLV("HL Limiter Cushion Volume", CS42L73_LMAXHL, 2, 7, 1, + limiter_tlv), + + SOC_SINGLE("SPK Limiter Attack Rate Volume", CS42L73_LIMARATESPK, 0, + 0x3F, 0), + SOC_SINGLE("SPK Limiter Release Rate Volume", CS42L73_LIMRRATESPK, 0, + 0x3F, 0), + SOC_SINGLE("SPK Limiter Switch", CS42L73_LIMRRATESPK, 7, 1, 0), + SOC_SINGLE("SPK Limiter All Channels Switch", CS42L73_LIMRRATESPK, + 6, 1, 0), + SOC_SINGLE_TLV("SPK Limiter Max Threshold Volume", CS42L73_LMAXSPK, 5, + 7, 1, limiter_tlv), + + SOC_SINGLE_TLV("SPK Limiter Cushion Volume", CS42L73_LMAXSPK, 2, 7, 1, + limiter_tlv), + + SOC_SINGLE("ESL Limiter Attack Rate Volume", CS42L73_LIMARATEESL, 0, + 0x3F, 0), + SOC_SINGLE("ESL Limiter Release Rate Volume", CS42L73_LIMRRATEESL, 0, + 0x3F, 0), + SOC_SINGLE("ESL Limiter Switch", CS42L73_LIMRRATEESL, 7, 1, 0), + SOC_SINGLE_TLV("ESL Limiter Max Threshold Volume", CS42L73_LMAXESL, 5, + 7, 1, limiter_tlv), + + SOC_SINGLE_TLV("ESL Limiter Cushion Volume", CS42L73_LMAXESL, 2, 7, 1, + limiter_tlv), + + SOC_SINGLE("ALC Attack Rate Volume", CS42L73_ALCARATE, 0, 0x3F, 0), + SOC_SINGLE("ALC Release Rate Volume", CS42L73_ALCRRATE, 0, 0x3F, 0), + SOC_DOUBLE("ALC Switch", CS42L73_ALCARATE, 6, 7, 1, 0), + SOC_SINGLE_TLV("ALC Max Threshold Volume", CS42L73_ALCMINMAX, 5, 7, 0, + limiter_tlv), + SOC_SINGLE_TLV("ALC Min Threshold Volume", CS42L73_ALCMINMAX, 2, 7, 0, + limiter_tlv), + + SOC_DOUBLE("NG Enable Switch", CS42L73_NGCAB, 6, 7, 1, 0), + SOC_SINGLE("NG Boost Switch", CS42L73_NGCAB, 5, 1, 0), + /* + NG Threshold depends on NG_BOOTSAB, which selects + between two threshold scales in decibels. + Set linear values for now .. + */ + SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0), + SOC_ENUM("NG Delay", ng_delay_enum), + + SOC_ENUM("Charge Pump Frequency", charge_pump_enum), + + SOC_DOUBLE_R_TLV("XSP-IP Volume", + CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("XSP-XSP Volume", + CS42L73_XSPAXSPAA, CS42L73_XSPBXSPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("XSP-ASP Volume", + CS42L73_XSPAASPAA, CS42L73_XSPAASPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("XSP-VSP Volume", + CS42L73_XSPAVSPMA, CS42L73_XSPBVSPMA, 0, 0x3F, 1, + attn_tlv), + + SOC_DOUBLE_R_TLV("ASP-IP Volume", + CS42L73_ASPAIPAA, CS42L73_ASPBIPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("ASP-XSP Volume", + CS42L73_ASPAXSPAA, CS42L73_ASPBXSPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("ASP-ASP Volume", + CS42L73_ASPAASPAA, CS42L73_ASPBASPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("ASP-VSP Volume", + CS42L73_ASPAVSPMA, CS42L73_ASPBVSPMA, 0, 0x3F, 1, + attn_tlv), + + SOC_DOUBLE_R_TLV("VSP-IP Volume", + CS42L73_VSPAIPAA, CS42L73_VSPBIPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("VSP-XSP Volume", + CS42L73_VSPAXSPAA, CS42L73_VSPBXSPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("VSP-ASP Volume", + CS42L73_VSPAASPAA, CS42L73_VSPBASPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("VSP-VSP Volume", + CS42L73_VSPAVSPMA, CS42L73_VSPBVSPMA, 0, 0x3F, 1, + attn_tlv), + + SOC_DOUBLE_R_TLV("HL-IP Volume", + CS42L73_HLAIPAA, CS42L73_HLBIPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("HL-XSP Volume", + CS42L73_HLAXSPAA, CS42L73_HLBXSPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("HL-ASP Volume", + CS42L73_HLAASPAA, CS42L73_HLBASPBA, 0, 0x3F, 1, + attn_tlv), + SOC_DOUBLE_R_TLV("HL-VSP Volume", + CS42L73_HLAVSPMA, CS42L73_HLBVSPMA, 0, 0x3F, 1, + attn_tlv), + + SOC_SINGLE_TLV("SPK-IP Mono Volume", + CS42L73_SPKMIPMA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("SPK-XSP Mono Volume", + CS42L73_SPKMXSPA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("SPK-ASP Mono Volume", + CS42L73_SPKMASPA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("SPK-VSP Mono Volume", + CS42L73_SPKMVSPMA, 0, 0x3E, 1, attn_tlv), + + SOC_SINGLE_TLV("ESL-IP Mono Volume", + CS42L73_ESLMIPMA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("ESL-XSP Mono Volume", + CS42L73_ESLMXSPA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("ESL-ASP Mono Volume", + CS42L73_ESLMASPA, 0, 0x3E, 1, attn_tlv), + SOC_SINGLE_TLV("ESL-VSP Mono Volume", + CS42L73_ESLMVSPMA, 0, 0x3E, 1, attn_tlv), + + SOC_ENUM("IP Digital Swap/Mono Select", ip_swap_enum), + + SOC_ENUM("VSPOUT Mono/Stereo Select", vsp_output_mux_enum), + SOC_ENUM("XSPOUT Mono/Stereo Select", xsp_output_mux_enum), +}; + +static const struct snd_soc_dapm_widget cs42l73_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("LINEINA"), + SND_SOC_DAPM_INPUT("LINEINB"), + SND_SOC_DAPM_INPUT("MIC1"), + SND_SOC_DAPM_SUPPLY("MIC1 Bias", CS42L73_PWRCTL2, 6, 1, NULL, 0), + SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_SUPPLY("MIC2 Bias", CS42L73_PWRCTL2, 7, 1, NULL, 0), + + SND_SOC_DAPM_AIF_OUT("XSPOUTL", "XSP Capture", 0, + CS42L73_PWRCTL2, 1, 1), + SND_SOC_DAPM_AIF_OUT("XSPOUTR", "XSP Capture", 0, + CS42L73_PWRCTL2, 1, 1), + SND_SOC_DAPM_AIF_OUT("ASPOUTL", "ASP Capture", 0, + CS42L73_PWRCTL2, 3, 1), + SND_SOC_DAPM_AIF_OUT("ASPOUTR", "ASP Capture", 0, + CS42L73_PWRCTL2, 3, 1), + SND_SOC_DAPM_AIF_OUT("VSPOUTL", "VSP Capture", 0, + CS42L73_PWRCTL2, 4, 1), + SND_SOC_DAPM_AIF_OUT("VSPOUTR", "VSP Capture", 0, + CS42L73_PWRCTL2, 4, 1), + + SND_SOC_DAPM_PGA("PGA Left", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("PGA Right", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("PGA Left Mux", SND_SOC_NOPM, 0, 0, &pgaa_mux), + SND_SOC_DAPM_MUX("PGA Right Mux", SND_SOC_NOPM, 0, 0, &pgab_mux), + + SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L73_PWRCTL1, 7, 1), + SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L73_PWRCTL1, 5, 1), + SND_SOC_DAPM_ADC("DMIC Left", NULL, CS42L73_PWRCTL1, 6, 1), + SND_SOC_DAPM_ADC("DMIC Right", NULL, CS42L73_PWRCTL1, 4, 1), + + SND_SOC_DAPM_MIXER_NAMED_CTL("Input Left Capture", SND_SOC_NOPM, + 0, 0, input_left_mixer, + ARRAY_SIZE(input_left_mixer)), + + SND_SOC_DAPM_MIXER_NAMED_CTL("Input Right Capture", SND_SOC_NOPM, + 0, 0, input_right_mixer, + ARRAY_SIZE(input_right_mixer)), + + SND_SOC_DAPM_MIXER("ASPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("ASPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("XSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("XSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("VSPL Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("VSPR Output Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_AIF_IN("XSPINL", "XSP Playback", 0, + CS42L73_PWRCTL2, 0, 1), + SND_SOC_DAPM_AIF_IN("XSPINR", "XSP Playback", 0, + CS42L73_PWRCTL2, 0, 1), + SND_SOC_DAPM_AIF_IN("XSPINM", "XSP Playback", 0, + CS42L73_PWRCTL2, 0, 1), + + SND_SOC_DAPM_AIF_IN("ASPINL", "ASP Playback", 0, + CS42L73_PWRCTL2, 2, 1), + SND_SOC_DAPM_AIF_IN("ASPINR", "ASP Playback", 0, + CS42L73_PWRCTL2, 2, 1), + SND_SOC_DAPM_AIF_IN("ASPINM", "ASP Playback", 0, + CS42L73_PWRCTL2, 2, 1), + + SND_SOC_DAPM_AIF_IN("VSPIN", "VSP Playback", 0, + CS42L73_PWRCTL2, 4, 1), + + SND_SOC_DAPM_MIXER("HL Left Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("HL Right Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("SPK Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("ESL Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MUX("ESL-XSP Mux", SND_SOC_NOPM, + 0, 0, &esl_xsp_mixer), + + SND_SOC_DAPM_MUX("ESL-ASP Mux", SND_SOC_NOPM, + 0, 0, &esl_asp_mixer), + + SND_SOC_DAPM_MUX("SPK-ASP Mux", SND_SOC_NOPM, + 0, 0, &spk_asp_mixer), + + SND_SOC_DAPM_MUX("SPK-XSP Mux", SND_SOC_NOPM, + 0, 0, &spk_xsp_mixer), + + SND_SOC_DAPM_PGA("HL Left DAC", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("HL Right DAC", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("SPK DAC", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_PGA("ESL DAC", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH("HP Amp", CS42L73_PWRCTL3, 0, 1, + &hp_amp_ctl), + SND_SOC_DAPM_SWITCH("LO Amp", CS42L73_PWRCTL3, 1, 1, + &lo_amp_ctl), + SND_SOC_DAPM_SWITCH("SPK Amp", CS42L73_PWRCTL3, 2, 1, + &spk_amp_ctl), + SND_SOC_DAPM_SWITCH("EAR Amp", CS42L73_PWRCTL3, 3, 1, + &ear_amp_ctl), + SND_SOC_DAPM_SWITCH("SPKLO Amp", CS42L73_PWRCTL3, 4, 1, + &spklo_amp_ctl), + + SND_SOC_DAPM_OUTPUT("HPOUTA"), + SND_SOC_DAPM_OUTPUT("HPOUTB"), + SND_SOC_DAPM_OUTPUT("LINEOUTA"), + SND_SOC_DAPM_OUTPUT("LINEOUTB"), + SND_SOC_DAPM_OUTPUT("EAROUT"), + SND_SOC_DAPM_OUTPUT("SPKOUT"), + SND_SOC_DAPM_OUTPUT("SPKLINEOUT"), +}; + +static const struct snd_soc_dapm_route cs42l73_audio_map[] = { + + /* SPKLO EARSPK Paths */ + {"EAROUT", NULL, "EAR Amp"}, + {"SPKLINEOUT", NULL, "SPKLO Amp"}, + + {"EAR Amp", "Switch", "ESL DAC"}, + {"SPKLO Amp", "Switch", "ESL DAC"}, + + {"ESL DAC", "ESL-ASP Mono Volume", "ESL Mixer"}, + {"ESL DAC", "ESL-XSP Mono Volume", "ESL Mixer"}, + {"ESL DAC", "ESL-VSP Mono Volume", "VSPIN"}, + /* Loopback */ + {"ESL DAC", "ESL-IP Mono Volume", "Input Left Capture"}, + {"ESL DAC", "ESL-IP Mono Volume", "Input Right Capture"}, + + {"ESL Mixer", NULL, "ESL-ASP Mux"}, + {"ESL Mixer", NULL, "ESL-XSP Mux"}, + + {"ESL-ASP Mux", "Left", "ASPINL"}, + {"ESL-ASP Mux", "Right", "ASPINR"}, + {"ESL-ASP Mux", "Mono Mix", "ASPINM"}, + + {"ESL-XSP Mux", "Left", "XSPINL"}, + {"ESL-XSP Mux", "Right", "XSPINR"}, + {"ESL-XSP Mux", "Mono Mix", "XSPINM"}, + + /* Speakerphone Paths */ + {"SPKOUT", NULL, "SPK Amp"}, + {"SPK Amp", "Switch", "SPK DAC"}, + + {"SPK DAC", "SPK-ASP Mono Volume", "SPK Mixer"}, + {"SPK DAC", "SPK-XSP Mono Volume", "SPK Mixer"}, + {"SPK DAC", "SPK-VSP Mono Volume", "VSPIN"}, + /* Loopback */ + {"SPK DAC", "SPK-IP Mono Volume", "Input Left Capture"}, + {"SPK DAC", "SPK-IP Mono Volume", "Input Right Capture"}, + + {"SPK Mixer", NULL, "SPK-ASP Mux"}, + {"SPK Mixer", NULL, "SPK-XSP Mux"}, + + {"SPK-ASP Mux", "Left", "ASPINL"}, + {"SPK-ASP Mux", "Mono Mix", "ASPINM"}, + {"SPK-ASP Mux", "Right", "ASPINR"}, + + {"SPK-XSP Mux", "Left", "XSPINL"}, + {"SPK-XSP Mux", "Mono Mix", "XSPINM"}, + {"SPK-XSP Mux", "Right", "XSPINR"}, + + /* HP LineOUT Paths */ + {"HPOUTA", NULL, "HP Amp"}, + {"HPOUTB", NULL, "HP Amp"}, + {"LINEOUTA", NULL, "LO Amp"}, + {"LINEOUTB", NULL, "LO Amp"}, + + {"HP Amp", "Switch", "HL Left DAC"}, + {"HP Amp", "Switch", "HL Right DAC"}, + {"LO Amp", "Switch", "HL Left DAC"}, + {"LO Amp", "Switch", "HL Right DAC"}, + + {"HL Left DAC", "HL-XSP Volume", "HL Left Mixer"}, + {"HL Right DAC", "HL-XSP Volume", "HL Right Mixer"}, + {"HL Left DAC", "HL-ASP Volume", "HL Left Mixer"}, + {"HL Right DAC", "HL-ASP Volume", "HL Right Mixer"}, + {"HL Left DAC", "HL-VSP Volume", "HL Left Mixer"}, + {"HL Right DAC", "HL-VSP Volume", "HL Right Mixer"}, + /* Loopback */ + {"HL Left DAC", "HL-IP Volume", "HL Left Mixer"}, + {"HL Right DAC", "HL-IP Volume", "HL Right Mixer"}, + {"HL Left Mixer", NULL, "Input Left Capture"}, + {"HL Right Mixer", NULL, "Input Right Capture"}, + + {"HL Left Mixer", NULL, "ASPINL"}, + {"HL Right Mixer", NULL, "ASPINR"}, + {"HL Left Mixer", NULL, "XSPINL"}, + {"HL Right Mixer", NULL, "XSPINR"}, + {"HL Left Mixer", NULL, "VSPIN"}, + {"HL Right Mixer", NULL, "VSPIN"}, + + /* Capture Paths */ + {"MIC1", NULL, "MIC1 Bias"}, + {"PGA Left Mux", "Mic 1", "MIC1"}, + {"MIC2", NULL, "MIC2 Bias"}, + {"PGA Right Mux", "Mic 2", "MIC2"}, + + {"PGA Left Mux", "Line A", "LINEINA"}, + {"PGA Right Mux", "Line B", "LINEINB"}, + + {"PGA Left", NULL, "PGA Left Mux"}, + {"PGA Right", NULL, "PGA Right Mux"}, + + {"ADC Left", NULL, "PGA Left"}, + {"ADC Right", NULL, "PGA Right"}, + + {"Input Left Capture", "ADC Left Input", "ADC Left"}, + {"Input Right Capture", "ADC Right Input", "ADC Right"}, + {"Input Left Capture", "DMIC Left Input", "DMIC Left"}, + {"Input Right Capture", "DMIC Right Input", "DMIC Right"}, + + /* Audio Capture */ + {"ASPL Output Mixer", NULL, "Input Left Capture"}, + {"ASPR Output Mixer", NULL, "Input Right Capture"}, + + {"ASPOUTL", "ASP-IP Volume", "ASPL Output Mixer"}, + {"ASPOUTR", "ASP-IP Volume", "ASPR Output Mixer"}, + + /* Auxillary Capture */ + {"XSPL Output Mixer", NULL, "Input Left Capture"}, + {"XSPR Output Mixer", NULL, "Input Right Capture"}, + + {"XSPOUTL", "XSP-IP Volume", "XSPL Output Mixer"}, + {"XSPOUTR", "XSP-IP Volume", "XSPR Output Mixer"}, + + {"XSPOUTL", NULL, "XSPL Output Mixer"}, + {"XSPOUTR", NULL, "XSPR Output Mixer"}, + + /* Voice Capture */ + {"VSPL Output Mixer", NULL, "Input Left Capture"}, + {"VSPR Output Mixer", NULL, "Input Left Capture"}, + + {"VSPOUTL", "VSP-IP Volume", "VSPL Output Mixer"}, + {"VSPOUTR", "VSP-IP Volume", "VSPR Output Mixer"}, + + {"VSPOUTL", NULL, "VSPL Output Mixer"}, + {"VSPOUTR", NULL, "VSPR Output Mixer"}, +}; + +struct cs42l73_mclk_div { + u32 mclk; + u32 srate; + u8 mmcc; +}; + +static struct cs42l73_mclk_div cs42l73_mclk_coeffs[] = { + /* MCLK, Sample Rate, xMMCC[5:0] */ + {5644800, 11025, 0x30}, + {5644800, 22050, 0x20}, + {5644800, 44100, 0x10}, + + {6000000, 8000, 0x39}, + {6000000, 11025, 0x33}, + {6000000, 12000, 0x31}, + {6000000, 16000, 0x29}, + {6000000, 22050, 0x23}, + {6000000, 24000, 0x21}, + {6000000, 32000, 0x19}, + {6000000, 44100, 0x13}, + {6000000, 48000, 0x11}, + + {6144000, 8000, 0x38}, + {6144000, 12000, 0x30}, + {6144000, 16000, 0x28}, + {6144000, 24000, 0x20}, + {6144000, 32000, 0x18}, + {6144000, 48000, 0x10}, + + {6500000, 8000, 0x3C}, + {6500000, 11025, 0x35}, + {6500000, 12000, 0x34}, + {6500000, 16000, 0x2C}, + {6500000, 22050, 0x25}, + {6500000, 24000, 0x24}, + {6500000, 32000, 0x1C}, + {6500000, 44100, 0x15}, + {6500000, 48000, 0x14}, + + {6400000, 8000, 0x3E}, + {6400000, 11025, 0x37}, + {6400000, 12000, 0x36}, + {6400000, 16000, 0x2E}, + {6400000, 22050, 0x27}, + {6400000, 24000, 0x26}, + {6400000, 32000, 0x1E}, + {6400000, 44100, 0x17}, + {6400000, 48000, 0x16}, +}; + +struct cs42l73_mclkx_div { + u32 mclkx; + u8 ratio; + u8 mclkdiv; +}; + +static struct cs42l73_mclkx_div cs42l73_mclkx_coeffs[] = { + {5644800, 1, 0}, /* 5644800 */ + {6000000, 1, 0}, /* 6000000 */ + {6144000, 1, 0}, /* 6144000 */ + {11289600, 2, 2}, /* 5644800 */ + {12288000, 2, 2}, /* 6144000 */ + {12000000, 2, 2}, /* 6000000 */ + {13000000, 2, 2}, /* 6500000 */ + {19200000, 3, 3}, /* 6400000 */ + {24000000, 4, 4}, /* 6000000 */ + {26000000, 4, 4}, /* 6500000 */ + {38400000, 6, 5} /* 6400000 */ +}; + +static int cs42l73_get_mclkx_coeff(int mclkx) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs42l73_mclkx_coeffs); i++) { + if (cs42l73_mclkx_coeffs[i].mclkx == mclkx) + return i; + } + return -EINVAL; +} + +static int cs42l73_get_mclk_coeff(int mclk, int srate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cs42l73_mclk_coeffs); i++) { + if (cs42l73_mclk_coeffs[i].mclk == mclk && + cs42l73_mclk_coeffs[i].srate == srate) + return i; + } + return -EINVAL; + +} + +static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); + + int mclkx_coeff; + u32 mclk = 0; + u8 dmmcc = 0; + + /* MCLKX -> MCLK */ + mclkx_coeff = cs42l73_get_mclkx_coeff(freq); + + mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx / + cs42l73_mclkx_coeffs[mclkx_coeff].ratio; + + dev_dbg(codec->dev, "MCLK%u %u <-> internal MCLK %u\n", + priv->mclksel + 1, cs42l73_mclkx_coeffs[mclkx_coeff].mclkx, + mclk); + + dmmcc = (priv->mclksel << 4) | + (cs42l73_mclkx_coeffs[mclkx_coeff].mclkdiv << 1); + + snd_soc_write(codec, CS42L73_DMMCC, dmmcc); + + priv->sysclk = mclkx_coeff; + priv->mclk = mclk; + + return 0; +} + +static int cs42l73_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); + + switch (clk_id) { + case CS42L73_CLKID_MCLK1: + break; + case CS42L73_CLKID_MCLK2: + break; + default: + return -EINVAL; + } + + if ((cs42l73_set_mclk(dai, freq)) < 0) { + dev_err(codec->dev, "Unable to set MCLK for dai %s\n", + dai->name); + return -EINVAL; + } + + priv->mclksel = clk_id; + + return 0; +} + +static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); + u8 id = codec_dai->id; + unsigned int inv, format; + u8 spc, mmcc; + + spc = snd_soc_read(codec, CS42L73_SPC(id)); + mmcc = snd_soc_read(codec, CS42L73_MMCC(id)); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + mmcc |= MS_MASTER; + break; + + case SND_SOC_DAIFMT_CBS_CFS: + mmcc &= ~MS_MASTER; + break; + + default: + return -EINVAL; + } + + format = (fmt & SND_SOC_DAIFMT_FORMAT_MASK); + inv = (fmt & SND_SOC_DAIFMT_INV_MASK); + + switch (format) { + case SND_SOC_DAIFMT_I2S: + spc &= ~SPDIF_PCM; + break; + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + if (mmcc & MS_MASTER) { + dev_err(codec->dev, + "PCM format in slave mode only\n"); + return -EINVAL; + } + if (id == CS42L73_ASP) { + dev_err(codec->dev, + "PCM format is not supported on ASP port\n"); + return -EINVAL; + } + spc |= SPDIF_PCM; + break; + default: + return -EINVAL; + } + + if (spc & SPDIF_PCM) { + /* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */ + spc &= ~(PCM_MODE_MASK | PCM_BIT_ORDER); + switch (format) { + case SND_SOC_DAIFMT_DSP_B: + if (inv == SND_SOC_DAIFMT_IB_IF) + spc |= PCM_MODE0; + if (inv == SND_SOC_DAIFMT_IB_NF) + spc |= PCM_MODE1; + break; + case SND_SOC_DAIFMT_DSP_A: + if (inv == SND_SOC_DAIFMT_IB_IF) + spc |= PCM_MODE1; + break; + default: + return -EINVAL; + } + } + + priv->config[id].spc = spc; + priv->config[id].mmcc = mmcc; + + return 0; +} + +static u32 cs42l73_asrc_rates[] = { + 8000, 11025, 12000, 16000, 22050, + 24000, 32000, 44100, 48000 +}; + +static unsigned int cs42l73_get_xspfs_coeff(u32 rate) +{ + int i; + for (i = 0; i < ARRAY_SIZE(cs42l73_asrc_rates); i++) { + if (cs42l73_asrc_rates[i] == rate) + return i + 1; + } + return 0; /* 0 = Don't know */ +} + +static void cs42l73_update_asrc(struct snd_soc_codec *codec, int id, int srate) +{ + u8 spfs = 0; + + if (srate > 0) + spfs = cs42l73_get_xspfs_coeff(srate); + + switch (id) { + case CS42L73_XSP: + snd_soc_update_bits(codec, CS42L73_VXSPFS, 0x0f, spfs); + break; + case CS42L73_ASP: + snd_soc_update_bits(codec, CS42L73_ASPC, 0x3c, spfs << 2); + break; + case CS42L73_VSP: + snd_soc_update_bits(codec, CS42L73_VXSPFS, 0xf0, spfs << 4); + break; + default: + break; + } +} + +static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct cs42l73_private *priv = snd_soc_codec_get_drvdata(codec); + int id = dai->id; + int mclk_coeff; + int srate = params_rate(params); + + if (priv->config[id].mmcc & MS_MASTER) { + /* CS42L73 Master */ + /* MCLK -> srate */ + mclk_coeff = + cs42l73_get_mclk_coeff(priv->mclk, srate); + + if (mclk_coeff < 0) + return -EINVAL; + + dev_dbg(codec->dev, + "DAI[%d]: MCLK %u, srate %u, MMCC[5:0] = %x\n", + id, priv->mclk, srate, + cs42l73_mclk_coeffs[mclk_coeff].mmcc); + + priv->config[id].mmcc &= 0xC0; + priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; + priv->config[id].spc &= 0xFC; + priv->config[id].spc &= MCK_SCLK_64FS; + } else { + /* CS42L73 Slave */ + priv->config[id].spc &= 0xFC; + priv->config[id].spc |= MCK_SCLK_64FS; + } + /* Update ASRCs */ + priv->config[id].srate = srate; + + snd_soc_write(codec, CS42L73_SPC(id), priv->config[id].spc); + snd_soc_write(codec, CS42L73_MMCC(id), priv->config[id].mmcc); + + cs42l73_update_asrc(codec, id, srate); + + return 0; +} + +static int cs42l73_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0); + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0); + break; + + case SND_SOC_BIAS_PREPARE: + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + regcache_cache_only(cs42l73->regmap, false); + regcache_sync(cs42l73->regmap); + } + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); + snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +static int cs42l73_set_tristate(struct snd_soc_dai *dai, int tristate) +{ + struct snd_soc_codec *codec = dai->codec; + int id = dai->id; + + return snd_soc_update_bits(codec, CS42L73_SPC(id), + 0x7F, tristate << 7); +} + +static struct snd_pcm_hw_constraint_list constraints_12_24 = { + .count = ARRAY_SIZE(cs42l73_asrc_rates), + .list = cs42l73_asrc_rates, +}; + +static int cs42l73_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_12_24); + return 0; +} + +/* SNDRV_PCM_RATE_KNOT -> 12000, 24000 Hz, limit with constraint list */ +#define CS42L73_RATES (SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_KNOT) + + +#define CS42L73_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE) + +static const struct snd_soc_dai_ops cs42l73_ops = { + .startup = cs42l73_pcm_startup, + .hw_params = cs42l73_pcm_hw_params, + .set_fmt = cs42l73_set_dai_fmt, + .set_sysclk = cs42l73_set_sysclk, + .set_tristate = cs42l73_set_tristate, +}; + +static struct snd_soc_dai_driver cs42l73_dai[] = { + { + .name = "cs42l73-xsp", + .id = CS42L73_XSP, + .playback = { + .stream_name = "XSP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .capture = { + .stream_name = "XSP Capture", + .channels_min = 1, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .ops = &cs42l73_ops, + .symmetric_rates = 1, + }, + { + .name = "cs42l73-asp", + .id = CS42L73_ASP, + .playback = { + .stream_name = "ASP Playback", + .channels_min = 2, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .capture = { + .stream_name = "ASP Capture", + .channels_min = 2, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .ops = &cs42l73_ops, + .symmetric_rates = 1, + }, + { + .name = "cs42l73-vsp", + .id = CS42L73_VSP, + .playback = { + .stream_name = "VSP Playback", + .channels_min = 1, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .capture = { + .stream_name = "VSP Capture", + .channels_min = 1, + .channels_max = 2, + .rates = CS42L73_RATES, + .formats = CS42L73_FORMATS, + }, + .ops = &cs42l73_ops, + .symmetric_rates = 1, + } +}; + +static int cs42l73_suspend(struct snd_soc_codec *codec) +{ + cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF); + + return 0; +} + +static int cs42l73_resume(struct snd_soc_codec *codec) +{ + cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} + +static int cs42l73_probe(struct snd_soc_codec *codec) +{ + int ret; + struct cs42l73_private *cs42l73 = snd_soc_codec_get_drvdata(codec); + + codec->control_data = cs42l73->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + regcache_cache_only(cs42l73->regmap, true); + + cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */ + cs42l73->mclk = 0; + + return ret; +} + +static int cs42l73_remove(struct snd_soc_codec *codec) +{ + cs42l73_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_cs42l73 = { + .probe = cs42l73_probe, + .remove = cs42l73_remove, + .suspend = cs42l73_suspend, + .resume = cs42l73_resume, + .set_bias_level = cs42l73_set_bias_level, + + .dapm_widgets = cs42l73_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs42l73_dapm_widgets), + .dapm_routes = cs42l73_audio_map, + .num_dapm_routes = ARRAY_SIZE(cs42l73_audio_map), + + .controls = cs42l73_snd_controls, + .num_controls = ARRAY_SIZE(cs42l73_snd_controls), +}; + +static struct regmap_config cs42l73_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = CS42L73_MAX_REGISTER, + .reg_defaults = cs42l73_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs42l73_reg_defaults), + .volatile_reg = cs42l73_volatile_register, + .readable_reg = cs42l73_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + +static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + struct cs42l73_private *cs42l73; + int ret; + unsigned int devid = 0; + unsigned int reg; + + cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private), + GFP_KERNEL); + if (!cs42l73) { + dev_err(&i2c_client->dev, "could not allocate codec\n"); + return -ENOMEM; + } + + i2c_set_clientdata(i2c_client, cs42l73); + + cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); + if (IS_ERR(cs42l73->regmap)) { + ret = PTR_ERR(cs42l73->regmap); + dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + goto err; + } + /* initialize codec */ + ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); + devid = (reg & 0xFF) << 12; + + ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_CD, ®); + devid |= (reg & 0xFF) << 4; + + ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); + devid |= (reg & 0xF0) >> 4; + + + if (devid != CS42L73_DEVID) { + ret = -ENODEV; + dev_err(&i2c_client->dev, + "CS42L73 Device ID (%X). Expected %X\n", + devid, CS42L73_DEVID); + goto err_regmap; + } + + ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); + if (ret < 0) { + dev_err(&i2c_client->dev, "Get Revision ID failed\n"); + goto err_regmap; + } + + dev_info(&i2c_client->dev, + "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); + + regcache_cache_only(cs42l73->regmap, true); + + ret = snd_soc_register_codec(&i2c_client->dev, + &soc_codec_dev_cs42l73, cs42l73_dai, + ARRAY_SIZE(cs42l73_dai)); + if (ret < 0) + goto err_regmap; + return 0; + +err_regmap: + regmap_exit(cs42l73->regmap); + +err: + return ret; +} + +static __devexit int cs42l73_i2c_remove(struct i2c_client *client) +{ + struct cs42l73_private *cs42l73 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + regmap_exit(cs42l73->regmap); + + return 0; +} + +static const struct i2c_device_id cs42l73_id[] = { + {"cs42l73", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs42l73_id); + +static struct i2c_driver cs42l73_i2c_driver = { + .driver = { + .name = "cs42l73", + .owner = THIS_MODULE, + }, + .id_table = cs42l73_id, + .probe = cs42l73_i2c_probe, + .remove = __devexit_p(cs42l73_i2c_remove), + +}; + +static int __init cs42l73_modinit(void) +{ + int ret; + ret = i2c_add_driver(&cs42l73_i2c_driver); + if (ret != 0) { + pr_err("Failed to register CS42L73 I2C driver: %d\n", ret); + return ret; + } + return 0; +} + +module_init(cs42l73_modinit); + +static void __exit cs42l73_exit(void) +{ + i2c_del_driver(&cs42l73_i2c_driver); +} + +module_exit(cs42l73_exit); + +MODULE_DESCRIPTION("ASoC CS42L73 driver"); +MODULE_AUTHOR("Georgi Vlaev, Nucleus Systems Ltd, <joe@nucleusys.com>"); +MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l73.h b/sound/soc/codecs/cs42l73.h new file mode 100644 index 00000000000..f30a4c4d62e --- /dev/null +++ b/sound/soc/codecs/cs42l73.h @@ -0,0 +1,227 @@ +/* + * ALSA SoC CS42L73 codec driver + * + * Copyright 2011 Cirrus Logic, Inc. + * + * Author: Georgi Vlaev <joe@nucleusys.com> + * Brian Austin <brian.austin@cirrus.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef __CS42L73_H__ +#define __CS42L73_H__ + +/* I2C Registers */ +/* I2C Address: 1001010[R/W] - 10010100 = 0x94(Write); 10010101 = 0x95(Read) */ +#define CS42L73_CHIP_ID 0x4a +#define CS42L73_DEVID_AB 0x01 /* Device ID A & B [RO]. */ +#define CS42L73_DEVID_CD 0x02 /* Device ID C & D [RO]. */ +#define CS42L73_DEVID_E 0x03 /* Device ID E [RO]. */ +#define CS42L73_REVID 0x05 /* Revision ID [RO]. */ +#define CS42L73_PWRCTL1 0x06 /* Power Control 1. */ +#define CS42L73_PWRCTL2 0x07 /* Power Control 2. */ +#define CS42L73_PWRCTL3 0x08 /* Power Control 3. */ +#define CS42L73_CPFCHC 0x09 /* Charge Pump Freq. Class H Ctl. */ +#define CS42L73_OLMBMSDC 0x0A /* Output Load, MIC Bias, MIC2 SDT */ +#define CS42L73_DMMCC 0x0B /* Digital MIC & Master Clock Ctl. */ +#define CS42L73_XSPC 0x0C /* Auxiliary Serial Port (XSP) Ctl. */ +#define CS42L73_XSPMMCC 0x0D /* XSP Master Mode Clocking Control. */ +#define CS42L73_ASPC 0x0E /* Audio Serial Port (ASP) Control. */ +#define CS42L73_ASPMMCC 0x0F /* ASP Master Mode Clocking Control. */ +#define CS42L73_VSPC 0x10 /* Voice Serial Port (VSP) Control. */ +#define CS42L73_VSPMMCC 0x11 /* VSP Master Mode Clocking Control. */ +#define CS42L73_VXSPFS 0x12 /* VSP & XSP Sample Rate. */ +#define CS42L73_MIOPC 0x13 /* Misc. Input & Output Path Control. */ +#define CS42L73_ADCIPC 0x14 /* ADC/IP Control. */ +#define CS42L73_MICAPREPGAAVOL 0x15 /* MIC 1 [A] PreAmp, PGAA Vol. */ +#define CS42L73_MICBPREPGABVOL 0x16 /* MIC 2 [B] PreAmp, PGAB Vol. */ +#define CS42L73_IPADVOL 0x17 /* Input Pat7h A Digital Volume. */ +#define CS42L73_IPBDVOL 0x18 /* Input Path B Digital Volume. */ +#define CS42L73_PBDC 0x19 /* Playback Digital Control. */ +#define CS42L73_HLADVOL 0x1A /* HP/Line A Out Digital Vol. */ +#define CS42L73_HLBDVOL 0x1B /* HP/Line B Out Digital Vol. */ +#define CS42L73_SPKDVOL 0x1C /* Spkphone Out [A] Digital Vol. */ +#define CS42L73_ESLDVOL 0x1D /* Ear/Spkphone LO [B] Digital */ +#define CS42L73_HPAAVOL 0x1E /* HP A Analog Volume. */ +#define CS42L73_HPBAVOL 0x1F /* HP B Analog Volume. */ +#define CS42L73_LOAAVOL 0x20 /* Line Out A Analog Volume. */ +#define CS42L73_LOBAVOL 0x21 /* Line Out B Analog Volume. */ +#define CS42L73_STRINV 0x22 /* Stereo Input Path Adv. Vol. */ +#define CS42L73_XSPINV 0x23 /* Auxiliary Port Input Advisory Vol. */ +#define CS42L73_ASPINV 0x24 /* Audio Port Input Advisory Vol. */ +#define CS42L73_VSPINV 0x25 /* Voice Port Input Advisory Vol. */ +#define CS42L73_LIMARATEHL 0x26 /* Lmtr Attack Rate HP/Line. */ +#define CS42L73_LIMRRATEHL 0x27 /* Lmtr Ctl, Rel.Rate HP/Line. */ +#define CS42L73_LMAXHL 0x28 /* Lmtr Thresholds HP/Line. */ +#define CS42L73_LIMARATESPK 0x29 /* Lmtr Attack Rate Spkphone [A]. */ +#define CS42L73_LIMRRATESPK 0x2A /* Lmtr Ctl,Release Rate Spk. [A]. */ +#define CS42L73_LMAXSPK 0x2B /* Lmtr Thresholds Spkphone [A]. */ +#define CS42L73_LIMARATEESL 0x2C /* Lmtr Attack Rate */ +#define CS42L73_LIMRRATEESL 0x2D /* Lmtr Ctl,Release Rate */ +#define CS42L73_LMAXESL 0x2E /* Lmtr Thresholds */ +#define CS42L73_ALCARATE 0x2F /* ALC Enable, Attack Rate AB. */ +#define CS42L73_ALCRRATE 0x30 /* ALC Release Rate AB. */ +#define CS42L73_ALCMINMAX 0x31 /* ALC Thresholds AB. */ +#define CS42L73_NGCAB 0x32 /* Noise Gate Ctl AB. */ +#define CS42L73_ALCNGMC 0x33 /* ALC & Noise Gate Misc Ctl. */ +#define CS42L73_MIXERCTL 0x34 /* Mixer Control. */ +#define CS42L73_HLAIPAA 0x35 /* HP/LO Left Mixer: L. */ +#define CS42L73_HLBIPBA 0x36 /* HP/LO Right Mixer: R. */ +#define CS42L73_HLAXSPAA 0x37 /* HP/LO Left Mixer: XSP L */ +#define CS42L73_HLBXSPBA 0x38 /* HP/LO Right Mixer: XSP R */ +#define CS42L73_HLAASPAA 0x39 /* HP/LO Left Mixer: ASP L */ +#define CS42L73_HLBASPBA 0x3A /* HP/LO Right Mixer: ASP R */ +#define CS42L73_HLAVSPMA 0x3B /* HP/LO Left Mixer: VSP. */ +#define CS42L73_HLBVSPMA 0x3C /* HP/LO Right Mixer: VSP */ +#define CS42L73_XSPAIPAA 0x3D /* XSP Left Mixer: Left */ +#define CS42L73_XSPBIPBA 0x3E /* XSP Rt. Mixer: Right */ +#define CS42L73_XSPAXSPAA 0x3F /* XSP Left Mixer: XSP L */ +#define CS42L73_XSPBXSPBA 0x40 /* XSP Rt. Mixer: XSP R */ +#define CS42L73_XSPAASPAA 0x41 /* XSP Left Mixer: ASP L */ +#define CS42L73_XSPAASPBA 0x42 /* XSP Rt. Mixer: ASP R */ +#define CS42L73_XSPAVSPMA 0x43 /* XSP Left Mixer: VSP */ +#define CS42L73_XSPBVSPMA 0x44 /* XSP Rt. Mixer: VSP */ +#define CS42L73_ASPAIPAA 0x45 /* ASP Left Mixer: Left */ +#define CS42L73_ASPBIPBA 0x46 /* ASP Rt. Mixer: Right */ +#define CS42L73_ASPAXSPAA 0x47 /* ASP Left Mixer: XSP L */ +#define CS42L73_ASPBXSPBA 0x48 /* ASP Rt. Mixer: XSP R */ +#define CS42L73_ASPAASPAA 0x49 /* ASP Left Mixer: ASP L */ +#define CS42L73_ASPBASPBA 0x4A /* ASP Rt. Mixer: ASP R */ +#define CS42L73_ASPAVSPMA 0x4B /* ASP Left Mixer: VSP */ +#define CS42L73_ASPBVSPMA 0x4C /* ASP Rt. Mixer: VSP */ +#define CS42L73_VSPAIPAA 0x4D /* VSP Left Mixer: Left */ +#define CS42L73_VSPBIPBA 0x4E /* VSP Rt. Mixer: Right */ +#define CS42L73_VSPAXSPAA 0x4F /* VSP Left Mixer: XSP L */ +#define CS42L73_VSPBXSPBA 0x50 /* VSP Rt. Mixer: XSP R */ +#define CS42L73_VSPAASPAA 0x51 /* VSP Left Mixer: ASP Left */ +#define CS42L73_VSPBASPBA 0x52 /* VSP Rt. Mixer: ASP Right */ +#define CS42L73_VSPAVSPMA 0x53 /* VSP Left Mixer: VSP */ +#define CS42L73_VSPBVSPMA 0x54 /* VSP Rt. Mixer: VSP */ +#define CS42L73_MMIXCTL 0x55 /* Mono Mixer Controls. */ +#define CS42L73_SPKMIPMA 0x56 /* SPK Mono Mixer: In. Path */ +#define CS42L73_SPKMXSPA 0x57 /* SPK Mono Mixer: XSP Mono/L/R Att. */ +#define CS42L73_SPKMASPA 0x58 /* SPK Mono Mixer: ASP Mono/L/R Att. */ +#define CS42L73_SPKMVSPMA 0x59 /* SPK Mono Mixer: VSP Mono Atten. */ +#define CS42L73_ESLMIPMA 0x5A /* Ear/SpLO Mono Mixer: */ +#define CS42L73_ESLMXSPA 0x5B /* Ear/SpLO Mono Mixer: XSP */ +#define CS42L73_ESLMASPA 0x5C /* Ear/SpLO Mono Mixer: ASP */ +#define CS42L73_ESLMVSPMA 0x5D /* Ear/SpLO Mono Mixer: VSP */ +#define CS42L73_IM1 0x5E /* Interrupt Mask 1. */ +#define CS42L73_IM2 0x5F /* Interrupt Mask 2. */ +#define CS42L73_IS1 0x60 /* Interrupt Status 1 [RO]. */ +#define CS42L73_IS2 0x61 /* Interrupt Status 2 [RO]. */ +#define CS42L73_MAX_REGISTER 0x61 /* Total Registers */ +/* Bitfield Definitions */ + +/* CS42L73_PWRCTL1 */ +#define PDN_ADCB (1 << 7) +#define PDN_DMICB (1 << 6) +#define PDN_ADCA (1 << 5) +#define PDN_DMICA (1 << 4) +#define PDN_LDO (1 << 2) +#define DISCHG_FILT (1 << 1) +#define PDN (1 << 0) + +/* CS42L73_PWRCTL2 */ +#define PDN_MIC2_BIAS (1 << 7) +#define PDN_MIC1_BIAS (1 << 6) +#define PDN_VSP (1 << 4) +#define PDN_ASP_SDOUT (1 << 3) +#define PDN_ASP_SDIN (1 << 2) +#define PDN_XSP_SDOUT (1 << 1) +#define PDN_XSP_SDIN (1 << 0) + +/* CS42L73_PWRCTL3 */ +#define PDN_THMS (1 << 5) +#define PDN_SPKLO (1 << 4) +#define PDN_EAR (1 << 3) +#define PDN_SPK (1 << 2) +#define PDN_LO (1 << 1) +#define PDN_HP (1 << 0) + +/* Thermal Overload Detect. Requires interrupt ... */ +#define THMOVLD_150C 0 +#define THMOVLD_132C 1 +#define THMOVLD_115C 2 +#define THMOVLD_098C 3 + + +/* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */ +#define SP_3ST (1 << 7) +#define SPDIF_I2S (0 << 6) +#define SPDIF_PCM (1 << 6) +#define PCM_MODE0 (0 << 4) +#define PCM_MODE1 (1 << 4) +#define PCM_MODE2 (2 << 4) +#define PCM_MODE_MASK (3 << 4) +#define PCM_BIT_ORDER (1 << 3) +#define MCK_SCLK_64FS (0 << 0) +#define MCK_SCLK_MCLK (2 << 0) +#define MCK_SCLK_PREMCLK (3 << 0) + +/* CS42L73_xSPMMCC */ +#define MS_MASTER (1 << 7) + + +/* CS42L73_DMMCC */ +#define MCLKDIS (1 << 0) +#define MCLKSEL_MCLK2 (1 << 4) +#define MCLKSEL_MCLK1 (0 << 4) + +/* CS42L73 MCLK derived from MCLK1 or MCLK2 */ +#define CS42L73_CLKID_MCLK1 0 +#define CS42L73_CLKID_MCLK2 1 + +#define CS42L73_MCLKXDIV 0 +#define CS42L73_MMCCDIV 1 + +#define CS42L73_XSP 0 +#define CS42L73_ASP 1 +#define CS42L73_VSP 2 + +/* IS1, IM1 */ +#define MIC2_SDET (1 << 6) +#define THMOVLD (1 << 4) +#define DIGMIXOVFL (1 << 3) +#define IPBOVFL (1 << 1) +#define IPAOVFL (1 << 0) + +/* Analog Softramp */ +#define ANLGOSFT (1 << 0) + +/* HP A/B Analog Mute */ +#define HPA_MUTE (1 << 7) +/* LO A/B Analog Mute */ +#define LOA_MUTE (1 << 7) +/* Digital Mute */ +#define HLAD_MUTE (1 << 0) +#define HLBD_MUTE (1 << 1) +#define SPKD_MUTE (1 << 2) +#define ESLD_MUTE (1 << 3) + +/* Misc defines for codec */ +#define CS42L73_RESET_GPIO 143 + +#define CS42L73_DEVID 0x00042A73 +#define CS42L73_MCLKX_MIN 5644800 +#define CS42L73_MCLKX_MAX 38400000 + +#define CS42L73_SPC(id) (CS42L73_XSPC + (id << 1)) +#define CS42L73_MMCC(id) (CS42L73_XSPMMCC + (id << 1)) +#define CS42L73_SPFS(id) ((id == CS42L73_ASP) ? CS42L73_ASPC : CS42L73_VXSPFS) + +#endif /* __CS42L73_H__ */ diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index bc7067db8ae..d5fd00a6474 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -16,6 +16,7 @@ #include <linux/tty.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/regulator/consumer.h> #include <sound/core.h> #include <sound/initval.h> @@ -25,8 +26,8 @@ struct cx20442_priv { - enum snd_soc_control_type control_type; void *control_data; + struct regulator *por; }; #define CX20442_PM 0x0 @@ -324,6 +325,38 @@ static struct snd_soc_dai_driver cx20442_dai = { }, }; +static int cx20442_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); + int err = 0; + + switch (level) { + case SND_SOC_BIAS_PREPARE: + if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY) + break; + if (IS_ERR(cx20442->por)) + err = PTR_ERR(cx20442->por); + else + err = regulator_enable(cx20442->por); + break; + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE) + break; + if (IS_ERR(cx20442->por)) + err = PTR_ERR(cx20442->por); + else + err = regulator_disable(cx20442->por); + break; + default: + break; + } + if (!err) + codec->dapm.bias_level = level; + + return err; +} + static int cx20442_codec_probe(struct snd_soc_codec *codec) { struct cx20442_priv *cx20442; @@ -331,9 +364,13 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL); if (cx20442 == NULL) return -ENOMEM; - snd_soc_codec_set_drvdata(codec, cx20442); + cx20442->por = regulator_get(codec->dev, "POR"); + if (IS_ERR(cx20442->por)) + dev_warn(codec->dev, "failed to get the regulator"); cx20442->control_data = NULL; + + snd_soc_codec_set_drvdata(codec, cx20442); codec->hw_write = NULL; codec->card->pop_time = 0; @@ -350,6 +387,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) tty_hangup(tty); } + if (!IS_ERR(cx20442->por)) { + /* should be already in STANDBY, hence disabled */ + regulator_put(cx20442->por); + } + + snd_soc_codec_set_drvdata(codec, NULL); kfree(cx20442); return 0; } @@ -359,6 +402,7 @@ static const u8 cx20442_reg; static struct snd_soc_codec_driver cx20442_codec_dev = { .probe = cx20442_codec_probe, .remove = cx20442_codec_remove, + .set_bias_level = cx20442_set_bias_level, .reg_cache_default = &cx20442_reg, .reg_cache_size = 1, .reg_word_size = sizeof(u8), @@ -391,17 +435,7 @@ static struct platform_driver cx20442_platform_driver = { .remove = __exit_p(cx20442_platform_remove), }; -static int __init cx20442_init(void) -{ - return platform_driver_register(&cx20442_platform_driver); -} -module_init(cx20442_init); - -static void __exit cx20442_exit(void) -{ - platform_driver_unregister(&cx20442_platform_driver); -} -module_exit(cx20442_exit); +module_platform_driver(cx20442_platform_driver); MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver"); MODULE_AUTHOR("Janusz Krzysztofik"); diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index b545b7d3722..ab38e93c354 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <linux/module.h> #include <sound/pcm.h> @@ -182,9 +181,14 @@ /* AUX1_L bit fields */ #define DA7210_AUX1_L_VOL (0x3F << 0) +#define DA7210_AUX1_L_EN (1 << 7) /* AUX1_R bit fields */ #define DA7210_AUX1_R_VOL (0x3F << 0) +#define DA7210_AUX1_R_EN (1 << 7) + +/* AUX2 bit fields */ +#define DA7210_AUX2_EN (1 << 3) /* Minimum INPGA and AUX1 volume to enable noise suppression */ #define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */ @@ -235,12 +239,22 @@ static const unsigned int mono_vol_tlv[] = { 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0) }; +static const unsigned int aux1_vol_tlv[] = { + TLV_DB_RANGE_HEAD(2), + 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), + /* -48dB to 21dB */ + 0x11, 0x3f, TLV_DB_SCALE_ITEM(-4800, 150, 0) +}; + static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1); static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0); +static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0); +static const DECLARE_TLV_DB_SCALE(aux2_vol_tlv, -600, 600, 0); +static const DECLARE_TLV_DB_SCALE(inpga_gain_tlv, -450, 150, 0); /* ADC and DAC high pass filter f0 value */ -static const char const *da7210_hpf_cutoff_txt[] = { +static const char * const da7210_hpf_cutoff_txt[] = { "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" }; @@ -251,7 +265,7 @@ static const struct soc_enum da7210_adc_hpf_cutoff = SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt); /* ADC and DAC voice (8kHz) high pass cutoff value */ -static const char const *da7210_vf_cutoff_txt[] = { +static const char * const da7210_vf_cutoff_txt[] = { "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" }; @@ -345,6 +359,17 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = { SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0, mono_vol_tlv), + SOC_DOUBLE_R_TLV("Mic Capture Volume", + DA7210_MIC_L, DA7210_MIC_R, + 0, 0x5, 0, mic_vol_tlv), + SOC_DOUBLE_R_TLV("Aux1 Capture Volume", + DA7210_AUX1_L, DA7210_AUX1_R, + 0, 0x3f, 0, aux1_vol_tlv), + SOC_SINGLE_TLV("Aux2 Capture Volume", DA7210_AUX2, 0, 0x3, 0, + aux2_vol_tlv), + SOC_DOUBLE_TLV("In PGA Capture Volume", DA7210_IN_GAIN, 0, 4, 0xF, 0, + inpga_gain_tlv), + /* DAC Equalizer controls */ SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0), SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1, @@ -422,26 +447,42 @@ static const struct snd_kcontrol_new da7210_snd_controls[] = { static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = { SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0), SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0), + SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_INMIX_L, 2, 1, 0), + SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_L, 3, 1, 0), + SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_INMIX_L, 4, 1, 0), }; /* In Mixer Right */ static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = { SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0), SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0), + SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_INMIX_R, 2, 1, 0), + SOC_DAPM_SINGLE("Aux2 Switch", DA7210_INMIX_R, 3, 1, 0), + SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_INMIX_R, 4, 1, 0), }; /* Out Mixer Left */ static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = { + SOC_DAPM_SINGLE("Aux1 Left Switch", DA7210_OUTMIX_L, 0, 1, 0), + SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_L, 1, 1, 0), + SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_L, 2, 1, 0), + SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_L, 3, 1, 0), SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0), }; /* Out Mixer Right */ static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = { + SOC_DAPM_SINGLE("Aux1 Right Switch", DA7210_OUTMIX_R, 0, 1, 0), + SOC_DAPM_SINGLE("Aux2 Switch", DA7210_OUTMIX_R, 1, 1, 0), + SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUTMIX_R, 2, 1, 0), + SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUTMIX_R, 3, 1, 0), SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0), }; /* Mono Mixer */ static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = { + SOC_DAPM_SINGLE("INPGA Right Switch", DA7210_OUT2, 3, 1, 0), + SOC_DAPM_SINGLE("INPGA Left Switch", DA7210_OUT2, 4, 1, 0), SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0), SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0), }; @@ -452,14 +493,23 @@ static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { /* Input Lines */ SND_SOC_DAPM_INPUT("MICL"), SND_SOC_DAPM_INPUT("MICR"), + SND_SOC_DAPM_INPUT("AUX1L"), + SND_SOC_DAPM_INPUT("AUX1R"), + SND_SOC_DAPM_INPUT("AUX2"), /* Input PGAs */ SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0), SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0), + SND_SOC_DAPM_PGA("Aux1 Left", DA7210_STARTUP3, 2, 1, NULL, 0), + SND_SOC_DAPM_PGA("Aux1 Right", DA7210_STARTUP3, 3, 1, NULL, 0), + SND_SOC_DAPM_PGA("Aux2 Mono", DA7210_STARTUP3, 4, 1, NULL, 0), SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0), SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0), + /* MICBIAS */ + SND_SOC_DAPM_SUPPLY("Mic Bias", DA7210_MIC_L, 6, 0, NULL, 0), + /* Input Mixers */ SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0, &da7210_dapm_inmixl_controls[0], @@ -515,12 +565,21 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = { /* Input path */ {"Mic Left", NULL, "MICL"}, {"Mic Right", NULL, "MICR"}, + {"Aux1 Left", NULL, "AUX1L"}, + {"Aux1 Right", NULL, "AUX1R"}, + {"Aux2 Mono", NULL, "AUX2"}, {"In Mixer Left", "Mic Left Switch", "Mic Left"}, {"In Mixer Left", "Mic Right Switch", "Mic Right"}, + {"In Mixer Left", "Aux1 Left Switch", "Aux1 Left"}, + {"In Mixer Left", "Aux2 Switch", "Aux2 Mono"}, + {"In Mixer Left", "Outmix Left Switch", "Out Mixer Left"}, {"In Mixer Right", "Mic Right Switch", "Mic Right"}, {"In Mixer Right", "Mic Left Switch", "Mic Left"}, + {"In Mixer Right", "Aux1 Right Switch", "Aux1 Right"}, + {"In Mixer Right", "Aux2 Switch", "Aux2 Mono"}, + {"In Mixer Right", "Outmix Right Switch", "Out Mixer Right"}, {"INPGA Left", NULL, "In Mixer Left"}, {"ADC Left", NULL, "INPGA Left"}, @@ -529,9 +588,20 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = { {"ADC Right", NULL, "INPGA Right"}, /* Output path */ + {"Out Mixer Left", "Aux1 Left Switch", "Aux1 Left"}, + {"Out Mixer Left", "Aux2 Switch", "Aux2 Mono"}, + {"Out Mixer Left", "INPGA Left Switch", "INPGA Left"}, + {"Out Mixer Left", "INPGA Right Switch", "INPGA Right"}, {"Out Mixer Left", "DAC Left Switch", "DAC Left"}, + + {"Out Mixer Right", "Aux1 Right Switch", "Aux1 Right"}, + {"Out Mixer Right", "Aux2 Switch", "Aux2 Mono"}, + {"Out Mixer Right", "INPGA Right Switch", "INPGA Right"}, + {"Out Mixer Right", "INPGA Left Switch", "INPGA Left"}, {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, + {"Mono Mixer", "INPGA Right Switch", "INPGA Right"}, + {"Mono Mixer", "INPGA Left Switch", "INPGA Left"}, {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"}, {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"}, @@ -761,7 +831,7 @@ static int da7210_mute(struct snd_soc_dai *dai, int mute) SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) /* DAI operations */ -static struct snd_soc_dai_ops da7210_dai_ops = { +static const struct snd_soc_dai_ops da7210_dai_ops = { .hw_params = da7210_hw_params, .set_fmt = da7210_set_dai_fmt, .digital_mute = da7210_mute, @@ -888,6 +958,12 @@ static int da7210_probe(struct snd_soc_codec *codec) snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN | DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R); + /* Enable Aux1 */ + snd_soc_write(codec, DA7210_AUX1_L, DA7210_AUX1_L_EN); + snd_soc_write(codec, DA7210_AUX1_R, DA7210_AUX1_R_EN); + /* Enable Aux2 */ + snd_soc_write(codec, DA7210_AUX2, DA7210_AUX2_EN); + /* Diable PLL and bypass it */ snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); @@ -945,7 +1021,8 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, struct da7210_priv *da7210; int ret; - da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL); + da7210 = devm_kzalloc(&i2c->dev, sizeof(struct da7210_priv), + GFP_KERNEL); if (!da7210) return -ENOMEM; @@ -954,16 +1031,12 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da7210, &da7210_dai, 1); - if (ret < 0) - kfree(da7210); - return ret; } static int __devexit da7210_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/dfbmcs320.c b/sound/soc/codecs/dfbmcs320.c index 704bbde6573..bfe46aa9036 100644 --- a/sound/soc/codecs/dfbmcs320.c +++ b/sound/soc/codecs/dfbmcs320.c @@ -55,17 +55,7 @@ static struct platform_driver dfmcs320_driver = { .remove = __devexit_p(dfbmcs320_remove), }; -static int __init dfbmcs320_init(void) -{ - return platform_driver_register(&dfmcs320_driver); -} -module_init(dfbmcs320_init); - -static void __exit dfbmcs320_exit(void) -{ - platform_driver_unregister(&dfmcs320_driver); -} -module_exit(dfbmcs320_exit); +module_platform_driver(dfmcs320_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("ASoC DFBM-CS320 bluethooth module driver"); diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index 6fae765e3ad..3e929f079a1 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c @@ -89,17 +89,7 @@ static struct platform_driver dmic_driver = { .remove = __devexit_p(dmic_dev_remove), }; -static int __init dmic_init(void) -{ - return platform_driver_register(&dmic_driver); -} -module_init(dmic_init); - -static void __exit dmic_exit(void) -{ - platform_driver_unregister(&dmic_driver); -} -module_exit(dmic_exit); +module_platform_driver(dmic_driver); MODULE_DESCRIPTION("Generic DMIC driver"); MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>"); diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index e373f8f0690..4624e752a18 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/io.h> #include <linux/delay.h> @@ -206,7 +207,7 @@ static int jz4740_codec_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops jz4740_codec_dai_ops = { +static const struct snd_soc_dai_ops jz4740_codec_dai_ops = { .hw_params = jz4740_codec_hw_params, }; @@ -311,7 +312,7 @@ static int jz4740_codec_dev_remove(struct snd_soc_codec *codec) #ifdef CONFIG_PM_SLEEP -static int jz4740_codec_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int jz4740_codec_suspend(struct snd_soc_codec *codec) { return jz4740_codec_set_bias_level(codec, SND_SOC_BIAS_OFF); } @@ -352,7 +353,8 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) struct jz4740_codec *jz4740_codec; struct resource *mem; - jz4740_codec = kzalloc(sizeof(*jz4740_codec), GFP_KERNEL); + jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec), + GFP_KERNEL); if (!jz4740_codec) return -ENOMEM; @@ -360,14 +362,14 @@ static int __devinit jz4740_codec_probe(struct platform_device *pdev) if (!mem) { dev_err(&pdev->dev, "Failed to get mmio memory resource\n"); ret = -ENOENT; - goto err_free_codec; + goto err_out; } mem = request_mem_region(mem->start, resource_size(mem), pdev->name); if (!mem) { dev_err(&pdev->dev, "Failed to request mmio memory region\n"); ret = -EBUSY; - goto err_free_codec; + goto err_out; } jz4740_codec->base = ioremap(mem->start, resource_size(mem)); @@ -393,9 +395,7 @@ err_iounmap: iounmap(jz4740_codec->base); err_release_mem_region: release_mem_region(mem->start, resource_size(mem)); -err_free_codec: - kfree(jz4740_codec); - +err_out: return ret; } @@ -410,7 +410,6 @@ static int __devexit jz4740_codec_remove(struct platform_device *pdev) release_mem_region(mem->start, resource_size(mem)); platform_set_drvdata(pdev, NULL); - kfree(jz4740_codec); return 0; } @@ -424,17 +423,7 @@ static struct platform_driver jz4740_codec_driver = { }, }; -static int __init jz4740_codec_init(void) -{ - return platform_driver_register(&jz4740_codec_driver); -} -module_init(jz4740_codec_init); - -static void __exit jz4740_codec_exit(void) -{ - platform_driver_unregister(&jz4740_codec_driver); -} -module_exit(jz4740_codec_exit); +module_platform_driver(jz4740_codec_driver); MODULE_DESCRIPTION("JZ4740 SoC internal codec driver"); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index c387dafc6ab..319039240e0 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -215,7 +215,7 @@ static int __devinit lm4857_i2c_probe(struct i2c_client *i2c, struct lm4857 *lm4857; int ret; - lm4857 = kzalloc(sizeof(*lm4857), GFP_KERNEL); + lm4857 = devm_kzalloc(&i2c->dev, sizeof(*lm4857), GFP_KERNEL); if (!lm4857) return -ENOMEM; @@ -225,21 +225,12 @@ static int __devinit lm4857_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_lm4857, NULL, 0); - if (ret) { - kfree(lm4857); - return ret; - } - - return 0; + return ret; } static int __devexit lm4857_i2c_remove(struct i2c_client *i2c) { - struct lm4857 *lm4857 = i2c_get_clientdata(i2c); - snd_soc_unregister_codec(&i2c->dev); - kfree(lm4857); - return 0; } diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ebbf63c79c3..006efcfe6dd 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -15,7 +15,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -1650,14 +1649,14 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, #define MAX98088_RATES SNDRV_PCM_RATE_8000_96000 #define MAX98088_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops max98088_dai1_ops = { +static const struct snd_soc_dai_ops max98088_dai1_ops = { .set_sysclk = max98088_dai_set_sysclk, .set_fmt = max98088_dai1_set_fmt, .hw_params = max98088_dai1_hw_params, .digital_mute = max98088_dai1_digital_mute, }; -static struct snd_soc_dai_ops max98088_dai2_ops = { +static const struct snd_soc_dai_ops max98088_dai2_ops = { .set_sysclk = max98088_dai_set_sysclk, .set_fmt = max98088_dai2_set_fmt, .hw_params = max98088_dai2_hw_params, @@ -1947,7 +1946,7 @@ static void max98088_handle_pdata(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int max98088_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int max98088_suspend(struct snd_soc_codec *codec) { max98088_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -2070,7 +2069,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c, struct max98088_priv *max98088; int ret; - max98088 = kzalloc(sizeof(struct max98088_priv), GFP_KERNEL); + max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv), + GFP_KERNEL); if (max98088 == NULL) return -ENOMEM; @@ -2081,15 +2081,12 @@ static int max98088_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98088, &max98088_dai[0], 2); - if (ret < 0) - kfree(max98088); return ret; } static int __devexit max98088_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 26d7b089fb9..fcfa7497d7b 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -15,7 +15,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -1782,19 +1781,19 @@ static int max98095_set_bias_level(struct snd_soc_codec *codec, #define MAX98095_RATES SNDRV_PCM_RATE_8000_96000 #define MAX98095_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops max98095_dai1_ops = { +static const struct snd_soc_dai_ops max98095_dai1_ops = { .set_sysclk = max98095_dai_set_sysclk, .set_fmt = max98095_dai1_set_fmt, .hw_params = max98095_dai1_hw_params, }; -static struct snd_soc_dai_ops max98095_dai2_ops = { +static const struct snd_soc_dai_ops max98095_dai2_ops = { .set_sysclk = max98095_dai_set_sysclk, .set_fmt = max98095_dai2_set_fmt, .hw_params = max98095_dai2_hw_params, }; -static struct snd_soc_dai_ops max98095_dai3_ops = { +static const struct snd_soc_dai_ops max98095_dai3_ops = { .set_sysclk = max98095_dai_set_sysclk, .set_fmt = max98095_dai3_set_fmt, .hw_params = max98095_dai3_hw_params, @@ -2175,7 +2174,7 @@ static void max98095_handle_pdata(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int max98095_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int max98095_suspend(struct snd_soc_codec *codec) { max98095_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -2341,7 +2340,8 @@ static int max98095_i2c_probe(struct i2c_client *i2c, struct max98095_priv *max98095; int ret; - max98095 = kzalloc(sizeof(struct max98095_priv), GFP_KERNEL); + max98095 = devm_kzalloc(&i2c->dev, sizeof(struct max98095_priv), + GFP_KERNEL); if (max98095 == NULL) return -ENOMEM; @@ -2351,16 +2351,12 @@ static int max98095_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095, max98095_dai, ARRAY_SIZE(max98095_dai)); - if (ret < 0) - kfree(max98095); return ret; } static int __devexit max98095_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); - return 0; } diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c index 208d2ee6185..a1913091f56 100644 --- a/sound/soc/codecs/max9850.c +++ b/sound/soc/codecs/max9850.c @@ -86,7 +86,7 @@ SND_SOC_DAPM_INPUT("INL"), SND_SOC_DAPM_INPUT("INR"), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route max9850_dapm_routes[] = { /* output mixer */ {"Output Mixer", NULL, "DAC"}, {"Output Mixer", "Line In Switch", "Line Input"}, @@ -254,7 +254,7 @@ static int max9850_set_bias_level(struct snd_soc_codec *codec, #define MAX9850_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops max9850_dai_ops = { +static const struct snd_soc_dai_ops max9850_dai_ops = { .hw_params = max9850_hw_params, .set_sysclk = max9850_set_dai_sysclk, .set_fmt = max9850_set_dai_fmt, @@ -273,7 +273,7 @@ static struct snd_soc_dai_driver max9850_dai = { }; #ifdef CONFIG_PM -static int max9850_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int max9850_suspend(struct snd_soc_codec *codec) { max9850_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -293,7 +293,6 @@ static int max9850_resume(struct snd_soc_codec *codec) static int max9850_probe(struct snd_soc_codec *codec) { - struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); @@ -309,13 +308,6 @@ static int max9850_probe(struct snd_soc_codec *codec) /* set slew-rate 125ms */ snd_soc_update_bits(codec, MAX9850_CHARGE_PUMP, 0xff, 0xc0); - snd_soc_dapm_new_controls(dapm, max9850_dapm_widgets, - ARRAY_SIZE(max9850_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - snd_soc_add_controls(codec, max9850_controls, - ARRAY_SIZE(max9850_controls)); - return 0; } @@ -328,6 +320,13 @@ static struct snd_soc_codec_driver soc_codec_dev_max9850 = { .reg_word_size = sizeof(u8), .reg_cache_default = max9850_reg, .volatile_register = max9850_volatile_register, + + .controls = max9850_controls, + .num_controls = ARRAY_SIZE(max9850_controls), + .dapm_widgets = max9850_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(max9850_dapm_widgets), + .dapm_routes = max9850_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(max9850_dapm_routes), }; static int __devinit max9850_i2c_probe(struct i2c_client *i2c, @@ -336,7 +335,8 @@ static int __devinit max9850_i2c_probe(struct i2c_client *i2c, struct max9850_priv *max9850; int ret; - max9850 = kzalloc(sizeof(struct max9850_priv), GFP_KERNEL); + max9850 = devm_kzalloc(&i2c->dev, sizeof(struct max9850_priv), + GFP_KERNEL); if (max9850 == NULL) return -ENOMEM; @@ -344,15 +344,12 @@ static int __devinit max9850_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max9850, &max9850_dai, 1); - if (ret < 0) - kfree(max9850); return ret; } static __devexit int max9850_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 9e7e964a5fa..dcf6f2a1600 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c @@ -106,13 +106,13 @@ static int max9877_set_2reg(struct snd_kcontrol *kcontrol, unsigned int mask = mc->max; unsigned int val = (ucontrol->value.integer.value[0] & mask); unsigned int val2 = (ucontrol->value.integer.value[1] & mask); - unsigned int change = 1; + unsigned int change = 0; - if (((max9877_regs[reg] >> shift) & mask) == val) - change = 0; + if (((max9877_regs[reg] >> shift) & mask) != val) + change = 1; - if (((max9877_regs[reg2] >> shift) & mask) == val2) - change = 0; + if (((max9877_regs[reg2] >> shift) & mask) != val2) + change = 1; if (change) { max9877_regs[reg] &= ~(mask << shift); diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c index f7316519432..edcaa7ea548 100644 --- a/sound/soc/codecs/pcm3008.c +++ b/sound/soc/codecs/pcm3008.c @@ -118,7 +118,7 @@ static int pcm3008_soc_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int pcm3008_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg) +static int pcm3008_soc_suspend(struct snd_soc_codec *codec) { struct pcm3008_setup_data *setup = codec->dev->platform_data; @@ -172,17 +172,7 @@ static struct platform_driver pcm3008_codec_driver = { }, }; -static int __init pcm3008_modinit(void) -{ - return platform_driver_register(&pcm3008_codec_driver); -} -module_init(pcm3008_modinit); - -static void __exit pcm3008_exit(void) -{ - platform_driver_unregister(&pcm3008_codec_driver); -} -module_exit(pcm3008_exit); +module_platform_driver(pcm3008_codec_driver); MODULE_DESCRIPTION("Soc PCM3008 driver"); MODULE_AUTHOR("Hugo Villeneuve"); diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 27a078cbb6e..20c324c7c34 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <sound/core.h> #include <sound/pcm.h> @@ -177,7 +176,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */ static unsigned int mic_bst_tlv[] = { - TLV_DB_RANGE_HEAD(6), + TLV_DB_RANGE_HEAD(7), 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), @@ -1642,7 +1641,7 @@ static int rt5631_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int rt5631_suspend(struct snd_soc_codec *codec) { rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1664,7 +1663,7 @@ static int rt5631_resume(struct snd_soc_codec *codec) SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt5631_ops = { +static const struct snd_soc_dai_ops rt5631_ops = { .hw_params = rt5631_hifi_pcm_params, .set_fmt = rt5631_hifi_codec_set_dai_fmt, .set_sysclk = rt5631_hifi_codec_set_dai_sysclk, @@ -1725,7 +1724,8 @@ static int rt5631_i2c_probe(struct i2c_client *i2c, struct rt5631_priv *rt5631; int ret; - rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL); + rt5631 = devm_kzalloc(&i2c->dev, sizeof(struct rt5631_priv), + GFP_KERNEL); if (NULL == rt5631) return -ENOMEM; @@ -1733,16 +1733,12 @@ static int rt5631_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631, rt5631_dai, ARRAY_SIZE(rt5631_dai)); - if (ret < 0) - kfree(rt5631); - return ret; } static __devexit int rt5631_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index d15695d1c27..d7bd9183161 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -16,7 +16,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/clk.h> -#include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/consumer.h> @@ -365,7 +364,7 @@ static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0); /* tlv for mic gain, 0db 20db 30db 40db */ static const unsigned int mic_gain_tlv[] = { - TLV_DB_RANGE_HEAD(4), + TLV_DB_RANGE_HEAD(2), 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), }; @@ -833,7 +832,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, ldo->voltage = voltage; ldo->dev = regulator_register(&ldo->desc, codec->dev, - init_data, ldo); + init_data, ldo, NULL); if (IS_ERR(ldo->dev)) { int ret = PTR_ERR(ldo->dev); @@ -923,7 +922,7 @@ static int sgtl5000_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops sgtl5000_ops = { +static const struct snd_soc_dai_ops sgtl5000_ops = { .hw_params = sgtl5000_pcm_hw_params, .digital_mute = sgtl5000_digital_mute, .set_fmt = sgtl5000_set_dai_fmt, @@ -968,7 +967,7 @@ static int sgtl5000_volatile_register(struct snd_soc_codec *codec, } #ifdef CONFIG_SUSPEND -static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int sgtl5000_suspend(struct snd_soc_codec *codec) { sgtl5000_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1077,7 +1076,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) /* according to datasheet, maximum voltage of supplies */ if (vdda > 3600 || vddio > 3600 || vddd > 1980) { dev_err(codec->dev, - "exceed max voltage vdda %dmv vddio %dma vddd %dma\n", + "exceed max voltage vdda %dmV vddio %dmV vddd %dmV\n", vdda, vddio, vddd); return -EINVAL; @@ -1402,7 +1401,8 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, struct sgtl5000_priv *sgtl5000; int ret; - sgtl5000 = kzalloc(sizeof(struct sgtl5000_priv), GFP_KERNEL); + sgtl5000 = devm_kzalloc(&client->dev, sizeof(struct sgtl5000_priv), + GFP_KERNEL); if (!sgtl5000) return -ENOMEM; @@ -1410,22 +1410,13 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, ret = snd_soc_register_codec(&client->dev, &sgtl5000_driver, &sgtl5000_dai, 1); - if (ret) { - dev_err(&client->dev, "Failed to register codec: %d\n", ret); - kfree(sgtl5000); - return ret; - } - - return 0; + return ret; } static __devexit int sgtl5000_i2c_remove(struct i2c_client *client) { - struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - kfree(sgtl5000); return 0; } diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c new file mode 100644 index 00000000000..5be42bf5699 --- /dev/null +++ b/sound/soc/codecs/sigmadsp.c @@ -0,0 +1,246 @@ +/* + * Load Analog Devices SigmaStudio firmware files + * + * Copyright 2009-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/crc32.h> +#include <linux/delay.h> +#include <linux/firmware.h> +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/module.h> + +#include "sigmadsp.h" + +#define SIGMA_MAGIC "ADISIGM" + +struct sigma_firmware_header { + unsigned char magic[7]; + u8 version; + __le32 crc; +} __packed; + +enum { + SIGMA_ACTION_WRITEXBYTES = 0, + SIGMA_ACTION_WRITESINGLE, + SIGMA_ACTION_WRITESAFELOAD, + SIGMA_ACTION_DELAY, + SIGMA_ACTION_PLLWAIT, + SIGMA_ACTION_NOOP, + SIGMA_ACTION_END, +}; + +struct sigma_action { + u8 instr; + u8 len_hi; + __le16 len; + __be16 addr; + unsigned char payload[]; +} __packed; + +struct sigma_firmware { + const struct firmware *fw; + size_t pos; + + void *control_data; + int (*write)(void *control_data, const struct sigma_action *sa, + size_t len); +}; + +static inline u32 sigma_action_len(struct sigma_action *sa) +{ + return (sa->len_hi << 16) | le16_to_cpu(sa->len); +} + +static size_t sigma_action_size(struct sigma_action *sa) +{ + size_t payload = 0; + + switch (sa->instr) { + case SIGMA_ACTION_WRITEXBYTES: + case SIGMA_ACTION_WRITESINGLE: + case SIGMA_ACTION_WRITESAFELOAD: + payload = sigma_action_len(sa); + break; + default: + break; + } + + payload = ALIGN(payload, 2); + + return payload + sizeof(struct sigma_action); +} + +/* + * Returns a negative error value in case of an error, 0 if processing of + * the firmware should be stopped after this action, 1 otherwise. + */ +static int +process_sigma_action(struct sigma_firmware *ssfw, struct sigma_action *sa) +{ + size_t len = sigma_action_len(sa); + int ret; + + pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, + sa->instr, sa->addr, len); + + switch (sa->instr) { + case SIGMA_ACTION_WRITEXBYTES: + case SIGMA_ACTION_WRITESINGLE: + case SIGMA_ACTION_WRITESAFELOAD: + ret = ssfw->write(ssfw->control_data, sa, len); + if (ret < 0) + return -EINVAL; + break; + case SIGMA_ACTION_DELAY: + udelay(len); + len = 0; + break; + case SIGMA_ACTION_END: + return 0; + default: + return -EINVAL; + } + + return 1; +} + +static int +process_sigma_actions(struct sigma_firmware *ssfw) +{ + struct sigma_action *sa; + size_t size; + int ret; + + while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { + sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); + + size = sigma_action_size(sa); + ssfw->pos += size; + if (ssfw->pos > ssfw->fw->size || size == 0) + break; + + ret = process_sigma_action(ssfw, sa); + + pr_debug("%s: action returned %i\n", __func__, ret); + + if (ret <= 0) + return ret; + } + + if (ssfw->pos != ssfw->fw->size) + return -EINVAL; + + return 0; +} + +static int _process_sigma_firmware(struct device *dev, + struct sigma_firmware *ssfw, const char *name) +{ + int ret; + struct sigma_firmware_header *ssfw_head; + const struct firmware *fw; + u32 crc; + + pr_debug("%s: loading firmware %s\n", __func__, name); + + /* first load the blob */ + ret = request_firmware(&fw, name, dev); + if (ret) { + pr_debug("%s: request_firmware() failed with %i\n", __func__, ret); + return ret; + } + ssfw->fw = fw; + + /* then verify the header */ + ret = -EINVAL; + + /* + * Reject too small or unreasonable large files. The upper limit has been + * chosen a bit arbitrarily, but it should be enough for all practical + * purposes and having the limit makes it easier to avoid integer + * overflows later in the loading process. + */ + if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) { + dev_err(dev, "Failed to load firmware: Invalid size\n"); + goto done; + } + + ssfw_head = (void *)fw->data; + if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) { + dev_err(dev, "Failed to load firmware: Invalid magic\n"); + goto done; + } + + crc = crc32(0, fw->data + sizeof(*ssfw_head), + fw->size - sizeof(*ssfw_head)); + pr_debug("%s: crc=%x\n", __func__, crc); + if (crc != le32_to_cpu(ssfw_head->crc)) { + dev_err(dev, "Failed to load firmware: Wrong crc checksum: expected %x got %x\n", + le32_to_cpu(ssfw_head->crc), crc); + goto done; + } + + ssfw->pos = sizeof(*ssfw_head); + + /* finally process all of the actions */ + ret = process_sigma_actions(ssfw); + + done: + release_firmware(fw); + + pr_debug("%s: loaded %s\n", __func__, name); + + return ret; +} + +#if IS_ENABLED(CONFIG_I2C) + +static int sigma_action_write_i2c(void *control_data, + const struct sigma_action *sa, size_t len) +{ + return i2c_master_send(control_data, (const unsigned char *)&sa->addr, + len); +} + +int process_sigma_firmware(struct i2c_client *client, const char *name) +{ + struct sigma_firmware ssfw; + + ssfw.control_data = client; + ssfw.write = sigma_action_write_i2c; + + return _process_sigma_firmware(&client->dev, &ssfw, name); +} +EXPORT_SYMBOL(process_sigma_firmware); + +#endif + +#if IS_ENABLED(CONFIG_REGMAP) + +static int sigma_action_write_regmap(void *control_data, + const struct sigma_action *sa, size_t len) +{ + return regmap_raw_write(control_data, le16_to_cpu(sa->addr), + sa->payload, len - 2); +} + +int process_sigma_firmware_regmap(struct device *dev, struct regmap *regmap, + const char *name) +{ + struct sigma_firmware ssfw; + + ssfw.control_data = regmap; + ssfw.write = sigma_action_write_regmap; + + return _process_sigma_firmware(dev, &ssfw, name); +} +EXPORT_SYMBOL(process_sigma_firmware_regmap); + +#endif + +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sigmadsp.h b/sound/soc/codecs/sigmadsp.h new file mode 100644 index 00000000000..e439cbd7af7 --- /dev/null +++ b/sound/soc/codecs/sigmadsp.h @@ -0,0 +1,21 @@ +/* + * Load firmware files from Analog Devices SigmaStudio + * + * Copyright 2009-2011 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef __SIGMA_FIRMWARE_H__ +#define __SIGMA_FIRMWARE_H__ + +#include <linux/device.h> +#include <linux/regmap.h> + +struct i2c_client; + +extern int process_sigma_firmware(struct i2c_client *client, const char *name); +extern int process_sigma_firmware_regmap(struct device *dev, + struct regmap *regmap, const char *name); + +#endif diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 887d618f4a6..f99baa0b8c3 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c @@ -698,21 +698,21 @@ static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, } /* Codec DAI section */ -static struct snd_soc_dai_ops sn95031_headset_dai_ops = { +static const struct snd_soc_dai_ops sn95031_headset_dai_ops = { .digital_mute = sn95031_pcm_hs_mute, .hw_params = sn95031_pcm_hw_params, }; -static struct snd_soc_dai_ops sn95031_speaker_dai_ops = { +static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = { .digital_mute = sn95031_pcm_spkr_mute, .hw_params = sn95031_pcm_hw_params, }; -static struct snd_soc_dai_ops sn95031_vib1_dai_ops = { +static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = { .hw_params = sn95031_pcm_hw_params, }; -static struct snd_soc_dai_ops sn95031_vib2_dai_ops = { +static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = { .hw_params = sn95031_pcm_hw_params, }; @@ -920,19 +920,7 @@ static struct platform_driver sn95031_codec_driver = { .remove = __devexit_p(sn95031_device_remove), }; -static int __init sn95031_init(void) -{ - pr_debug("driver init called\n"); - return platform_driver_register(&sn95031_codec_driver); -} -module_init(sn95031_init); - -static void __exit sn95031_exit(void) -{ - pr_debug("driver exit called\n"); - platform_driver_unregister(&sn95031_codec_driver); -} -module_exit(sn95031_exit); +module_platform_driver(sn95031_codec_driver); MODULE_DESCRIPTION("ASoC TI SN95031 codec driver"); MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c index 6a1a7e705cd..112a49d66e3 100644 --- a/sound/soc/codecs/spdif_transciever.c +++ b/sound/soc/codecs/spdif_transciever.c @@ -61,18 +61,7 @@ static struct platform_driver spdif_dit_driver = { }, }; -static int __init dit_modinit(void) -{ - return platform_driver_register(&spdif_dit_driver); -} - -static void __exit dit_exit(void) -{ - platform_driver_unregister(&spdif_dit_driver); -} - -module_init(dit_modinit); -module_exit(dit_exit); +module_platform_driver(spdif_dit_driver); MODULE_AUTHOR("Steve Chen <schen@mvista.com>"); MODULE_DESCRIPTION("SPDIF dummy codec driver"); diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 3cb3271c5fe..333dd98af39 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -33,7 +33,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/spi/spi.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -498,7 +497,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops ssm2602_dai_ops = { +static const struct snd_soc_dai_ops ssm2602_dai_ops = { .startup = ssm2602_startup, .hw_params = ssm2602_hw_params, .shutdown = ssm2602_shutdown, @@ -524,7 +523,7 @@ static struct snd_soc_dai_driver ssm2602_dai = { .ops = &ssm2602_dai_ops, }; -static int ssm2602_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int ssm2602_suspend(struct snd_soc_codec *codec) { ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -653,7 +652,8 @@ static int __devinit ssm2602_spi_probe(struct spi_device *spi) struct ssm2602_priv *ssm2602; int ret; - ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL); + ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv), + GFP_KERNEL); if (ssm2602 == NULL) return -ENOMEM; @@ -663,15 +663,12 @@ static int __devinit ssm2602_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_ssm2602, &ssm2602_dai, 1); - if (ret < 0) - kfree(ssm2602); return ret; } static int __devexit ssm2602_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -698,7 +695,8 @@ static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c, struct ssm2602_priv *ssm2602; int ret; - ssm2602 = kzalloc(sizeof(struct ssm2602_priv), GFP_KERNEL); + ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv), + GFP_KERNEL); if (ssm2602 == NULL) return -ENOMEM; @@ -708,15 +706,12 @@ static int __devinit ssm2602_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_ssm2602, &ssm2602_dai, 1); - if (ret < 0) - kfree(ssm2602); return ret; } static int __devexit ssm2602_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index bb82408ab8e..7db6fa51502 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -24,9 +24,9 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> +#include <linux/workqueue.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> @@ -35,6 +35,7 @@ #include <sound/initval.h> #include <sound/tlv.h> +#include <sound/sta32x.h> #include "sta32x.h" #define STA32X_RATES (SNDRV_PCM_RATE_32000 | \ @@ -73,9 +74,14 @@ static const char *sta32x_supply_names[] = { struct sta32x_priv { struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)]; struct snd_soc_codec *codec; + struct sta32x_platform_data *pdata; unsigned int mclk; unsigned int format; + + u32 coef_shadow[STA32X_COEF_COUNT]; + struct delayed_work watchdog_work; + int shutdown; }; static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); @@ -227,6 +233,7 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; unsigned int cfud; @@ -239,6 +246,11 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, snd_soc_write(codec, STA32X_CFUD, cfud); snd_soc_write(codec, STA32X_CFADDR2, index); + for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++) + sta32x->coef_shadow[index + i] = + (ucontrol->value.bytes.data[3 * i] << 16) + | (ucontrol->value.bytes.data[3 * i + 1] << 8) + | (ucontrol->value.bytes.data[3 * i + 2]); for (i = 0; i < 3 * numcoef; i++) snd_soc_write(codec, STA32X_B1CF1 + i, ucontrol->value.bytes.data[i]); @@ -252,6 +264,88 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, return 0; } +static int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) +{ + struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); + unsigned int cfud; + int i; + + /* preserve reserved bits in STA32X_CFUD */ + cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; + + for (i = 0; i < STA32X_COEF_COUNT; i++) { + snd_soc_write(codec, STA32X_CFADDR2, i); + snd_soc_write(codec, STA32X_B1CF1, + (sta32x->coef_shadow[i] >> 16) & 0xff); + snd_soc_write(codec, STA32X_B1CF2, + (sta32x->coef_shadow[i] >> 8) & 0xff); + snd_soc_write(codec, STA32X_B1CF3, + (sta32x->coef_shadow[i]) & 0xff); + /* chip documentation does not say if the bits are + * self-clearing, so do it explicitly */ + snd_soc_write(codec, STA32X_CFUD, cfud); + snd_soc_write(codec, STA32X_CFUD, cfud | 0x01); + } + return 0; +} + +static int sta32x_cache_sync(struct snd_soc_codec *codec) +{ + unsigned int mute; + int rc; + + if (!codec->cache_sync) + return 0; + + /* mute during register sync */ + mute = snd_soc_read(codec, STA32X_MMUTE); + snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); + sta32x_sync_coef_shadow(codec); + rc = snd_soc_cache_sync(codec); + snd_soc_write(codec, STA32X_MMUTE, mute); + return rc; +} + +/* work around ESD issue where sta32x resets and loses all configuration */ +static void sta32x_watchdog(struct work_struct *work) +{ + struct sta32x_priv *sta32x = container_of(work, struct sta32x_priv, + watchdog_work.work); + struct snd_soc_codec *codec = sta32x->codec; + unsigned int confa, confa_cached; + + /* check if sta32x has reset itself */ + confa_cached = snd_soc_read(codec, STA32X_CONFA); + codec->cache_bypass = 1; + confa = snd_soc_read(codec, STA32X_CONFA); + codec->cache_bypass = 0; + if (confa != confa_cached) { + codec->cache_sync = 1; + sta32x_cache_sync(codec); + } + + if (!sta32x->shutdown) + schedule_delayed_work(&sta32x->watchdog_work, + round_jiffies_relative(HZ)); +} + +static void sta32x_watchdog_start(struct sta32x_priv *sta32x) +{ + if (sta32x->pdata->needs_esd_watchdog) { + sta32x->shutdown = 0; + schedule_delayed_work(&sta32x->watchdog_work, + round_jiffies_relative(HZ)); + } +} + +static void sta32x_watchdog_stop(struct sta32x_priv *sta32x) +{ + if (sta32x->pdata->needs_esd_watchdog) { + sta32x->shutdown = 1; + cancel_delayed_work_sync(&sta32x->watchdog_work); + } +} + #define SINGLE_COEF(xname, index) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = sta32x_coefficient_info, \ @@ -428,6 +522,7 @@ static int sta32x_set_dai_sysclk(struct snd_soc_dai *codec_dai, rate_min = fs; if (fs > rate_max) rate_max = fs; + break; } } } @@ -661,7 +756,8 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, return ret; } - snd_soc_cache_sync(codec); + sta32x_cache_sync(codec); + sta32x_watchdog_start(sta32x); } /* Power up to mute */ @@ -678,7 +774,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, STA32X_CONFF_PWDN | STA32X_CONFF_EAPD, STA32X_CONFF_PWDN); msleep(300); - + sta32x_watchdog_stop(sta32x); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); break; @@ -687,7 +783,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, return 0; } -static struct snd_soc_dai_ops sta32x_dai_ops = { +static const struct snd_soc_dai_ops sta32x_dai_ops = { .hw_params = sta32x_hw_params, .set_sysclk = sta32x_set_dai_sysclk, .set_fmt = sta32x_set_dai_fmt, @@ -706,7 +802,7 @@ static struct snd_soc_dai_driver sta32x_dai = { }; #ifdef CONFIG_PM -static int sta32x_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int sta32x_suspend(struct snd_soc_codec *codec) { sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -725,9 +821,10 @@ static int sta32x_resume(struct snd_soc_codec *codec) static int sta32x_probe(struct snd_soc_codec *codec) { struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); - int i, ret = 0; + int i, ret = 0, thermal = 0; sta32x->codec = codec; + sta32x->pdata = dev_get_platdata(codec->dev); /* regulators */ for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++) @@ -770,25 +867,48 @@ static int sta32x_probe(struct snd_soc_codec *codec) snd_soc_cache_write(codec, STA32X_AUTO3, 0x00); snd_soc_cache_write(codec, STA32X_C3CFG, 0x40); - /* FIXME enable thermal warning adjustment and recovery */ + /* set thermal warning adjustment and recovery */ + if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE)) + thermal |= STA32X_CONFA_TWAB; + if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_RECOVERY_ENABLE)) + thermal |= STA32X_CONFA_TWRB; snd_soc_update_bits(codec, STA32X_CONFA, - STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, 0); + STA32X_CONFA_TWAB | STA32X_CONFA_TWRB, + thermal); - /* FIXME select 2.1 mode */ + /* select output configuration */ snd_soc_update_bits(codec, STA32X_CONFF, STA32X_CONFF_OCFG_MASK, - 1 << STA32X_CONFF_OCFG_SHIFT); + sta32x->pdata->output_conf + << STA32X_CONFF_OCFG_SHIFT); - /* FIXME channel to output mapping */ + /* channel to output mapping */ snd_soc_update_bits(codec, STA32X_C1CFG, STA32X_CxCFG_OM_MASK, - 0 << STA32X_CxCFG_OM_SHIFT); + sta32x->pdata->ch1_output_mapping + << STA32X_CxCFG_OM_SHIFT); snd_soc_update_bits(codec, STA32X_C2CFG, STA32X_CxCFG_OM_MASK, - 1 << STA32X_CxCFG_OM_SHIFT); + sta32x->pdata->ch2_output_mapping + << STA32X_CxCFG_OM_SHIFT); snd_soc_update_bits(codec, STA32X_C3CFG, STA32X_CxCFG_OM_MASK, - 2 << STA32X_CxCFG_OM_SHIFT); + sta32x->pdata->ch3_output_mapping + << STA32X_CxCFG_OM_SHIFT); + + /* initialize coefficient shadow RAM with reset values */ + for (i = 4; i <= 49; i += 5) + sta32x->coef_shadow[i] = 0x400000; + for (i = 50; i <= 54; i++) + sta32x->coef_shadow[i] = 0x7fffff; + sta32x->coef_shadow[55] = 0x5a9df7; + sta32x->coef_shadow[56] = 0x7fffff; + sta32x->coef_shadow[59] = 0x7fffff; + sta32x->coef_shadow[60] = 0x400000; + sta32x->coef_shadow[61] = 0x400000; + + if (sta32x->pdata->needs_esd_watchdog) + INIT_DELAYED_WORK(&sta32x->watchdog_work, sta32x_watchdog); sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ @@ -806,6 +926,7 @@ static int sta32x_remove(struct snd_soc_codec *codec) { struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); + sta32x_watchdog_stop(sta32x); sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); @@ -848,28 +969,23 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, struct sta32x_priv *sta32x; int ret; - sta32x = kzalloc(sizeof(struct sta32x_priv), GFP_KERNEL); + sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv), + GFP_KERNEL); if (!sta32x) return -ENOMEM; i2c_set_clientdata(i2c, sta32x); ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1); - if (ret != 0) { + if (ret != 0) dev_err(&i2c->dev, "Failed to register codec (%d)\n", ret); - kfree(sta32x); - return ret; - } - return 0; + return ret; } static __devexit int sta32x_i2c_remove(struct i2c_client *client) { - struct sta32x_priv *sta32x = i2c_get_clientdata(client); - snd_soc_unregister_codec(&client->dev); - kfree(sta32x); return 0; } diff --git a/sound/soc/codecs/sta32x.h b/sound/soc/codecs/sta32x.h index b97ee5a7566..d8e32a6262e 100644 --- a/sound/soc/codecs/sta32x.h +++ b/sound/soc/codecs/sta32x.h @@ -19,6 +19,7 @@ /* STA326 register addresses */ #define STA32X_REGISTER_COUNT 0x2d +#define STA32X_COEF_COUNT 62 #define STA32X_CONFA 0x00 #define STA32X_CONFB 0x01 diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 78b2b50271e..cc0566c22ec 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -256,8 +256,7 @@ static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) return 0; } -static int stac9766_codec_suspend(struct snd_soc_codec *codec, - pm_message_t state) +static int stac9766_codec_suspend(struct snd_soc_codec *codec) { stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -286,11 +285,11 @@ reset: return 0; } -static struct snd_soc_dai_ops stac9766_dai_ops_analog = { +static const struct snd_soc_dai_ops stac9766_dai_ops_analog = { .prepare = ac97_analog_prepare, }; -static struct snd_soc_dai_ops stac9766_dai_ops_digital = { +static const struct snd_soc_dai_ops stac9766_dai_ops_digital = { .prepare = ac97_digital_prepare, }; @@ -380,7 +379,7 @@ static struct snd_soc_codec_driver soc_codec_dev_stac9766 = { .remove = stac9766_codec_remove, .suspend = stac9766_codec_suspend, .resume = stac9766_codec_resume, - .reg_cache_size = sizeof(stac9766_reg), + .reg_cache_size = ARRAY_SIZE(stac9766_reg), .reg_word_size = sizeof(u16), .reg_cache_step = 2, .reg_cache_default = stac9766_reg, @@ -408,17 +407,7 @@ static struct platform_driver stac9766_codec_driver = { .remove = __devexit_p(stac9766_remove), }; -static int __init stac9766_init(void) -{ - return platform_driver_register(&stac9766_codec_driver); -} -module_init(stac9766_init); - -static void __exit stac9766_exit(void) -{ - platform_driver_unregister(&stac9766_codec_driver); -} -module_exit(stac9766_exit); +module_platform_driver(stac9766_codec_driver); MODULE_DESCRIPTION("ASoC stac9766 driver"); MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 336de8f69a0..dfa41a96599 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -24,7 +24,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -503,7 +502,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, #define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops tlv320aic23_dai_ops = { +static const struct snd_soc_dai_ops tlv320aic23_dai_ops = { .prepare = tlv320aic23_pcm_prepare, .hw_params = tlv320aic23_hw_params, .shutdown = tlv320aic23_shutdown, @@ -529,8 +528,7 @@ static struct snd_soc_dai_driver tlv320aic23_dai = { .ops = &tlv320aic23_dai_ops, }; -static int tlv320aic23_suspend(struct snd_soc_codec *codec, - pm_message_t state) +static int tlv320aic23_suspend(struct snd_soc_codec *codec) { tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -636,7 +634,7 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c, if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EINVAL; - aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL); + aic23 = devm_kzalloc(&i2c->dev, sizeof(struct aic23), GFP_KERNEL); if (aic23 == NULL) return -ENOMEM; @@ -645,14 +643,11 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_tlv320aic23, &tlv320aic23_dai, 1); - if (ret < 0) - kfree(aic23); return ret; } static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); return 0; } diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 7859bdcc93d..a038daec682 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -275,7 +275,7 @@ static int aic26_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) #define AIC26_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |\ SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) -static struct snd_soc_dai_ops aic26_dai_ops = { +static const struct snd_soc_dai_ops aic26_dai_ops = { .hw_params = aic26_hw_params, .digital_mute = aic26_mute, .set_sysclk = aic26_set_sysclk, @@ -416,7 +416,7 @@ static int aic26_spi_probe(struct spi_device *spi) dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n"); /* Allocate driver data */ - aic26 = kzalloc(sizeof *aic26, GFP_KERNEL); + aic26 = devm_kzalloc(&spi->dev, sizeof *aic26, GFP_KERNEL); if (!aic26) return -ENOMEM; @@ -427,18 +427,12 @@ static int aic26_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &aic26_soc_codec_dev, &aic26_dai, 1); - if (ret < 0) - kfree(aic26); return ret; - - dev_dbg(&spi->dev, "SPI device initialized\n"); - return 0; } static int aic26_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index b21c610051c..eb401ef021f 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -29,7 +29,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/cdev.h> #include <linux/slab.h> @@ -597,7 +596,7 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, #define AIC32X4_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops aic32x4_ops = { +static const struct snd_soc_dai_ops aic32x4_ops = { .hw_params = aic32x4_hw_params, .digital_mute = aic32x4_mute, .set_fmt = aic32x4_set_dai_fmt, @@ -622,7 +621,7 @@ static struct snd_soc_dai_driver aic32x4_dai = { .symmetric_rates = 1, }; -static int aic32x4_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int aic32x4_suspend(struct snd_soc_codec *codec) { aic32x4_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -710,7 +709,8 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, struct aic32x4_priv *aic32x4; int ret; - aic32x4 = kzalloc(sizeof(struct aic32x4_priv), GFP_KERNEL); + aic32x4 = devm_kzalloc(&i2c->dev, sizeof(struct aic32x4_priv), + GFP_KERNEL); if (aic32x4 == NULL) return -ENOMEM; @@ -729,15 +729,12 @@ static __devinit int aic32x4_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aic32x4, &aic32x4_dai, 1); - if (ret < 0) - kfree(aic32x4); return ret; } static __devexit int aic32x4_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 87d5ef188e2..492f22f8a4d 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -40,7 +40,6 @@ #include <linux/i2c.h> #include <linux/gpio.h> #include <linux/regulator/consumer.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -833,7 +832,6 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; u16 d, pll_d = 1; - u8 reg; int clk; /* select data word length */ @@ -869,14 +867,13 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT); snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV); /* disable PLL if it is bypassed */ - reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); - snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg & ~PLL_ENABLE); + snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0); } else { snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV); /* enable PLL when it is used */ - reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); - snd_soc_write(codec, AIC3X_PLL_PROGA_REG, reg | PLL_ENABLE); + snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, + PLL_ENABLE, PLL_ENABLE); } /* Route Left DAC to left channel input and @@ -1156,7 +1153,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); - u8 reg; switch (level) { case SND_SOC_BIAS_ON: @@ -1165,9 +1161,8 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY && aic3x->master) { /* enable pll */ - reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); - snd_soc_write(codec, AIC3X_PLL_PROGA_REG, - reg | PLL_ENABLE); + snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, + PLL_ENABLE, PLL_ENABLE); } break; case SND_SOC_BIAS_STANDBY: @@ -1176,9 +1171,8 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE && aic3x->master) { /* disable pll */ - reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); - snd_soc_write(codec, AIC3X_PLL_PROGA_REG, - reg & ~PLL_ENABLE); + snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, + PLL_ENABLE, 0); } break; case SND_SOC_BIAS_OFF: @@ -1249,7 +1243,7 @@ EXPORT_SYMBOL_GPL(aic3x_button_pressed); #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops aic3x_dai_ops = { +static const struct snd_soc_dai_ops aic3x_dai_ops = { .hw_params = aic3x_hw_params, .digital_mute = aic3x_mute, .set_sysclk = aic3x_set_dai_sysclk, @@ -1274,7 +1268,7 @@ static struct snd_soc_dai_driver aic3x_dai = { .symmetric_rates = 1, }; -static int aic3x_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int aic3x_suspend(struct snd_soc_codec *codec) { aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1295,7 +1289,6 @@ static int aic3x_resume(struct snd_soc_codec *codec) static int aic3x_init(struct snd_soc_codec *codec) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); - int reg; snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); snd_soc_write(codec, AIC3X_RESET, SOFT_RESET); @@ -1317,20 +1310,13 @@ static int aic3x_init(struct snd_soc_codec *codec) snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON); /* unmute all outputs */ - reg = snd_soc_read(codec, LLOPM_CTRL); - snd_soc_write(codec, LLOPM_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, RLOPM_CTRL); - snd_soc_write(codec, RLOPM_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, MONOLOPM_CTRL); - snd_soc_write(codec, MONOLOPM_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, HPLOUT_CTRL); - snd_soc_write(codec, HPLOUT_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, HPROUT_CTRL); - snd_soc_write(codec, HPROUT_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, HPLCOM_CTRL); - snd_soc_write(codec, HPLCOM_CTRL, reg | UNMUTE); - reg = snd_soc_read(codec, HPRCOM_CTRL); - snd_soc_write(codec, HPRCOM_CTRL, reg | UNMUTE); + snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE); + snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE); /* ADC default volume and unmute */ snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN); @@ -1494,7 +1480,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { .resume = aic3x_resume, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) /* * AIC3X 2 wire address can be up to 4 devices with device addresses * 0x18, 0x19, 0x1A, 0x1B @@ -1519,7 +1504,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, struct aic3x_priv *aic3x; int ret; - aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); + aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL); if (aic3x == NULL) { dev_err(&i2c->dev, "failed to create private data\n"); return -ENOMEM; @@ -1539,15 +1524,12 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aic3x, &aic3x_dai, 1); - if (ret < 0) - kfree(aic3x); return ret; } static int aic3x_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } @@ -1561,27 +1543,22 @@ static struct i2c_driver aic3x_i2c_driver = { .remove = aic3x_i2c_remove, .id_table = aic3x_i2c_id, }; -#endif static int __init aic3x_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&aic3x_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n", ret); } -#endif return ret; } module_init(aic3x_modinit); static void __exit aic3x_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&aic3x_i2c_driver); -#endif } module_exit(aic3x_exit); diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index dc8a2b2bdc1..f0aad26cdb3 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -27,7 +27,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/gpio.h> #include <linux/regulator/consumer.h> @@ -1461,7 +1460,7 @@ static int dac33_soc_remove(struct snd_soc_codec *codec) return 0; } -static int dac33_soc_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int dac33_soc_suspend(struct snd_soc_codec *codec) { dac33_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1499,7 +1498,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { SNDRV_PCM_RATE_48000) #define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops dac33_dai_ops = { +static const struct snd_soc_dai_ops dac33_dai_ops = { .startup = dac33_startup, .shutdown = dac33_shutdown, .hw_params = dac33_hw_params, @@ -1533,7 +1532,8 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, } pdata = client->dev.platform_data; - dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL); + dac33 = devm_kzalloc(&client->dev, sizeof(struct tlv320dac33_priv), + GFP_KERNEL); if (dac33 == NULL) return -ENOMEM; @@ -1588,7 +1588,6 @@ err_get: if (dac33->power_gpio >= 0) gpio_free(dac33->power_gpio); err_gpio: - kfree(dac33); return ret; } @@ -1605,8 +1604,6 @@ static int __devexit dac33_i2c_remove(struct i2c_client *client) regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); snd_soc_unregister_codec(&client->dev); - kfree(dac33); - return 0; } diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 7eeca79d738..363b99dad8e 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -376,7 +376,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client, return -ENODEV; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); if (data == NULL) { dev_err(dev, "Can not allocate memory\n"); return -ENOMEM; @@ -450,7 +450,6 @@ err_regulator: if (data->power_gpio >= 0) gpio_free(data->power_gpio); err_gpio: - kfree(data); tpa6130a2_client = NULL; return ret; @@ -466,8 +465,6 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client) gpio_free(data->power_gpio); regulator_put(data->supply); - - kfree(data); tpa6130a2_client = NULL; return 0; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index f798247ac1b..18e71014cc2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2149,7 +2149,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops twl4030_dai_hifi_ops = { +static const struct snd_soc_dai_ops twl4030_dai_hifi_ops = { .startup = twl4030_startup, .shutdown = twl4030_shutdown, .hw_params = twl4030_hw_params, @@ -2158,7 +2158,7 @@ static struct snd_soc_dai_ops twl4030_dai_hifi_ops = { .set_tristate = twl4030_set_tristate, }; -static struct snd_soc_dai_ops twl4030_dai_voice_ops = { +static const struct snd_soc_dai_ops twl4030_dai_voice_ops = { .startup = twl4030_voice_startup, .shutdown = twl4030_voice_shutdown, .hw_params = twl4030_voice_hw_params, @@ -2202,7 +2202,7 @@ static struct snd_soc_dai_driver twl4030_dai[] = { }, }; -static int twl4030_soc_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int twl4030_soc_suspend(struct snd_soc_codec *codec) { twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -2294,17 +2294,7 @@ static struct platform_driver twl4030_codec_driver = { }, }; -static int __init twl4030_modinit(void) -{ - return platform_driver_register(&twl4030_codec_driver); -} -module_init(twl4030_modinit); - -static void __exit twl4030_exit(void) -{ - platform_driver_unregister(&twl4030_codec_driver); -} -module_exit(twl4030_exit); +module_platform_driver(twl4030_codec_driver); MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); MODULE_AUTHOR("Steve Sakoman"); diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 73e11f022de..5b9c79b6f65 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -33,6 +33,7 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> @@ -1012,6 +1013,28 @@ static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, return 0; } +int twl6040_get_dl1_gain(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = &codec->dapm; + + if (snd_soc_dapm_get_pin_status(dapm, "EP")) + return -1; /* -1dB */ + + if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || + snd_soc_dapm_get_pin_status(dapm, "HSOL")) { + + u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL); + if (val & TWL6040_HSDACMODE) + /* HSDACL in LP mode */ + return -8; /* -8dB */ + else + /* HSDACL in HP mode */ + return -1; /* -1dB */ + } + return 0; /* 0dB */ +} +EXPORT_SYMBOL_GPL(twl6040_get_dl1_gain); + int twl6040_get_clk_id(struct snd_soc_codec *codec) { struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); @@ -1397,7 +1420,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, return 0; } -static struct snd_soc_dai_ops twl6040_dai_ops = { +static const struct snd_soc_dai_ops twl6040_dai_ops = { .startup = twl6040_startup, .hw_params = twl6040_hw_params, .prepare = twl6040_prepare, @@ -1470,7 +1493,7 @@ static struct snd_soc_dai_driver twl6040_dai[] = { }; #ifdef CONFIG_PM -static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int twl6040_suspend(struct snd_soc_codec *codec) { twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1620,17 +1643,7 @@ static struct platform_driver twl6040_codec_driver = { .remove = __devexit_p(twl6040_codec_remove), }; -static int __init twl6040_codec_init(void) -{ - return platform_driver_register(&twl6040_codec_driver); -} -module_init(twl6040_codec_init); - -static void __exit twl6040_codec_exit(void) -{ - platform_driver_unregister(&twl6040_codec_driver); -} -module_exit(twl6040_codec_exit); +module_platform_driver(twl6040_codec_driver); MODULE_DESCRIPTION("ASoC TWL6040 codec driver"); MODULE_AUTHOR("Misael Lopez Cruz"); diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index a83277bdb85..ef273f1fac2 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -34,6 +34,7 @@ enum twl6040_trim { #define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f) #define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f) +int twl6040_get_dl1_gain(struct snd_soc_codec *codec); void twl6040_hs_jack_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int report); int twl6040_get_clk_id(struct snd_soc_codec *codec); diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index a7b8f301bad..8f4f469d641 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -452,7 +452,7 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), }; -static struct snd_soc_dai_ops uda134x_dai_ops = { +static const struct snd_soc_dai_ops uda134x_dai_ops = { .startup = uda134x_startup, .shutdown = uda134x_shutdown, .hw_params = uda134x_hw_params, @@ -571,8 +571,7 @@ static int uda134x_soc_remove(struct snd_soc_codec *codec) } #if defined(CONFIG_PM) -static int uda134x_soc_suspend(struct snd_soc_codec *codec, - pm_message_t state) +static int uda134x_soc_suspend(struct snd_soc_codec *codec) { uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -625,17 +624,7 @@ static struct platform_driver uda134x_codec_driver = { .remove = __devexit_p(uda134x_codec_remove), }; -static int __init uda134x_codec_init(void) -{ - return platform_driver_register(&uda134x_codec_driver); -} -module_init(uda134x_codec_init); - -static void __exit uda134x_codec_exit(void) -{ - platform_driver_unregister(&uda134x_codec_driver); -} -module_exit(uda134x_codec_exit); +module_platform_driver(uda134x_codec_driver); MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index c5ca8cfea60..4f1b23d7e40 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -373,7 +373,7 @@ static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { SND_SOC_DAPM_PGA("HeadPhone Driver", UDA1380_PM, 13, 0, NULL, 0), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route uda1380_dapm_routes[] = { /* output mux */ {"HeadPhone Driver", NULL, "Output Mux"}, @@ -410,17 +410,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Right PGA", NULL, "VINR"}, }; -static int uda1380_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, - ARRAY_SIZE(uda1380_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - static int uda1380_set_dai_fmt_both(struct snd_soc_dai *codec_dai, unsigned int fmt) { @@ -643,21 +632,21 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops uda1380_dai_ops = { +static const struct snd_soc_dai_ops uda1380_dai_ops = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, .trigger = uda1380_trigger, .set_fmt = uda1380_set_dai_fmt_both, }; -static struct snd_soc_dai_ops uda1380_dai_ops_playback = { +static const struct snd_soc_dai_ops uda1380_dai_ops_playback = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, .trigger = uda1380_trigger, .set_fmt = uda1380_set_dai_fmt_playback, }; -static struct snd_soc_dai_ops uda1380_dai_ops_capture = { +static const struct snd_soc_dai_ops uda1380_dai_ops_capture = { .hw_params = uda1380_pcm_hw_params, .shutdown = uda1380_pcm_shutdown, .trigger = uda1380_trigger, @@ -705,7 +694,7 @@ static struct snd_soc_dai_driver uda1380_dai[] = { }, }; -static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int uda1380_suspend(struct snd_soc_codec *codec) { uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -732,27 +721,21 @@ static int uda1380_probe(struct snd_soc_codec *codec) return -EINVAL; if (gpio_is_valid(pdata->gpio_reset)) { - ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); + ret = gpio_request_one(pdata->gpio_reset, GPIOF_OUT_INIT_LOW, + "uda1380 reset"); if (ret) goto err_out; - ret = gpio_direction_output(pdata->gpio_reset, 0); - if (ret) - goto err_gpio_reset_conf; } if (gpio_is_valid(pdata->gpio_power)) { - ret = gpio_request(pdata->gpio_power, "uda1380 power"); - if (ret) - goto err_gpio; - ret = gpio_direction_output(pdata->gpio_power, 0); + ret = gpio_request_one(pdata->gpio_power, GPIOF_OUT_INIT_LOW, + "uda1380 power"); if (ret) - goto err_gpio_power_conf; + goto err_free_gpio; } else { ret = uda1380_reset(codec); - if (ret) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_reset; - } + if (ret) + goto err_free_gpio; } INIT_WORK(&uda1380->work, uda1380_flush_work); @@ -770,19 +753,9 @@ static int uda1380_probe(struct snd_soc_codec *codec) break; } - snd_soc_add_controls(codec, uda1380_snd_controls, - ARRAY_SIZE(uda1380_snd_controls)); - uda1380_add_widgets(codec); - return 0; -err_reset: -err_gpio_power_conf: - if (gpio_is_valid(pdata->gpio_power)) - gpio_free(pdata->gpio_power); - -err_gpio_reset_conf: -err_gpio: +err_free_gpio: if (gpio_is_valid(pdata->gpio_reset)) gpio_free(pdata->gpio_reset); err_out: @@ -814,6 +787,13 @@ static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { .reg_word_size = sizeof(u16), .reg_cache_default = uda1380_reg, .reg_cache_step = 1, + + .controls = uda1380_snd_controls, + .num_controls = ARRAY_SIZE(uda1380_snd_controls), + .dapm_widgets = uda1380_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), + .dapm_routes = uda1380_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(uda1380_dapm_routes), }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) @@ -823,7 +803,8 @@ static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, struct uda1380_priv *uda1380; int ret; - uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); + uda1380 = devm_kzalloc(&i2c->dev, sizeof(struct uda1380_priv), + GFP_KERNEL); if (uda1380 == NULL) return -ENOMEM; @@ -832,15 +813,12 @@ static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); - if (ret < 0) - kfree(uda1380); return ret; } static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) { snd_soc_unregister_codec(&i2c->dev); - kfree(i2c_get_clientdata(i2c)); return 0; } @@ -863,13 +841,13 @@ static struct i2c_driver uda1380_i2c_driver = { static int __init uda1380_modinit(void) { - int ret; + int ret = 0; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&uda1380_i2c_driver); if (ret != 0) pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); #endif - return 0; + return ret; } module_init(uda1380_modinit); diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index a8549898299..44aacf927ba 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -386,7 +386,7 @@ static int wl1273_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops wl1273_dai_ops = { +static const struct snd_soc_dai_ops wl1273_dai_ops = { .startup = wl1273_startup, .hw_params = wl1273_hw_params, }; @@ -510,17 +510,7 @@ static struct platform_driver wl1273_platform_driver = { .remove = __devexit_p(wl1273_platform_remove), }; -static int __init wl1273_init(void) -{ - return platform_driver_register(&wl1273_platform_driver); -} -module_init(wl1273_init); - -static void __exit wl1273_exit(void) -{ - platform_driver_unregister(&wl1273_platform_driver); -} -module_exit(wl1273_exit); +module_platform_driver(wl1273_platform_driver); MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>"); MODULE_DESCRIPTION("ASoC WL1273 codec driver"); diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index cd0ec0fd1db..aefb4f89be0 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c @@ -116,7 +116,7 @@ static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c) if (!pdata) return 0; - wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL); + wm1250 = devm_kzalloc(&i2c->dev, sizeof(*wm1250), GFP_KERNEL); if (!wm1250) { dev_err(&i2c->dev, "Unable to allocate private data\n"); ret = -ENOMEM; @@ -134,15 +134,13 @@ static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c) ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); if (ret != 0) { dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret); - goto err_alloc; + goto err; } dev_set_drvdata(&i2c->dev, wm1250); return ret; -err_alloc: - kfree(wm1250); err: return ret; } @@ -151,10 +149,8 @@ static void wm1250_ev1_free(struct i2c_client *i2c) { struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev); - if (wm1250) { + if (wm1250) gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); - kfree(wm1250); - } } static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index a3b9cbb20ee..c2880907fce 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -29,7 +29,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/debugfs.h> #include <linux/slab.h> #include <sound/core.h> @@ -52,6 +52,7 @@ enum wm2000_anc_mode { struct wm2000_priv { struct i2c_client *i2c; + struct regmap *regmap; enum wm2000_anc_mode anc_mode; @@ -66,59 +67,24 @@ struct wm2000_priv { char *anc_download; }; -static struct i2c_client *wm2000_i2c; - static int wm2000_write(struct i2c_client *i2c, unsigned int reg, unsigned int value) { - u8 data[3]; - int ret; - - data[0] = (reg >> 8) & 0xff; - data[1] = reg & 0xff; - data[2] = value & 0xff; - - dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value); - - ret = i2c_master_send(i2c, data, 3); - if (ret == 3) - return 0; - if (ret < 0) - return ret; - else - return -EIO; + struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c); + return regmap_write(wm2000->regmap, reg, value); } static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r) { - struct i2c_msg xfer[2]; - u8 reg[2]; - u8 data; + struct wm2000_priv *wm2000 = i2c_get_clientdata(i2c); + unsigned int val; int ret; - /* Write register */ - reg[0] = (r >> 8) & 0xff; - reg[1] = r & 0xff; - xfer[0].addr = i2c->addr; - xfer[0].flags = 0; - xfer[0].len = sizeof(reg); - xfer[0].buf = ®[0]; - - /* Read data */ - xfer[1].addr = i2c->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 1; - xfer[1].buf = &data; - - ret = i2c_transfer(i2c->adapter, xfer, 2); - if (ret != 2) { - dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret); - return 0; - } - - dev_vdbg(&i2c->dev, "read %x from %x\n", data, r); + ret = regmap_read(wm2000->regmap, r, &val); + if (ret < 0) + return -1; - return data; + return val; } static void wm2000_reset(struct wm2000_priv *wm2000) @@ -612,7 +578,8 @@ static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev); + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->anc_active; @@ -622,7 +589,8 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev); + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int anc_active = ucontrol->value.enumerated.item[0]; if (anc_active > 1) @@ -636,7 +604,8 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev); + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->spk_ena; @@ -646,7 +615,8 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev); + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int val = ucontrol->value.enumerated.item[0]; if (val > 1) @@ -669,7 +639,8 @@ static const struct snd_kcontrol_new wm2000_controls[] = { static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { - struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev); + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); if (SND_SOC_DAPM_EVENT_ON(event)) wm2000->anc_eng_ena = 1; @@ -682,11 +653,11 @@ static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w, static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = { /* Externally visible pins */ -SND_SOC_DAPM_OUTPUT("WM2000 SPKN"), -SND_SOC_DAPM_OUTPUT("WM2000 SPKP"), +SND_SOC_DAPM_OUTPUT("SPKN"), +SND_SOC_DAPM_OUTPUT("SPKP"), -SND_SOC_DAPM_INPUT("WM2000 LINN"), -SND_SOC_DAPM_INPUT("WM2000 LINP"), +SND_SOC_DAPM_INPUT("LINN"), +SND_SOC_DAPM_INPUT("LINP"), SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0, wm2000_anc_power_event, @@ -694,37 +665,67 @@ SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0, }; /* Target, Path, Source */ -static const struct snd_soc_dapm_route audio_map[] = { - { "WM2000 SPKN", NULL, "ANC Engine" }, - { "WM2000 SPKP", NULL, "ANC Engine" }, - { "ANC Engine", NULL, "WM2000 LINN" }, - { "ANC Engine", NULL, "WM2000 LINP" }, +static const struct snd_soc_dapm_route wm2000_audio_map[] = { + { "SPKN", NULL, "ANC Engine" }, + { "SPKP", NULL, "ANC Engine" }, + { "ANC Engine", NULL, "LINN" }, + { "ANC Engine", NULL, "LINP" }, }; -/* Called from the machine driver */ -int wm2000_add_controls(struct snd_soc_codec *codec) +#ifdef CONFIG_PM +static int wm2000_suspend(struct snd_soc_codec *codec) { - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - if (!wm2000_i2c) { - pr_err("WM2000 not yet probed\n"); - return -ENODEV; - } + return wm2000_anc_transition(wm2000, ANC_OFF); +} - ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets, - ARRAY_SIZE(wm2000_dapm_widgets)); - if (ret < 0) - return ret; +static int wm2000_resume(struct snd_soc_codec *codec) +{ + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - if (ret < 0) - return ret; + return wm2000_anc_set_mode(wm2000); +} +#else +#define wm2000_suspend NULL +#define wm2000_resume NULL +#endif + +static const struct regmap_config wm2000_regmap = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int wm2000_probe(struct snd_soc_codec *codec) +{ + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); + + /* This will trigger a transition to standby mode by default */ + wm2000_anc_set_mode(wm2000); + + return 0; +} + +static int wm2000_remove(struct snd_soc_codec *codec) +{ + struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); - return snd_soc_add_controls(codec, wm2000_controls, - ARRAY_SIZE(wm2000_controls)); + return wm2000_anc_transition(wm2000, ANC_OFF); } -EXPORT_SYMBOL_GPL(wm2000_add_controls); + +static struct snd_soc_codec_driver soc_codec_dev_wm2000 = { + .probe = wm2000_probe, + .remove = wm2000_remove, + .suspend = wm2000_suspend, + .resume = wm2000_resume, + + .dapm_widgets = wm2000_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets), + .dapm_routes = wm2000_audio_map, + .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map), + .controls = wm2000_controls, + .num_controls = ARRAY_SIZE(wm2000_controls), +}; static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) @@ -736,17 +737,23 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, int reg, ret; u16 id; - if (wm2000_i2c) { - dev_err(&i2c->dev, "Another WM2000 is already registered\n"); - return -EINVAL; - } - - wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL); + wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), + GFP_KERNEL); if (wm2000 == NULL) { dev_err(&i2c->dev, "Unable to allocate private data\n"); return -ENOMEM; } + dev_set_drvdata(&i2c->dev, wm2000); + + wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap); + if (IS_ERR(wm2000->regmap)) { + ret = PTR_ERR(wm2000->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + /* Verify that this is a WM2000 */ reg = wm2000_read(i2c, WM2000_REG_ID1); id = reg << 8; @@ -756,7 +763,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, if (id != 0x2000) { dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); ret = -ENODEV; - goto err; + goto err_regmap; } reg = wm2000_read(i2c, WM2000_REG_REVISON); @@ -775,12 +782,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, ret = request_firmware(&fw, filename, &i2c->dev); if (ret != 0) { dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); - goto err; + goto err_regmap; } /* Pre-cook the concatenation of the register address onto the image */ wm2000->anc_download_size = fw->size + 2; - wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL); + wm2000->anc_download = devm_kzalloc(&i2c->dev, + wm2000->anc_download_size, + GFP_KERNEL); if (wm2000->anc_download == NULL) { dev_err(&i2c->dev, "Out of memory\n"); ret = -ENOMEM; @@ -793,7 +802,6 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, release_firmware(fw); - dev_set_drvdata(&i2c->dev, wm2000); wm2000->anc_eng_ena = 1; wm2000->anc_active = 1; wm2000->spk_ena = 1; @@ -801,17 +809,18 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, wm2000_reset(wm2000); - /* This will trigger a transition to standby mode by default */ - wm2000_anc_set_mode(wm2000); - - wm2000_i2c = i2c; + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, + NULL, 0); + if (ret != 0) + goto err_fw; return 0; err_fw: release_firmware(fw); +err_regmap: + regmap_exit(wm2000->regmap); err: - kfree(wm2000); return ret; } @@ -819,42 +828,12 @@ static __devexit int wm2000_i2c_remove(struct i2c_client *i2c) { struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - wm2000_anc_transition(wm2000, ANC_OFF); - - wm2000_i2c = NULL; - kfree(wm2000->anc_download); - kfree(wm2000); + snd_soc_unregister_codec(&i2c->dev); + regmap_exit(wm2000->regmap); return 0; } -static void wm2000_i2c_shutdown(struct i2c_client *i2c) -{ - struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - - wm2000_anc_transition(wm2000, ANC_OFF); -} - -#ifdef CONFIG_PM -static int wm2000_i2c_suspend(struct device *dev) -{ - struct i2c_client *i2c = to_i2c_client(dev); - struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - - return wm2000_anc_transition(wm2000, ANC_OFF); -} - -static int wm2000_i2c_resume(struct device *dev) -{ - struct i2c_client *i2c = to_i2c_client(dev); - struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev); - - return wm2000_anc_set_mode(wm2000); -} -#endif - -static SIMPLE_DEV_PM_OPS(wm2000_pm, wm2000_i2c_suspend, wm2000_i2c_resume); - static const struct i2c_device_id wm2000_i2c_id[] = { { "wm2000", 0 }, { } @@ -865,11 +844,9 @@ static struct i2c_driver wm2000_i2c_driver = { .driver = { .name = "wm2000", .owner = THIS_MODULE, - .pm = &wm2000_pm, }, .probe = wm2000_i2c_probe, .remove = __devexit_p(wm2000_i2c_remove), - .shutdown = wm2000_i2c_shutdown, .id_table = wm2000_i2c_id, }; diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h index 0b6f056f73c..abcd82a9399 100644 --- a/sound/soc/codecs/wm2000.h +++ b/sound/soc/codecs/wm2000.h @@ -9,13 +9,6 @@ #ifndef _WM2000_H #define _WM2000_H -struct wm2000_setup_data { - unsigned short i2c_address; - int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */ -}; - -extern int wm2000_add_controls(struct snd_soc_codec *codec); - #define WM2000_REG_SYS_START 0x8000 #define WM2000_REG_SPEECH_CLARITY 0x8fef #define WM2000_REG_SYS_WATCHDOG 0x8ff6 diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c index e9ce81a57b8..9a18fae6820 100644 --- a/sound/soc/codecs/wm5100-tables.c +++ b/sound/soc/codecs/wm5100-tables.c @@ -13,7 +13,7 @@ #include "wm5100.h" -int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg) +bool wm5100_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM5100_SOFTWARE_RESET: @@ -36,7 +36,7 @@ int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg) } } -int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg) +bool wm5100_readable_register(struct device *dev, unsigned int reg) { switch (reg) { case WM5100_SOFTWARE_RESET: @@ -85,6 +85,7 @@ int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg) case WM5100_MIC_DETECT_1: case WM5100_MIC_DETECT_2: case WM5100_MIC_DETECT_3: + case WM5100_MISC_CONTROL: case WM5100_INPUT_ENABLES: case WM5100_INPUT_ENABLES_STATUS: case WM5100_IN1L_CONTROL: @@ -696,836 +697,668 @@ int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg) case WM5100_HPLPF3_2: case WM5100_HPLPF4_1: case WM5100_HPLPF4_2: - case WM5100_DSP1_DM_0: - case WM5100_DSP1_DM_1: - case WM5100_DSP1_DM_2: - case WM5100_DSP1_DM_3: - case WM5100_DSP1_DM_508: - case WM5100_DSP1_DM_509: - case WM5100_DSP1_DM_510: - case WM5100_DSP1_DM_511: - case WM5100_DSP1_PM_0: - case WM5100_DSP1_PM_1: - case WM5100_DSP1_PM_2: - case WM5100_DSP1_PM_3: - case WM5100_DSP1_PM_4: - case WM5100_DSP1_PM_5: - case WM5100_DSP1_PM_1530: - case WM5100_DSP1_PM_1531: - case WM5100_DSP1_PM_1532: - case WM5100_DSP1_PM_1533: - case WM5100_DSP1_PM_1534: - case WM5100_DSP1_PM_1535: - case WM5100_DSP1_ZM_0: - case WM5100_DSP1_ZM_1: - case WM5100_DSP1_ZM_2: - case WM5100_DSP1_ZM_3: - case WM5100_DSP1_ZM_2044: - case WM5100_DSP1_ZM_2045: - case WM5100_DSP1_ZM_2046: - case WM5100_DSP1_ZM_2047: - case WM5100_DSP2_DM_0: - case WM5100_DSP2_DM_1: - case WM5100_DSP2_DM_2: - case WM5100_DSP2_DM_3: - case WM5100_DSP2_DM_508: - case WM5100_DSP2_DM_509: - case WM5100_DSP2_DM_510: - case WM5100_DSP2_DM_511: - case WM5100_DSP2_PM_0: - case WM5100_DSP2_PM_1: - case WM5100_DSP2_PM_2: - case WM5100_DSP2_PM_3: - case WM5100_DSP2_PM_4: - case WM5100_DSP2_PM_5: - case WM5100_DSP2_PM_1530: - case WM5100_DSP2_PM_1531: - case WM5100_DSP2_PM_1532: - case WM5100_DSP2_PM_1533: - case WM5100_DSP2_PM_1534: - case WM5100_DSP2_PM_1535: - case WM5100_DSP2_ZM_0: - case WM5100_DSP2_ZM_1: - case WM5100_DSP2_ZM_2: - case WM5100_DSP2_ZM_3: - case WM5100_DSP2_ZM_2044: - case WM5100_DSP2_ZM_2045: - case WM5100_DSP2_ZM_2046: - case WM5100_DSP2_ZM_2047: - case WM5100_DSP3_DM_0: - case WM5100_DSP3_DM_1: - case WM5100_DSP3_DM_2: - case WM5100_DSP3_DM_3: - case WM5100_DSP3_DM_508: - case WM5100_DSP3_DM_509: - case WM5100_DSP3_DM_510: - case WM5100_DSP3_DM_511: - case WM5100_DSP3_PM_0: - case WM5100_DSP3_PM_1: - case WM5100_DSP3_PM_2: - case WM5100_DSP3_PM_3: - case WM5100_DSP3_PM_4: - case WM5100_DSP3_PM_5: - case WM5100_DSP3_PM_1530: - case WM5100_DSP3_PM_1531: - case WM5100_DSP3_PM_1532: - case WM5100_DSP3_PM_1533: - case WM5100_DSP3_PM_1534: - case WM5100_DSP3_PM_1535: - case WM5100_DSP3_ZM_0: - case WM5100_DSP3_ZM_1: - case WM5100_DSP3_ZM_2: - case WM5100_DSP3_ZM_3: - case WM5100_DSP3_ZM_2044: - case WM5100_DSP3_ZM_2045: - case WM5100_DSP3_ZM_2046: - case WM5100_DSP3_ZM_2047: return 1; default: return 0; } } -u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = { - [0x0000] = 0x0000, /* R0 - software reset */ - [0x0001] = 0x0000, /* R1 - Device Revision */ - [0x0010] = 0x0801, /* R16 - Ctrl IF 1 */ - [0x0020] = 0x0000, /* R32 - Tone Generator 1 */ - [0x0030] = 0x0000, /* R48 - PWM Drive 1 */ - [0x0031] = 0x0100, /* R49 - PWM Drive 2 */ - [0x0032] = 0x0100, /* R50 - PWM Drive 3 */ - [0x0100] = 0x0002, /* R256 - Clocking 1 */ - [0x0101] = 0x0000, /* R257 - Clocking 3 */ - [0x0102] = 0x0011, /* R258 - Clocking 4 */ - [0x0103] = 0x0011, /* R259 - Clocking 5 */ - [0x0104] = 0x0011, /* R260 - Clocking 6 */ - [0x0107] = 0x0000, /* R263 - Clocking 7 */ - [0x0108] = 0x0000, /* R264 - Clocking 8 */ - [0x0120] = 0x0000, /* R288 - ASRC_ENABLE */ - [0x0121] = 0x0000, /* R289 - ASRC_STATUS */ - [0x0122] = 0x0000, /* R290 - ASRC_RATE1 */ - [0x0141] = 0x8000, /* R321 - ISRC 1 CTRL 1 */ - [0x0142] = 0x0000, /* R322 - ISRC 1 CTRL 2 */ - [0x0143] = 0x8000, /* R323 - ISRC 2 CTRL1 */ - [0x0144] = 0x0000, /* R324 - ISRC 2 CTRL 2 */ - [0x0182] = 0x0000, /* R386 - FLL1 Control 1 */ - [0x0183] = 0x0000, /* R387 - FLL1 Control 2 */ - [0x0184] = 0x0000, /* R388 - FLL1 Control 3 */ - [0x0186] = 0x0177, /* R390 - FLL1 Control 5 */ - [0x0187] = 0x0001, /* R391 - FLL1 Control 6 */ - [0x0188] = 0x0000, /* R392 - FLL1 EFS 1 */ - [0x01A2] = 0x0000, /* R418 - FLL2 Control 1 */ - [0x01A3] = 0x0000, /* R419 - FLL2 Control 2 */ - [0x01A4] = 0x0000, /* R420 - FLL2 Control 3 */ - [0x01A6] = 0x0177, /* R422 - FLL2 Control 5 */ - [0x01A7] = 0x0001, /* R423 - FLL2 Control 6 */ - [0x01A8] = 0x0000, /* R424 - FLL2 EFS 1 */ - [0x0200] = 0x0020, /* R512 - Mic Charge Pump 1 */ - [0x0201] = 0xB084, /* R513 - Mic Charge Pump 2 */ - [0x0202] = 0xBBDE, /* R514 - HP Charge Pump 1 */ - [0x0211] = 0x20D4, /* R529 - LDO1 Control */ - [0x0215] = 0x0062, /* R533 - Mic Bias Ctrl 1 */ - [0x0216] = 0x0062, /* R534 - Mic Bias Ctrl 2 */ - [0x0217] = 0x0062, /* R535 - Mic Bias Ctrl 3 */ - [0x0280] = 0x0004, /* R640 - Accessory Detect Mode 1 */ - [0x0288] = 0x0020, /* R648 - Headphone Detect 1 */ - [0x0289] = 0x0000, /* R649 - Headphone Detect 2 */ - [0x0290] = 0x1100, /* R656 - Mic Detect 1 */ - [0x0291] = 0x009F, /* R657 - Mic Detect 2 */ - [0x0292] = 0x0000, /* R658 - Mic Detect 3 */ - [0x0301] = 0x0000, /* R769 - Input Enables */ - [0x0302] = 0x0000, /* R770 - Input Enables Status */ - [0x0310] = 0x2280, /* R784 - Status */ - [0x0311] = 0x0080, /* R785 - IN1R Control */ - [0x0312] = 0x2280, /* R786 - IN2L Control */ - [0x0313] = 0x0080, /* R787 - IN2R Control */ - [0x0314] = 0x2280, /* R788 - IN3L Control */ - [0x0315] = 0x0080, /* R789 - IN3R Control */ - [0x0316] = 0x2280, /* R790 - IN4L Control */ - [0x0317] = 0x0080, /* R791 - IN4R Control */ - [0x0318] = 0x0000, /* R792 - RXANC_SRC */ - [0x0319] = 0x0022, /* R793 - Input Volume Ramp */ - [0x0320] = 0x0180, /* R800 - ADC Digital Volume 1L */ - [0x0321] = 0x0180, /* R801 - ADC Digital Volume 1R */ - [0x0322] = 0x0180, /* R802 - ADC Digital Volume 2L */ - [0x0323] = 0x0180, /* R803 - ADC Digital Volume 2R */ - [0x0324] = 0x0180, /* R804 - ADC Digital Volume 3L */ - [0x0325] = 0x0180, /* R805 - ADC Digital Volume 3R */ - [0x0326] = 0x0180, /* R806 - ADC Digital Volume 4L */ - [0x0327] = 0x0180, /* R807 - ADC Digital Volume 4R */ - [0x0401] = 0x0000, /* R1025 - Output Enables 2 */ - [0x0402] = 0x0000, /* R1026 - Output Status 1 */ - [0x0403] = 0x0000, /* R1027 - Output Status 2 */ - [0x0408] = 0x0000, /* R1032 - Channel Enables 1 */ - [0x0410] = 0x0080, /* R1040 - Out Volume 1L */ - [0x0411] = 0x0080, /* R1041 - Out Volume 1R */ - [0x0412] = 0x0080, /* R1042 - DAC Volume Limit 1L */ - [0x0413] = 0x0080, /* R1043 - DAC Volume Limit 1R */ - [0x0414] = 0x0080, /* R1044 - Out Volume 2L */ - [0x0415] = 0x0080, /* R1045 - Out Volume 2R */ - [0x0416] = 0x0080, /* R1046 - DAC Volume Limit 2L */ - [0x0417] = 0x0080, /* R1047 - DAC Volume Limit 2R */ - [0x0418] = 0x0080, /* R1048 - Out Volume 3L */ - [0x0419] = 0x0080, /* R1049 - Out Volume 3R */ - [0x041A] = 0x0080, /* R1050 - DAC Volume Limit 3L */ - [0x041B] = 0x0080, /* R1051 - DAC Volume Limit 3R */ - [0x041C] = 0x0080, /* R1052 - Out Volume 4L */ - [0x041D] = 0x0080, /* R1053 - Out Volume 4R */ - [0x041E] = 0x0080, /* R1054 - DAC Volume Limit 5L */ - [0x041F] = 0x0080, /* R1055 - DAC Volume Limit 5R */ - [0x0420] = 0x0080, /* R1056 - DAC Volume Limit 6L */ - [0x0421] = 0x0080, /* R1057 - DAC Volume Limit 6R */ - [0x0440] = 0x0000, /* R1088 - DAC AEC Control 1 */ - [0x0441] = 0x0022, /* R1089 - Output Volume Ramp */ - [0x0480] = 0x0180, /* R1152 - DAC Digital Volume 1L */ - [0x0481] = 0x0180, /* R1153 - DAC Digital Volume 1R */ - [0x0482] = 0x0180, /* R1154 - DAC Digital Volume 2L */ - [0x0483] = 0x0180, /* R1155 - DAC Digital Volume 2R */ - [0x0484] = 0x0180, /* R1156 - DAC Digital Volume 3L */ - [0x0485] = 0x0180, /* R1157 - DAC Digital Volume 3R */ - [0x0486] = 0x0180, /* R1158 - DAC Digital Volume 4L */ - [0x0487] = 0x0180, /* R1159 - DAC Digital Volume 4R */ - [0x0488] = 0x0180, /* R1160 - DAC Digital Volume 5L */ - [0x0489] = 0x0180, /* R1161 - DAC Digital Volume 5R */ - [0x048A] = 0x0180, /* R1162 - DAC Digital Volume 6L */ - [0x048B] = 0x0180, /* R1163 - DAC Digital Volume 6R */ - [0x04C0] = 0x0069, /* R1216 - PDM SPK1 CTRL 1 */ - [0x04C1] = 0x0000, /* R1217 - PDM SPK1 CTRL 2 */ - [0x04C2] = 0x0069, /* R1218 - PDM SPK2 CTRL 1 */ - [0x04C3] = 0x0000, /* R1219 - PDM SPK2 CTRL 2 */ - [0x0500] = 0x000C, /* R1280 - Audio IF 1_1 */ - [0x0501] = 0x0008, /* R1281 - Audio IF 1_2 */ - [0x0502] = 0x0000, /* R1282 - Audio IF 1_3 */ - [0x0503] = 0x0000, /* R1283 - Audio IF 1_4 */ - [0x0504] = 0x0000, /* R1284 - Audio IF 1_5 */ - [0x0505] = 0x0300, /* R1285 - Audio IF 1_6 */ - [0x0506] = 0x0300, /* R1286 - Audio IF 1_7 */ - [0x0507] = 0x1820, /* R1287 - Audio IF 1_8 */ - [0x0508] = 0x1820, /* R1288 - Audio IF 1_9 */ - [0x0509] = 0x0000, /* R1289 - Audio IF 1_10 */ - [0x050A] = 0x0001, /* R1290 - Audio IF 1_11 */ - [0x050B] = 0x0002, /* R1291 - Audio IF 1_12 */ - [0x050C] = 0x0003, /* R1292 - Audio IF 1_13 */ - [0x050D] = 0x0004, /* R1293 - Audio IF 1_14 */ - [0x050E] = 0x0005, /* R1294 - Audio IF 1_15 */ - [0x050F] = 0x0006, /* R1295 - Audio IF 1_16 */ - [0x0510] = 0x0007, /* R1296 - Audio IF 1_17 */ - [0x0511] = 0x0000, /* R1297 - Audio IF 1_18 */ - [0x0512] = 0x0001, /* R1298 - Audio IF 1_19 */ - [0x0513] = 0x0002, /* R1299 - Audio IF 1_20 */ - [0x0514] = 0x0003, /* R1300 - Audio IF 1_21 */ - [0x0515] = 0x0004, /* R1301 - Audio IF 1_22 */ - [0x0516] = 0x0005, /* R1302 - Audio IF 1_23 */ - [0x0517] = 0x0006, /* R1303 - Audio IF 1_24 */ - [0x0518] = 0x0007, /* R1304 - Audio IF 1_25 */ - [0x0519] = 0x0000, /* R1305 - Audio IF 1_26 */ - [0x051A] = 0x0000, /* R1306 - Audio IF 1_27 */ - [0x0540] = 0x000C, /* R1344 - Audio IF 2_1 */ - [0x0541] = 0x0008, /* R1345 - Audio IF 2_2 */ - [0x0542] = 0x0000, /* R1346 - Audio IF 2_3 */ - [0x0543] = 0x0000, /* R1347 - Audio IF 2_4 */ - [0x0544] = 0x0000, /* R1348 - Audio IF 2_5 */ - [0x0545] = 0x0300, /* R1349 - Audio IF 2_6 */ - [0x0546] = 0x0300, /* R1350 - Audio IF 2_7 */ - [0x0547] = 0x1820, /* R1351 - Audio IF 2_8 */ - [0x0548] = 0x1820, /* R1352 - Audio IF 2_9 */ - [0x0549] = 0x0000, /* R1353 - Audio IF 2_10 */ - [0x054A] = 0x0001, /* R1354 - Audio IF 2_11 */ - [0x0551] = 0x0000, /* R1361 - Audio IF 2_18 */ - [0x0552] = 0x0001, /* R1362 - Audio IF 2_19 */ - [0x0559] = 0x0000, /* R1369 - Audio IF 2_26 */ - [0x055A] = 0x0000, /* R1370 - Audio IF 2_27 */ - [0x0580] = 0x000C, /* R1408 - Audio IF 3_1 */ - [0x0581] = 0x0008, /* R1409 - Audio IF 3_2 */ - [0x0582] = 0x0000, /* R1410 - Audio IF 3_3 */ - [0x0583] = 0x0000, /* R1411 - Audio IF 3_4 */ - [0x0584] = 0x0000, /* R1412 - Audio IF 3_5 */ - [0x0585] = 0x0300, /* R1413 - Audio IF 3_6 */ - [0x0586] = 0x0300, /* R1414 - Audio IF 3_7 */ - [0x0587] = 0x1820, /* R1415 - Audio IF 3_8 */ - [0x0588] = 0x1820, /* R1416 - Audio IF 3_9 */ - [0x0589] = 0x0000, /* R1417 - Audio IF 3_10 */ - [0x058A] = 0x0001, /* R1418 - Audio IF 3_11 */ - [0x0591] = 0x0000, /* R1425 - Audio IF 3_18 */ - [0x0592] = 0x0001, /* R1426 - Audio IF 3_19 */ - [0x0599] = 0x0000, /* R1433 - Audio IF 3_26 */ - [0x059A] = 0x0000, /* R1434 - Audio IF 3_27 */ - [0x0640] = 0x0000, /* R1600 - PWM1MIX Input 1 Source */ - [0x0641] = 0x0080, /* R1601 - PWM1MIX Input 1 Volume */ - [0x0642] = 0x0000, /* R1602 - PWM1MIX Input 2 Source */ - [0x0643] = 0x0080, /* R1603 - PWM1MIX Input 2 Volume */ - [0x0644] = 0x0000, /* R1604 - PWM1MIX Input 3 Source */ - [0x0645] = 0x0080, /* R1605 - PWM1MIX Input 3 Volume */ - [0x0646] = 0x0000, /* R1606 - PWM1MIX Input 4 Source */ - [0x0647] = 0x0080, /* R1607 - PWM1MIX Input 4 Volume */ - [0x0648] = 0x0000, /* R1608 - PWM2MIX Input 1 Source */ - [0x0649] = 0x0080, /* R1609 - PWM2MIX Input 1 Volume */ - [0x064A] = 0x0000, /* R1610 - PWM2MIX Input 2 Source */ - [0x064B] = 0x0080, /* R1611 - PWM2MIX Input 2 Volume */ - [0x064C] = 0x0000, /* R1612 - PWM2MIX Input 3 Source */ - [0x064D] = 0x0080, /* R1613 - PWM2MIX Input 3 Volume */ - [0x064E] = 0x0000, /* R1614 - PWM2MIX Input 4 Source */ - [0x064F] = 0x0080, /* R1615 - PWM2MIX Input 4 Volume */ - [0x0680] = 0x0000, /* R1664 - OUT1LMIX Input 1 Source */ - [0x0681] = 0x0080, /* R1665 - OUT1LMIX Input 1 Volume */ - [0x0682] = 0x0000, /* R1666 - OUT1LMIX Input 2 Source */ - [0x0683] = 0x0080, /* R1667 - OUT1LMIX Input 2 Volume */ - [0x0684] = 0x0000, /* R1668 - OUT1LMIX Input 3 Source */ - [0x0685] = 0x0080, /* R1669 - OUT1LMIX Input 3 Volume */ - [0x0686] = 0x0000, /* R1670 - OUT1LMIX Input 4 Source */ - [0x0687] = 0x0080, /* R1671 - OUT1LMIX Input 4 Volume */ - [0x0688] = 0x0000, /* R1672 - OUT1RMIX Input 1 Source */ - [0x0689] = 0x0080, /* R1673 - OUT1RMIX Input 1 Volume */ - [0x068A] = 0x0000, /* R1674 - OUT1RMIX Input 2 Source */ - [0x068B] = 0x0080, /* R1675 - OUT1RMIX Input 2 Volume */ - [0x068C] = 0x0000, /* R1676 - OUT1RMIX Input 3 Source */ - [0x068D] = 0x0080, /* R1677 - OUT1RMIX Input 3 Volume */ - [0x068E] = 0x0000, /* R1678 - OUT1RMIX Input 4 Source */ - [0x068F] = 0x0080, /* R1679 - OUT1RMIX Input 4 Volume */ - [0x0690] = 0x0000, /* R1680 - OUT2LMIX Input 1 Source */ - [0x0691] = 0x0080, /* R1681 - OUT2LMIX Input 1 Volume */ - [0x0692] = 0x0000, /* R1682 - OUT2LMIX Input 2 Source */ - [0x0693] = 0x0080, /* R1683 - OUT2LMIX Input 2 Volume */ - [0x0694] = 0x0000, /* R1684 - OUT2LMIX Input 3 Source */ - [0x0695] = 0x0080, /* R1685 - OUT2LMIX Input 3 Volume */ - [0x0696] = 0x0000, /* R1686 - OUT2LMIX Input 4 Source */ - [0x0697] = 0x0080, /* R1687 - OUT2LMIX Input 4 Volume */ - [0x0698] = 0x0000, /* R1688 - OUT2RMIX Input 1 Source */ - [0x0699] = 0x0080, /* R1689 - OUT2RMIX Input 1 Volume */ - [0x069A] = 0x0000, /* R1690 - OUT2RMIX Input 2 Source */ - [0x069B] = 0x0080, /* R1691 - OUT2RMIX Input 2 Volume */ - [0x069C] = 0x0000, /* R1692 - OUT2RMIX Input 3 Source */ - [0x069D] = 0x0080, /* R1693 - OUT2RMIX Input 3 Volume */ - [0x069E] = 0x0000, /* R1694 - OUT2RMIX Input 4 Source */ - [0x069F] = 0x0080, /* R1695 - OUT2RMIX Input 4 Volume */ - [0x06A0] = 0x0000, /* R1696 - OUT3LMIX Input 1 Source */ - [0x06A1] = 0x0080, /* R1697 - OUT3LMIX Input 1 Volume */ - [0x06A2] = 0x0000, /* R1698 - OUT3LMIX Input 2 Source */ - [0x06A3] = 0x0080, /* R1699 - OUT3LMIX Input 2 Volume */ - [0x06A4] = 0x0000, /* R1700 - OUT3LMIX Input 3 Source */ - [0x06A5] = 0x0080, /* R1701 - OUT3LMIX Input 3 Volume */ - [0x06A6] = 0x0000, /* R1702 - OUT3LMIX Input 4 Source */ - [0x06A7] = 0x0080, /* R1703 - OUT3LMIX Input 4 Volume */ - [0x06A8] = 0x0000, /* R1704 - OUT3RMIX Input 1 Source */ - [0x06A9] = 0x0080, /* R1705 - OUT3RMIX Input 1 Volume */ - [0x06AA] = 0x0000, /* R1706 - OUT3RMIX Input 2 Source */ - [0x06AB] = 0x0080, /* R1707 - OUT3RMIX Input 2 Volume */ - [0x06AC] = 0x0000, /* R1708 - OUT3RMIX Input 3 Source */ - [0x06AD] = 0x0080, /* R1709 - OUT3RMIX Input 3 Volume */ - [0x06AE] = 0x0000, /* R1710 - OUT3RMIX Input 4 Source */ - [0x06AF] = 0x0080, /* R1711 - OUT3RMIX Input 4 Volume */ - [0x06B0] = 0x0000, /* R1712 - OUT4LMIX Input 1 Source */ - [0x06B1] = 0x0080, /* R1713 - OUT4LMIX Input 1 Volume */ - [0x06B2] = 0x0000, /* R1714 - OUT4LMIX Input 2 Source */ - [0x06B3] = 0x0080, /* R1715 - OUT4LMIX Input 2 Volume */ - [0x06B4] = 0x0000, /* R1716 - OUT4LMIX Input 3 Source */ - [0x06B5] = 0x0080, /* R1717 - OUT4LMIX Input 3 Volume */ - [0x06B6] = 0x0000, /* R1718 - OUT4LMIX Input 4 Source */ - [0x06B7] = 0x0080, /* R1719 - OUT4LMIX Input 4 Volume */ - [0x06B8] = 0x0000, /* R1720 - OUT4RMIX Input 1 Source */ - [0x06B9] = 0x0080, /* R1721 - OUT4RMIX Input 1 Volume */ - [0x06BA] = 0x0000, /* R1722 - OUT4RMIX Input 2 Source */ - [0x06BB] = 0x0080, /* R1723 - OUT4RMIX Input 2 Volume */ - [0x06BC] = 0x0000, /* R1724 - OUT4RMIX Input 3 Source */ - [0x06BD] = 0x0080, /* R1725 - OUT4RMIX Input 3 Volume */ - [0x06BE] = 0x0000, /* R1726 - OUT4RMIX Input 4 Source */ - [0x06BF] = 0x0080, /* R1727 - OUT4RMIX Input 4 Volume */ - [0x06C0] = 0x0000, /* R1728 - OUT5LMIX Input 1 Source */ - [0x06C1] = 0x0080, /* R1729 - OUT5LMIX Input 1 Volume */ - [0x06C2] = 0x0000, /* R1730 - OUT5LMIX Input 2 Source */ - [0x06C3] = 0x0080, /* R1731 - OUT5LMIX Input 2 Volume */ - [0x06C4] = 0x0000, /* R1732 - OUT5LMIX Input 3 Source */ - [0x06C5] = 0x0080, /* R1733 - OUT5LMIX Input 3 Volume */ - [0x06C6] = 0x0000, /* R1734 - OUT5LMIX Input 4 Source */ - [0x06C7] = 0x0080, /* R1735 - OUT5LMIX Input 4 Volume */ - [0x06C8] = 0x0000, /* R1736 - OUT5RMIX Input 1 Source */ - [0x06C9] = 0x0080, /* R1737 - OUT5RMIX Input 1 Volume */ - [0x06CA] = 0x0000, /* R1738 - OUT5RMIX Input 2 Source */ - [0x06CB] = 0x0080, /* R1739 - OUT5RMIX Input 2 Volume */ - [0x06CC] = 0x0000, /* R1740 - OUT5RMIX Input 3 Source */ - [0x06CD] = 0x0080, /* R1741 - OUT5RMIX Input 3 Volume */ - [0x06CE] = 0x0000, /* R1742 - OUT5RMIX Input 4 Source */ - [0x06CF] = 0x0080, /* R1743 - OUT5RMIX Input 4 Volume */ - [0x06D0] = 0x0000, /* R1744 - OUT6LMIX Input 1 Source */ - [0x06D1] = 0x0080, /* R1745 - OUT6LMIX Input 1 Volume */ - [0x06D2] = 0x0000, /* R1746 - OUT6LMIX Input 2 Source */ - [0x06D3] = 0x0080, /* R1747 - OUT6LMIX Input 2 Volume */ - [0x06D4] = 0x0000, /* R1748 - OUT6LMIX Input 3 Source */ - [0x06D5] = 0x0080, /* R1749 - OUT6LMIX Input 3 Volume */ - [0x06D6] = 0x0000, /* R1750 - OUT6LMIX Input 4 Source */ - [0x06D7] = 0x0080, /* R1751 - OUT6LMIX Input 4 Volume */ - [0x06D8] = 0x0000, /* R1752 - OUT6RMIX Input 1 Source */ - [0x06D9] = 0x0080, /* R1753 - OUT6RMIX Input 1 Volume */ - [0x06DA] = 0x0000, /* R1754 - OUT6RMIX Input 2 Source */ - [0x06DB] = 0x0080, /* R1755 - OUT6RMIX Input 2 Volume */ - [0x06DC] = 0x0000, /* R1756 - OUT6RMIX Input 3 Source */ - [0x06DD] = 0x0080, /* R1757 - OUT6RMIX Input 3 Volume */ - [0x06DE] = 0x0000, /* R1758 - OUT6RMIX Input 4 Source */ - [0x06DF] = 0x0080, /* R1759 - OUT6RMIX Input 4 Volume */ - [0x0700] = 0x0000, /* R1792 - AIF1TX1MIX Input 1 Source */ - [0x0701] = 0x0080, /* R1793 - AIF1TX1MIX Input 1 Volume */ - [0x0702] = 0x0000, /* R1794 - AIF1TX1MIX Input 2 Source */ - [0x0703] = 0x0080, /* R1795 - AIF1TX1MIX Input 2 Volume */ - [0x0704] = 0x0000, /* R1796 - AIF1TX1MIX Input 3 Source */ - [0x0705] = 0x0080, /* R1797 - AIF1TX1MIX Input 3 Volume */ - [0x0706] = 0x0000, /* R1798 - AIF1TX1MIX Input 4 Source */ - [0x0707] = 0x0080, /* R1799 - AIF1TX1MIX Input 4 Volume */ - [0x0708] = 0x0000, /* R1800 - AIF1TX2MIX Input 1 Source */ - [0x0709] = 0x0080, /* R1801 - AIF1TX2MIX Input 1 Volume */ - [0x070A] = 0x0000, /* R1802 - AIF1TX2MIX Input 2 Source */ - [0x070B] = 0x0080, /* R1803 - AIF1TX2MIX Input 2 Volume */ - [0x070C] = 0x0000, /* R1804 - AIF1TX2MIX Input 3 Source */ - [0x070D] = 0x0080, /* R1805 - AIF1TX2MIX Input 3 Volume */ - [0x070E] = 0x0000, /* R1806 - AIF1TX2MIX Input 4 Source */ - [0x070F] = 0x0080, /* R1807 - AIF1TX2MIX Input 4 Volume */ - [0x0710] = 0x0000, /* R1808 - AIF1TX3MIX Input 1 Source */ - [0x0711] = 0x0080, /* R1809 - AIF1TX3MIX Input 1 Volume */ - [0x0712] = 0x0000, /* R1810 - AIF1TX3MIX Input 2 Source */ - [0x0713] = 0x0080, /* R1811 - AIF1TX3MIX Input 2 Volume */ - [0x0714] = 0x0000, /* R1812 - AIF1TX3MIX Input 3 Source */ - [0x0715] = 0x0080, /* R1813 - AIF1TX3MIX Input 3 Volume */ - [0x0716] = 0x0000, /* R1814 - AIF1TX3MIX Input 4 Source */ - [0x0717] = 0x0080, /* R1815 - AIF1TX3MIX Input 4 Volume */ - [0x0718] = 0x0000, /* R1816 - AIF1TX4MIX Input 1 Source */ - [0x0719] = 0x0080, /* R1817 - AIF1TX4MIX Input 1 Volume */ - [0x071A] = 0x0000, /* R1818 - AIF1TX4MIX Input 2 Source */ - [0x071B] = 0x0080, /* R1819 - AIF1TX4MIX Input 2 Volume */ - [0x071C] = 0x0000, /* R1820 - AIF1TX4MIX Input 3 Source */ - [0x071D] = 0x0080, /* R1821 - AIF1TX4MIX Input 3 Volume */ - [0x071E] = 0x0000, /* R1822 - AIF1TX4MIX Input 4 Source */ - [0x071F] = 0x0080, /* R1823 - AIF1TX4MIX Input 4 Volume */ - [0x0720] = 0x0000, /* R1824 - AIF1TX5MIX Input 1 Source */ - [0x0721] = 0x0080, /* R1825 - AIF1TX5MIX Input 1 Volume */ - [0x0722] = 0x0000, /* R1826 - AIF1TX5MIX Input 2 Source */ - [0x0723] = 0x0080, /* R1827 - AIF1TX5MIX Input 2 Volume */ - [0x0724] = 0x0000, /* R1828 - AIF1TX5MIX Input 3 Source */ - [0x0725] = 0x0080, /* R1829 - AIF1TX5MIX Input 3 Volume */ - [0x0726] = 0x0000, /* R1830 - AIF1TX5MIX Input 4 Source */ - [0x0727] = 0x0080, /* R1831 - AIF1TX5MIX Input 4 Volume */ - [0x0728] = 0x0000, /* R1832 - AIF1TX6MIX Input 1 Source */ - [0x0729] = 0x0080, /* R1833 - AIF1TX6MIX Input 1 Volume */ - [0x072A] = 0x0000, /* R1834 - AIF1TX6MIX Input 2 Source */ - [0x072B] = 0x0080, /* R1835 - AIF1TX6MIX Input 2 Volume */ - [0x072C] = 0x0000, /* R1836 - AIF1TX6MIX Input 3 Source */ - [0x072D] = 0x0080, /* R1837 - AIF1TX6MIX Input 3 Volume */ - [0x072E] = 0x0000, /* R1838 - AIF1TX6MIX Input 4 Source */ - [0x072F] = 0x0080, /* R1839 - AIF1TX6MIX Input 4 Volume */ - [0x0730] = 0x0000, /* R1840 - AIF1TX7MIX Input 1 Source */ - [0x0731] = 0x0080, /* R1841 - AIF1TX7MIX Input 1 Volume */ - [0x0732] = 0x0000, /* R1842 - AIF1TX7MIX Input 2 Source */ - [0x0733] = 0x0080, /* R1843 - AIF1TX7MIX Input 2 Volume */ - [0x0734] = 0x0000, /* R1844 - AIF1TX7MIX Input 3 Source */ - [0x0735] = 0x0080, /* R1845 - AIF1TX7MIX Input 3 Volume */ - [0x0736] = 0x0000, /* R1846 - AIF1TX7MIX Input 4 Source */ - [0x0737] = 0x0080, /* R1847 - AIF1TX7MIX Input 4 Volume */ - [0x0738] = 0x0000, /* R1848 - AIF1TX8MIX Input 1 Source */ - [0x0739] = 0x0080, /* R1849 - AIF1TX8MIX Input 1 Volume */ - [0x073A] = 0x0000, /* R1850 - AIF1TX8MIX Input 2 Source */ - [0x073B] = 0x0080, /* R1851 - AIF1TX8MIX Input 2 Volume */ - [0x073C] = 0x0000, /* R1852 - AIF1TX8MIX Input 3 Source */ - [0x073D] = 0x0080, /* R1853 - AIF1TX8MIX Input 3 Volume */ - [0x073E] = 0x0000, /* R1854 - AIF1TX8MIX Input 4 Source */ - [0x073F] = 0x0080, /* R1855 - AIF1TX8MIX Input 4 Volume */ - [0x0740] = 0x0000, /* R1856 - AIF2TX1MIX Input 1 Source */ - [0x0741] = 0x0080, /* R1857 - AIF2TX1MIX Input 1 Volume */ - [0x0742] = 0x0000, /* R1858 - AIF2TX1MIX Input 2 Source */ - [0x0743] = 0x0080, /* R1859 - AIF2TX1MIX Input 2 Volume */ - [0x0744] = 0x0000, /* R1860 - AIF2TX1MIX Input 3 Source */ - [0x0745] = 0x0080, /* R1861 - AIF2TX1MIX Input 3 Volume */ - [0x0746] = 0x0000, /* R1862 - AIF2TX1MIX Input 4 Source */ - [0x0747] = 0x0080, /* R1863 - AIF2TX1MIX Input 4 Volume */ - [0x0748] = 0x0000, /* R1864 - AIF2TX2MIX Input 1 Source */ - [0x0749] = 0x0080, /* R1865 - AIF2TX2MIX Input 1 Volume */ - [0x074A] = 0x0000, /* R1866 - AIF2TX2MIX Input 2 Source */ - [0x074B] = 0x0080, /* R1867 - AIF2TX2MIX Input 2 Volume */ - [0x074C] = 0x0000, /* R1868 - AIF2TX2MIX Input 3 Source */ - [0x074D] = 0x0080, /* R1869 - AIF2TX2MIX Input 3 Volume */ - [0x074E] = 0x0000, /* R1870 - AIF2TX2MIX Input 4 Source */ - [0x074F] = 0x0080, /* R1871 - AIF2TX2MIX Input 4 Volume */ - [0x0780] = 0x0000, /* R1920 - AIF3TX1MIX Input 1 Source */ - [0x0781] = 0x0080, /* R1921 - AIF3TX1MIX Input 1 Volume */ - [0x0782] = 0x0000, /* R1922 - AIF3TX1MIX Input 2 Source */ - [0x0783] = 0x0080, /* R1923 - AIF3TX1MIX Input 2 Volume */ - [0x0784] = 0x0000, /* R1924 - AIF3TX1MIX Input 3 Source */ - [0x0785] = 0x0080, /* R1925 - AIF3TX1MIX Input 3 Volume */ - [0x0786] = 0x0000, /* R1926 - AIF3TX1MIX Input 4 Source */ - [0x0787] = 0x0080, /* R1927 - AIF3TX1MIX Input 4 Volume */ - [0x0788] = 0x0000, /* R1928 - AIF3TX2MIX Input 1 Source */ - [0x0789] = 0x0080, /* R1929 - AIF3TX2MIX Input 1 Volume */ - [0x078A] = 0x0000, /* R1930 - AIF3TX2MIX Input 2 Source */ - [0x078B] = 0x0080, /* R1931 - AIF3TX2MIX Input 2 Volume */ - [0x078C] = 0x0000, /* R1932 - AIF3TX2MIX Input 3 Source */ - [0x078D] = 0x0080, /* R1933 - AIF3TX2MIX Input 3 Volume */ - [0x078E] = 0x0000, /* R1934 - AIF3TX2MIX Input 4 Source */ - [0x078F] = 0x0080, /* R1935 - AIF3TX2MIX Input 4 Volume */ - [0x0880] = 0x0000, /* R2176 - EQ1MIX Input 1 Source */ - [0x0881] = 0x0080, /* R2177 - EQ1MIX Input 1 Volume */ - [0x0882] = 0x0000, /* R2178 - EQ1MIX Input 2 Source */ - [0x0883] = 0x0080, /* R2179 - EQ1MIX Input 2 Volume */ - [0x0884] = 0x0000, /* R2180 - EQ1MIX Input 3 Source */ - [0x0885] = 0x0080, /* R2181 - EQ1MIX Input 3 Volume */ - [0x0886] = 0x0000, /* R2182 - EQ1MIX Input 4 Source */ - [0x0887] = 0x0080, /* R2183 - EQ1MIX Input 4 Volume */ - [0x0888] = 0x0000, /* R2184 - EQ2MIX Input 1 Source */ - [0x0889] = 0x0080, /* R2185 - EQ2MIX Input 1 Volume */ - [0x088A] = 0x0000, /* R2186 - EQ2MIX Input 2 Source */ - [0x088B] = 0x0080, /* R2187 - EQ2MIX Input 2 Volume */ - [0x088C] = 0x0000, /* R2188 - EQ2MIX Input 3 Source */ - [0x088D] = 0x0080, /* R2189 - EQ2MIX Input 3 Volume */ - [0x088E] = 0x0000, /* R2190 - EQ2MIX Input 4 Source */ - [0x088F] = 0x0080, /* R2191 - EQ2MIX Input 4 Volume */ - [0x0890] = 0x0000, /* R2192 - EQ3MIX Input 1 Source */ - [0x0891] = 0x0080, /* R2193 - EQ3MIX Input 1 Volume */ - [0x0892] = 0x0000, /* R2194 - EQ3MIX Input 2 Source */ - [0x0893] = 0x0080, /* R2195 - EQ3MIX Input 2 Volume */ - [0x0894] = 0x0000, /* R2196 - EQ3MIX Input 3 Source */ - [0x0895] = 0x0080, /* R2197 - EQ3MIX Input 3 Volume */ - [0x0896] = 0x0000, /* R2198 - EQ3MIX Input 4 Source */ - [0x0897] = 0x0080, /* R2199 - EQ3MIX Input 4 Volume */ - [0x0898] = 0x0000, /* R2200 - EQ4MIX Input 1 Source */ - [0x0899] = 0x0080, /* R2201 - EQ4MIX Input 1 Volume */ - [0x089A] = 0x0000, /* R2202 - EQ4MIX Input 2 Source */ - [0x089B] = 0x0080, /* R2203 - EQ4MIX Input 2 Volume */ - [0x089C] = 0x0000, /* R2204 - EQ4MIX Input 3 Source */ - [0x089D] = 0x0080, /* R2205 - EQ4MIX Input 3 Volume */ - [0x089E] = 0x0000, /* R2206 - EQ4MIX Input 4 Source */ - [0x089F] = 0x0080, /* R2207 - EQ4MIX Input 4 Volume */ - [0x08C0] = 0x0000, /* R2240 - DRC1LMIX Input 1 Source */ - [0x08C1] = 0x0080, /* R2241 - DRC1LMIX Input 1 Volume */ - [0x08C2] = 0x0000, /* R2242 - DRC1LMIX Input 2 Source */ - [0x08C3] = 0x0080, /* R2243 - DRC1LMIX Input 2 Volume */ - [0x08C4] = 0x0000, /* R2244 - DRC1LMIX Input 3 Source */ - [0x08C5] = 0x0080, /* R2245 - DRC1LMIX Input 3 Volume */ - [0x08C6] = 0x0000, /* R2246 - DRC1LMIX Input 4 Source */ - [0x08C7] = 0x0080, /* R2247 - DRC1LMIX Input 4 Volume */ - [0x08C8] = 0x0000, /* R2248 - DRC1RMIX Input 1 Source */ - [0x08C9] = 0x0080, /* R2249 - DRC1RMIX Input 1 Volume */ - [0x08CA] = 0x0000, /* R2250 - DRC1RMIX Input 2 Source */ - [0x08CB] = 0x0080, /* R2251 - DRC1RMIX Input 2 Volume */ - [0x08CC] = 0x0000, /* R2252 - DRC1RMIX Input 3 Source */ - [0x08CD] = 0x0080, /* R2253 - DRC1RMIX Input 3 Volume */ - [0x08CE] = 0x0000, /* R2254 - DRC1RMIX Input 4 Source */ - [0x08CF] = 0x0080, /* R2255 - DRC1RMIX Input 4 Volume */ - [0x0900] = 0x0000, /* R2304 - HPLP1MIX Input 1 Source */ - [0x0901] = 0x0080, /* R2305 - HPLP1MIX Input 1 Volume */ - [0x0902] = 0x0000, /* R2306 - HPLP1MIX Input 2 Source */ - [0x0903] = 0x0080, /* R2307 - HPLP1MIX Input 2 Volume */ - [0x0904] = 0x0000, /* R2308 - HPLP1MIX Input 3 Source */ - [0x0905] = 0x0080, /* R2309 - HPLP1MIX Input 3 Volume */ - [0x0906] = 0x0000, /* R2310 - HPLP1MIX Input 4 Source */ - [0x0907] = 0x0080, /* R2311 - HPLP1MIX Input 4 Volume */ - [0x0908] = 0x0000, /* R2312 - HPLP2MIX Input 1 Source */ - [0x0909] = 0x0080, /* R2313 - HPLP2MIX Input 1 Volume */ - [0x090A] = 0x0000, /* R2314 - HPLP2MIX Input 2 Source */ - [0x090B] = 0x0080, /* R2315 - HPLP2MIX Input 2 Volume */ - [0x090C] = 0x0000, /* R2316 - HPLP2MIX Input 3 Source */ - [0x090D] = 0x0080, /* R2317 - HPLP2MIX Input 3 Volume */ - [0x090E] = 0x0000, /* R2318 - HPLP2MIX Input 4 Source */ - [0x090F] = 0x0080, /* R2319 - HPLP2MIX Input 4 Volume */ - [0x0910] = 0x0000, /* R2320 - HPLP3MIX Input 1 Source */ - [0x0911] = 0x0080, /* R2321 - HPLP3MIX Input 1 Volume */ - [0x0912] = 0x0000, /* R2322 - HPLP3MIX Input 2 Source */ - [0x0913] = 0x0080, /* R2323 - HPLP3MIX Input 2 Volume */ - [0x0914] = 0x0000, /* R2324 - HPLP3MIX Input 3 Source */ - [0x0915] = 0x0080, /* R2325 - HPLP3MIX Input 3 Volume */ - [0x0916] = 0x0000, /* R2326 - HPLP3MIX Input 4 Source */ - [0x0917] = 0x0080, /* R2327 - HPLP3MIX Input 4 Volume */ - [0x0918] = 0x0000, /* R2328 - HPLP4MIX Input 1 Source */ - [0x0919] = 0x0080, /* R2329 - HPLP4MIX Input 1 Volume */ - [0x091A] = 0x0000, /* R2330 - HPLP4MIX Input 2 Source */ - [0x091B] = 0x0080, /* R2331 - HPLP4MIX Input 2 Volume */ - [0x091C] = 0x0000, /* R2332 - HPLP4MIX Input 3 Source */ - [0x091D] = 0x0080, /* R2333 - HPLP4MIX Input 3 Volume */ - [0x091E] = 0x0000, /* R2334 - HPLP4MIX Input 4 Source */ - [0x091F] = 0x0080, /* R2335 - HPLP4MIX Input 4 Volume */ - [0x0940] = 0x0000, /* R2368 - DSP1LMIX Input 1 Source */ - [0x0941] = 0x0080, /* R2369 - DSP1LMIX Input 1 Volume */ - [0x0942] = 0x0000, /* R2370 - DSP1LMIX Input 2 Source */ - [0x0943] = 0x0080, /* R2371 - DSP1LMIX Input 2 Volume */ - [0x0944] = 0x0000, /* R2372 - DSP1LMIX Input 3 Source */ - [0x0945] = 0x0080, /* R2373 - DSP1LMIX Input 3 Volume */ - [0x0946] = 0x0000, /* R2374 - DSP1LMIX Input 4 Source */ - [0x0947] = 0x0080, /* R2375 - DSP1LMIX Input 4 Volume */ - [0x0948] = 0x0000, /* R2376 - DSP1RMIX Input 1 Source */ - [0x0949] = 0x0080, /* R2377 - DSP1RMIX Input 1 Volume */ - [0x094A] = 0x0000, /* R2378 - DSP1RMIX Input 2 Source */ - [0x094B] = 0x0080, /* R2379 - DSP1RMIX Input 2 Volume */ - [0x094C] = 0x0000, /* R2380 - DSP1RMIX Input 3 Source */ - [0x094D] = 0x0080, /* R2381 - DSP1RMIX Input 3 Volume */ - [0x094E] = 0x0000, /* R2382 - DSP1RMIX Input 4 Source */ - [0x094F] = 0x0080, /* R2383 - DSP1RMIX Input 4 Volume */ - [0x0950] = 0x0000, /* R2384 - DSP1AUX1MIX Input 1 Source */ - [0x0958] = 0x0000, /* R2392 - DSP1AUX2MIX Input 1 Source */ - [0x0960] = 0x0000, /* R2400 - DSP1AUX3MIX Input 1 Source */ - [0x0968] = 0x0000, /* R2408 - DSP1AUX4MIX Input 1 Source */ - [0x0970] = 0x0000, /* R2416 - DSP1AUX5MIX Input 1 Source */ - [0x0978] = 0x0000, /* R2424 - DSP1AUX6MIX Input 1 Source */ - [0x0980] = 0x0000, /* R2432 - DSP2LMIX Input 1 Source */ - [0x0981] = 0x0080, /* R2433 - DSP2LMIX Input 1 Volume */ - [0x0982] = 0x0000, /* R2434 - DSP2LMIX Input 2 Source */ - [0x0983] = 0x0080, /* R2435 - DSP2LMIX Input 2 Volume */ - [0x0984] = 0x0000, /* R2436 - DSP2LMIX Input 3 Source */ - [0x0985] = 0x0080, /* R2437 - DSP2LMIX Input 3 Volume */ - [0x0986] = 0x0000, /* R2438 - DSP2LMIX Input 4 Source */ - [0x0987] = 0x0080, /* R2439 - DSP2LMIX Input 4 Volume */ - [0x0988] = 0x0000, /* R2440 - DSP2RMIX Input 1 Source */ - [0x0989] = 0x0080, /* R2441 - DSP2RMIX Input 1 Volume */ - [0x098A] = 0x0000, /* R2442 - DSP2RMIX Input 2 Source */ - [0x098B] = 0x0080, /* R2443 - DSP2RMIX Input 2 Volume */ - [0x098C] = 0x0000, /* R2444 - DSP2RMIX Input 3 Source */ - [0x098D] = 0x0080, /* R2445 - DSP2RMIX Input 3 Volume */ - [0x098E] = 0x0000, /* R2446 - DSP2RMIX Input 4 Source */ - [0x098F] = 0x0080, /* R2447 - DSP2RMIX Input 4 Volume */ - [0x0990] = 0x0000, /* R2448 - DSP2AUX1MIX Input 1 Source */ - [0x0998] = 0x0000, /* R2456 - DSP2AUX2MIX Input 1 Source */ - [0x09A0] = 0x0000, /* R2464 - DSP2AUX3MIX Input 1 Source */ - [0x09A8] = 0x0000, /* R2472 - DSP2AUX4MIX Input 1 Source */ - [0x09B0] = 0x0000, /* R2480 - DSP2AUX5MIX Input 1 Source */ - [0x09B8] = 0x0000, /* R2488 - DSP2AUX6MIX Input 1 Source */ - [0x09C0] = 0x0000, /* R2496 - DSP3LMIX Input 1 Source */ - [0x09C1] = 0x0080, /* R2497 - DSP3LMIX Input 1 Volume */ - [0x09C2] = 0x0000, /* R2498 - DSP3LMIX Input 2 Source */ - [0x09C3] = 0x0080, /* R2499 - DSP3LMIX Input 2 Volume */ - [0x09C4] = 0x0000, /* R2500 - DSP3LMIX Input 3 Source */ - [0x09C5] = 0x0080, /* R2501 - DSP3LMIX Input 3 Volume */ - [0x09C6] = 0x0000, /* R2502 - DSP3LMIX Input 4 Source */ - [0x09C7] = 0x0080, /* R2503 - DSP3LMIX Input 4 Volume */ - [0x09C8] = 0x0000, /* R2504 - DSP3RMIX Input 1 Source */ - [0x09C9] = 0x0080, /* R2505 - DSP3RMIX Input 1 Volume */ - [0x09CA] = 0x0000, /* R2506 - DSP3RMIX Input 2 Source */ - [0x09CB] = 0x0080, /* R2507 - DSP3RMIX Input 2 Volume */ - [0x09CC] = 0x0000, /* R2508 - DSP3RMIX Input 3 Source */ - [0x09CD] = 0x0080, /* R2509 - DSP3RMIX Input 3 Volume */ - [0x09CE] = 0x0000, /* R2510 - DSP3RMIX Input 4 Source */ - [0x09CF] = 0x0080, /* R2511 - DSP3RMIX Input 4 Volume */ - [0x09D0] = 0x0000, /* R2512 - DSP3AUX1MIX Input 1 Source */ - [0x09D8] = 0x0000, /* R2520 - DSP3AUX2MIX Input 1 Source */ - [0x09E0] = 0x0000, /* R2528 - DSP3AUX3MIX Input 1 Source */ - [0x09E8] = 0x0000, /* R2536 - DSP3AUX4MIX Input 1 Source */ - [0x09F0] = 0x0000, /* R2544 - DSP3AUX5MIX Input 1 Source */ - [0x09F8] = 0x0000, /* R2552 - DSP3AUX6MIX Input 1 Source */ - [0x0A80] = 0x0000, /* R2688 - ASRC1LMIX Input 1 Source */ - [0x0A88] = 0x0000, /* R2696 - ASRC1RMIX Input 1 Source */ - [0x0A90] = 0x0000, /* R2704 - ASRC2LMIX Input 1 Source */ - [0x0A98] = 0x0000, /* R2712 - ASRC2RMIX Input 1 Source */ - [0x0B00] = 0x0000, /* R2816 - ISRC1DEC1MIX Input 1 Source */ - [0x0B08] = 0x0000, /* R2824 - ISRC1DEC2MIX Input 1 Source */ - [0x0B10] = 0x0000, /* R2832 - ISRC1DEC3MIX Input 1 Source */ - [0x0B18] = 0x0000, /* R2840 - ISRC1DEC4MIX Input 1 Source */ - [0x0B20] = 0x0000, /* R2848 - ISRC1INT1MIX Input 1 Source */ - [0x0B28] = 0x0000, /* R2856 - ISRC1INT2MIX Input 1 Source */ - [0x0B30] = 0x0000, /* R2864 - ISRC1INT3MIX Input 1 Source */ - [0x0B38] = 0x0000, /* R2872 - ISRC1INT4MIX Input 1 Source */ - [0x0B40] = 0x0000, /* R2880 - ISRC2DEC1MIX Input 1 Source */ - [0x0B48] = 0x0000, /* R2888 - ISRC2DEC2MIX Input 1 Source */ - [0x0B50] = 0x0000, /* R2896 - ISRC2DEC3MIX Input 1 Source */ - [0x0B58] = 0x0000, /* R2904 - ISRC2DEC4MIX Input 1 Source */ - [0x0B60] = 0x0000, /* R2912 - ISRC2INT1MIX Input 1 Source */ - [0x0B68] = 0x0000, /* R2920 - ISRC2INT2MIX Input 1 Source */ - [0x0B70] = 0x0000, /* R2928 - ISRC2INT3MIX Input 1 Source */ - [0x0B78] = 0x0000, /* R2936 - ISRC2INT4MIX Input 1 Source */ - [0x0C00] = 0xA001, /* R3072 - GPIO CTRL 1 */ - [0x0C01] = 0xA001, /* R3073 - GPIO CTRL 2 */ - [0x0C02] = 0xA001, /* R3074 - GPIO CTRL 3 */ - [0x0C03] = 0xA001, /* R3075 - GPIO CTRL 4 */ - [0x0C04] = 0xA001, /* R3076 - GPIO CTRL 5 */ - [0x0C05] = 0xA001, /* R3077 - GPIO CTRL 6 */ - [0x0C23] = 0x4003, /* R3107 - Misc Pad Ctrl 1 */ - [0x0C24] = 0x0000, /* R3108 - Misc Pad Ctrl 2 */ - [0x0C25] = 0x0000, /* R3109 - Misc Pad Ctrl 3 */ - [0x0C26] = 0x0000, /* R3110 - Misc Pad Ctrl 4 */ - [0x0C27] = 0x0000, /* R3111 - Misc Pad Ctrl 5 */ - [0x0C28] = 0x0000, /* R3112 - Misc GPIO 1 */ - [0x0D00] = 0x0000, /* R3328 - Interrupt Status 1 */ - [0x0D01] = 0x0000, /* R3329 - Interrupt Status 2 */ - [0x0D02] = 0x0000, /* R3330 - Interrupt Status 3 */ - [0x0D03] = 0x0000, /* R3331 - Interrupt Status 4 */ - [0x0D04] = 0x0000, /* R3332 - Interrupt Raw Status 2 */ - [0x0D05] = 0x0000, /* R3333 - Interrupt Raw Status 3 */ - [0x0D06] = 0x0000, /* R3334 - Interrupt Raw Status 4 */ - [0x0D07] = 0xFFFF, /* R3335 - Interrupt Status 1 Mask */ - [0x0D08] = 0xFFFF, /* R3336 - Interrupt Status 2 Mask */ - [0x0D09] = 0xFFFF, /* R3337 - Interrupt Status 3 Mask */ - [0x0D0A] = 0xFFFF, /* R3338 - Interrupt Status 4 Mask */ - [0x0D1F] = 0x0000, /* R3359 - Interrupt Control */ - [0x0D20] = 0xFFFF, /* R3360 - IRQ Debounce 1 */ - [0x0D21] = 0xFFFF, /* R3361 - IRQ Debounce 2 */ - [0x0E00] = 0x0000, /* R3584 - FX_Ctrl */ - [0x0E10] = 0x6318, /* R3600 - EQ1_1 */ - [0x0E11] = 0x6300, /* R3601 - EQ1_2 */ - [0x0E12] = 0x0FC8, /* R3602 - EQ1_3 */ - [0x0E13] = 0x03FE, /* R3603 - EQ1_4 */ - [0x0E14] = 0x00E0, /* R3604 - EQ1_5 */ - [0x0E15] = 0x1EC4, /* R3605 - EQ1_6 */ - [0x0E16] = 0xF136, /* R3606 - EQ1_7 */ - [0x0E17] = 0x0409, /* R3607 - EQ1_8 */ - [0x0E18] = 0x04CC, /* R3608 - EQ1_9 */ - [0x0E19] = 0x1C9B, /* R3609 - EQ1_10 */ - [0x0E1A] = 0xF337, /* R3610 - EQ1_11 */ - [0x0E1B] = 0x040B, /* R3611 - EQ1_12 */ - [0x0E1C] = 0x0CBB, /* R3612 - EQ1_13 */ - [0x0E1D] = 0x16F8, /* R3613 - EQ1_14 */ - [0x0E1E] = 0xF7D9, /* R3614 - EQ1_15 */ - [0x0E1F] = 0x040A, /* R3615 - EQ1_16 */ - [0x0E20] = 0x1F14, /* R3616 - EQ1_17 */ - [0x0E21] = 0x058C, /* R3617 - EQ1_18 */ - [0x0E22] = 0x0563, /* R3618 - EQ1_19 */ - [0x0E23] = 0x4000, /* R3619 - EQ1_20 */ - [0x0E26] = 0x6318, /* R3622 - EQ2_1 */ - [0x0E27] = 0x6300, /* R3623 - EQ2_2 */ - [0x0E28] = 0x0FC8, /* R3624 - EQ2_3 */ - [0x0E29] = 0x03FE, /* R3625 - EQ2_4 */ - [0x0E2A] = 0x00E0, /* R3626 - EQ2_5 */ - [0x0E2B] = 0x1EC4, /* R3627 - EQ2_6 */ - [0x0E2C] = 0xF136, /* R3628 - EQ2_7 */ - [0x0E2D] = 0x0409, /* R3629 - EQ2_8 */ - [0x0E2E] = 0x04CC, /* R3630 - EQ2_9 */ - [0x0E2F] = 0x1C9B, /* R3631 - EQ2_10 */ - [0x0E30] = 0xF337, /* R3632 - EQ2_11 */ - [0x0E31] = 0x040B, /* R3633 - EQ2_12 */ - [0x0E32] = 0x0CBB, /* R3634 - EQ2_13 */ - [0x0E33] = 0x16F8, /* R3635 - EQ2_14 */ - [0x0E34] = 0xF7D9, /* R3636 - EQ2_15 */ - [0x0E35] = 0x040A, /* R3637 - EQ2_16 */ - [0x0E36] = 0x1F14, /* R3638 - EQ2_17 */ - [0x0E37] = 0x058C, /* R3639 - EQ2_18 */ - [0x0E38] = 0x0563, /* R3640 - EQ2_19 */ - [0x0E39] = 0x4000, /* R3641 - EQ2_20 */ - [0x0E3C] = 0x6318, /* R3644 - EQ3_1 */ - [0x0E3D] = 0x6300, /* R3645 - EQ3_2 */ - [0x0E3E] = 0x0FC8, /* R3646 - EQ3_3 */ - [0x0E3F] = 0x03FE, /* R3647 - EQ3_4 */ - [0x0E40] = 0x00E0, /* R3648 - EQ3_5 */ - [0x0E41] = 0x1EC4, /* R3649 - EQ3_6 */ - [0x0E42] = 0xF136, /* R3650 - EQ3_7 */ - [0x0E43] = 0x0409, /* R3651 - EQ3_8 */ - [0x0E44] = 0x04CC, /* R3652 - EQ3_9 */ - [0x0E45] = 0x1C9B, /* R3653 - EQ3_10 */ - [0x0E46] = 0xF337, /* R3654 - EQ3_11 */ - [0x0E47] = 0x040B, /* R3655 - EQ3_12 */ - [0x0E48] = 0x0CBB, /* R3656 - EQ3_13 */ - [0x0E49] = 0x16F8, /* R3657 - EQ3_14 */ - [0x0E4A] = 0xF7D9, /* R3658 - EQ3_15 */ - [0x0E4B] = 0x040A, /* R3659 - EQ3_16 */ - [0x0E4C] = 0x1F14, /* R3660 - EQ3_17 */ - [0x0E4D] = 0x058C, /* R3661 - EQ3_18 */ - [0x0E4E] = 0x0563, /* R3662 - EQ3_19 */ - [0x0E4F] = 0x4000, /* R3663 - EQ3_20 */ - [0x0E52] = 0x6318, /* R3666 - EQ4_1 */ - [0x0E53] = 0x6300, /* R3667 - EQ4_2 */ - [0x0E54] = 0x0FC8, /* R3668 - EQ4_3 */ - [0x0E55] = 0x03FE, /* R3669 - EQ4_4 */ - [0x0E56] = 0x00E0, /* R3670 - EQ4_5 */ - [0x0E57] = 0x1EC4, /* R3671 - EQ4_6 */ - [0x0E58] = 0xF136, /* R3672 - EQ4_7 */ - [0x0E59] = 0x0409, /* R3673 - EQ4_8 */ - [0x0E5A] = 0x04CC, /* R3674 - EQ4_9 */ - [0x0E5B] = 0x1C9B, /* R3675 - EQ4_10 */ - [0x0E5C] = 0xF337, /* R3676 - EQ4_11 */ - [0x0E5D] = 0x040B, /* R3677 - EQ4_12 */ - [0x0E5E] = 0x0CBB, /* R3678 - EQ4_13 */ - [0x0E5F] = 0x16F8, /* R3679 - EQ4_14 */ - [0x0E60] = 0xF7D9, /* R3680 - EQ4_15 */ - [0x0E61] = 0x040A, /* R3681 - EQ4_16 */ - [0x0E62] = 0x1F14, /* R3682 - EQ4_17 */ - [0x0E63] = 0x058C, /* R3683 - EQ4_18 */ - [0x0E64] = 0x0563, /* R3684 - EQ4_19 */ - [0x0E65] = 0x4000, /* R3685 - EQ4_20 */ - [0x0E80] = 0x0018, /* R3712 - DRC1 ctrl1 */ - [0x0E81] = 0x0933, /* R3713 - DRC1 ctrl2 */ - [0x0E82] = 0x0018, /* R3714 - DRC1 ctrl3 */ - [0x0E83] = 0x0000, /* R3715 - DRC1 ctrl4 */ - [0x0E84] = 0x0000, /* R3716 - DRC1 ctrl5 */ - [0x0EC0] = 0x0000, /* R3776 - HPLPF1_1 */ - [0x0EC1] = 0x0000, /* R3777 - HPLPF1_2 */ - [0x0EC4] = 0x0000, /* R3780 - HPLPF2_1 */ - [0x0EC5] = 0x0000, /* R3781 - HPLPF2_2 */ - [0x0EC8] = 0x0000, /* R3784 - HPLPF3_1 */ - [0x0EC9] = 0x0000, /* R3785 - HPLPF3_2 */ - [0x0ECC] = 0x0000, /* R3788 - HPLPF4_1 */ - [0x0ECD] = 0x0000, /* R3789 - HPLPF4_2 */ - [0x4000] = 0x0000, /* R16384 - DSP1 DM 0 */ - [0x4001] = 0x0000, /* R16385 - DSP1 DM 1 */ - [0x4002] = 0x0000, /* R16386 - DSP1 DM 2 */ - [0x4003] = 0x0000, /* R16387 - DSP1 DM 3 */ - [0x41FC] = 0x0000, /* R16892 - DSP1 DM 508 */ - [0x41FD] = 0x0000, /* R16893 - DSP1 DM 509 */ - [0x41FE] = 0x0000, /* R16894 - DSP1 DM 510 */ - [0x41FF] = 0x0000, /* R16895 - DSP1 DM 511 */ - [0x4800] = 0x0000, /* R18432 - DSP1 PM 0 */ - [0x4801] = 0x0000, /* R18433 - DSP1 PM 1 */ - [0x4802] = 0x0000, /* R18434 - DSP1 PM 2 */ - [0x4803] = 0x0000, /* R18435 - DSP1 PM 3 */ - [0x4804] = 0x0000, /* R18436 - DSP1 PM 4 */ - [0x4805] = 0x0000, /* R18437 - DSP1 PM 5 */ - [0x4DFA] = 0x0000, /* R19962 - DSP1 PM 1530 */ - [0x4DFB] = 0x0000, /* R19963 - DSP1 PM 1531 */ - [0x4DFC] = 0x0000, /* R19964 - DSP1 PM 1532 */ - [0x4DFD] = 0x0000, /* R19965 - DSP1 PM 1533 */ - [0x4DFE] = 0x0000, /* R19966 - DSP1 PM 1534 */ - [0x4DFF] = 0x0000, /* R19967 - DSP1 PM 1535 */ - [0x5000] = 0x0000, /* R20480 - DSP1 ZM 0 */ - [0x5001] = 0x0000, /* R20481 - DSP1 ZM 1 */ - [0x5002] = 0x0000, /* R20482 - DSP1 ZM 2 */ - [0x5003] = 0x0000, /* R20483 - DSP1 ZM 3 */ - [0x57FC] = 0x0000, /* R22524 - DSP1 ZM 2044 */ - [0x57FD] = 0x0000, /* R22525 - DSP1 ZM 2045 */ - [0x57FE] = 0x0000, /* R22526 - DSP1 ZM 2046 */ - [0x57FF] = 0x0000, /* R22527 - DSP1 ZM 2047 */ - [0x6000] = 0x0000, /* R24576 - DSP2 DM 0 */ - [0x6001] = 0x0000, /* R24577 - DSP2 DM 1 */ - [0x6002] = 0x0000, /* R24578 - DSP2 DM 2 */ - [0x6003] = 0x0000, /* R24579 - DSP2 DM 3 */ - [0x61FC] = 0x0000, /* R25084 - DSP2 DM 508 */ - [0x61FD] = 0x0000, /* R25085 - DSP2 DM 509 */ - [0x61FE] = 0x0000, /* R25086 - DSP2 DM 510 */ - [0x61FF] = 0x0000, /* R25087 - DSP2 DM 511 */ - [0x6800] = 0x0000, /* R26624 - DSP2 PM 0 */ - [0x6801] = 0x0000, /* R26625 - DSP2 PM 1 */ - [0x6802] = 0x0000, /* R26626 - DSP2 PM 2 */ - [0x6803] = 0x0000, /* R26627 - DSP2 PM 3 */ - [0x6804] = 0x0000, /* R26628 - DSP2 PM 4 */ - [0x6805] = 0x0000, /* R26629 - DSP2 PM 5 */ - [0x6DFA] = 0x0000, /* R28154 - DSP2 PM 1530 */ - [0x6DFB] = 0x0000, /* R28155 - DSP2 PM 1531 */ - [0x6DFC] = 0x0000, /* R28156 - DSP2 PM 1532 */ - [0x6DFD] = 0x0000, /* R28157 - DSP2 PM 1533 */ - [0x6DFE] = 0x0000, /* R28158 - DSP2 PM 1534 */ - [0x6DFF] = 0x0000, /* R28159 - DSP2 PM 1535 */ - [0x7000] = 0x0000, /* R28672 - DSP2 ZM 0 */ - [0x7001] = 0x0000, /* R28673 - DSP2 ZM 1 */ - [0x7002] = 0x0000, /* R28674 - DSP2 ZM 2 */ - [0x7003] = 0x0000, /* R28675 - DSP2 ZM 3 */ - [0x77FC] = 0x0000, /* R30716 - DSP2 ZM 2044 */ - [0x77FD] = 0x0000, /* R30717 - DSP2 ZM 2045 */ - [0x77FE] = 0x0000, /* R30718 - DSP2 ZM 2046 */ - [0x77FF] = 0x0000, /* R30719 - DSP2 ZM 2047 */ - [0x8000] = 0x0000, /* R32768 - DSP3 DM 0 */ - [0x8001] = 0x0000, /* R32769 - DSP3 DM 1 */ - [0x8002] = 0x0000, /* R32770 - DSP3 DM 2 */ - [0x8003] = 0x0000, /* R32771 - DSP3 DM 3 */ - [0x81FC] = 0x0000, /* R33276 - DSP3 DM 508 */ - [0x81FD] = 0x0000, /* R33277 - DSP3 DM 509 */ - [0x81FE] = 0x0000, /* R33278 - DSP3 DM 510 */ - [0x81FF] = 0x0000, /* R33279 - DSP3 DM 511 */ - [0x8800] = 0x0000, /* R34816 - DSP3 PM 0 */ - [0x8801] = 0x0000, /* R34817 - DSP3 PM 1 */ - [0x8802] = 0x0000, /* R34818 - DSP3 PM 2 */ - [0x8803] = 0x0000, /* R34819 - DSP3 PM 3 */ - [0x8804] = 0x0000, /* R34820 - DSP3 PM 4 */ - [0x8805] = 0x0000, /* R34821 - DSP3 PM 5 */ - [0x8DFA] = 0x0000, /* R36346 - DSP3 PM 1530 */ - [0x8DFB] = 0x0000, /* R36347 - DSP3 PM 1531 */ - [0x8DFC] = 0x0000, /* R36348 - DSP3 PM 1532 */ - [0x8DFD] = 0x0000, /* R36349 - DSP3 PM 1533 */ - [0x8DFE] = 0x0000, /* R36350 - DSP3 PM 1534 */ - [0x8DFF] = 0x0000, /* R36351 - DSP3 PM 1535 */ - [0x9000] = 0x0000, /* R36864 - DSP3 ZM 0 */ - [0x9001] = 0x0000, /* R36865 - DSP3 ZM 1 */ - [0x9002] = 0x0000, /* R36866 - DSP3 ZM 2 */ - [0x9003] = 0x0000, /* R36867 - DSP3 ZM 3 */ - [0x97FC] = 0x0000, /* R38908 - DSP3 ZM 2044 */ - [0x97FD] = 0x0000, /* R38909 - DSP3 ZM 2045 */ - [0x97FE] = 0x0000, /* R38910 - DSP3 ZM 2046 */ - [0x97FF] = 0x0000 /* R38911 - DSP3 ZM 2047 */ +struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT] = { + { 0x0000, 0x0000 }, /* R0 - software reset */ + { 0x0001, 0x0000 }, /* R1 - Device Revision */ + { 0x0010, 0x0801 }, /* R16 - Ctrl IF 1 */ + { 0x0020, 0x0000 }, /* R32 - Tone Generator 1 */ + { 0x0030, 0x0000 }, /* R48 - PWM Drive 1 */ + { 0x0031, 0x0100 }, /* R49 - PWM Drive 2 */ + { 0x0032, 0x0100 }, /* R50 - PWM Drive 3 */ + { 0x0100, 0x0002 }, /* R256 - Clocking 1 */ + { 0x0101, 0x0000 }, /* R257 - Clocking 3 */ + { 0x0102, 0x0011 }, /* R258 - Clocking 4 */ + { 0x0103, 0x0011 }, /* R259 - Clocking 5 */ + { 0x0104, 0x0011 }, /* R260 - Clocking 6 */ + { 0x0107, 0x0000 }, /* R263 - Clocking 7 */ + { 0x0108, 0x0000 }, /* R264 - Clocking 8 */ + { 0x0120, 0x0000 }, /* R288 - ASRC_ENABLE */ + { 0x0121, 0x0000 }, /* R289 - ASRC_STATUS */ + { 0x0122, 0x0000 }, /* R290 - ASRC_RATE1 */ + { 0x0141, 0x8000 }, /* R321 - ISRC 1 CTRL 1 */ + { 0x0142, 0x0000 }, /* R322 - ISRC 1 CTRL 2 */ + { 0x0143, 0x8000 }, /* R323 - ISRC 2 CTRL1 */ + { 0x0144, 0x0000 }, /* R324 - ISRC 2 CTRL 2 */ + { 0x0182, 0x0000 }, /* R386 - FLL1 Control 1 */ + { 0x0183, 0x0000 }, /* R387 - FLL1 Control 2 */ + { 0x0184, 0x0000 }, /* R388 - FLL1 Control 3 */ + { 0x0186, 0x0177 }, /* R390 - FLL1 Control 5 */ + { 0x0187, 0x0001 }, /* R391 - FLL1 Control 6 */ + { 0x0188, 0x0000 }, /* R392 - FLL1 EFS 1 */ + { 0x01A2, 0x0000 }, /* R418 - FLL2 Control 1 */ + { 0x01A3, 0x0000 }, /* R419 - FLL2 Control 2 */ + { 0x01A4, 0x0000 }, /* R420 - FLL2 Control 3 */ + { 0x01A6, 0x0177 }, /* R422 - FLL2 Control 5 */ + { 0x01A7, 0x0001 }, /* R423 - FLL2 Control 6 */ + { 0x01A8, 0x0000 }, /* R424 - FLL2 EFS 1 */ + { 0x0200, 0x0020 }, /* R512 - Mic Charge Pump 1 */ + { 0x0201, 0xB084 }, /* R513 - Mic Charge Pump 2 */ + { 0x0202, 0xBBDE }, /* R514 - HP Charge Pump 1 */ + { 0x0211, 0x20D4 }, /* R529 - LDO1 Control */ + { 0x0215, 0x0062 }, /* R533 - Mic Bias Ctrl 1 */ + { 0x0216, 0x0062 }, /* R534 - Mic Bias Ctrl 2 */ + { 0x0217, 0x0062 }, /* R535 - Mic Bias Ctrl 3 */ + { 0x0280, 0x0004 }, /* R640 - Accessory Detect Mode 1 */ + { 0x0288, 0x0020 }, /* R648 - Headphone Detect 1 */ + { 0x0289, 0x0000 }, /* R649 - Headphone Detect 2 */ + { 0x0290, 0x1100 }, /* R656 - Mic Detect 1 */ + { 0x0291, 0x009F }, /* R657 - Mic Detect 2 */ + { 0x0292, 0x0000 }, /* R658 - Mic Detect 3 */ + { 0x0301, 0x0000 }, /* R769 - Input Enables */ + { 0x0302, 0x0000 }, /* R770 - Input Enables Status */ + { 0x0310, 0x2280 }, /* R784 - Status */ + { 0x0311, 0x0080 }, /* R785 - IN1R Control */ + { 0x0312, 0x2280 }, /* R786 - IN2L Control */ + { 0x0313, 0x0080 }, /* R787 - IN2R Control */ + { 0x0314, 0x2280 }, /* R788 - IN3L Control */ + { 0x0315, 0x0080 }, /* R789 - IN3R Control */ + { 0x0316, 0x2280 }, /* R790 - IN4L Control */ + { 0x0317, 0x0080 }, /* R791 - IN4R Control */ + { 0x0318, 0x0000 }, /* R792 - RXANC_SRC */ + { 0x0319, 0x0022 }, /* R793 - Input Volume Ramp */ + { 0x0320, 0x0180 }, /* R800 - ADC Digital Volume 1L */ + { 0x0321, 0x0180 }, /* R801 - ADC Digital Volume 1R */ + { 0x0322, 0x0180 }, /* R802 - ADC Digital Volume 2L */ + { 0x0323, 0x0180 }, /* R803 - ADC Digital Volume 2R */ + { 0x0324, 0x0180 }, /* R804 - ADC Digital Volume 3L */ + { 0x0325, 0x0180 }, /* R805 - ADC Digital Volume 3R */ + { 0x0326, 0x0180 }, /* R806 - ADC Digital Volume 4L */ + { 0x0327, 0x0180 }, /* R807 - ADC Digital Volume 4R */ + { 0x0401, 0x0000 }, /* R1025 - Output Enables 2 */ + { 0x0402, 0x0000 }, /* R1026 - Output Status 1 */ + { 0x0403, 0x0000 }, /* R1027 - Output Status 2 */ + { 0x0408, 0x0000 }, /* R1032 - Channel Enables 1 */ + { 0x0410, 0x0080 }, /* R1040 - Out Volume 1L */ + { 0x0411, 0x0080 }, /* R1041 - Out Volume 1R */ + { 0x0412, 0x0080 }, /* R1042 - DAC Volume Limit 1L */ + { 0x0413, 0x0080 }, /* R1043 - DAC Volume Limit 1R */ + { 0x0414, 0x0080 }, /* R1044 - Out Volume 2L */ + { 0x0415, 0x0080 }, /* R1045 - Out Volume 2R */ + { 0x0416, 0x0080 }, /* R1046 - DAC Volume Limit 2L */ + { 0x0417, 0x0080 }, /* R1047 - DAC Volume Limit 2R */ + { 0x0418, 0x0080 }, /* R1048 - Out Volume 3L */ + { 0x0419, 0x0080 }, /* R1049 - Out Volume 3R */ + { 0x041A, 0x0080 }, /* R1050 - DAC Volume Limit 3L */ + { 0x041B, 0x0080 }, /* R1051 - DAC Volume Limit 3R */ + { 0x041C, 0x0080 }, /* R1052 - Out Volume 4L */ + { 0x041D, 0x0080 }, /* R1053 - Out Volume 4R */ + { 0x041E, 0x0080 }, /* R1054 - DAC Volume Limit 5L */ + { 0x041F, 0x0080 }, /* R1055 - DAC Volume Limit 5R */ + { 0x0420, 0x0080 }, /* R1056 - DAC Volume Limit 6L */ + { 0x0421, 0x0080 }, /* R1057 - DAC Volume Limit 6R */ + { 0x0440, 0x0000 }, /* R1088 - DAC AEC Control 1 */ + { 0x0441, 0x0022 }, /* R1089 - Output Volume Ramp */ + { 0x0480, 0x0180 }, /* R1152 - DAC Digital Volume 1L */ + { 0x0481, 0x0180 }, /* R1153 - DAC Digital Volume 1R */ + { 0x0482, 0x0180 }, /* R1154 - DAC Digital Volume 2L */ + { 0x0483, 0x0180 }, /* R1155 - DAC Digital Volume 2R */ + { 0x0484, 0x0180 }, /* R1156 - DAC Digital Volume 3L */ + { 0x0485, 0x0180 }, /* R1157 - DAC Digital Volume 3R */ + { 0x0486, 0x0180 }, /* R1158 - DAC Digital Volume 4L */ + { 0x0487, 0x0180 }, /* R1159 - DAC Digital Volume 4R */ + { 0x0488, 0x0180 }, /* R1160 - DAC Digital Volume 5L */ + { 0x0489, 0x0180 }, /* R1161 - DAC Digital Volume 5R */ + { 0x048A, 0x0180 }, /* R1162 - DAC Digital Volume 6L */ + { 0x048B, 0x0180 }, /* R1163 - DAC Digital Volume 6R */ + { 0x04C0, 0x0069 }, /* R1216 - PDM SPK1 CTRL 1 */ + { 0x04C1, 0x0000 }, /* R1217 - PDM SPK1 CTRL 2 */ + { 0x04C2, 0x0069 }, /* R1218 - PDM SPK2 CTRL 1 */ + { 0x04C3, 0x0000 }, /* R1219 - PDM SPK2 CTRL 2 */ + { 0x0500, 0x000C }, /* R1280 - Audio IF 1_1 */ + { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */ + { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */ + { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */ + { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */ + { 0x0505, 0x0300 }, /* R1285 - Audio IF 1_6 */ + { 0x0506, 0x0300 }, /* R1286 - Audio IF 1_7 */ + { 0x0507, 0x1820 }, /* R1287 - Audio IF 1_8 */ + { 0x0508, 0x1820 }, /* R1288 - Audio IF 1_9 */ + { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */ + { 0x050A, 0x0001 }, /* R1290 - Audio IF 1_11 */ + { 0x050B, 0x0002 }, /* R1291 - Audio IF 1_12 */ + { 0x050C, 0x0003 }, /* R1292 - Audio IF 1_13 */ + { 0x050D, 0x0004 }, /* R1293 - Audio IF 1_14 */ + { 0x050E, 0x0005 }, /* R1294 - Audio IF 1_15 */ + { 0x050F, 0x0006 }, /* R1295 - Audio IF 1_16 */ + { 0x0510, 0x0007 }, /* R1296 - Audio IF 1_17 */ + { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */ + { 0x0512, 0x0001 }, /* R1298 - Audio IF 1_19 */ + { 0x0513, 0x0002 }, /* R1299 - Audio IF 1_20 */ + { 0x0514, 0x0003 }, /* R1300 - Audio IF 1_21 */ + { 0x0515, 0x0004 }, /* R1301 - Audio IF 1_22 */ + { 0x0516, 0x0005 }, /* R1302 - Audio IF 1_23 */ + { 0x0517, 0x0006 }, /* R1303 - Audio IF 1_24 */ + { 0x0518, 0x0007 }, /* R1304 - Audio IF 1_25 */ + { 0x0519, 0x0000 }, /* R1305 - Audio IF 1_26 */ + { 0x051A, 0x0000 }, /* R1306 - Audio IF 1_27 */ + { 0x0540, 0x000C }, /* R1344 - Audio IF 2_1 */ + { 0x0541, 0x0008 }, /* R1345 - Audio IF 2_2 */ + { 0x0542, 0x0000 }, /* R1346 - Audio IF 2_3 */ + { 0x0543, 0x0000 }, /* R1347 - Audio IF 2_4 */ + { 0x0544, 0x0000 }, /* R1348 - Audio IF 2_5 */ + { 0x0545, 0x0300 }, /* R1349 - Audio IF 2_6 */ + { 0x0546, 0x0300 }, /* R1350 - Audio IF 2_7 */ + { 0x0547, 0x1820 }, /* R1351 - Audio IF 2_8 */ + { 0x0548, 0x1820 }, /* R1352 - Audio IF 2_9 */ + { 0x0549, 0x0000 }, /* R1353 - Audio IF 2_10 */ + { 0x054A, 0x0001 }, /* R1354 - Audio IF 2_11 */ + { 0x0551, 0x0000 }, /* R1361 - Audio IF 2_18 */ + { 0x0552, 0x0001 }, /* R1362 - Audio IF 2_19 */ + { 0x0559, 0x0000 }, /* R1369 - Audio IF 2_26 */ + { 0x055A, 0x0000 }, /* R1370 - Audio IF 2_27 */ + { 0x0580, 0x000C }, /* R1408 - Audio IF 3_1 */ + { 0x0581, 0x0008 }, /* R1409 - Audio IF 3_2 */ + { 0x0582, 0x0000 }, /* R1410 - Audio IF 3_3 */ + { 0x0583, 0x0000 }, /* R1411 - Audio IF 3_4 */ + { 0x0584, 0x0000 }, /* R1412 - Audio IF 3_5 */ + { 0x0585, 0x0300 }, /* R1413 - Audio IF 3_6 */ + { 0x0586, 0x0300 }, /* R1414 - Audio IF 3_7 */ + { 0x0587, 0x1820 }, /* R1415 - Audio IF 3_8 */ + { 0x0588, 0x1820 }, /* R1416 - Audio IF 3_9 */ + { 0x0589, 0x0000 }, /* R1417 - Audio IF 3_10 */ + { 0x058A, 0x0001 }, /* R1418 - Audio IF 3_11 */ + { 0x0591, 0x0000 }, /* R1425 - Audio IF 3_18 */ + { 0x0592, 0x0001 }, /* R1426 - Audio IF 3_19 */ + { 0x0599, 0x0000 }, /* R1433 - Audio IF 3_26 */ + { 0x059A, 0x0000 }, /* R1434 - Audio IF 3_27 */ + { 0x0640, 0x0000 }, /* R1600 - PWM1MIX Input 1 Source */ + { 0x0641, 0x0080 }, /* R1601 - PWM1MIX Input 1 Volume */ + { 0x0642, 0x0000 }, /* R1602 - PWM1MIX Input 2 Source */ + { 0x0643, 0x0080 }, /* R1603 - PWM1MIX Input 2 Volume */ + { 0x0644, 0x0000 }, /* R1604 - PWM1MIX Input 3 Source */ + { 0x0645, 0x0080 }, /* R1605 - PWM1MIX Input 3 Volume */ + { 0x0646, 0x0000 }, /* R1606 - PWM1MIX Input 4 Source */ + { 0x0647, 0x0080 }, /* R1607 - PWM1MIX Input 4 Volume */ + { 0x0648, 0x0000 }, /* R1608 - PWM2MIX Input 1 Source */ + { 0x0649, 0x0080 }, /* R1609 - PWM2MIX Input 1 Volume */ + { 0x064A, 0x0000 }, /* R1610 - PWM2MIX Input 2 Source */ + { 0x064B, 0x0080 }, /* R1611 - PWM2MIX Input 2 Volume */ + { 0x064C, 0x0000 }, /* R1612 - PWM2MIX Input 3 Source */ + { 0x064D, 0x0080 }, /* R1613 - PWM2MIX Input 3 Volume */ + { 0x064E, 0x0000 }, /* R1614 - PWM2MIX Input 4 Source */ + { 0x064F, 0x0080 }, /* R1615 - PWM2MIX Input 4 Volume */ + { 0x0680, 0x0000 }, /* R1664 - OUT1LMIX Input 1 Source */ + { 0x0681, 0x0080 }, /* R1665 - OUT1LMIX Input 1 Volume */ + { 0x0682, 0x0000 }, /* R1666 - OUT1LMIX Input 2 Source */ + { 0x0683, 0x0080 }, /* R1667 - OUT1LMIX Input 2 Volume */ + { 0x0684, 0x0000 }, /* R1668 - OUT1LMIX Input 3 Source */ + { 0x0685, 0x0080 }, /* R1669 - OUT1LMIX Input 3 Volume */ + { 0x0686, 0x0000 }, /* R1670 - OUT1LMIX Input 4 Source */ + { 0x0687, 0x0080 }, /* R1671 - OUT1LMIX Input 4 Volume */ + { 0x0688, 0x0000 }, /* R1672 - OUT1RMIX Input 1 Source */ + { 0x0689, 0x0080 }, /* R1673 - OUT1RMIX Input 1 Volume */ + { 0x068A, 0x0000 }, /* R1674 - OUT1RMIX Input 2 Source */ + { 0x068B, 0x0080 }, /* R1675 - OUT1RMIX Input 2 Volume */ + { 0x068C, 0x0000 }, /* R1676 - OUT1RMIX Input 3 Source */ + { 0x068D, 0x0080 }, /* R1677 - OUT1RMIX Input 3 Volume */ + { 0x068E, 0x0000 }, /* R1678 - OUT1RMIX Input 4 Source */ + { 0x068F, 0x0080 }, /* R1679 - OUT1RMIX Input 4 Volume */ + { 0x0690, 0x0000 }, /* R1680 - OUT2LMIX Input 1 Source */ + { 0x0691, 0x0080 }, /* R1681 - OUT2LMIX Input 1 Volume */ + { 0x0692, 0x0000 }, /* R1682 - OUT2LMIX Input 2 Source */ + { 0x0693, 0x0080 }, /* R1683 - OUT2LMIX Input 2 Volume */ + { 0x0694, 0x0000 }, /* R1684 - OUT2LMIX Input 3 Source */ + { 0x0695, 0x0080 }, /* R1685 - OUT2LMIX Input 3 Volume */ + { 0x0696, 0x0000 }, /* R1686 - OUT2LMIX Input 4 Source */ + { 0x0697, 0x0080 }, /* R1687 - OUT2LMIX Input 4 Volume */ + { 0x0698, 0x0000 }, /* R1688 - OUT2RMIX Input 1 Source */ + { 0x0699, 0x0080 }, /* R1689 - OUT2RMIX Input 1 Volume */ + { 0x069A, 0x0000 }, /* R1690 - OUT2RMIX Input 2 Source */ + { 0x069B, 0x0080 }, /* R1691 - OUT2RMIX Input 2 Volume */ + { 0x069C, 0x0000 }, /* R1692 - OUT2RMIX Input 3 Source */ + { 0x069D, 0x0080 }, /* R1693 - OUT2RMIX Input 3 Volume */ + { 0x069E, 0x0000 }, /* R1694 - OUT2RMIX Input 4 Source */ + { 0x069F, 0x0080 }, /* R1695 - OUT2RMIX Input 4 Volume */ + { 0x06A0, 0x0000 }, /* R1696 - OUT3LMIX Input 1 Source */ + { 0x06A1, 0x0080 }, /* R1697 - OUT3LMIX Input 1 Volume */ + { 0x06A2, 0x0000 }, /* R1698 - OUT3LMIX Input 2 Source */ + { 0x06A3, 0x0080 }, /* R1699 - OUT3LMIX Input 2 Volume */ + { 0x06A4, 0x0000 }, /* R1700 - OUT3LMIX Input 3 Source */ + { 0x06A5, 0x0080 }, /* R1701 - OUT3LMIX Input 3 Volume */ + { 0x06A6, 0x0000 }, /* R1702 - OUT3LMIX Input 4 Source */ + { 0x06A7, 0x0080 }, /* R1703 - OUT3LMIX Input 4 Volume */ + { 0x06A8, 0x0000 }, /* R1704 - OUT3RMIX Input 1 Source */ + { 0x06A9, 0x0080 }, /* R1705 - OUT3RMIX Input 1 Volume */ + { 0x06AA, 0x0000 }, /* R1706 - OUT3RMIX Input 2 Source */ + { 0x06AB, 0x0080 }, /* R1707 - OUT3RMIX Input 2 Volume */ + { 0x06AC, 0x0000 }, /* R1708 - OUT3RMIX Input 3 Source */ + { 0x06AD, 0x0080 }, /* R1709 - OUT3RMIX Input 3 Volume */ + { 0x06AE, 0x0000 }, /* R1710 - OUT3RMIX Input 4 Source */ + { 0x06AF, 0x0080 }, /* R1711 - OUT3RMIX Input 4 Volume */ + { 0x06B0, 0x0000 }, /* R1712 - OUT4LMIX Input 1 Source */ + { 0x06B1, 0x0080 }, /* R1713 - OUT4LMIX Input 1 Volume */ + { 0x06B2, 0x0000 }, /* R1714 - OUT4LMIX Input 2 Source */ + { 0x06B3, 0x0080 }, /* R1715 - OUT4LMIX Input 2 Volume */ + { 0x06B4, 0x0000 }, /* R1716 - OUT4LMIX Input 3 Source */ + { 0x06B5, 0x0080 }, /* R1717 - OUT4LMIX Input 3 Volume */ + { 0x06B6, 0x0000 }, /* R1718 - OUT4LMIX Input 4 Source */ + { 0x06B7, 0x0080 }, /* R1719 - OUT4LMIX Input 4 Volume */ + { 0x06B8, 0x0000 }, /* R1720 - OUT4RMIX Input 1 Source */ + { 0x06B9, 0x0080 }, /* R1721 - OUT4RMIX Input 1 Volume */ + { 0x06BA, 0x0000 }, /* R1722 - OUT4RMIX Input 2 Source */ + { 0x06BB, 0x0080 }, /* R1723 - OUT4RMIX Input 2 Volume */ + { 0x06BC, 0x0000 }, /* R1724 - OUT4RMIX Input 3 Source */ + { 0x06BD, 0x0080 }, /* R1725 - OUT4RMIX Input 3 Volume */ + { 0x06BE, 0x0000 }, /* R1726 - OUT4RMIX Input 4 Source */ + { 0x06BF, 0x0080 }, /* R1727 - OUT4RMIX Input 4 Volume */ + { 0x06C0, 0x0000 }, /* R1728 - OUT5LMIX Input 1 Source */ + { 0x06C1, 0x0080 }, /* R1729 - OUT5LMIX Input 1 Volume */ + { 0x06C2, 0x0000 }, /* R1730 - OUT5LMIX Input 2 Source */ + { 0x06C3, 0x0080 }, /* R1731 - OUT5LMIX Input 2 Volume */ + { 0x06C4, 0x0000 }, /* R1732 - OUT5LMIX Input 3 Source */ + { 0x06C5, 0x0080 }, /* R1733 - OUT5LMIX Input 3 Volume */ + { 0x06C6, 0x0000 }, /* R1734 - OUT5LMIX Input 4 Source */ + { 0x06C7, 0x0080 }, /* R1735 - OUT5LMIX Input 4 Volume */ + { 0x06C8, 0x0000 }, /* R1736 - OUT5RMIX Input 1 Source */ + { 0x06C9, 0x0080 }, /* R1737 - OUT5RMIX Input 1 Volume */ + { 0x06CA, 0x0000 }, /* R1738 - OUT5RMIX Input 2 Source */ + { 0x06CB, 0x0080 }, /* R1739 - OUT5RMIX Input 2 Volume */ + { 0x06CC, 0x0000 }, /* R1740 - OUT5RMIX Input 3 Source */ + { 0x06CD, 0x0080 }, /* R1741 - OUT5RMIX Input 3 Volume */ + { 0x06CE, 0x0000 }, /* R1742 - OUT5RMIX Input 4 Source */ + { 0x06CF, 0x0080 }, /* R1743 - OUT5RMIX Input 4 Volume */ + { 0x06D0, 0x0000 }, /* R1744 - OUT6LMIX Input 1 Source */ + { 0x06D1, 0x0080 }, /* R1745 - OUT6LMIX Input 1 Volume */ + { 0x06D2, 0x0000 }, /* R1746 - OUT6LMIX Input 2 Source */ + { 0x06D3, 0x0080 }, /* R1747 - OUT6LMIX Input 2 Volume */ + { 0x06D4, 0x0000 }, /* R1748 - OUT6LMIX Input 3 Source */ + { 0x06D5, 0x0080 }, /* R1749 - OUT6LMIX Input 3 Volume */ + { 0x06D6, 0x0000 }, /* R1750 - OUT6LMIX Input 4 Source */ + { 0x06D7, 0x0080 }, /* R1751 - OUT6LMIX Input 4 Volume */ + { 0x06D8, 0x0000 }, /* R1752 - OUT6RMIX Input 1 Source */ + { 0x06D9, 0x0080 }, /* R1753 - OUT6RMIX Input 1 Volume */ + { 0x06DA, 0x0000 }, /* R1754 - OUT6RMIX Input 2 Source */ + { 0x06DB, 0x0080 }, /* R1755 - OUT6RMIX Input 2 Volume */ + { 0x06DC, 0x0000 }, /* R1756 - OUT6RMIX Input 3 Source */ + { 0x06DD, 0x0080 }, /* R1757 - OUT6RMIX Input 3 Volume */ + { 0x06DE, 0x0000 }, /* R1758 - OUT6RMIX Input 4 Source */ + { 0x06DF, 0x0080 }, /* R1759 - OUT6RMIX Input 4 Volume */ + { 0x0700, 0x0000 }, /* R1792 - AIF1TX1MIX Input 1 Source */ + { 0x0701, 0x0080 }, /* R1793 - AIF1TX1MIX Input 1 Volume */ + { 0x0702, 0x0000 }, /* R1794 - AIF1TX1MIX Input 2 Source */ + { 0x0703, 0x0080 }, /* R1795 - AIF1TX1MIX Input 2 Volume */ + { 0x0704, 0x0000 }, /* R1796 - AIF1TX1MIX Input 3 Source */ + { 0x0705, 0x0080 }, /* R1797 - AIF1TX1MIX Input 3 Volume */ + { 0x0706, 0x0000 }, /* R1798 - AIF1TX1MIX Input 4 Source */ + { 0x0707, 0x0080 }, /* R1799 - AIF1TX1MIX Input 4 Volume */ + { 0x0708, 0x0000 }, /* R1800 - AIF1TX2MIX Input 1 Source */ + { 0x0709, 0x0080 }, /* R1801 - AIF1TX2MIX Input 1 Volume */ + { 0x070A, 0x0000 }, /* R1802 - AIF1TX2MIX Input 2 Source */ + { 0x070B, 0x0080 }, /* R1803 - AIF1TX2MIX Input 2 Volume */ + { 0x070C, 0x0000 }, /* R1804 - AIF1TX2MIX Input 3 Source */ + { 0x070D, 0x0080 }, /* R1805 - AIF1TX2MIX Input 3 Volume */ + { 0x070E, 0x0000 }, /* R1806 - AIF1TX2MIX Input 4 Source */ + { 0x070F, 0x0080 }, /* R1807 - AIF1TX2MIX Input 4 Volume */ + { 0x0710, 0x0000 }, /* R1808 - AIF1TX3MIX Input 1 Source */ + { 0x0711, 0x0080 }, /* R1809 - AIF1TX3MIX Input 1 Volume */ + { 0x0712, 0x0000 }, /* R1810 - AIF1TX3MIX Input 2 Source */ + { 0x0713, 0x0080 }, /* R1811 - AIF1TX3MIX Input 2 Volume */ + { 0x0714, 0x0000 }, /* R1812 - AIF1TX3MIX Input 3 Source */ + { 0x0715, 0x0080 }, /* R1813 - AIF1TX3MIX Input 3 Volume */ + { 0x0716, 0x0000 }, /* R1814 - AIF1TX3MIX Input 4 Source */ + { 0x0717, 0x0080 }, /* R1815 - AIF1TX3MIX Input 4 Volume */ + { 0x0718, 0x0000 }, /* R1816 - AIF1TX4MIX Input 1 Source */ + { 0x0719, 0x0080 }, /* R1817 - AIF1TX4MIX Input 1 Volume */ + { 0x071A, 0x0000 }, /* R1818 - AIF1TX4MIX Input 2 Source */ + { 0x071B, 0x0080 }, /* R1819 - AIF1TX4MIX Input 2 Volume */ + { 0x071C, 0x0000 }, /* R1820 - AIF1TX4MIX Input 3 Source */ + { 0x071D, 0x0080 }, /* R1821 - AIF1TX4MIX Input 3 Volume */ + { 0x071E, 0x0000 }, /* R1822 - AIF1TX4MIX Input 4 Source */ + { 0x071F, 0x0080 }, /* R1823 - AIF1TX4MIX Input 4 Volume */ + { 0x0720, 0x0000 }, /* R1824 - AIF1TX5MIX Input 1 Source */ + { 0x0721, 0x0080 }, /* R1825 - AIF1TX5MIX Input 1 Volume */ + { 0x0722, 0x0000 }, /* R1826 - AIF1TX5MIX Input 2 Source */ + { 0x0723, 0x0080 }, /* R1827 - AIF1TX5MIX Input 2 Volume */ + { 0x0724, 0x0000 }, /* R1828 - AIF1TX5MIX Input 3 Source */ + { 0x0725, 0x0080 }, /* R1829 - AIF1TX5MIX Input 3 Volume */ + { 0x0726, 0x0000 }, /* R1830 - AIF1TX5MIX Input 4 Source */ + { 0x0727, 0x0080 }, /* R1831 - AIF1TX5MIX Input 4 Volume */ + { 0x0728, 0x0000 }, /* R1832 - AIF1TX6MIX Input 1 Source */ + { 0x0729, 0x0080 }, /* R1833 - AIF1TX6MIX Input 1 Volume */ + { 0x072A, 0x0000 }, /* R1834 - AIF1TX6MIX Input 2 Source */ + { 0x072B, 0x0080 }, /* R1835 - AIF1TX6MIX Input 2 Volume */ + { 0x072C, 0x0000 }, /* R1836 - AIF1TX6MIX Input 3 Source */ + { 0x072D, 0x0080 }, /* R1837 - AIF1TX6MIX Input 3 Volume */ + { 0x072E, 0x0000 }, /* R1838 - AIF1TX6MIX Input 4 Source */ + { 0x072F, 0x0080 }, /* R1839 - AIF1TX6MIX Input 4 Volume */ + { 0x0730, 0x0000 }, /* R1840 - AIF1TX7MIX Input 1 Source */ + { 0x0731, 0x0080 }, /* R1841 - AIF1TX7MIX Input 1 Volume */ + { 0x0732, 0x0000 }, /* R1842 - AIF1TX7MIX Input 2 Source */ + { 0x0733, 0x0080 }, /* R1843 - AIF1TX7MIX Input 2 Volume */ + { 0x0734, 0x0000 }, /* R1844 - AIF1TX7MIX Input 3 Source */ + { 0x0735, 0x0080 }, /* R1845 - AIF1TX7MIX Input 3 Volume */ + { 0x0736, 0x0000 }, /* R1846 - AIF1TX7MIX Input 4 Source */ + { 0x0737, 0x0080 }, /* R1847 - AIF1TX7MIX Input 4 Volume */ + { 0x0738, 0x0000 }, /* R1848 - AIF1TX8MIX Input 1 Source */ + { 0x0739, 0x0080 }, /* R1849 - AIF1TX8MIX Input 1 Volume */ + { 0x073A, 0x0000 }, /* R1850 - AIF1TX8MIX Input 2 Source */ + { 0x073B, 0x0080 }, /* R1851 - AIF1TX8MIX Input 2 Volume */ + { 0x073C, 0x0000 }, /* R1852 - AIF1TX8MIX Input 3 Source */ + { 0x073D, 0x0080 }, /* R1853 - AIF1TX8MIX Input 3 Volume */ + { 0x073E, 0x0000 }, /* R1854 - AIF1TX8MIX Input 4 Source */ + { 0x073F, 0x0080 }, /* R1855 - AIF1TX8MIX Input 4 Volume */ + { 0x0740, 0x0000 }, /* R1856 - AIF2TX1MIX Input 1 Source */ + { 0x0741, 0x0080 }, /* R1857 - AIF2TX1MIX Input 1 Volume */ + { 0x0742, 0x0000 }, /* R1858 - AIF2TX1MIX Input 2 Source */ + { 0x0743, 0x0080 }, /* R1859 - AIF2TX1MIX Input 2 Volume */ + { 0x0744, 0x0000 }, /* R1860 - AIF2TX1MIX Input 3 Source */ + { 0x0745, 0x0080 }, /* R1861 - AIF2TX1MIX Input 3 Volume */ + { 0x0746, 0x0000 }, /* R1862 - AIF2TX1MIX Input 4 Source */ + { 0x0747, 0x0080 }, /* R1863 - AIF2TX1MIX Input 4 Volume */ + { 0x0748, 0x0000 }, /* R1864 - AIF2TX2MIX Input 1 Source */ + { 0x0749, 0x0080 }, /* R1865 - AIF2TX2MIX Input 1 Volume */ + { 0x074A, 0x0000 }, /* R1866 - AIF2TX2MIX Input 2 Source */ + { 0x074B, 0x0080 }, /* R1867 - AIF2TX2MIX Input 2 Volume */ + { 0x074C, 0x0000 }, /* R1868 - AIF2TX2MIX Input 3 Source */ + { 0x074D, 0x0080 }, /* R1869 - AIF2TX2MIX Input 3 Volume */ + { 0x074E, 0x0000 }, /* R1870 - AIF2TX2MIX Input 4 Source */ + { 0x074F, 0x0080 }, /* R1871 - AIF2TX2MIX Input 4 Volume */ + { 0x0780, 0x0000 }, /* R1920 - AIF3TX1MIX Input 1 Source */ + { 0x0781, 0x0080 }, /* R1921 - AIF3TX1MIX Input 1 Volume */ + { 0x0782, 0x0000 }, /* R1922 - AIF3TX1MIX Input 2 Source */ + { 0x0783, 0x0080 }, /* R1923 - AIF3TX1MIX Input 2 Volume */ + { 0x0784, 0x0000 }, /* R1924 - AIF3TX1MIX Input 3 Source */ + { 0x0785, 0x0080 }, /* R1925 - AIF3TX1MIX Input 3 Volume */ + { 0x0786, 0x0000 }, /* R1926 - AIF3TX1MIX Input 4 Source */ + { 0x0787, 0x0080 }, /* R1927 - AIF3TX1MIX Input 4 Volume */ + { 0x0788, 0x0000 }, /* R1928 - AIF3TX2MIX Input 1 Source */ + { 0x0789, 0x0080 }, /* R1929 - AIF3TX2MIX Input 1 Volume */ + { 0x078A, 0x0000 }, /* R1930 - AIF3TX2MIX Input 2 Source */ + { 0x078B, 0x0080 }, /* R1931 - AIF3TX2MIX Input 2 Volume */ + { 0x078C, 0x0000 }, /* R1932 - AIF3TX2MIX Input 3 Source */ + { 0x078D, 0x0080 }, /* R1933 - AIF3TX2MIX Input 3 Volume */ + { 0x078E, 0x0000 }, /* R1934 - AIF3TX2MIX Input 4 Source */ + { 0x078F, 0x0080 }, /* R1935 - AIF3TX2MIX Input 4 Volume */ + { 0x0880, 0x0000 }, /* R2176 - EQ1MIX Input 1 Source */ + { 0x0881, 0x0080 }, /* R2177 - EQ1MIX Input 1 Volume */ + { 0x0882, 0x0000 }, /* R2178 - EQ1MIX Input 2 Source */ + { 0x0883, 0x0080 }, /* R2179 - EQ1MIX Input 2 Volume */ + { 0x0884, 0x0000 }, /* R2180 - EQ1MIX Input 3 Source */ + { 0x0885, 0x0080 }, /* R2181 - EQ1MIX Input 3 Volume */ + { 0x0886, 0x0000 }, /* R2182 - EQ1MIX Input 4 Source */ + { 0x0887, 0x0080 }, /* R2183 - EQ1MIX Input 4 Volume */ + { 0x0888, 0x0000 }, /* R2184 - EQ2MIX Input 1 Source */ + { 0x0889, 0x0080 }, /* R2185 - EQ2MIX Input 1 Volume */ + { 0x088A, 0x0000 }, /* R2186 - EQ2MIX Input 2 Source */ + { 0x088B, 0x0080 }, /* R2187 - EQ2MIX Input 2 Volume */ + { 0x088C, 0x0000 }, /* R2188 - EQ2MIX Input 3 Source */ + { 0x088D, 0x0080 }, /* R2189 - EQ2MIX Input 3 Volume */ + { 0x088E, 0x0000 }, /* R2190 - EQ2MIX Input 4 Source */ + { 0x088F, 0x0080 }, /* R2191 - EQ2MIX Input 4 Volume */ + { 0x0890, 0x0000 }, /* R2192 - EQ3MIX Input 1 Source */ + { 0x0891, 0x0080 }, /* R2193 - EQ3MIX Input 1 Volume */ + { 0x0892, 0x0000 }, /* R2194 - EQ3MIX Input 2 Source */ + { 0x0893, 0x0080 }, /* R2195 - EQ3MIX Input 2 Volume */ + { 0x0894, 0x0000 }, /* R2196 - EQ3MIX Input 3 Source */ + { 0x0895, 0x0080 }, /* R2197 - EQ3MIX Input 3 Volume */ + { 0x0896, 0x0000 }, /* R2198 - EQ3MIX Input 4 Source */ + { 0x0897, 0x0080 }, /* R2199 - EQ3MIX Input 4 Volume */ + { 0x0898, 0x0000 }, /* R2200 - EQ4MIX Input 1 Source */ + { 0x0899, 0x0080 }, /* R2201 - EQ4MIX Input 1 Volume */ + { 0x089A, 0x0000 }, /* R2202 - EQ4MIX Input 2 Source */ + { 0x089B, 0x0080 }, /* R2203 - EQ4MIX Input 2 Volume */ + { 0x089C, 0x0000 }, /* R2204 - EQ4MIX Input 3 Source */ + { 0x089D, 0x0080 }, /* R2205 - EQ4MIX Input 3 Volume */ + { 0x089E, 0x0000 }, /* R2206 - EQ4MIX Input 4 Source */ + { 0x089F, 0x0080 }, /* R2207 - EQ4MIX Input 4 Volume */ + { 0x08C0, 0x0000 }, /* R2240 - DRC1LMIX Input 1 Source */ + { 0x08C1, 0x0080 }, /* R2241 - DRC1LMIX Input 1 Volume */ + { 0x08C2, 0x0000 }, /* R2242 - DRC1LMIX Input 2 Source */ + { 0x08C3, 0x0080 }, /* R2243 - DRC1LMIX Input 2 Volume */ + { 0x08C4, 0x0000 }, /* R2244 - DRC1LMIX Input 3 Source */ + { 0x08C5, 0x0080 }, /* R2245 - DRC1LMIX Input 3 Volume */ + { 0x08C6, 0x0000 }, /* R2246 - DRC1LMIX Input 4 Source */ + { 0x08C7, 0x0080 }, /* R2247 - DRC1LMIX Input 4 Volume */ + { 0x08C8, 0x0000 }, /* R2248 - DRC1RMIX Input 1 Source */ + { 0x08C9, 0x0080 }, /* R2249 - DRC1RMIX Input 1 Volume */ + { 0x08CA, 0x0000 }, /* R2250 - DRC1RMIX Input 2 Source */ + { 0x08CB, 0x0080 }, /* R2251 - DRC1RMIX Input 2 Volume */ + { 0x08CC, 0x0000 }, /* R2252 - DRC1RMIX Input 3 Source */ + { 0x08CD, 0x0080 }, /* R2253 - DRC1RMIX Input 3 Volume */ + { 0x08CE, 0x0000 }, /* R2254 - DRC1RMIX Input 4 Source */ + { 0x08CF, 0x0080 }, /* R2255 - DRC1RMIX Input 4 Volume */ + { 0x0900, 0x0000 }, /* R2304 - HPLP1MIX Input 1 Source */ + { 0x0901, 0x0080 }, /* R2305 - HPLP1MIX Input 1 Volume */ + { 0x0902, 0x0000 }, /* R2306 - HPLP1MIX Input 2 Source */ + { 0x0903, 0x0080 }, /* R2307 - HPLP1MIX Input 2 Volume */ + { 0x0904, 0x0000 }, /* R2308 - HPLP1MIX Input 3 Source */ + { 0x0905, 0x0080 }, /* R2309 - HPLP1MIX Input 3 Volume */ + { 0x0906, 0x0000 }, /* R2310 - HPLP1MIX Input 4 Source */ + { 0x0907, 0x0080 }, /* R2311 - HPLP1MIX Input 4 Volume */ + { 0x0908, 0x0000 }, /* R2312 - HPLP2MIX Input 1 Source */ + { 0x0909, 0x0080 }, /* R2313 - HPLP2MIX Input 1 Volume */ + { 0x090A, 0x0000 }, /* R2314 - HPLP2MIX Input 2 Source */ + { 0x090B, 0x0080 }, /* R2315 - HPLP2MIX Input 2 Volume */ + { 0x090C, 0x0000 }, /* R2316 - HPLP2MIX Input 3 Source */ + { 0x090D, 0x0080 }, /* R2317 - HPLP2MIX Input 3 Volume */ + { 0x090E, 0x0000 }, /* R2318 - HPLP2MIX Input 4 Source */ + { 0x090F, 0x0080 }, /* R2319 - HPLP2MIX Input 4 Volume */ + { 0x0910, 0x0000 }, /* R2320 - HPLP3MIX Input 1 Source */ + { 0x0911, 0x0080 }, /* R2321 - HPLP3MIX Input 1 Volume */ + { 0x0912, 0x0000 }, /* R2322 - HPLP3MIX Input 2 Source */ + { 0x0913, 0x0080 }, /* R2323 - HPLP3MIX Input 2 Volume */ + { 0x0914, 0x0000 }, /* R2324 - HPLP3MIX Input 3 Source */ + { 0x0915, 0x0080 }, /* R2325 - HPLP3MIX Input 3 Volume */ + { 0x0916, 0x0000 }, /* R2326 - HPLP3MIX Input 4 Source */ + { 0x0917, 0x0080 }, /* R2327 - HPLP3MIX Input 4 Volume */ + { 0x0918, 0x0000 }, /* R2328 - HPLP4MIX Input 1 Source */ + { 0x0919, 0x0080 }, /* R2329 - HPLP4MIX Input 1 Volume */ + { 0x091A, 0x0000 }, /* R2330 - HPLP4MIX Input 2 Source */ + { 0x091B, 0x0080 }, /* R2331 - HPLP4MIX Input 2 Volume */ + { 0x091C, 0x0000 }, /* R2332 - HPLP4MIX Input 3 Source */ + { 0x091D, 0x0080 }, /* R2333 - HPLP4MIX Input 3 Volume */ + { 0x091E, 0x0000 }, /* R2334 - HPLP4MIX Input 4 Source */ + { 0x091F, 0x0080 }, /* R2335 - HPLP4MIX Input 4 Volume */ + { 0x0940, 0x0000 }, /* R2368 - DSP1LMIX Input 1 Source */ + { 0x0941, 0x0080 }, /* R2369 - DSP1LMIX Input 1 Volume */ + { 0x0942, 0x0000 }, /* R2370 - DSP1LMIX Input 2 Source */ + { 0x0943, 0x0080 }, /* R2371 - DSP1LMIX Input 2 Volume */ + { 0x0944, 0x0000 }, /* R2372 - DSP1LMIX Input 3 Source */ + { 0x0945, 0x0080 }, /* R2373 - DSP1LMIX Input 3 Volume */ + { 0x0946, 0x0000 }, /* R2374 - DSP1LMIX Input 4 Source */ + { 0x0947, 0x0080 }, /* R2375 - DSP1LMIX Input 4 Volume */ + { 0x0948, 0x0000 }, /* R2376 - DSP1RMIX Input 1 Source */ + { 0x0949, 0x0080 }, /* R2377 - DSP1RMIX Input 1 Volume */ + { 0x094A, 0x0000 }, /* R2378 - DSP1RMIX Input 2 Source */ + { 0x094B, 0x0080 }, /* R2379 - DSP1RMIX Input 2 Volume */ + { 0x094C, 0x0000 }, /* R2380 - DSP1RMIX Input 3 Source */ + { 0x094D, 0x0080 }, /* R2381 - DSP1RMIX Input 3 Volume */ + { 0x094E, 0x0000 }, /* R2382 - DSP1RMIX Input 4 Source */ + { 0x094F, 0x0080 }, /* R2383 - DSP1RMIX Input 4 Volume */ + { 0x0950, 0x0000 }, /* R2384 - DSP1AUX1MIX Input 1 Source */ + { 0x0958, 0x0000 }, /* R2392 - DSP1AUX2MIX Input 1 Source */ + { 0x0960, 0x0000 }, /* R2400 - DSP1AUX3MIX Input 1 Source */ + { 0x0968, 0x0000 }, /* R2408 - DSP1AUX4MIX Input 1 Source */ + { 0x0970, 0x0000 }, /* R2416 - DSP1AUX5MIX Input 1 Source */ + { 0x0978, 0x0000 }, /* R2424 - DSP1AUX6MIX Input 1 Source */ + { 0x0980, 0x0000 }, /* R2432 - DSP2LMIX Input 1 Source */ + { 0x0981, 0x0080 }, /* R2433 - DSP2LMIX Input 1 Volume */ + { 0x0982, 0x0000 }, /* R2434 - DSP2LMIX Input 2 Source */ + { 0x0983, 0x0080 }, /* R2435 - DSP2LMIX Input 2 Volume */ + { 0x0984, 0x0000 }, /* R2436 - DSP2LMIX Input 3 Source */ + { 0x0985, 0x0080 }, /* R2437 - DSP2LMIX Input 3 Volume */ + { 0x0986, 0x0000 }, /* R2438 - DSP2LMIX Input 4 Source */ + { 0x0987, 0x0080 }, /* R2439 - DSP2LMIX Input 4 Volume */ + { 0x0988, 0x0000 }, /* R2440 - DSP2RMIX Input 1 Source */ + { 0x0989, 0x0080 }, /* R2441 - DSP2RMIX Input 1 Volume */ + { 0x098A, 0x0000 }, /* R2442 - DSP2RMIX Input 2 Source */ + { 0x098B, 0x0080 }, /* R2443 - DSP2RMIX Input 2 Volume */ + { 0x098C, 0x0000 }, /* R2444 - DSP2RMIX Input 3 Source */ + { 0x098D, 0x0080 }, /* R2445 - DSP2RMIX Input 3 Volume */ + { 0x098E, 0x0000 }, /* R2446 - DSP2RMIX Input 4 Source */ + { 0x098F, 0x0080 }, /* R2447 - DSP2RMIX Input 4 Volume */ + { 0x0990, 0x0000 }, /* R2448 - DSP2AUX1MIX Input 1 Source */ + { 0x0998, 0x0000 }, /* R2456 - DSP2AUX2MIX Input 1 Source */ + { 0x09A0, 0x0000 }, /* R2464 - DSP2AUX3MIX Input 1 Source */ + { 0x09A8, 0x0000 }, /* R2472 - DSP2AUX4MIX Input 1 Source */ + { 0x09B0, 0x0000 }, /* R2480 - DSP2AUX5MIX Input 1 Source */ + { 0x09B8, 0x0000 }, /* R2488 - DSP2AUX6MIX Input 1 Source */ + { 0x09C0, 0x0000 }, /* R2496 - DSP3LMIX Input 1 Source */ + { 0x09C1, 0x0080 }, /* R2497 - DSP3LMIX Input 1 Volume */ + { 0x09C2, 0x0000 }, /* R2498 - DSP3LMIX Input 2 Source */ + { 0x09C3, 0x0080 }, /* R2499 - DSP3LMIX Input 2 Volume */ + { 0x09C4, 0x0000 }, /* R2500 - DSP3LMIX Input 3 Source */ + { 0x09C5, 0x0080 }, /* R2501 - DSP3LMIX Input 3 Volume */ + { 0x09C6, 0x0000 }, /* R2502 - DSP3LMIX Input 4 Source */ + { 0x09C7, 0x0080 }, /* R2503 - DSP3LMIX Input 4 Volume */ + { 0x09C8, 0x0000 }, /* R2504 - DSP3RMIX Input 1 Source */ + { 0x09C9, 0x0080 }, /* R2505 - DSP3RMIX Input 1 Volume */ + { 0x09CA, 0x0000 }, /* R2506 - DSP3RMIX Input 2 Source */ + { 0x09CB, 0x0080 }, /* R2507 - DSP3RMIX Input 2 Volume */ + { 0x09CC, 0x0000 }, /* R2508 - DSP3RMIX Input 3 Source */ + { 0x09CD, 0x0080 }, /* R2509 - DSP3RMIX Input 3 Volume */ + { 0x09CE, 0x0000 }, /* R2510 - DSP3RMIX Input 4 Source */ + { 0x09CF, 0x0080 }, /* R2511 - DSP3RMIX Input 4 Volume */ + { 0x09D0, 0x0000 }, /* R2512 - DSP3AUX1MIX Input 1 Source */ + { 0x09D8, 0x0000 }, /* R2520 - DSP3AUX2MIX Input 1 Source */ + { 0x09E0, 0x0000 }, /* R2528 - DSP3AUX3MIX Input 1 Source */ + { 0x09E8, 0x0000 }, /* R2536 - DSP3AUX4MIX Input 1 Source */ + { 0x09F0, 0x0000 }, /* R2544 - DSP3AUX5MIX Input 1 Source */ + { 0x09F8, 0x0000 }, /* R2552 - DSP3AUX6MIX Input 1 Source */ + { 0x0A80, 0x0000 }, /* R2688 - ASRC1LMIX Input 1 Source */ + { 0x0A88, 0x0000 }, /* R2696 - ASRC1RMIX Input 1 Source */ + { 0x0A90, 0x0000 }, /* R2704 - ASRC2LMIX Input 1 Source */ + { 0x0A98, 0x0000 }, /* R2712 - ASRC2RMIX Input 1 Source */ + { 0x0B00, 0x0000 }, /* R2816 - ISRC1DEC1MIX Input 1 Source */ + { 0x0B08, 0x0000 }, /* R2824 - ISRC1DEC2MIX Input 1 Source */ + { 0x0B10, 0x0000 }, /* R2832 - ISRC1DEC3MIX Input 1 Source */ + { 0x0B18, 0x0000 }, /* R2840 - ISRC1DEC4MIX Input 1 Source */ + { 0x0B20, 0x0000 }, /* R2848 - ISRC1INT1MIX Input 1 Source */ + { 0x0B28, 0x0000 }, /* R2856 - ISRC1INT2MIX Input 1 Source */ + { 0x0B30, 0x0000 }, /* R2864 - ISRC1INT3MIX Input 1 Source */ + { 0x0B38, 0x0000 }, /* R2872 - ISRC1INT4MIX Input 1 Source */ + { 0x0B40, 0x0000 }, /* R2880 - ISRC2DEC1MIX Input 1 Source */ + { 0x0B48, 0x0000 }, /* R2888 - ISRC2DEC2MIX Input 1 Source */ + { 0x0B50, 0x0000 }, /* R2896 - ISRC2DEC3MIX Input 1 Source */ + { 0x0B58, 0x0000 }, /* R2904 - ISRC2DEC4MIX Input 1 Source */ + { 0x0B60, 0x0000 }, /* R2912 - ISRC2INT1MIX Input 1 Source */ + { 0x0B68, 0x0000 }, /* R2920 - ISRC2INT2MIX Input 1 Source */ + { 0x0B70, 0x0000 }, /* R2928 - ISRC2INT3MIX Input 1 Source */ + { 0x0B78, 0x0000 }, /* R2936 - ISRC2INT4MIX Input 1 Source */ + { 0x0C00, 0xA001 }, /* R3072 - GPIO CTRL 1 */ + { 0x0C01, 0xA001 }, /* R3073 - GPIO CTRL 2 */ + { 0x0C02, 0xA001 }, /* R3074 - GPIO CTRL 3 */ + { 0x0C03, 0xA001 }, /* R3075 - GPIO CTRL 4 */ + { 0x0C04, 0xA001 }, /* R3076 - GPIO CTRL 5 */ + { 0x0C05, 0xA001 }, /* R3077 - GPIO CTRL 6 */ + { 0x0C23, 0x4003 }, /* R3107 - Misc Pad Ctrl 1 */ + { 0x0C24, 0x0000 }, /* R3108 - Misc Pad Ctrl 2 */ + { 0x0C25, 0x0000 }, /* R3109 - Misc Pad Ctrl 3 */ + { 0x0C26, 0x0000 }, /* R3110 - Misc Pad Ctrl 4 */ + { 0x0C27, 0x0000 }, /* R3111 - Misc Pad Ctrl 5 */ + { 0x0C28, 0x0000 }, /* R3112 - Misc GPIO 1 */ + { 0x0D00, 0x0000 }, /* R3328 - Interrupt Status 1 */ + { 0x0D01, 0x0000 }, /* R3329 - Interrupt Status 2 */ + { 0x0D02, 0x0000 }, /* R3330 - Interrupt Status 3 */ + { 0x0D03, 0x0000 }, /* R3331 - Interrupt Status 4 */ + { 0x0D04, 0x0000 }, /* R3332 - Interrupt Raw Status 2 */ + { 0x0D05, 0x0000 }, /* R3333 - Interrupt Raw Status 3 */ + { 0x0D06, 0x0000 }, /* R3334 - Interrupt Raw Status 4 */ + { 0x0D07, 0xFFFF }, /* R3335 - Interrupt Status 1 Mask */ + { 0x0D08, 0xFFFF }, /* R3336 - Interrupt Status 2 Mask */ + { 0x0D09, 0xFFFF }, /* R3337 - Interrupt Status 3 Mask */ + { 0x0D0A, 0xFFFF }, /* R3338 - Interrupt Status 4 Mask */ + { 0x0D1F, 0x0000 }, /* R3359 - Interrupt Control */ + { 0x0D20, 0xFFFF }, /* R3360 - IRQ Debounce 1 */ + { 0x0D21, 0xFFFF }, /* R3361 - IRQ Debounce 2 */ + { 0x0E00, 0x0000 }, /* R3584 - FX_Ctrl */ + { 0x0E10, 0x6318 }, /* R3600 - EQ1_1 */ + { 0x0E11, 0x6300 }, /* R3601 - EQ1_2 */ + { 0x0E12, 0x0FC8 }, /* R3602 - EQ1_3 */ + { 0x0E13, 0x03FE }, /* R3603 - EQ1_4 */ + { 0x0E14, 0x00E0 }, /* R3604 - EQ1_5 */ + { 0x0E15, 0x1EC4 }, /* R3605 - EQ1_6 */ + { 0x0E16, 0xF136 }, /* R3606 - EQ1_7 */ + { 0x0E17, 0x0409 }, /* R3607 - EQ1_8 */ + { 0x0E18, 0x04CC }, /* R3608 - EQ1_9 */ + { 0x0E19, 0x1C9B }, /* R3609 - EQ1_10 */ + { 0x0E1A, 0xF337 }, /* R3610 - EQ1_11 */ + { 0x0E1B, 0x040B }, /* R3611 - EQ1_12 */ + { 0x0E1C, 0x0CBB }, /* R3612 - EQ1_13 */ + { 0x0E1D, 0x16F8 }, /* R3613 - EQ1_14 */ + { 0x0E1E, 0xF7D9 }, /* R3614 - EQ1_15 */ + { 0x0E1F, 0x040A }, /* R3615 - EQ1_16 */ + { 0x0E20, 0x1F14 }, /* R3616 - EQ1_17 */ + { 0x0E21, 0x058C }, /* R3617 - EQ1_18 */ + { 0x0E22, 0x0563 }, /* R3618 - EQ1_19 */ + { 0x0E23, 0x4000 }, /* R3619 - EQ1_20 */ + { 0x0E26, 0x6318 }, /* R3622 - EQ2_1 */ + { 0x0E27, 0x6300 }, /* R3623 - EQ2_2 */ + { 0x0E28, 0x0FC8 }, /* R3624 - EQ2_3 */ + { 0x0E29, 0x03FE }, /* R3625 - EQ2_4 */ + { 0x0E2A, 0x00E0 }, /* R3626 - EQ2_5 */ + { 0x0E2B, 0x1EC4 }, /* R3627 - EQ2_6 */ + { 0x0E2C, 0xF136 }, /* R3628 - EQ2_7 */ + { 0x0E2D, 0x0409 }, /* R3629 - EQ2_8 */ + { 0x0E2E, 0x04CC }, /* R3630 - EQ2_9 */ + { 0x0E2F, 0x1C9B }, /* R3631 - EQ2_10 */ + { 0x0E30, 0xF337 }, /* R3632 - EQ2_11 */ + { 0x0E31, 0x040B }, /* R3633 - EQ2_12 */ + { 0x0E32, 0x0CBB }, /* R3634 - EQ2_13 */ + { 0x0E33, 0x16F8 }, /* R3635 - EQ2_14 */ + { 0x0E34, 0xF7D9 }, /* R3636 - EQ2_15 */ + { 0x0E35, 0x040A }, /* R3637 - EQ2_16 */ + { 0x0E36, 0x1F14 }, /* R3638 - EQ2_17 */ + { 0x0E37, 0x058C }, /* R3639 - EQ2_18 */ + { 0x0E38, 0x0563 }, /* R3640 - EQ2_19 */ + { 0x0E39, 0x4000 }, /* R3641 - EQ2_20 */ + { 0x0E3C, 0x6318 }, /* R3644 - EQ3_1 */ + { 0x0E3D, 0x6300 }, /* R3645 - EQ3_2 */ + { 0x0E3E, 0x0FC8 }, /* R3646 - EQ3_3 */ + { 0x0E3F, 0x03FE }, /* R3647 - EQ3_4 */ + { 0x0E40, 0x00E0 }, /* R3648 - EQ3_5 */ + { 0x0E41, 0x1EC4 }, /* R3649 - EQ3_6 */ + { 0x0E42, 0xF136 }, /* R3650 - EQ3_7 */ + { 0x0E43, 0x0409 }, /* R3651 - EQ3_8 */ + { 0x0E44, 0x04CC }, /* R3652 - EQ3_9 */ + { 0x0E45, 0x1C9B }, /* R3653 - EQ3_10 */ + { 0x0E46, 0xF337 }, /* R3654 - EQ3_11 */ + { 0x0E47, 0x040B }, /* R3655 - EQ3_12 */ + { 0x0E48, 0x0CBB }, /* R3656 - EQ3_13 */ + { 0x0E49, 0x16F8 }, /* R3657 - EQ3_14 */ + { 0x0E4A, 0xF7D9 }, /* R3658 - EQ3_15 */ + { 0x0E4B, 0x040A }, /* R3659 - EQ3_16 */ + { 0x0E4C, 0x1F14 }, /* R3660 - EQ3_17 */ + { 0x0E4D, 0x058C }, /* R3661 - EQ3_18 */ + { 0x0E4E, 0x0563 }, /* R3662 - EQ3_19 */ + { 0x0E4F, 0x4000 }, /* R3663 - EQ3_20 */ + { 0x0E52, 0x6318 }, /* R3666 - EQ4_1 */ + { 0x0E53, 0x6300 }, /* R3667 - EQ4_2 */ + { 0x0E54, 0x0FC8 }, /* R3668 - EQ4_3 */ + { 0x0E55, 0x03FE }, /* R3669 - EQ4_4 */ + { 0x0E56, 0x00E0 }, /* R3670 - EQ4_5 */ + { 0x0E57, 0x1EC4 }, /* R3671 - EQ4_6 */ + { 0x0E58, 0xF136 }, /* R3672 - EQ4_7 */ + { 0x0E59, 0x0409 }, /* R3673 - EQ4_8 */ + { 0x0E5A, 0x04CC }, /* R3674 - EQ4_9 */ + { 0x0E5B, 0x1C9B }, /* R3675 - EQ4_10 */ + { 0x0E5C, 0xF337 }, /* R3676 - EQ4_11 */ + { 0x0E5D, 0x040B }, /* R3677 - EQ4_12 */ + { 0x0E5E, 0x0CBB }, /* R3678 - EQ4_13 */ + { 0x0E5F, 0x16F8 }, /* R3679 - EQ4_14 */ + { 0x0E60, 0xF7D9 }, /* R3680 - EQ4_15 */ + { 0x0E61, 0x040A }, /* R3681 - EQ4_16 */ + { 0x0E62, 0x1F14 }, /* R3682 - EQ4_17 */ + { 0x0E63, 0x058C }, /* R3683 - EQ4_18 */ + { 0x0E64, 0x0563 }, /* R3684 - EQ4_19 */ + { 0x0E65, 0x4000 }, /* R3685 - EQ4_20 */ + { 0x0E80, 0x0018 }, /* R3712 - DRC1 ctrl1 */ + { 0x0E81, 0x0933 }, /* R3713 - DRC1 ctrl2 */ + { 0x0E82, 0x0018 }, /* R3714 - DRC1 ctrl3 */ + { 0x0E83, 0x0000 }, /* R3715 - DRC1 ctrl4 */ + { 0x0E84, 0x0000 }, /* R3716 - DRC1 ctrl5 */ + { 0x0EC0, 0x0000 }, /* R3776 - HPLPF1_1 */ + { 0x0EC1, 0x0000 }, /* R3777 - HPLPF1_2 */ + { 0x0EC4, 0x0000 }, /* R3780 - HPLPF2_1 */ + { 0x0EC5, 0x0000 }, /* R3781 - HPLPF2_2 */ + { 0x0EC8, 0x0000 }, /* R3784 - HPLPF3_1 */ + { 0x0EC9, 0x0000 }, /* R3785 - HPLPF3_2 */ + { 0x0ECC, 0x0000 }, /* R3788 - HPLPF4_1 */ + { 0x0ECD, 0x0000 }, /* R3789 - HPLPF4_2 */ }; diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 42d9039a49e..8b24323d6b2 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -18,7 +18,6 @@ #include <linux/gcd.h> #include <linux/gpio.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/regulator/fixed.h> #include <linux/slab.h> @@ -51,6 +50,7 @@ struct wm5100_fll { /* codec private data */ struct wm5100_priv { + struct regmap *regmap; struct snd_soc_codec *codec; struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; @@ -204,17 +204,15 @@ static void wm5100_free_sr(struct snd_soc_codec *codec, int rate) } } -static int wm5100_reset(struct snd_soc_codec *codec) +static int wm5100_reset(struct wm5100_priv *wm5100) { - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); - if (wm5100->pdata.reset) { gpio_set_value_cansleep(wm5100->pdata.reset, 0); gpio_set_value_cansleep(wm5100->pdata.reset, 1); return 0; } else { - return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0); + return regmap_write(wm5100->regmap, WM5100_SOFTWARE_RESET, 0); } } @@ -954,7 +952,7 @@ SND_SOC_DAPM_INPUT("IN3L"), SND_SOC_DAPM_INPUT("IN3R"), SND_SOC_DAPM_INPUT("IN4L"), SND_SOC_DAPM_INPUT("IN4R"), -SND_SOC_DAPM_INPUT("TONE"), +SND_SOC_DAPM_SIGGEN("TONE"), SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0, NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), @@ -1375,7 +1373,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, msleep(2); } - codec->cache_only = false; + regcache_cache_only(wm5100->regmap, false); switch (wm5100->rev) { case 0: @@ -1399,7 +1397,7 @@ static int wm5100_set_bias_level(struct snd_soc_codec *codec, break; } - snd_soc_cache_sync(codec); + regcache_sync(wm5100->regmap); } break; @@ -1662,7 +1660,7 @@ static int wm5100_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops wm5100_dai_ops = { +static const struct snd_soc_dai_ops wm5100_dai_ops = { .set_fmt = wm5100_set_fmt, .hw_params = wm5100_hw_params, }; @@ -1993,6 +1991,9 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, else timeout = 50; + snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA, + WM5100_SYSCLK_ENA); + /* Poll for the lock; will use interrupt when we can test */ for (i = 0; i < timeout; i++) { if (i2c->irq) { @@ -2350,24 +2351,22 @@ static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip) static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); - struct snd_soc_codec *codec = wm5100->codec; - snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, - WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT); + regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, + WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT); } static int wm5100_gpio_direction_out(struct gpio_chip *chip, unsigned offset, int value) { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); - struct snd_soc_codec *codec = wm5100->codec; int val, ret; val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); - ret = snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, - WM5100_GP1_FN_MASK | WM5100_GP1_DIR | - WM5100_GP1_LVL, val); + ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, + WM5100_GP1_FN_MASK | WM5100_GP1_DIR | + WM5100_GP1_LVL, val); if (ret < 0) return ret; else @@ -2377,25 +2376,24 @@ static int wm5100_gpio_direction_out(struct gpio_chip *chip, static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); - struct snd_soc_codec *codec = wm5100->codec; + unsigned int reg; int ret; - ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset); + ret = regmap_read(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, ®); if (ret < 0) return ret; - return (ret & WM5100_GP1_LVL) != 0; + return (reg & WM5100_GP1_LVL) != 0; } static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); - struct snd_soc_codec *codec = wm5100->codec; - return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, - WM5100_GP1_FN_MASK | WM5100_GP1_DIR, - (1 << WM5100_GP1_FN_SHIFT) | - (1 << WM5100_GP1_DIR_SHIFT)); + return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, + WM5100_GP1_FN_MASK | WM5100_GP1_DIR, + (1 << WM5100_GP1_FN_SHIFT) | + (1 << WM5100_GP1_DIR_SHIFT)); } static struct gpio_chip wm5100_template_chip = { @@ -2408,14 +2406,14 @@ static struct gpio_chip wm5100_template_chip = { .can_sleep = 1, }; -static void wm5100_init_gpio(struct snd_soc_codec *codec) +static void wm5100_init_gpio(struct i2c_client *i2c) { - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); + struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); int ret; wm5100->gpio_chip = wm5100_template_chip; wm5100->gpio_chip.ngpio = 6; - wm5100->gpio_chip.dev = codec->dev; + wm5100->gpio_chip.dev = &i2c->dev; if (wm5100->pdata.gpio_base) wm5100->gpio_chip.base = wm5100->pdata.gpio_base; @@ -2424,24 +2422,24 @@ static void wm5100_init_gpio(struct snd_soc_codec *codec) ret = gpiochip_add(&wm5100->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); + dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret); } -static void wm5100_free_gpio(struct snd_soc_codec *codec) +static void wm5100_free_gpio(struct i2c_client *i2c) { - struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); + struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); int ret; ret = gpiochip_remove(&wm5100->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); + dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret); } #else -static void wm5100_init_gpio(struct snd_soc_codec *codec) +static void wm5100_init_gpio(struct i2c_client *i2c) { } -static void wm5100_free_gpio(struct snd_soc_codec *codec) +static void wm5100_free_gpio(struct i2c_client *i2c) { } #endif @@ -2453,131 +2451,21 @@ static int wm5100_probe(struct snd_soc_codec *codec) int ret, i, irq_flags; wm5100->codec = codec; + codec->control_data = wm5100->regmap; - ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) - wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; - - ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to request core supplies: %d\n", - ret); - return ret; - } - - wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD"); - if (IS_ERR(wm5100->cpvdd)) { - ret = PTR_ERR(wm5100->cpvdd); - dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); - goto err_core; - } - - wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2"); - if (IS_ERR(wm5100->dbvdd2)) { - ret = PTR_ERR(wm5100->dbvdd2); - dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); - goto err_cpvdd; - } + regcache_cache_only(wm5100->regmap, true); - wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3"); - if (IS_ERR(wm5100->dbvdd3)) { - ret = PTR_ERR(wm5100->dbvdd3); - dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); - goto err_dbvdd2; - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable core supplies: %d\n", - ret); - goto err_dbvdd3; - } - - if (wm5100->pdata.ldo_ena) { - ret = gpio_request_one(wm5100->pdata.ldo_ena, - GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA"); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", - wm5100->pdata.ldo_ena, ret); - goto err_enable; - } - msleep(2); - } - - if (wm5100->pdata.reset) { - ret = gpio_request_one(wm5100->pdata.reset, - GPIOF_OUT_INIT_HIGH, "WM5100 /RESET"); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", - wm5100->pdata.reset, ret); - goto err_ldo; - } - } - - ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET); - if (ret < 0) { - dev_err(codec->dev, "Failed to read ID register\n"); - goto err_reset; - } - switch (ret) { - case 0x8997: - case 0x5100: - break; - - default: - dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret); - ret = -EINVAL; - goto err_reset; - } - - ret = snd_soc_read(codec, WM5100_DEVICE_REVISION); - if (ret < 0) { - dev_err(codec->dev, "Failed to read revision register\n"); - goto err_reset; - } - wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK; - - dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A'); - - ret = wm5100_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_reset; - } - - codec->cache_only = true; - - wm5100_init_gpio(codec); for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, WM5100_OUT_VU); - for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { - snd_soc_update_bits(codec, WM5100_IN1L_CONTROL, - WM5100_IN1_MODE_MASK | - WM5100_IN1_DMIC_SUP_MASK, - (wm5100->pdata.in_mode[i] << - WM5100_IN1_MODE_SHIFT) | - (wm5100->pdata.dmic_sup[i] << - WM5100_IN1_DMIC_SUP_SHIFT)); - } - - for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { - if (!wm5100->pdata.gpio_defaults[i]) - continue; - - snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i, - wm5100->pdata.gpio_defaults[i]); - } - /* Don't debounce interrupts to support use of SYSCLK only */ snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0); snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0); @@ -2662,29 +2550,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) err_gpio: if (i2c->irq) free_irq(i2c->irq, codec); - wm5100_free_gpio(codec); -err_reset: - if (wm5100->pdata.reset) { - gpio_set_value_cansleep(wm5100->pdata.reset, 1); - gpio_free(wm5100->pdata.reset); - } -err_ldo: - if (wm5100->pdata.ldo_ena) { - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); - gpio_free(wm5100->pdata.ldo_ena); - } -err_enable: - regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); -err_dbvdd3: - regulator_put(wm5100->dbvdd3); -err_dbvdd2: - regulator_put(wm5100->dbvdd2); -err_cpvdd: - regulator_put(wm5100->cpvdd); -err_core: - regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); return ret; } @@ -2700,23 +2565,16 @@ static int wm5100_remove(struct snd_soc_codec *codec) } if (i2c->irq) free_irq(i2c->irq, codec); - wm5100_free_gpio(codec); - if (wm5100->pdata.reset) { - gpio_set_value_cansleep(wm5100->pdata.reset, 1); - gpio_free(wm5100->pdata.reset); - } - if (wm5100->pdata.ldo_ena) { - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); - gpio_free(wm5100->pdata.ldo_ena); - } - regulator_put(wm5100->dbvdd3); - regulator_put(wm5100->dbvdd2); - regulator_put(wm5100->cpvdd); - regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), - wm5100->core_supplies); return 0; } +static int wm5100_soc_volatile(struct snd_soc_codec *codec, + unsigned int reg) +{ + return true; +} + + static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .probe = wm5100_probe, .remove = wm5100_remove, @@ -2725,6 +2583,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .set_pll = wm5100_set_fll, .set_bias_level = wm5100_set_bias_level, .idle_bias_off = 1, + .reg_cache_size = WM5100_MAX_REGISTER, + .volatile_register = wm5100_soc_volatile, .seq_notifier = wm5100_seq_notifier, .controls = wm5100_snd_controls, @@ -2733,14 +2593,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), .dapm_routes = wm5100_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), +}; - .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults), - .reg_word_size = sizeof(u16), - .compress_type = SND_SOC_RBTREE_COMPRESSION, - .reg_cache_default = wm5100_reg_defaults, +static const struct regmap_config wm5100_regmap = { + .reg_bits = 16, + .val_bits = 16, - .volatile_register = wm5100_volatile_register, - .readable_register = wm5100_readable_register, + .max_register = WM5100_MAX_REGISTER, + .reg_defaults = wm5100_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm5100_reg_defaults), + .volatile_reg = wm5100_volatile_register, + .readable_reg = wm5100_readable_register, + .cache_type = REGCACHE_RBTREE, }; static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, @@ -2748,12 +2612,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, { struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); struct wm5100_priv *wm5100; + unsigned int reg; int ret, i; - wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL); + wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv), + GFP_KERNEL); if (wm5100 == NULL) return -ENOMEM; + wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); + if (IS_ERR(wm5100->regmap)) { + ret = PTR_ERR(wm5100->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++) init_completion(&wm5100->fll[i].lock); @@ -2762,21 +2636,178 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm5100); + for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) + wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; + + ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request core supplies: %d\n", + ret); + goto err_regmap; + } + + wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD"); + if (IS_ERR(wm5100->cpvdd)) { + ret = PTR_ERR(wm5100->cpvdd); + dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); + goto err_core; + } + + wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2"); + if (IS_ERR(wm5100->dbvdd2)) { + ret = PTR_ERR(wm5100->dbvdd2); + dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); + goto err_cpvdd; + } + + wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3"); + if (IS_ERR(wm5100->dbvdd3)) { + ret = PTR_ERR(wm5100->dbvdd3); + dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); + goto err_dbvdd2; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", + ret); + goto err_dbvdd3; + } + + if (wm5100->pdata.ldo_ena) { + ret = gpio_request_one(wm5100->pdata.ldo_ena, + GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", + wm5100->pdata.ldo_ena, ret); + goto err_enable; + } + msleep(2); + } + + if (wm5100->pdata.reset) { + ret = gpio_request_one(wm5100->pdata.reset, + GPIOF_OUT_INIT_HIGH, "WM5100 /RESET"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", + wm5100->pdata.reset, ret); + goto err_ldo; + } + } + + ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register\n"); + goto err_reset; + } + switch (reg) { + case 0x8997: + case 0x5100: + break; + + default: + dev_err(&i2c->dev, "Device is not a WM5100, ID is %x\n", reg); + ret = -EINVAL; + goto err_reset; + } + + ret = regmap_read(wm5100->regmap, WM5100_DEVICE_REVISION, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read revision register\n"); + goto err_reset; + } + wm5100->rev = reg & WM5100_DEVICE_REVISION_MASK; + + dev_info(&i2c->dev, "revision %c\n", wm5100->rev + 'A'); + + ret = wm5100_reset(wm5100); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset\n"); + goto err_reset; + } + + wm5100_init_gpio(i2c); + + for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { + if (!wm5100->pdata.gpio_defaults[i]) + continue; + + regmap_write(wm5100->regmap, WM5100_GPIO_CTRL_1 + i, + wm5100->pdata.gpio_defaults[i]); + } + + for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { + regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, + WM5100_IN1_MODE_MASK | + WM5100_IN1_DMIC_SUP_MASK, + (wm5100->pdata.in_mode[i] << + WM5100_IN1_MODE_SHIFT) | + (wm5100->pdata.dmic_sup[i] << + WM5100_IN1_DMIC_SUP_SHIFT)); + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm5100, wm5100_dai, ARRAY_SIZE(wm5100_dai)); if (ret < 0) { dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret); - kfree(wm5100); + goto err_reset; } return ret; + +err_reset: + wm5100_free_gpio(i2c); + if (wm5100->pdata.reset) { + gpio_set_value_cansleep(wm5100->pdata.reset, 1); + gpio_free(wm5100->pdata.reset); + } +err_ldo: + if (wm5100->pdata.ldo_ena) { + gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); + gpio_free(wm5100->pdata.ldo_ena); + } +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); +err_dbvdd3: + regulator_put(wm5100->dbvdd3); +err_dbvdd2: + regulator_put(wm5100->dbvdd2); +err_cpvdd: + regulator_put(wm5100->cpvdd); +err_core: + regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); +err_regmap: + regmap_exit(wm5100->regmap); +err: + return ret; } static __devexit int wm5100_i2c_remove(struct i2c_client *client) { + struct wm5100_priv *wm5100 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + wm5100_free_gpio(client); + if (wm5100->pdata.reset) { + gpio_set_value_cansleep(wm5100->pdata.reset, 1); + gpio_free(wm5100->pdata.reset); + } + if (wm5100->pdata.ldo_ena) { + gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); + gpio_free(wm5100->pdata.ldo_ena); + } + regulator_put(wm5100->dbvdd3); + regulator_put(wm5100->dbvdd2); + regulator_put(wm5100->cpvdd); + regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), + wm5100->core_supplies); + regmap_exit(wm5100->regmap); + return 0; } diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h index 970759636bd..25cb6016f9d 100644 --- a/sound/soc/codecs/wm5100.h +++ b/sound/soc/codecs/wm5100.h @@ -15,6 +15,7 @@ #define WM5100_ASOC_H #include <sound/soc.h> +#include <linux/regmap.h> int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); @@ -5147,9 +5148,9 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); #define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */ #define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */ -int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg); -int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg); +bool wm5100_readable_register(struct device *dev, unsigned int reg); +bool wm5100_volatile_register(struct device *dev, unsigned int reg); -extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1]; +extern struct reg_default wm5100_reg_defaults[WM5100_REGISTER_COUNT]; #endif diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 35f3ad83dfb..8c4c9591ec0 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -696,7 +696,7 @@ static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = { SND_SOC_DAPM_INPUT("IN3L"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8350_dapm_routes[] = { /* left playback mixer */ {"Left Playback Mixer", "Playback Switch", "Left DAC"}, @@ -777,29 +777,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Beep", NULL, "IN3R PGA"}, }; -static int wm8350_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - ret = snd_soc_dapm_new_controls(dapm, - wm8350_dapm_widgets, - ARRAY_SIZE(wm8350_dapm_widgets)); - if (ret != 0) { - dev_err(codec->dev, "dapm control register failed\n"); - return ret; - } - - /* set up audio paths */ - ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - if (ret != 0) { - dev_err(codec->dev, "DAPM route register failed\n"); - return ret; - } - - return 0; -} - static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id, unsigned int freq, int dir) { @@ -1315,7 +1292,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8350_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8350_suspend(struct snd_soc_codec *codec) { wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1511,7 +1488,7 @@ EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8350_dai_ops = { +static const struct snd_soc_dai_ops wm8350_dai_ops = { .hw_params = wm8350_pcm_hw_params, .digital_mute = wm8350_mute, .trigger = wm8350_pcm_trigger, @@ -1553,7 +1530,8 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) return -EINVAL; } - priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL); + priv = devm_kzalloc(codec->dev, sizeof(struct wm8350_data), + GFP_KERNEL); if (priv == NULL) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); @@ -1564,7 +1542,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), priv->supplies); if (ret != 0) - goto err_priv; + return ret; wm8350->codec.codec = codec; codec->control_data = wm8350; @@ -1633,17 +1611,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) wm8350_mic_handler, 0, "Microphone detect", priv); - snd_soc_add_controls(codec, wm8350_snd_controls, - ARRAY_SIZE(wm8350_snd_controls)); - wm8350_add_widgets(codec); - wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; - -err_priv: - kfree(priv); - return ret; } static int wm8350_codec_remove(struct snd_soc_codec *codec) @@ -1676,7 +1646,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies); - kfree(priv); + return 0; } @@ -1688,6 +1658,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .read = wm8350_codec_read, .write = wm8350_codec_write, .set_bias_level = wm8350_set_bias_level, + + .controls = wm8350_snd_controls, + .num_controls = ARRAY_SIZE(wm8350_snd_controls), + .dapm_widgets = wm8350_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8350_dapm_widgets), + .dapm_routes = wm8350_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8350_dapm_routes), }; static int __devinit wm8350_probe(struct platform_device *pdev) @@ -1711,17 +1688,7 @@ static struct platform_driver wm8350_codec_driver = { .remove = __devexit_p(wm8350_remove), }; -static __init int wm8350_init(void) -{ - return platform_driver_register(&wm8350_codec_driver); -} -module_init(wm8350_init); - -static __exit void wm8350_exit(void) -{ - platform_driver_unregister(&wm8350_codec_driver); -} -module_exit(wm8350_exit); +module_platform_driver(wm8350_codec_driver); MODULE_DESCRIPTION("ASoC WM8350 driver"); MODULE_AUTHOR("Liam Girdwood"); diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index dc13be2a09c..898979d2301 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -353,13 +353,6 @@ SOC_SINGLE("RIN34 Mute Switch", WM8400_RIGHT_LINE_INPUT_3_4_VOLUME, }; -/* add non dapm controls */ -static int wm8400_add_controls(struct snd_soc_codec *codec) -{ - return snd_soc_add_controls(codec, wm8400_snd_controls, - ARRAY_SIZE(wm8400_snd_controls)); -} - /* * _DAPM_ Controls */ @@ -766,8 +759,8 @@ SND_SOC_DAPM_PGA("ROPGA", WM8400_POWER_MANAGEMENT_3, WM8400_ROPGA_ENA_SHIFT, 0, NULL, 0), /* MICBIAS */ -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8400_POWER_MANAGEMENT_1, - WM8400_MIC1BIAS_ENA_SHIFT, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS", WM8400_POWER_MANAGEMENT_1, + WM8400_MIC1BIAS_ENA_SHIFT, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("LON"), SND_SOC_DAPM_OUTPUT("LOP"), @@ -783,7 +776,7 @@ SND_SOC_DAPM_OUTPUT("RON"), SND_SOC_DAPM_OUTPUT("Internal DAC Sink"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8400_dapm_routes[] = { /* Make DACs turn on when playing even if not mixed into any outputs */ {"Internal DAC Sink", NULL, "Left DAC"}, {"Internal DAC Sink", NULL, "Right DAC"}, @@ -909,17 +902,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"RON", NULL, "RONMIX"}, }; -static int wm8400_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets, - ARRAY_SIZE(wm8400_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* * Clock after FLL and dividers */ @@ -1059,7 +1041,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, wm8400_write(codec, WM8400_FLL_CONTROL_3, factors.n); reg = wm8400_read(codec, WM8400_FLL_CONTROL_4); - reg &= WM8400_FLL_OUTDIV_MASK; + reg &= ~WM8400_FLL_OUTDIV_MASK; reg |= factors.outdiv; wm8400_write(codec, WM8400_FLL_CONTROL_4, reg); @@ -1316,7 +1298,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec, #define WM8400_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8400_dai_ops = { +static const struct snd_soc_dai_ops wm8400_dai_ops = { .hw_params = wm8400_hw_params, .digital_mute = wm8400_mute, .set_fmt = wm8400_set_dai_fmt, @@ -1352,7 +1334,7 @@ static struct snd_soc_dai_driver wm8400_dai = { .ops = &wm8400_dai_ops, }; -static int wm8400_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8400_suspend(struct snd_soc_codec *codec) { wm8400_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1383,7 +1365,8 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) int ret; u16 reg; - priv = kzalloc(sizeof(struct wm8400_priv), GFP_KERNEL); + priv = devm_kzalloc(codec->dev, sizeof(struct wm8400_priv), + GFP_KERNEL); if (priv == NULL) return -ENOMEM; @@ -1395,7 +1378,7 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) ARRAY_SIZE(power), &power[0]); if (ret != 0) { dev_err(codec->dev, "Failed to get regulators: %d\n", ret); - goto err; + return ret; } INIT_WORK(&priv->work, wm8400_probe_deferred); @@ -1420,20 +1403,15 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) ret = -EINVAL; goto err_regulator; } - wm8400_add_controls(codec); - wm8400_add_widgets(codec); return 0; err_regulator: regulator_bulk_free(ARRAY_SIZE(power), power); -err: - kfree(priv); return ret; } static int wm8400_codec_remove(struct snd_soc_codec *codec) { - struct wm8400_priv *priv = snd_soc_codec_get_drvdata(codec); u16 reg; reg = wm8400_read(codec, WM8400_POWER_MANAGEMENT_1); @@ -1441,7 +1419,6 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) reg & (~WM8400_CODEC_ENA)); regulator_bulk_free(ARRAY_SIZE(power), power); - kfree(priv); return 0; } @@ -1454,6 +1431,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { .read = wm8400_read, .write = wm8400_write, .set_bias_level = wm8400_set_bias_level, + + .controls = wm8400_snd_controls, + .num_controls = ARRAY_SIZE(wm8400_snd_controls), + .dapm_widgets = wm8400_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8400_dapm_widgets), + .dapm_routes = wm8400_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8400_dapm_routes), }; static int __devinit wm8400_probe(struct platform_device *pdev) @@ -1477,17 +1461,7 @@ static struct platform_driver wm8400_codec_driver = { .remove = __devexit_p(wm8400_remove), }; -static __init int wm8400_init(void) -{ - return platform_driver_register(&wm8400_codec_driver); -} -module_init(wm8400_init); - -static __exit void wm8400_exit(void) -{ - platform_driver_unregister(&wm8400_codec_driver); -} -module_exit(wm8400_exit); +module_platform_driver(wm8400_codec_driver); MODULE_DESCRIPTION("ASoC WM8400 driver"); MODULE_AUTHOR("Mark Brown"); diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 07c9cc759e9..9166126bd31 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -182,7 +181,7 @@ SND_SOC_DAPM_OUTPUT("SPKOUTP"), SND_SOC_DAPM_OUTPUT("SPKOUTN"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8510_dapm_routes[] = { /* Mono output mixer */ {"Mono Mixer", "PCM Playback Switch", "DAC"}, {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, @@ -214,17 +213,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ADC", NULL, "Boost Mixer"}, }; -static int wm8510_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets, - ARRAY_SIZE(wm8510_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - struct pll_ { unsigned int pre_div:4; /* prescale - 1 */ unsigned int n:4; @@ -509,7 +497,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, #define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8510_dai_ops = { +static const struct snd_soc_dai_ops wm8510_dai_ops = { .hw_params = wm8510_pcm_hw_params, .digital_mute = wm8510_mute, .set_fmt = wm8510_set_dai_fmt, @@ -535,7 +523,7 @@ static struct snd_soc_dai_driver wm8510_dai = { .symmetric_rates = 1, }; -static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8510_suspend(struct snd_soc_codec *codec) { wm8510_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -562,9 +550,6 @@ static int wm8510_probe(struct snd_soc_codec *codec) /* power on device */ wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8510_snd_controls, - ARRAY_SIZE(wm8510_snd_controls)); - wm8510_add_widgets(codec); return ret; } @@ -588,6 +573,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { .reg_cache_size = ARRAY_SIZE(wm8510_reg), .reg_word_size = sizeof(u16), .reg_cache_default =wm8510_reg, + + .controls = wm8510_snd_controls, + .num_controls = ARRAY_SIZE(wm8510_snd_controls), + .dapm_widgets = wm8510_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8510_dapm_widgets), + .dapm_routes = wm8510_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8510_dapm_routes), }; static const struct of_device_id wm8510_of_match[] = { @@ -667,7 +659,7 @@ MODULE_DEVICE_TABLE(i2c, wm8510_i2c_id); static struct i2c_driver wm8510_i2c_driver = { .driver = { - .name = "wm8510-codec", + .name = "wm8510", .owner = THIS_MODULE, .of_match_table = wm8510_of_match, }, diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index db7a6819499..7fea2c3bf7e 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -365,7 +364,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, #define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8523_dai_ops = { +static const struct snd_soc_dai_ops wm8523_dai_ops = { .startup = wm8523_startup, .hw_params = wm8523_hw_params, .set_sysclk = wm8523_set_dai_sysclk, @@ -385,7 +384,7 @@ static struct snd_soc_dai_driver wm8523_dai = { }; #ifdef CONFIG_PM -static int wm8523_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8523_suspend(struct snd_soc_codec *codec) { wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 8212b3c8bfd..211285164d7 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -23,7 +23,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -273,7 +272,7 @@ SND_SOC_DAPM_INPUT("AINL"), SND_SOC_DAPM_INPUT("AINR"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8580_dapm_routes[] = { { "VOUT1L", NULL, "DAC1" }, { "VOUT1R", NULL, "DAC1" }, @@ -287,17 +286,6 @@ static const struct snd_soc_dapm_route audio_map[] = { { "ADC", NULL, "AINR" }, }; -static int wm8580_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets, - ARRAY_SIZE(wm8580_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* PLL divisors */ struct _pll_div { u32 prescale:1; @@ -682,7 +670,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id, { struct snd_soc_codec *codec = dai->codec; struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); - int sel, sel_mask, sel_shift; + int ret, sel, sel_mask, sel_shift; switch (dai->driver->id) { case WM8580_DAI_PAIFRX: @@ -723,7 +711,11 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id, /* We really should validate PLL settings but not yet */ wm8580->sysclk[dai->driver->id] = freq; - return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel); + ret = snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel); + if (ret < 0) + return ret; + + return 0; } static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute) @@ -776,7 +768,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8580_dai_ops_playback = { +static const struct snd_soc_dai_ops wm8580_dai_ops_playback = { .set_sysclk = wm8580_set_sysclk, .hw_params = wm8580_paif_hw_params, .set_fmt = wm8580_set_paif_dai_fmt, @@ -785,7 +777,7 @@ static struct snd_soc_dai_ops wm8580_dai_ops_playback = { .digital_mute = wm8580_digital_mute, }; -static struct snd_soc_dai_ops wm8580_dai_ops_capture = { +static const struct snd_soc_dai_ops wm8580_dai_ops_capture = { .set_sysclk = wm8580_set_sysclk, .hw_params = wm8580_paif_hw_params, .set_fmt = wm8580_set_paif_dai_fmt, @@ -857,10 +849,6 @@ static int wm8580_probe(struct snd_soc_codec *codec) wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8580_snd_controls, - ARRAY_SIZE(wm8580_snd_controls)); - wm8580_add_widgets(codec); - return 0; err_regulator_enable: @@ -890,6 +878,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { .reg_cache_size = ARRAY_SIZE(wm8580_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8580_reg, + + .controls = wm8580_snd_controls, + .num_controls = ARRAY_SIZE(wm8580_snd_controls), + .dapm_widgets = wm8580_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8580_dapm_widgets), + .dapm_routes = wm8580_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8580_dapm_routes), }; static const struct of_device_id wm8580_of_match[] = { diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 076bdb9930a..0b76d1dca5e 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -318,7 +317,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec, #define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8711_ops = { +static const struct snd_soc_dai_ops wm8711_ops = { .prepare = wm8711_pcm_prepare, .hw_params = wm8711_hw_params, .shutdown = wm8711_shutdown, @@ -339,7 +338,7 @@ static struct snd_soc_dai_driver wm8711_dai = { .ops = &wm8711_ops, }; -static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8711_suspend(struct snd_soc_codec *codec) { snd_soc_write(codec, WM8711_ACTIVE, 0x0); wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -375,9 +374,6 @@ static int wm8711_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100); - snd_soc_add_controls(codec, wm8711_snd_controls, - ARRAY_SIZE(wm8711_snd_controls)); - return ret; } @@ -398,6 +394,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { .reg_cache_size = ARRAY_SIZE(wm8711_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8711_reg, + .controls = wm8711_snd_controls, + .num_controls = ARRAY_SIZE(wm8711_snd_controls), .dapm_widgets = wm8711_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8711_dapm_widgets), .dapm_routes = wm8711_intercon, diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c index 74880828511..e8170562071 100644 --- a/sound/soc/codecs/wm8727.c +++ b/sound/soc/codecs/wm8727.c @@ -59,7 +59,7 @@ static int __devexit wm8727_remove(struct platform_device *pdev) static struct platform_driver wm8727_codec_driver = { .driver = { - .name = "wm8727-codec", + .name = "wm8727", .owner = THIS_MODULE, }, @@ -67,17 +67,7 @@ static struct platform_driver wm8727_codec_driver = { .remove = __devexit_p(wm8727_remove), }; -static int __init wm8727_init(void) -{ - return platform_driver_register(&wm8727_codec_driver); -} -module_init(wm8727_init); - -static void __exit wm8727_exit(void) -{ - platform_driver_unregister(&wm8727_codec_driver); -} -module_exit(wm8727_exit); +module_platform_driver(wm8727_codec_driver); MODULE_DESCRIPTION("ASoC wm8727 driver"); MODULE_AUTHOR("Neil Jones"); diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 04b027efd5c..fc3d59e4908 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -196,7 +196,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, #define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8728_dai_ops = { +static const struct snd_soc_dai_ops wm8728_dai_ops = { .hw_params = wm8728_hw_params, .digital_mute = wm8728_mute, .set_fmt = wm8728_set_dai_fmt, @@ -214,7 +214,7 @@ static struct snd_soc_dai_driver wm8728_dai = { .ops = &wm8728_dai_ops, }; -static int wm8728_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8728_suspend(struct snd_soc_codec *codec) { wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -243,9 +243,6 @@ static int wm8728_probe(struct snd_soc_codec *codec) /* power on device */ wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8728_snd_controls, - ARRAY_SIZE(wm8728_snd_controls)); - return ret; } @@ -264,6 +261,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { .reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults), .reg_word_size = sizeof(u16), .reg_cache_default = wm8728_reg_defaults, + .controls = wm8728_snd_controls, + .num_controls = ARRAY_SIZE(wm8728_snd_controls), .dapm_widgets = wm8728_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8728_dapm_widgets), .dapm_routes = wm8728_intercon, diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 7e5ec03f6f8..8821af70e66 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -19,7 +19,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/slab.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> #include <linux/of_device.h> @@ -453,6 +452,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8731_PWR, 0xffff); regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); + codec->cache_sync = 1; break; } codec->dapm.bias_level = level; @@ -464,7 +464,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8731_dai_ops = { +static const struct snd_soc_dai_ops wm8731_dai_ops = { .hw_params = wm8731_hw_params, .digital_mute = wm8731_mute, .set_sysclk = wm8731_set_dai_sysclk, @@ -490,7 +490,7 @@ static struct snd_soc_dai_driver wm8731_dai = { }; #ifdef CONFIG_PM -static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8731_suspend(struct snd_soc_codec *codec) { wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -553,9 +553,6 @@ static int wm8731_probe(struct snd_soc_codec *codec) /* Disable bypass path by default */ snd_soc_update_bits(codec, WM8731_APANA, 0x8, 0); - snd_soc_add_controls(codec, wm8731_snd_controls, - ARRAY_SIZE(wm8731_snd_controls)); - /* Regulators will have been enabled by bias management */ regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); @@ -595,6 +592,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), .dapm_routes = wm8731_intercon, .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), + .controls = wm8731_snd_controls, + .num_controls = ARRAY_SIZE(wm8731_snd_controls), }; static const struct of_device_id wm8731_of_match[] = { diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index f6aef58845c..ff95e62c56b 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -16,7 +16,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/spi/spi.h> #include <linux/slab.h> @@ -521,7 +520,7 @@ static int wm8737_set_bias_level(struct snd_soc_codec *codec, #define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8737_dai_ops = { +static const struct snd_soc_dai_ops wm8737_dai_ops = { .hw_params = wm8737_hw_params, .set_sysclk = wm8737_set_dai_sysclk, .set_fmt = wm8737_set_dai_fmt, @@ -540,7 +539,7 @@ static struct snd_soc_dai_driver wm8737_dai = { }; #ifdef CONFIG_PM -static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8737_suspend(struct snd_soc_codec *codec) { wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 57ad22aacc5..3941f50bf18 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -18,7 +18,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/spi/spi.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -86,24 +85,13 @@ SND_SOC_DAPM_OUTPUT("VOUTRP"), SND_SOC_DAPM_OUTPUT("VOUTRN"), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route wm8741_dapm_routes[] = { { "VOUTLP", NULL, "DACL" }, { "VOUTLN", NULL, "DACL" }, { "VOUTRP", NULL, "DACR" }, { "VOUTRN", NULL, "DACR" }, }; -static int wm8741_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets, - ARRAY_SIZE(wm8741_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); - - return 0; -} - static struct { int value; int ratio; @@ -382,7 +370,7 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, #define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8741_dai_ops = { +static const struct snd_soc_dai_ops wm8741_dai_ops = { .startup = wm8741_startup, .hw_params = wm8741_hw_params, .set_sysclk = wm8741_set_dai_sysclk, @@ -457,10 +445,6 @@ static int wm8741_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION, WM8741_UPDATERM, WM8741_UPDATERM); - snd_soc_add_controls(codec, wm8741_snd_controls, - ARRAY_SIZE(wm8741_snd_controls)); - wm8741_add_widgets(codec); - dev_dbg(codec->dev, "Successful registration\n"); return ret; @@ -489,6 +473,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), .reg_word_size = sizeof(u16), .reg_cache_default = wm8741_reg_defaults, + + .controls = wm8741_snd_controls, + .num_controls = ARRAY_SIZE(wm8741_snd_controls), + .dapm_widgets = wm8741_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8741_dapm_widgets), + .dapm_routes = wm8741_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8741_dapm_routes), }; static const struct of_device_id wm8741_of_match[] = { @@ -504,7 +495,8 @@ static int wm8741_i2c_probe(struct i2c_client *i2c, struct wm8741_priv *wm8741; int ret; - wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); + wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv), + GFP_KERNEL); if (wm8741 == NULL) return -ENOMEM; @@ -513,20 +505,13 @@ static int wm8741_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8741, &wm8741_dai, 1); - if (ret != 0) - goto err; return ret; - -err: - kfree(wm8741); - return ret; } static int wm8741_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } @@ -554,7 +539,8 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) struct wm8741_priv *wm8741; int ret; - wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); + wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv), + GFP_KERNEL); if (wm8741 == NULL) return -ENOMEM; @@ -563,15 +549,12 @@ static int __devinit wm8741_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8741, &wm8741_dai, 1); - if (ret < 0) - kfree(wm8741); return ret; } static int __devexit wm8741_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index ca75a818070..e4c50ce7d9c 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/of_device.h> @@ -302,7 +301,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { SND_SOC_DAPM_INPUT("RINPUT3"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8750_dapm_routes[] = { /* left mixer */ {"Left Mixer", "Playback Switch", "Left DAC"}, {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, @@ -396,17 +395,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Right ADC", NULL, "Right ADC Mux"}, }; -static int wm8750_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - struct _coeff_div { u32 mclk; u32 rate; @@ -643,7 +631,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, #define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8750_dai_ops = { +static const struct snd_soc_dai_ops wm8750_dai_ops = { .hw_params = wm8750_pcm_hw_params, .digital_mute = wm8750_mute, .set_fmt = wm8750_set_dai_fmt, @@ -667,7 +655,7 @@ static struct snd_soc_dai_driver wm8750_dai = { .ops = &wm8750_dai_ops, }; -static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8750_suspend(struct snd_soc_codec *codec) { wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -709,9 +697,6 @@ static int wm8750_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100); - snd_soc_add_controls(codec, wm8750_snd_controls, - ARRAY_SIZE(wm8750_snd_controls)); - wm8750_add_widgets(codec); return ret; } @@ -730,6 +715,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { .reg_cache_size = ARRAY_SIZE(wm8750_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8750_reg, + + .controls = wm8750_snd_controls, + .num_controls = ARRAY_SIZE(wm8750_snd_controls), + .dapm_widgets = wm8750_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), + .dapm_routes = wm8750_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8750_dapm_routes), }; static const struct of_device_id wm8750_of_match[] = { @@ -745,7 +737,8 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) struct wm8750_priv *wm8750; int ret; - wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); + wm8750 = devm_kzalloc(&spi->dev, sizeof(struct wm8750_priv), + GFP_KERNEL); if (wm8750 == NULL) return -ENOMEM; @@ -754,15 +747,12 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8750, &wm8750_dai, 1); - if (ret < 0) - kfree(wm8750); return ret; } static int __devexit wm8750_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -792,7 +782,8 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, struct wm8750_priv *wm8750; int ret; - wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL); + wm8750 = devm_kzalloc(&i2c->dev, sizeof(struct wm8750_priv), + GFP_KERNEL); if (wm8750 == NULL) return -ENOMEM; @@ -801,15 +792,12 @@ static __devinit int wm8750_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8750, &wm8750_dai, 1); - if (ret < 0) - kfree(wm8750); return ret; } static __devexit int wm8750_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index a9504710bb6..b114c19f530 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -39,7 +39,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/of_device.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <sound/core.h> @@ -190,6 +189,9 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); u16 ioctl; + if (wm8753->dai_func == ucontrol->value.integer.value[0]) + return 0; + if (codec->active) return -EBUSY; @@ -483,7 +485,7 @@ SND_SOC_DAPM_INPUT("MIC2"), SND_SOC_DAPM_VMID("VREF"), }; -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8753_dapm_routes[] = { /* left mixer */ {"Left Mixer", "Left Playback Switch", "Left DAC"}, {"Left Mixer", "Voice Playback Switch", "Voice DAC"}, @@ -637,17 +639,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"ACOP", NULL, "ALC Mixer"}, }; -static int wm8753_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, - ARRAY_SIZE(wm8753_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - /* PLL divisors */ struct _pll_div { u32 div2:1; @@ -1323,7 +1314,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, * 3. Voice disabled - HIFI over HIFI * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture */ -static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = { +static const struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = { .hw_params = wm8753_i2s_hw_params, .digital_mute = wm8753_mute, .set_fmt = wm8753_hifi_set_dai_fmt, @@ -1332,7 +1323,7 @@ static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode = { .set_sysclk = wm8753_set_dai_sysclk, }; -static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = { +static const struct snd_soc_dai_ops wm8753_dai_ops_voice_mode = { .hw_params = wm8753_pcm_hw_params, .digital_mute = wm8753_mute, .set_fmt = wm8753_voice_set_dai_fmt, @@ -1389,7 +1380,7 @@ static void wm8753_work(struct work_struct *work) wm8753_set_bias_level(codec, dapm->bias_level); } -static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8753_suspend(struct snd_soc_codec *codec) { wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1464,10 +1455,6 @@ static int wm8753_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100); snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100); - snd_soc_add_controls(codec, wm8753_snd_controls, - ARRAY_SIZE(wm8753_snd_controls)); - wm8753_add_widgets(codec); - return 0; } @@ -1489,6 +1476,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { .reg_cache_size = ARRAY_SIZE(wm8753_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8753_reg, + + .controls = wm8753_snd_controls, + .num_controls = ARRAY_SIZE(wm8753_snd_controls), + .dapm_widgets = wm8753_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8753_dapm_widgets), + .dapm_routes = wm8753_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8753_dapm_routes), }; static const struct of_device_id wm8753_of_match[] = { diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index aa05e6507f8..19374a9e5ba 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -16,7 +16,6 @@ #include <linux/delay.h> #include <linux/of_device.h> #include <linux/pm.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> @@ -528,7 +527,7 @@ static int wm8770_set_bias_level(struct snd_soc_codec *codec, #define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8770_dai_ops = { +static const struct snd_soc_dai_ops wm8770_dai_ops = { .digital_mute = wm8770_mute, .hw_params = wm8770_hw_params, .set_fmt = wm8770_set_fmt, @@ -556,7 +555,7 @@ static struct snd_soc_dai_driver wm8770_dai = { }; #ifdef CONFIG_PM -static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8770_suspend(struct snd_soc_codec *codec) { wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -691,13 +690,13 @@ static const struct of_device_id wm8770_of_match[] = { }; MODULE_DEVICE_TABLE(of, wm8770_of_match); -#if defined(CONFIG_SPI_MASTER) static int __devinit wm8770_spi_probe(struct spi_device *spi) { struct wm8770_priv *wm8770; int ret; - wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL); + wm8770 = devm_kzalloc(&spi->dev, sizeof(struct wm8770_priv), + GFP_KERNEL); if (!wm8770) return -ENOMEM; @@ -706,15 +705,13 @@ static int __devinit wm8770_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8770, &wm8770_dai, 1); - if (ret < 0) - kfree(wm8770); + return ret; } static int __devexit wm8770_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -727,28 +724,23 @@ static struct spi_driver wm8770_spi_driver = { .probe = wm8770_spi_probe, .remove = __devexit_p(wm8770_spi_remove) }; -#endif static int __init wm8770_modinit(void) { int ret = 0; -#if defined(CONFIG_SPI_MASTER) ret = spi_register_driver(&wm8770_spi_driver); if (ret) { printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n", ret); } -#endif return ret; } module_init(wm8770_modinit); static void __exit wm8770_exit(void) { -#if defined(CONFIG_SPI_MASTER) spi_unregister_driver(&wm8770_spi_driver); -#endif } module_exit(wm8770_exit); diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index bfdc52370ad..33e97d1d8f4 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -19,7 +19,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/of_device.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <sound/core.h> @@ -235,6 +234,7 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream, switch (snd_pcm_format_width(params_format(params))) { case 16: iface = 0; + break; case 20: iface = 0x10; break; @@ -327,14 +327,14 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, #define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8776_dac_ops = { +static const struct snd_soc_dai_ops wm8776_dac_ops = { .digital_mute = wm8776_mute, .hw_params = wm8776_hw_params, .set_fmt = wm8776_set_fmt, .set_sysclk = wm8776_set_sysclk, }; -static struct snd_soc_dai_ops wm8776_adc_ops = { +static const struct snd_soc_dai_ops wm8776_adc_ops = { .hw_params = wm8776_hw_params, .set_fmt = wm8776_set_fmt, .set_sysclk = wm8776_set_sysclk, @@ -372,7 +372,7 @@ static struct snd_soc_dai_driver wm8776_dai[] = { }; #ifdef CONFIG_PM -static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8776_suspend(struct snd_soc_codec *codec) { wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -392,7 +392,6 @@ static int wm8776_resume(struct snd_soc_codec *codec) static int wm8776_probe(struct snd_soc_codec *codec) { struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); - struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); @@ -414,12 +413,6 @@ static int wm8776_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100); snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100); - snd_soc_add_controls(codec, wm8776_snd_controls, - ARRAY_SIZE(wm8776_snd_controls)); - snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets, - ARRAY_SIZE(wm8776_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); - return ret; } @@ -439,6 +432,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { .reg_cache_size = ARRAY_SIZE(wm8776_reg), .reg_word_size = sizeof(u16), .reg_cache_default = wm8776_reg, + + .controls = wm8776_snd_controls, + .num_controls = ARRAY_SIZE(wm8776_snd_controls), + .dapm_widgets = wm8776_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8776_dapm_widgets), + .dapm_routes = routes, + .num_dapm_routes = ARRAY_SIZE(routes), }; static const struct of_device_id wm8776_of_match[] = { @@ -453,7 +453,8 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi) struct wm8776_priv *wm8776; int ret; - wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); + wm8776 = devm_kzalloc(&spi->dev, sizeof(struct wm8776_priv), + GFP_KERNEL); if (wm8776 == NULL) return -ENOMEM; @@ -462,15 +463,13 @@ static int __devinit wm8776_spi_probe(struct spi_device *spi) ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); - if (ret < 0) - kfree(wm8776); + return ret; } static int __devexit wm8776_spi_remove(struct spi_device *spi) { snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); return 0; } @@ -492,7 +491,8 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, struct wm8776_priv *wm8776; int ret; - wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL); + wm8776 = devm_kzalloc(&i2c->dev, sizeof(struct wm8776_priv), + GFP_KERNEL); if (wm8776 == NULL) return -ENOMEM; @@ -501,15 +501,13 @@ static __devinit int wm8776_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai)); - if (ret < 0) - kfree(wm8776); + return ret; } static __devexit int wm8776_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index f2ced71328b..3fdea98f732 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c @@ -63,17 +63,7 @@ static struct platform_driver wm8782_codec_driver = { .remove = __devexit_p(wm8782_remove), }; -static int __init wm8782_init(void) -{ - return platform_driver_register(&wm8782_codec_driver); -} -module_init(wm8782_init); - -static void __exit wm8782_exit(void) -{ - platform_driver_unregister(&wm8782_codec_driver); -} -module_exit(wm8782_exit); +module_platform_driver(wm8782_codec_driver); MODULE_DESCRIPTION("ASoC WM8782 driver"); MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>"); diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 9ee072b8597..d54a3ca5e19 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -542,7 +542,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, } #ifdef CONFIG_PM -static int wm8804_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8804_suspend(struct snd_soc_codec *codec) { wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -659,8 +659,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - snd_soc_add_controls(codec, wm8804_snd_controls, - ARRAY_SIZE(wm8804_snd_controls)); return 0; err_reg_enable: @@ -670,7 +668,7 @@ err_reg_get: return ret; } -static struct snd_soc_dai_ops wm8804_dai_ops = { +static const struct snd_soc_dai_ops wm8804_dai_ops = { .hw_params = wm8804_hw_params, .set_fmt = wm8804_set_fmt, .set_sysclk = wm8804_set_sysclk, @@ -715,7 +713,10 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs), .reg_word_size = sizeof(u8), .reg_cache_default = wm8804_reg_defs, - .volatile_register = wm8804_volatile + .volatile_register = wm8804_volatile, + + .controls = wm8804_snd_controls, + .num_controls = ARRAY_SIZE(wm8804_snd_controls), }; static const struct of_device_id wm8804_of_match[] = { diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 3d0dc1591ec..f18c554efc9 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -24,7 +24,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/spi/spi.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -513,7 +512,7 @@ SND_SOC_DAPM_MIXER("Right Input Mixer", WM8900_REG_POWER2, 4, 0, wm8900_rinmix_controls, ARRAY_SIZE(wm8900_rinmix_controls)), -SND_SOC_DAPM_MICBIAS("Mic Bias", WM8900_REG_POWER1, 4, 0), +SND_SOC_DAPM_SUPPLY("Mic Bias", WM8900_REG_POWER1, 4, 0, NULL, 0), SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8900_REG_POWER2, 1, 0), SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8900_REG_POWER2, 0, 0), @@ -543,7 +542,7 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8900_REG_POWER3, 2, 0, }; /* Target, Path, Source */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route wm8900_dapm_routes[] = { /* Inputs */ {"Left Input PGA", "LINPUT1 Switch", "LINPUT1"}, {"Left Input PGA", "LINPUT2 Switch", "LINPUT2"}, @@ -607,17 +606,6 @@ static const struct snd_soc_dapm_route audio_map[] = { {"HP_R", NULL, "Headphone Amplifier"}, }; -static int wm8900_add_widgets(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets, - ARRAY_SIZE(wm8900_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - return 0; -} - static int wm8900_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -987,7 +975,7 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute) (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_LE) -static struct snd_soc_dai_ops wm8900_dai_ops = { +static const struct snd_soc_dai_ops wm8900_dai_ops = { .hw_params = wm8900_hw_params, .set_clkdiv = wm8900_set_dai_clkdiv, .set_pll = wm8900_set_dai_pll, @@ -1107,7 +1095,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8900_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8900_suspend(struct snd_soc_codec *codec) { struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); int fll_out = wm8900->fll_out; @@ -1204,10 +1192,6 @@ static int wm8900_probe(struct snd_soc_codec *codec) /* Set the DAC and mixer output bias */ snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); - snd_soc_add_controls(codec, wm8900_snd_controls, - ARRAY_SIZE(wm8900_snd_controls)); - wm8900_add_widgets(codec); - return 0; } @@ -1228,6 +1212,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8900 = { .reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults), .reg_word_size = sizeof(u16), .reg_cache_default = wm8900_reg_defaults, + + .controls = wm8900_snd_controls, + .num_controls = ARRAY_SIZE(wm8900_snd_controls), + .dapm_widgets = wm8900_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8900_dapm_widgets), + .dapm_routes = wm8900_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes), }; #if defined(CONFIG_SPI_MASTER) @@ -1259,7 +1250,7 @@ static int __devexit wm8900_spi_remove(struct spi_device *spi) static struct spi_driver wm8900_spi_driver = { .driver = { - .name = "wm8900-codec", + .name = "wm8900", .owner = THIS_MODULE, }, .probe = wm8900_spi_probe, @@ -1303,7 +1294,7 @@ MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id); static struct i2c_driver wm8900_i2c_driver = { .driver = { - .name = "wm8900-codec", + .name = "wm8900", .owner = THIS_MODULE, }, .probe = wm8900_i2c_probe, diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 4ad8ebd290e..c91fb2f99c1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -23,8 +23,9 @@ #include <linux/gpio.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/slab.h> +#include <linux/irq.h> #include <sound/core.h> #include <sound/jack.h> #include <sound/pcm.h> @@ -38,184 +39,85 @@ #include "wm8903.h" /* Register defaults at reset */ -static u16 wm8903_reg_defaults[] = { - 0x8903, /* R0 - SW Reset and ID */ - 0x0000, /* R1 - Revision Number */ - 0x0000, /* R2 */ - 0x0000, /* R3 */ - 0x0018, /* R4 - Bias Control 0 */ - 0x0000, /* R5 - VMID Control 0 */ - 0x0000, /* R6 - Mic Bias Control 0 */ - 0x0000, /* R7 */ - 0x0001, /* R8 - Analogue DAC 0 */ - 0x0000, /* R9 */ - 0x0001, /* R10 - Analogue ADC 0 */ - 0x0000, /* R11 */ - 0x0000, /* R12 - Power Management 0 */ - 0x0000, /* R13 - Power Management 1 */ - 0x0000, /* R14 - Power Management 2 */ - 0x0000, /* R15 - Power Management 3 */ - 0x0000, /* R16 - Power Management 4 */ - 0x0000, /* R17 - Power Management 5 */ - 0x0000, /* R18 - Power Management 6 */ - 0x0000, /* R19 */ - 0x0400, /* R20 - Clock Rates 0 */ - 0x0D07, /* R21 - Clock Rates 1 */ - 0x0000, /* R22 - Clock Rates 2 */ - 0x0000, /* R23 */ - 0x0050, /* R24 - Audio Interface 0 */ - 0x0242, /* R25 - Audio Interface 1 */ - 0x0008, /* R26 - Audio Interface 2 */ - 0x0022, /* R27 - Audio Interface 3 */ - 0x0000, /* R28 */ - 0x0000, /* R29 */ - 0x00C0, /* R30 - DAC Digital Volume Left */ - 0x00C0, /* R31 - DAC Digital Volume Right */ - 0x0000, /* R32 - DAC Digital 0 */ - 0x0000, /* R33 - DAC Digital 1 */ - 0x0000, /* R34 */ - 0x0000, /* R35 */ - 0x00C0, /* R36 - ADC Digital Volume Left */ - 0x00C0, /* R37 - ADC Digital Volume Right */ - 0x0000, /* R38 - ADC Digital 0 */ - 0x0073, /* R39 - Digital Microphone 0 */ - 0x09BF, /* R40 - DRC 0 */ - 0x3241, /* R41 - DRC 1 */ - 0x0020, /* R42 - DRC 2 */ - 0x0000, /* R43 - DRC 3 */ - 0x0085, /* R44 - Analogue Left Input 0 */ - 0x0085, /* R45 - Analogue Right Input 0 */ - 0x0044, /* R46 - Analogue Left Input 1 */ - 0x0044, /* R47 - Analogue Right Input 1 */ - 0x0000, /* R48 */ - 0x0000, /* R49 */ - 0x0008, /* R50 - Analogue Left Mix 0 */ - 0x0004, /* R51 - Analogue Right Mix 0 */ - 0x0000, /* R52 - Analogue Spk Mix Left 0 */ - 0x0000, /* R53 - Analogue Spk Mix Left 1 */ - 0x0000, /* R54 - Analogue Spk Mix Right 0 */ - 0x0000, /* R55 - Analogue Spk Mix Right 1 */ - 0x0000, /* R56 */ - 0x002D, /* R57 - Analogue OUT1 Left */ - 0x002D, /* R58 - Analogue OUT1 Right */ - 0x0039, /* R59 - Analogue OUT2 Left */ - 0x0039, /* R60 - Analogue OUT2 Right */ - 0x0100, /* R61 */ - 0x0139, /* R62 - Analogue OUT3 Left */ - 0x0139, /* R63 - Analogue OUT3 Right */ - 0x0000, /* R64 */ - 0x0000, /* R65 - Analogue SPK Output Control 0 */ - 0x0000, /* R66 */ - 0x0010, /* R67 - DC Servo 0 */ - 0x0100, /* R68 */ - 0x00A4, /* R69 - DC Servo 2 */ - 0x0807, /* R70 */ - 0x0000, /* R71 */ - 0x0000, /* R72 */ - 0x0000, /* R73 */ - 0x0000, /* R74 */ - 0x0000, /* R75 */ - 0x0000, /* R76 */ - 0x0000, /* R77 */ - 0x0000, /* R78 */ - 0x000E, /* R79 */ - 0x0000, /* R80 */ - 0x0000, /* R81 */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 */ - 0x0000, /* R85 */ - 0x0000, /* R86 */ - 0x0006, /* R87 */ - 0x0000, /* R88 */ - 0x0000, /* R89 */ - 0x0000, /* R90 - Analogue HP 0 */ - 0x0060, /* R91 */ - 0x0000, /* R92 */ - 0x0000, /* R93 */ - 0x0000, /* R94 - Analogue Lineout 0 */ - 0x0060, /* R95 */ - 0x0000, /* R96 */ - 0x0000, /* R97 */ - 0x0000, /* R98 - Charge Pump 0 */ - 0x1F25, /* R99 */ - 0x2B19, /* R100 */ - 0x01C0, /* R101 */ - 0x01EF, /* R102 */ - 0x2B00, /* R103 */ - 0x0000, /* R104 - Class W 0 */ - 0x01C0, /* R105 */ - 0x1C10, /* R106 */ - 0x0000, /* R107 */ - 0x0000, /* R108 - Write Sequencer 0 */ - 0x0000, /* R109 - Write Sequencer 1 */ - 0x0000, /* R110 - Write Sequencer 2 */ - 0x0000, /* R111 - Write Sequencer 3 */ - 0x0000, /* R112 - Write Sequencer 4 */ - 0x0000, /* R113 */ - 0x0000, /* R114 - Control Interface */ - 0x0000, /* R115 */ - 0x00A8, /* R116 - GPIO Control 1 */ - 0x00A8, /* R117 - GPIO Control 2 */ - 0x00A8, /* R118 - GPIO Control 3 */ - 0x0220, /* R119 - GPIO Control 4 */ - 0x01A0, /* R120 - GPIO Control 5 */ - 0x0000, /* R121 - Interrupt Status 1 */ - 0xFFFF, /* R122 - Interrupt Status 1 Mask */ - 0x0000, /* R123 - Interrupt Polarity 1 */ - 0x0000, /* R124 */ - 0x0003, /* R125 */ - 0x0000, /* R126 - Interrupt Control */ - 0x0000, /* R127 */ - 0x0005, /* R128 */ - 0x0000, /* R129 - Control Interface Test 1 */ - 0x0000, /* R130 */ - 0x0000, /* R131 */ - 0x0000, /* R132 */ - 0x0000, /* R133 */ - 0x0000, /* R134 */ - 0x03FF, /* R135 */ - 0x0007, /* R136 */ - 0x0040, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0000, /* R140 */ - 0x0000, /* R141 */ - 0x0000, /* R142 */ - 0x0000, /* R143 */ - 0x0000, /* R144 */ - 0x0000, /* R145 */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x4000, /* R148 */ - 0x6810, /* R149 - Charge Pump Test 1 */ - 0x0004, /* R150 */ - 0x0000, /* R151 */ - 0x0000, /* R152 */ - 0x0000, /* R153 */ - 0x0000, /* R154 */ - 0x0000, /* R155 */ - 0x0000, /* R156 */ - 0x0000, /* R157 */ - 0x0000, /* R158 */ - 0x0000, /* R159 */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 */ - 0x0028, /* R164 - Clock Rate Test 4 */ - 0x0004, /* R165 */ - 0x0000, /* R166 */ - 0x0060, /* R167 */ - 0x0000, /* R168 */ - 0x0000, /* R169 */ - 0x0000, /* R170 */ - 0x0000, /* R171 */ - 0x0000, /* R172 - Analogue Output Bias 0 */ +static const struct reg_default wm8903_reg_defaults[] = { + { 4, 0x0018 }, /* R4 - Bias Control 0 */ + { 5, 0x0000 }, /* R5 - VMID Control 0 */ + { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */ + { 8, 0x0001 }, /* R8 - Analogue DAC 0 */ + { 10, 0x0001 }, /* R10 - Analogue ADC 0 */ + { 12, 0x0000 }, /* R12 - Power Management 0 */ + { 13, 0x0000 }, /* R13 - Power Management 1 */ + { 14, 0x0000 }, /* R14 - Power Management 2 */ + { 15, 0x0000 }, /* R15 - Power Management 3 */ + { 16, 0x0000 }, /* R16 - Power Management 4 */ + { 17, 0x0000 }, /* R17 - Power Management 5 */ + { 18, 0x0000 }, /* R18 - Power Management 6 */ + { 20, 0x0400 }, /* R20 - Clock Rates 0 */ + { 21, 0x0D07 }, /* R21 - Clock Rates 1 */ + { 22, 0x0000 }, /* R22 - Clock Rates 2 */ + { 24, 0x0050 }, /* R24 - Audio Interface 0 */ + { 25, 0x0242 }, /* R25 - Audio Interface 1 */ + { 26, 0x0008 }, /* R26 - Audio Interface 2 */ + { 27, 0x0022 }, /* R27 - Audio Interface 3 */ + { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */ + { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */ + { 32, 0x0000 }, /* R32 - DAC Digital 0 */ + { 33, 0x0000 }, /* R33 - DAC Digital 1 */ + { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */ + { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */ + { 38, 0x0000 }, /* R38 - ADC Digital 0 */ + { 39, 0x0073 }, /* R39 - Digital Microphone 0 */ + { 40, 0x09BF }, /* R40 - DRC 0 */ + { 41, 0x3241 }, /* R41 - DRC 1 */ + { 42, 0x0020 }, /* R42 - DRC 2 */ + { 43, 0x0000 }, /* R43 - DRC 3 */ + { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */ + { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */ + { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */ + { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */ + { 50, 0x0008 }, /* R50 - Analogue Left Mix 0 */ + { 51, 0x0004 }, /* R51 - Analogue Right Mix 0 */ + { 52, 0x0000 }, /* R52 - Analogue Spk Mix Left 0 */ + { 53, 0x0000 }, /* R53 - Analogue Spk Mix Left 1 */ + { 54, 0x0000 }, /* R54 - Analogue Spk Mix Right 0 */ + { 55, 0x0000 }, /* R55 - Analogue Spk Mix Right 1 */ + { 57, 0x002D }, /* R57 - Analogue OUT1 Left */ + { 58, 0x002D }, /* R58 - Analogue OUT1 Right */ + { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */ + { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */ + { 62, 0x0139 }, /* R62 - Analogue OUT3 Left */ + { 63, 0x0139 }, /* R63 - Analogue OUT3 Right */ + { 64, 0x0000 }, /* R65 - Analogue SPK Output Control 0 */ + { 67, 0x0010 }, /* R67 - DC Servo 0 */ + { 69, 0x00A4 }, /* R69 - DC Servo 2 */ + { 90, 0x0000 }, /* R90 - Analogue HP 0 */ + { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */ + { 98, 0x0000 }, /* R98 - Charge Pump 0 */ + { 104, 0x0000 }, /* R104 - Class W 0 */ + { 108, 0x0000 }, /* R108 - Write Sequencer 0 */ + { 109, 0x0000 }, /* R109 - Write Sequencer 1 */ + { 110, 0x0000 }, /* R110 - Write Sequencer 2 */ + { 111, 0x0000 }, /* R111 - Write Sequencer 3 */ + { 112, 0x0000 }, /* R112 - Write Sequencer 4 */ + { 114, 0x0000 }, /* R114 - Control Interface */ + { 116, 0x00A8 }, /* R116 - GPIO Control 1 */ + { 117, 0x00A8 }, /* R117 - GPIO Control 2 */ + { 118, 0x00A8 }, /* R118 - GPIO Control 3 */ + { 119, 0x0220 }, /* R119 - GPIO Control 4 */ + { 120, 0x01A0 }, /* R120 - GPIO Control 5 */ + { 122, 0xFFFF }, /* R122 - Interrupt Status 1 Mask */ + { 123, 0x0000 }, /* R123 - Interrupt Polarity 1 */ + { 126, 0x0000 }, /* R126 - Interrupt Control */ + { 129, 0x0000 }, /* R129 - Control Interface Test 1 */ + { 149, 0x6810 }, /* R149 - Charge Pump Test 1 */ + { 164, 0x0028 }, /* R164 - Clock Rate Test 4 */ + { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */ }; struct wm8903_priv { + struct wm8903_platform_data *pdata; struct snd_soc_codec *codec; + struct regmap *regmap; int sysclk; int irq; @@ -240,7 +142,93 @@ struct wm8903_priv { #endif }; -static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8903_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8903_SW_RESET_AND_ID: + case WM8903_REVISION_NUMBER: + case WM8903_BIAS_CONTROL_0: + case WM8903_VMID_CONTROL_0: + case WM8903_MIC_BIAS_CONTROL_0: + case WM8903_ANALOGUE_DAC_0: + case WM8903_ANALOGUE_ADC_0: + case WM8903_POWER_MANAGEMENT_0: + case WM8903_POWER_MANAGEMENT_1: + case WM8903_POWER_MANAGEMENT_2: + case WM8903_POWER_MANAGEMENT_3: + case WM8903_POWER_MANAGEMENT_4: + case WM8903_POWER_MANAGEMENT_5: + case WM8903_POWER_MANAGEMENT_6: + case WM8903_CLOCK_RATES_0: + case WM8903_CLOCK_RATES_1: + case WM8903_CLOCK_RATES_2: + case WM8903_AUDIO_INTERFACE_0: + case WM8903_AUDIO_INTERFACE_1: + case WM8903_AUDIO_INTERFACE_2: + case WM8903_AUDIO_INTERFACE_3: + case WM8903_DAC_DIGITAL_VOLUME_LEFT: + case WM8903_DAC_DIGITAL_VOLUME_RIGHT: + case WM8903_DAC_DIGITAL_0: + case WM8903_DAC_DIGITAL_1: + case WM8903_ADC_DIGITAL_VOLUME_LEFT: + case WM8903_ADC_DIGITAL_VOLUME_RIGHT: + case WM8903_ADC_DIGITAL_0: + case WM8903_DIGITAL_MICROPHONE_0: + case WM8903_DRC_0: + case WM8903_DRC_1: + case WM8903_DRC_2: + case WM8903_DRC_3: + case WM8903_ANALOGUE_LEFT_INPUT_0: + case WM8903_ANALOGUE_RIGHT_INPUT_0: + case WM8903_ANALOGUE_LEFT_INPUT_1: + case WM8903_ANALOGUE_RIGHT_INPUT_1: + case WM8903_ANALOGUE_LEFT_MIX_0: + case WM8903_ANALOGUE_RIGHT_MIX_0: + case WM8903_ANALOGUE_SPK_MIX_LEFT_0: + case WM8903_ANALOGUE_SPK_MIX_LEFT_1: + case WM8903_ANALOGUE_SPK_MIX_RIGHT_0: + case WM8903_ANALOGUE_SPK_MIX_RIGHT_1: + case WM8903_ANALOGUE_OUT1_LEFT: + case WM8903_ANALOGUE_OUT1_RIGHT: + case WM8903_ANALOGUE_OUT2_LEFT: + case WM8903_ANALOGUE_OUT2_RIGHT: + case WM8903_ANALOGUE_OUT3_LEFT: + case WM8903_ANALOGUE_OUT3_RIGHT: + case WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0: + case WM8903_DC_SERVO_0: + case WM8903_DC_SERVO_2: + case WM8903_DC_SERVO_READBACK_1: + case WM8903_DC_SERVO_READBACK_2: + case WM8903_DC_SERVO_READBACK_3: + case WM8903_DC_SERVO_READBACK_4: + case WM8903_ANALOGUE_HP_0: + case WM8903_ANALOGUE_LINEOUT_0: + case WM8903_CHARGE_PUMP_0: + case WM8903_CLASS_W_0: + case WM8903_WRITE_SEQUENCER_0: + case WM8903_WRITE_SEQUENCER_1: + case WM8903_WRITE_SEQUENCER_2: + case WM8903_WRITE_SEQUENCER_3: + case WM8903_WRITE_SEQUENCER_4: + case WM8903_CONTROL_INTERFACE: + case WM8903_GPIO_CONTROL_1: + case WM8903_GPIO_CONTROL_2: + case WM8903_GPIO_CONTROL_3: + case WM8903_GPIO_CONTROL_4: + case WM8903_GPIO_CONTROL_5: + case WM8903_INTERRUPT_STATUS_1: + case WM8903_INTERRUPT_STATUS_1_MASK: + case WM8903_INTERRUPT_POLARITY_1: + case WM8903_INTERRUPT_CONTROL: + case WM8903_CLOCK_RATE_TEST_4: + case WM8903_ANALOGUE_OUTPUT_BIAS_0: + return true; + default: + return false; + } +} + +static bool wm8903_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM8903_SW_RESET_AND_ID: @@ -258,13 +246,6 @@ static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int re } } -static void wm8903_reset(struct snd_soc_codec *codec) -{ - snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); - memcpy(codec->reg_cache, wm8903_reg_defaults, - sizeof(wm8903_reg_defaults)); -} - static int wm8903_cp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -839,7 +820,7 @@ SND_SOC_DAPM_OUTPUT("LON"), SND_SOC_DAPM_OUTPUT("ROP"), SND_SOC_DAPM_OUTPUT("RON"), -SND_SOC_DAPM_MICBIAS("Mic Bias", WM8903_MIC_BIAS_CONTROL_0, 0, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS", WM8903_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0), SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux), SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0, @@ -948,7 +929,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), static const struct snd_soc_dapm_route wm8903_intercon[] = { { "CLK_DSP", NULL, "CLK_SYS" }, - { "Mic Bias", NULL, "CLK_SYS" }, + { "MICBIAS", NULL, "CLK_SYS" }, { "HPL_DCS", NULL, "CLK_SYS" }, { "HPR_DCS", NULL, "CLK_SYS" }, { "LINEOUTL_DCS", NULL, "CLK_SYS" }, @@ -1732,7 +1713,7 @@ static irqreturn_t wm8903_irq(int irq, void *data) SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8903_dai_ops = { +static const struct snd_soc_dai_ops wm8903_dai_ops = { .hw_params = wm8903_hw_params, .digital_mute = wm8903_digital_mute, .set_fmt = wm8903_set_dai_fmt, @@ -1759,7 +1740,7 @@ static struct snd_soc_dai_driver wm8903_dai = { .symmetric_rates = 1, }; -static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8903_suspend(struct snd_soc_codec *codec) { wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1768,23 +1749,11 @@ static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm8903_resume(struct snd_soc_codec *codec) { - int i; - u16 *reg_cache = codec->reg_cache; - u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), - GFP_KERNEL); + struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - /* Bring the codec back up to standby first to minimise pop/clicks */ - wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + regcache_sync(wm8903->regmap); - /* Sync back everything else */ - if (tmp_cache) { - for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++) - if (tmp_cache[i] != reg_cache[i]) - snd_soc_write(codec, i, tmp_cache[i]); - kfree(tmp_cache); - } else { - dev_err(codec->dev, "Failed to allocate temporary cache\n"); - } + wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); return 0; } @@ -1808,13 +1777,18 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); struct snd_soc_codec *codec = wm8903->codec; unsigned int mask, val; + int ret; mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK; val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | WM8903_GP1_DIR; - return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, - mask, val); + ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, + mask, val); + if (ret < 0) + return ret; + + return 0; } static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) @@ -1834,13 +1808,18 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip, struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); struct snd_soc_codec *codec = wm8903->codec; unsigned int mask, val; + int ret; mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK; val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | (value << WM8903_GP2_LVL_SHIFT); - return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, - mask, val); + ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, + mask, val); + if (ret < 0) + return ret; + + return 0; } static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) @@ -1867,14 +1846,14 @@ static struct gpio_chip wm8903_template_chip = { static void wm8903_init_gpio(struct snd_soc_codec *codec) { struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); + struct wm8903_platform_data *pdata = wm8903->pdata; int ret; wm8903->gpio_chip = wm8903_template_chip; wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; wm8903->gpio_chip.dev = codec->dev; - if (pdata && pdata->gpio_base) + if (pdata->gpio_base) wm8903->gpio_chip.base = pdata->gpio_base; else wm8903->gpio_chip.base = -1; @@ -1905,78 +1884,65 @@ static void wm8903_free_gpio(struct snd_soc_codec *codec) static int wm8903_probe(struct snd_soc_codec *codec) { - struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); + struct wm8903_platform_data *pdata = wm8903->pdata; int ret, i; int trigger, irq_pol; u16 val; + bool mic_gpio = false; wm8903->codec = codec; + codec->control_data = wm8903->regmap; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); - if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { - dev_err(codec->dev, - "Device with ID register %x is not a WM8903\n", val); - return -ENODEV; - } - - val = snd_soc_read(codec, WM8903_REVISION_NUMBER); - dev_info(codec->dev, "WM8903 revision %c\n", - (val & WM8903_CHIP_REV_MASK) + 'A'); + /* Set up GPIOs, detect if any are MIC detect outputs */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { + if ((!pdata->gpio_cfg[i]) || + (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) + continue; - wm8903_reset(codec); + snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, + pdata->gpio_cfg[i] & 0x7fff); - /* Set up GPIOs and microphone detection */ - if (pdata) { - bool mic_gpio = false; + val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) + >> WM8903_GP1_FN_SHIFT; - for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { - if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG) - continue; - - snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, - pdata->gpio_cfg[i] & 0xffff); - - val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) - >> WM8903_GP1_FN_SHIFT; - - switch (val) { - case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: - case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: - mic_gpio = true; - break; - default: - break; - } + switch (val) { + case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: + case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: + mic_gpio = true; + break; + default: + break; } + } + + /* Set up microphone detection */ + snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, + pdata->micdet_cfg); - snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, - pdata->micdet_cfg); + /* Microphone detection needs the WSEQ clock */ + if (pdata->micdet_cfg) + snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, + WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); - /* Microphone detection needs the WSEQ clock */ - if (pdata->micdet_cfg) - snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, - WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); + /* If microphone detection is enabled by pdata but + * detected via IRQ then interrupts can be lost before + * the machine driver has set up microphone detection + * IRQs as the IRQs are clear on read. The detection + * will be enabled when the machine driver configures. + */ + WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); - /* If microphone detection is enabled by pdata but - * detected via IRQ then interrupts can be lost before - * the machine driver has set up microphone detection - * IRQs as the IRQs are clear on read. The detection - * will be enabled when the machine driver configures. - */ - WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); + wm8903->mic_delay = pdata->micdet_delay; - wm8903->mic_delay = pdata->micdet_delay; - } - if (wm8903->irq) { - if (pdata && pdata->irq_active_low) { + if (pdata->irq_active_low) { trigger = IRQF_TRIGGER_LOW; irq_pol = WM8903_IRQ_POL; } else { @@ -2035,9 +2001,6 @@ static int wm8903_probe(struct snd_soc_codec *codec) WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); - snd_soc_add_controls(codec, wm8903_snd_controls, - ARRAY_SIZE(wm8903_snd_controls)); - wm8903_init_gpio(codec); return ret; @@ -2062,45 +2025,198 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { .suspend = wm8903_suspend, .resume = wm8903_resume, .set_bias_level = wm8903_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8903_reg_defaults, - .volatile_register = wm8903_volatile_register, .seq_notifier = wm8903_seq_notifier, + .controls = wm8903_snd_controls, + .num_controls = ARRAY_SIZE(wm8903_snd_controls), .dapm_widgets = wm8903_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), .dapm_routes = wm8903_intercon, .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static const struct regmap_config wm8903_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM8903_MAX_REGISTER, + .volatile_reg = wm8903_volatile_register, + .readable_reg = wm8903_readable_register, + + .cache_type = REGCACHE_RBTREE, + .reg_defaults = wm8903_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8903_reg_defaults), +}; + +static int wm8903_set_pdata_irq_trigger(struct i2c_client *i2c, + struct wm8903_platform_data *pdata) +{ + struct irq_data *irq_data = irq_get_irq_data(i2c->irq); + if (!irq_data) { + dev_err(&i2c->dev, "Invalid IRQ: %d\n", + i2c->irq); + return -EINVAL; + } + + switch (irqd_get_trigger_type(irq_data)) { + case IRQ_TYPE_NONE: + default: + /* + * We assume the controller imposes no restrictions, + * so we are able to select active-high + */ + /* Fall-through */ + case IRQ_TYPE_LEVEL_HIGH: + pdata->irq_active_low = false; + break; + case IRQ_TYPE_LEVEL_LOW: + pdata->irq_active_low = true; + break; + } + + return 0; +} + +static int wm8903_set_pdata_from_of(struct i2c_client *i2c, + struct wm8903_platform_data *pdata) +{ + const struct device_node *np = i2c->dev.of_node; + u32 val32; + int i; + + if (of_property_read_u32(np, "micdet-cfg", &val32) >= 0) + pdata->micdet_cfg = val32; + + if (of_property_read_u32(np, "micdet-delay", &val32) >= 0) + pdata->micdet_delay = val32; + + if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_cfg, + ARRAY_SIZE(pdata->gpio_cfg)) >= 0) { + /* + * In device tree: 0 means "write 0", + * 0xffffffff means "don't touch". + * + * In platform data: 0 means "don't touch", + * 0x8000 means "write 0". + * + * Note: WM8903_GPIO_CONFIG_ZERO == 0x8000. + * + * Convert from DT to pdata representation here, + * so no other code needs to change. + */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { + if (pdata->gpio_cfg[i] == 0) { + pdata->gpio_cfg[i] = WM8903_GPIO_CONFIG_ZERO; + } else if (pdata->gpio_cfg[i] == 0xffffffff) { + pdata->gpio_cfg[i] = 0; + } else if (pdata->gpio_cfg[i] > 0x7fff) { + dev_err(&i2c->dev, "Invalid gpio-cfg[%d] %x\n", + i, pdata->gpio_cfg[i]); + return -EINVAL; + } + } + } + + return 0; +} + static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { + struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); struct wm8903_priv *wm8903; + unsigned int val; int ret; - wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); + wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), + GFP_KERNEL); if (wm8903 == NULL) return -ENOMEM; + wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); + if (IS_ERR(wm8903->regmap)) { + ret = PTR_ERR(wm8903->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + ret); + return ret; + } + i2c_set_clientdata(i2c, wm8903); wm8903->irq = i2c->irq; + /* If no platform data was supplied, create storage for defaults */ + if (pdata) { + wm8903->pdata = pdata; + } else { + wm8903->pdata = devm_kzalloc(&i2c->dev, + sizeof(struct wm8903_platform_data), + GFP_KERNEL); + if (wm8903->pdata == NULL) { + dev_err(&i2c->dev, "Failed to allocate pdata\n"); + return -ENOMEM; + } + + if (i2c->irq) { + ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata); + if (ret != 0) + return ret; + } + + if (i2c->dev.of_node) { + ret = wm8903_set_pdata_from_of(i2c, wm8903->pdata); + if (ret != 0) + return ret; + } + } + + ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); + goto err; + } + if (val != 0x8903) { + dev_err(&i2c->dev, "Device with ID %x is not a WM8903\n", val); + ret = -ENODEV; + goto err; + } + + ret = regmap_read(wm8903->regmap, WM8903_REVISION_NUMBER, &val); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); + goto err; + } + dev_info(&i2c->dev, "WM8903 revision %c\n", + (val & WM8903_CHIP_REV_MASK) + 'A'); + + /* Reset the device */ + regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8903, &wm8903_dai, 1); - if (ret < 0) - kfree(wm8903); + if (ret != 0) + goto err; + + return 0; +err: + regmap_exit(wm8903->regmap); return ret; } static __devexit int wm8903_i2c_remove(struct i2c_client *client) { + struct wm8903_priv *wm8903 = i2c_get_clientdata(client); + + regmap_exit(wm8903->regmap); snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } +static const struct of_device_id wm8903_of_match[] = { + { .compatible = "wlf,wm8903", }, + {}, +}; +MODULE_DEVICE_TABLE(of, wm8903_of_match); + static const struct i2c_device_id wm8903_i2c_id[] = { { "wm8903", 0 }, { } @@ -2111,32 +2227,28 @@ static struct i2c_driver wm8903_i2c_driver = { .driver = { .name = "wm8903", .owner = THIS_MODULE, + .of_match_table = wm8903_of_match, }, .probe = wm8903_i2c_probe, .remove = __devexit_p(wm8903_i2c_remove), .id_table = wm8903_i2c_id, }; -#endif static int __init wm8903_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8903_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8903_modinit); static void __exit wm8903_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8903_i2c_driver); -#endif } module_exit(wm8903_exit); diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 285ef87e670..f31c754c886 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <sound/core.h> @@ -1196,7 +1195,7 @@ SND_SOC_DAPM_INPUT("IN2R"), SND_SOC_DAPM_INPUT("IN3L"), SND_SOC_DAPM_INPUT("IN3R"), -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0), SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux), SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0, @@ -2205,7 +2204,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, #define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8904_dai_ops = { +static const struct snd_soc_dai_ops wm8904_dai_ops = { .set_sysclk = wm8904_set_sysclk, .set_fmt = wm8904_set_fmt, .set_tdm_slot = wm8904_set_tdm_slot, @@ -2235,7 +2234,7 @@ static struct snd_soc_dai_driver wm8904_dai = { }; #ifdef CONFIG_PM -static int wm8904_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8904_suspend(struct snd_soc_codec *codec) { wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -2565,7 +2564,7 @@ MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id); static struct i2c_driver wm8904_i2c_driver = { .driver = { - .name = "wm8904-codec", + .name = "wm8904", .owner = THIS_MODULE, }, .probe = wm8904_i2c_probe, diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index de9ec9b8b7d..14039ea2f3e 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -28,7 +28,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/slab.h> #include <sound/core.h> @@ -629,8 +628,8 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5)); break; case WM8940_OPCLKDIV: - reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF; - ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4)); + reg = snd_soc_read(codec, WM8940_GPIO) & 0xFFCF; + ret = snd_soc_write(codec, WM8940_GPIO, reg | (div << 4)); break; } return ret; @@ -644,7 +643,7 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8940_dai_ops = { +static const struct snd_soc_dai_ops wm8940_dai_ops = { .hw_params = wm8940_i2s_hw_params, .set_sysclk = wm8940_set_dai_sysclk, .digital_mute = wm8940_mute, @@ -673,7 +672,7 @@ static struct snd_soc_dai_driver wm8940_dai = { .symmetric_rates = 1, }; -static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8940_suspend(struct snd_soc_codec *codec) { return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); } @@ -780,7 +779,7 @@ MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id); static struct i2c_driver wm8940_i2c_driver = { .driver = { - .name = "wm8940-codec", + .name = "wm8940", .owner = THIS_MODULE, }, .probe = wm8940_i2c_probe, diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 3c7198779c3..924548182d5 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -16,7 +16,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <sound/core.h> @@ -859,7 +858,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, #define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8955_dai_ops = { +static const struct snd_soc_dai_ops wm8955_dai_ops = { .set_sysclk = wm8955_set_sysclk, .set_fmt = wm8955_set_fmt, .hw_params = wm8955_hw_params, @@ -879,7 +878,7 @@ static struct snd_soc_dai_driver wm8955_dai = { }; #ifdef CONFIG_PM -static int wm8955_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8955_suspend(struct snd_soc_codec *codec) { wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1038,7 +1037,7 @@ MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id); static struct i2c_driver wm8955_i2c_driver = { .driver = { - .name = "wm8955-codec", + .name = "wm8955", .owner = THIS_MODULE, }, .probe = wm8955_i2c_probe, diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 0293763debe..8d4ea43d40a 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -55,11 +55,14 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, return 0; if (fw->size < 32) { - dev_err(codec->dev, "%s: firmware too short\n", name); + dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", + name, fw->size); goto err; } if (memcmp(fw->data, "WMFW", 4) != 0) { + memcpy(&data32, fw->data, sizeof(data32)); + data32 = be32_to_cpu(data32); dev_err(codec->dev, "%s: firmware has bad file magic %08x\n", name, data32); goto err; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 2df253c1856..e5caae32e54 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -14,7 +14,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -26,8 +25,6 @@ #include "wm8960.h" -#define AUDIO_NAME "wm8960" - /* R25 - Power 1 */ #define WM8960_VMID_MASK 0x180 #define WM8960_VREF 0x40 @@ -265,7 +262,7 @@ SND_SOC_DAPM_INPUT("RINPUT2"), SND_SOC_DAPM_INPUT("LINPUT3"), SND_SOC_DAPM_INPUT("RINPUT3"), -SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0), +SND_SOC_DAPM_SUPPLY("MICB", WM8960_POWER1, 1, 0, NULL, 0), SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0, wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)), @@ -546,30 +543,24 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream, static int wm8960_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = snd_soc_read(codec, WM8960_DACCTL1) & 0xfff7; if (mute) - snd_soc_write(codec, WM8960_DACCTL1, mute_reg | 0x8); + snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0x8); else - snd_soc_write(codec, WM8960_DACCTL1, mute_reg); + snd_soc_update_bits(codec, WM8960_DACCTL1, 0x8, 0); return 0; } static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg; - switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: /* Set VMID to 2x50k */ - reg = snd_soc_read(codec, WM8960_POWER1); - reg &= ~0x180; - reg |= 0x80; - snd_soc_write(codec, WM8960_POWER1, reg); + snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80); break; case SND_SOC_BIAS_STANDBY: @@ -582,23 +573,19 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, WM8960_BUFDCOPEN | WM8960_BUFIOEN); /* Enable & ramp VMID at 2x50k */ - reg = snd_soc_read(codec, WM8960_POWER1); - reg |= 0x80; - snd_soc_write(codec, WM8960_POWER1, reg); + snd_soc_update_bits(codec, WM8960_POWER1, 0x80, 0x80); msleep(100); /* Enable VREF */ - snd_soc_write(codec, WM8960_POWER1, reg | WM8960_VREF); + snd_soc_update_bits(codec, WM8960_POWER1, WM8960_VREF, + WM8960_VREF); /* Disable anti-pop features */ snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN); } /* Set VMID to 2x250k */ - reg = snd_soc_read(codec, WM8960_POWER1); - reg &= ~0x180; - reg |= 0x100; - snd_soc_write(codec, WM8960_POWER1, reg); + snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100); break; case SND_SOC_BIAS_OFF: @@ -790,10 +777,8 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, /* Disable the PLL: even if we are changing the frequency the * PLL needs to be disabled while we do so. */ - snd_soc_write(codec, WM8960_CLOCK1, - snd_soc_read(codec, WM8960_CLOCK1) & ~1); - snd_soc_write(codec, WM8960_POWER2, - snd_soc_read(codec, WM8960_POWER2) & ~1); + snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0); + snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0); if (!freq_in || !freq_out) return 0; @@ -812,11 +797,9 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, snd_soc_write(codec, WM8960_PLL1, reg); /* Turn it on */ - snd_soc_write(codec, WM8960_POWER2, - snd_soc_read(codec, WM8960_POWER2) | 1); + snd_soc_update_bits(codec, WM8960_POWER2, 0x1, 0x1); msleep(250); - snd_soc_write(codec, WM8960_CLOCK1, - snd_soc_read(codec, WM8960_CLOCK1) | 1); + snd_soc_update_bits(codec, WM8960_CLOCK1, 0x1, 0x1); return 0; } @@ -869,7 +852,7 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8960_dai_ops = { +static const struct snd_soc_dai_ops wm8960_dai_ops = { .hw_params = wm8960_hw_params, .digital_mute = wm8960_mute, .set_fmt = wm8960_set_dai_fmt, @@ -895,7 +878,7 @@ static struct snd_soc_dai_driver wm8960_dai = { .symmetric_rates = 1, }; -static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8960_suspend(struct snd_soc_codec *codec) { struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); @@ -916,7 +899,6 @@ static int wm8960_probe(struct snd_soc_codec *codec) struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); struct wm8960_data *pdata = dev_get_platdata(codec->dev); int ret; - u16 reg; wm8960->set_bias_level = wm8960_set_bias_level_out3; @@ -947,26 +929,16 @@ static int wm8960_probe(struct snd_soc_codec *codec) wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Latch the update bits */ - reg = snd_soc_read(codec, WM8960_LINVOL); - snd_soc_write(codec, WM8960_LINVOL, reg | 0x100); - reg = snd_soc_read(codec, WM8960_RINVOL); - snd_soc_write(codec, WM8960_RINVOL, reg | 0x100); - reg = snd_soc_read(codec, WM8960_LADC); - snd_soc_write(codec, WM8960_LADC, reg | 0x100); - reg = snd_soc_read(codec, WM8960_RADC); - snd_soc_write(codec, WM8960_RADC, reg | 0x100); - reg = snd_soc_read(codec, WM8960_LDAC); - snd_soc_write(codec, WM8960_LDAC, reg | 0x100); - reg = snd_soc_read(codec, WM8960_RDAC); - snd_soc_write(codec, WM8960_RDAC, reg | 0x100); - reg = snd_soc_read(codec, WM8960_LOUT1); - snd_soc_write(codec, WM8960_LOUT1, reg | 0x100); - reg = snd_soc_read(codec, WM8960_ROUT1); - snd_soc_write(codec, WM8960_ROUT1, reg | 0x100); - reg = snd_soc_read(codec, WM8960_LOUT2); - snd_soc_write(codec, WM8960_LOUT2, reg | 0x100); - reg = snd_soc_read(codec, WM8960_ROUT2); - snd_soc_write(codec, WM8960_ROUT2, reg | 0x100); + snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); + snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); snd_soc_add_controls(codec, wm8960_snd_controls, ARRAY_SIZE(wm8960_snd_controls)); @@ -995,14 +967,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { .reg_cache_default = wm8960_reg, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8960_priv *wm8960; int ret; - wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL); + wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv), + GFP_KERNEL); if (wm8960 == NULL) return -ENOMEM; @@ -1011,15 +983,13 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8960, &wm8960_dai, 1); - if (ret < 0) - kfree(wm8960); + return ret; } static __devexit int wm8960_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); return 0; } @@ -1031,34 +1001,29 @@ MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); static struct i2c_driver wm8960_i2c_driver = { .driver = { - .name = "wm8960-codec", + .name = "wm8960", .owner = THIS_MODULE, }, .probe = wm8960_i2c_probe, .remove = __devexit_p(wm8960_i2c_remove), .id_table = wm8960_i2c_id, }; -#endif static int __init wm8960_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8960_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8960_modinit); static void __exit wm8960_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8960_i2c_driver); -#endif } module_exit(wm8960_exit); diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 9568c8a49f9..4f20c72a0f1 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -423,11 +422,11 @@ static int wm8961_spk_event(struct snd_soc_dapm_widget *w, } if (event & SND_SOC_DAPM_PRE_PMD) { - /* Enable the amplifier */ + /* Disable the amplifier */ spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA); snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg); - /* Enable the PGA */ + /* Disable the PGA */ pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA); snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg); } @@ -531,7 +530,7 @@ SND_SOC_DAPM_PGA("Right Input", WM8961_PWR_MGMT_1, 4, 0, NULL, 0), SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0), SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0), -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8961_PWR_MGMT_1, 1, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS", WM8961_PWR_MGMT_1, 1, 0, NULL, 0), SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux), SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux), @@ -929,7 +928,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8961_dai_ops = { +static const struct snd_soc_dai_ops wm8961_dai_ops = { .hw_params = wm8961_hw_params, .set_sysclk = wm8961_set_sysclk, .set_fmt = wm8961_set_fmt, @@ -1039,7 +1038,7 @@ static int wm8961_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8961_suspend(struct snd_soc_codec *codec) { wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1048,18 +1047,7 @@ static int wm8961_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm8961_resume(struct snd_soc_codec *codec) { - u16 *reg_cache = codec->reg_cache; - int i; - - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (reg_cache[i] == wm8961_reg_defaults[i]) - continue; - - if (i == WM8961_SOFTWARE_RESET) - continue; - - snd_soc_write(codec, i, reg_cache[i]); - } + snd_soc_cache_sync(codec); wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1082,14 +1070,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { .volatile_register = wm8961_volatile_register, }; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8961_priv *wm8961; int ret; - wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL); + wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv), + GFP_KERNEL); if (wm8961 == NULL) return -ENOMEM; @@ -1097,15 +1085,14 @@ static __devinit int wm8961_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8961, &wm8961_dai, 1); - if (ret < 0) - kfree(wm8961); + return ret; } static __devexit int wm8961_i2c_remove(struct i2c_client *client) { snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + return 0; } @@ -1117,34 +1104,29 @@ MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id); static struct i2c_driver wm8961_i2c_driver = { .driver = { - .name = "wm8961-codec", + .name = "wm8961", .owner = THIS_MODULE, }, .probe = wm8961_i2c_probe, .remove = __devexit_p(wm8961_i2c_remove), .id_table = wm8961_i2c_id, }; -#endif static int __init wm8961_modinit(void) { int ret = 0; -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&wm8961_i2c_driver); if (ret != 0) { printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n", ret); } -#endif return ret; } module_init(wm8961_modinit); static void __exit wm8961_exit(void) { -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) i2c_del_driver(&wm8961_i2c_driver); -#endif } module_exit(wm8961_exit); diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 91d3c6dbeba..296de4e30d2 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -20,7 +20,7 @@ #include <linux/gpio.h> #include <linux/i2c.h> #include <linux/input.h> -#include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/workqueue.h> @@ -50,6 +50,7 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { /* codec private data */ struct wm8962_priv { + struct regmap *regmap; struct snd_soc_codec *codec; int sysclk; @@ -95,7 +96,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \ struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - wm8962->codec->cache_sync = 1; \ + regcache_cache_only(wm8962->regmap, true); \ } \ return 0; \ } @@ -109,691 +110,691 @@ WM8962_REGULATOR_EVENT(5) WM8962_REGULATOR_EVENT(6) WM8962_REGULATOR_EVENT(7) -static const u16 wm8962_reg[WM8962_MAX_REGISTER + 1] = { - [0] = 0x009F, /* R0 - Left Input volume */ - [1] = 0x049F, /* R1 - Right Input volume */ - [2] = 0x0000, /* R2 - HPOUTL volume */ - [3] = 0x0000, /* R3 - HPOUTR volume */ - [4] = 0x0020, /* R4 - Clocking1 */ - [5] = 0x0018, /* R5 - ADC & DAC Control 1 */ - [6] = 0x2008, /* R6 - ADC & DAC Control 2 */ - [7] = 0x000A, /* R7 - Audio Interface 0 */ - [8] = 0x01E4, /* R8 - Clocking2 */ - [9] = 0x0300, /* R9 - Audio Interface 1 */ - [10] = 0x00C0, /* R10 - Left DAC volume */ - [11] = 0x00C0, /* R11 - Right DAC volume */ - - [14] = 0x0040, /* R14 - Audio Interface 2 */ - [15] = 0x6243, /* R15 - Software Reset */ - - [17] = 0x007B, /* R17 - ALC1 */ - [18] = 0x0000, /* R18 - ALC2 */ - [19] = 0x1C32, /* R19 - ALC3 */ - [20] = 0x3200, /* R20 - Noise Gate */ - [21] = 0x00C0, /* R21 - Left ADC volume */ - [22] = 0x00C0, /* R22 - Right ADC volume */ - [23] = 0x0160, /* R23 - Additional control(1) */ - [24] = 0x0000, /* R24 - Additional control(2) */ - [25] = 0x0000, /* R25 - Pwr Mgmt (1) */ - [26] = 0x0000, /* R26 - Pwr Mgmt (2) */ - [27] = 0x0010, /* R27 - Additional Control (3) */ - [28] = 0x0000, /* R28 - Anti-pop */ - - [30] = 0x005E, /* R30 - Clocking 3 */ - [31] = 0x0000, /* R31 - Input mixer control (1) */ - [32] = 0x0145, /* R32 - Left input mixer volume */ - [33] = 0x0145, /* R33 - Right input mixer volume */ - [34] = 0x0009, /* R34 - Input mixer control (2) */ - [35] = 0x0003, /* R35 - Input bias control */ - [37] = 0x0008, /* R37 - Left input PGA control */ - [38] = 0x0008, /* R38 - Right input PGA control */ - - [40] = 0x0000, /* R40 - SPKOUTL volume */ - [41] = 0x0000, /* R41 - SPKOUTR volume */ - - [47] = 0x0000, /* R47 - Thermal Shutdown Status */ - [48] = 0x8027, /* R48 - Additional Control (4) */ - [49] = 0x0010, /* R49 - Class D Control 1 */ - - [51] = 0x0003, /* R51 - Class D Control 2 */ - - [56] = 0x0506, /* R56 - Clocking 4 */ - [57] = 0x0000, /* R57 - DAC DSP Mixing (1) */ - [58] = 0x0000, /* R58 - DAC DSP Mixing (2) */ - - [60] = 0x0300, /* R60 - DC Servo 0 */ - [61] = 0x0300, /* R61 - DC Servo 1 */ - - [64] = 0x0810, /* R64 - DC Servo 4 */ - - [66] = 0x0000, /* R66 - DC Servo 6 */ - - [68] = 0x001B, /* R68 - Analogue PGA Bias */ - [69] = 0x0000, /* R69 - Analogue HP 0 */ - - [71] = 0x01FB, /* R71 - Analogue HP 2 */ - [72] = 0x0000, /* R72 - Charge Pump 1 */ - - [82] = 0x0004, /* R82 - Charge Pump B */ - - [87] = 0x0000, /* R87 - Write Sequencer Control 1 */ - - [90] = 0x0000, /* R90 - Write Sequencer Control 2 */ - - [93] = 0x0000, /* R93 - Write Sequencer Control 3 */ - [94] = 0x0000, /* R94 - Control Interface */ - - [99] = 0x0000, /* R99 - Mixer Enables */ - [100] = 0x0000, /* R100 - Headphone Mixer (1) */ - [101] = 0x0000, /* R101 - Headphone Mixer (2) */ - [102] = 0x013F, /* R102 - Headphone Mixer (3) */ - [103] = 0x013F, /* R103 - Headphone Mixer (4) */ - - [105] = 0x0000, /* R105 - Speaker Mixer (1) */ - [106] = 0x0000, /* R106 - Speaker Mixer (2) */ - [107] = 0x013F, /* R107 - Speaker Mixer (3) */ - [108] = 0x013F, /* R108 - Speaker Mixer (4) */ - [109] = 0x0003, /* R109 - Speaker Mixer (5) */ - [110] = 0x0002, /* R110 - Beep Generator (1) */ - - [115] = 0x0006, /* R115 - Oscillator Trim (3) */ - [116] = 0x0026, /* R116 - Oscillator Trim (4) */ - - [119] = 0x0000, /* R119 - Oscillator Trim (7) */ - - [124] = 0x0011, /* R124 - Analogue Clocking1 */ - [125] = 0x004B, /* R125 - Analogue Clocking2 */ - [126] = 0x000D, /* R126 - Analogue Clocking3 */ - [127] = 0x0000, /* R127 - PLL Software Reset */ - - [129] = 0x0000, /* R129 - PLL2 */ - - [131] = 0x0000, /* R131 - PLL 4 */ - - [136] = 0x0067, /* R136 - PLL 9 */ - [137] = 0x001C, /* R137 - PLL 10 */ - [138] = 0x0071, /* R138 - PLL 11 */ - [139] = 0x00C7, /* R139 - PLL 12 */ - [140] = 0x0067, /* R140 - PLL 13 */ - [141] = 0x0048, /* R141 - PLL 14 */ - [142] = 0x0022, /* R142 - PLL 15 */ - [143] = 0x0097, /* R143 - PLL 16 */ - - [155] = 0x000C, /* R155 - FLL Control (1) */ - [156] = 0x0039, /* R156 - FLL Control (2) */ - [157] = 0x0180, /* R157 - FLL Control (3) */ - - [159] = 0x0032, /* R159 - FLL Control (5) */ - [160] = 0x0018, /* R160 - FLL Control (6) */ - [161] = 0x007D, /* R161 - FLL Control (7) */ - [162] = 0x0008, /* R162 - FLL Control (8) */ - - [252] = 0x0005, /* R252 - General test 1 */ - - [256] = 0x0000, /* R256 - DF1 */ - [257] = 0x0000, /* R257 - DF2 */ - [258] = 0x0000, /* R258 - DF3 */ - [259] = 0x0000, /* R259 - DF4 */ - [260] = 0x0000, /* R260 - DF5 */ - [261] = 0x0000, /* R261 - DF6 */ - [262] = 0x0000, /* R262 - DF7 */ - - [264] = 0x0000, /* R264 - LHPF1 */ - [265] = 0x0000, /* R265 - LHPF2 */ - - [268] = 0x0000, /* R268 - THREED1 */ - [269] = 0x0000, /* R269 - THREED2 */ - [270] = 0x0000, /* R270 - THREED3 */ - [271] = 0x0000, /* R271 - THREED4 */ - - [276] = 0x000C, /* R276 - DRC 1 */ - [277] = 0x0925, /* R277 - DRC 2 */ - [278] = 0x0000, /* R278 - DRC 3 */ - [279] = 0x0000, /* R279 - DRC 4 */ - [280] = 0x0000, /* R280 - DRC 5 */ - - [285] = 0x0000, /* R285 - Tloopback */ - - [335] = 0x0004, /* R335 - EQ1 */ - [336] = 0x6318, /* R336 - EQ2 */ - [337] = 0x6300, /* R337 - EQ3 */ - [338] = 0x0FCA, /* R338 - EQ4 */ - [339] = 0x0400, /* R339 - EQ5 */ - [340] = 0x00D8, /* R340 - EQ6 */ - [341] = 0x1EB5, /* R341 - EQ7 */ - [342] = 0xF145, /* R342 - EQ8 */ - [343] = 0x0B75, /* R343 - EQ9 */ - [344] = 0x01C5, /* R344 - EQ10 */ - [345] = 0x1C58, /* R345 - EQ11 */ - [346] = 0xF373, /* R346 - EQ12 */ - [347] = 0x0A54, /* R347 - EQ13 */ - [348] = 0x0558, /* R348 - EQ14 */ - [349] = 0x168E, /* R349 - EQ15 */ - [350] = 0xF829, /* R350 - EQ16 */ - [351] = 0x07AD, /* R351 - EQ17 */ - [352] = 0x1103, /* R352 - EQ18 */ - [353] = 0x0564, /* R353 - EQ19 */ - [354] = 0x0559, /* R354 - EQ20 */ - [355] = 0x4000, /* R355 - EQ21 */ - [356] = 0x6318, /* R356 - EQ22 */ - [357] = 0x6300, /* R357 - EQ23 */ - [358] = 0x0FCA, /* R358 - EQ24 */ - [359] = 0x0400, /* R359 - EQ25 */ - [360] = 0x00D8, /* R360 - EQ26 */ - [361] = 0x1EB5, /* R361 - EQ27 */ - [362] = 0xF145, /* R362 - EQ28 */ - [363] = 0x0B75, /* R363 - EQ29 */ - [364] = 0x01C5, /* R364 - EQ30 */ - [365] = 0x1C58, /* R365 - EQ31 */ - [366] = 0xF373, /* R366 - EQ32 */ - [367] = 0x0A54, /* R367 - EQ33 */ - [368] = 0x0558, /* R368 - EQ34 */ - [369] = 0x168E, /* R369 - EQ35 */ - [370] = 0xF829, /* R370 - EQ36 */ - [371] = 0x07AD, /* R371 - EQ37 */ - [372] = 0x1103, /* R372 - EQ38 */ - [373] = 0x0564, /* R373 - EQ39 */ - [374] = 0x0559, /* R374 - EQ40 */ - [375] = 0x4000, /* R375 - EQ41 */ - - [513] = 0x0000, /* R513 - GPIO 2 */ - [514] = 0x0000, /* R514 - GPIO 3 */ - - [516] = 0x8100, /* R516 - GPIO 5 */ - [517] = 0x8100, /* R517 - GPIO 6 */ - - [560] = 0x0000, /* R560 - Interrupt Status 1 */ - [561] = 0x0000, /* R561 - Interrupt Status 2 */ - - [568] = 0x0030, /* R568 - Interrupt Status 1 Mask */ - [569] = 0xFFED, /* R569 - Interrupt Status 2 Mask */ - - [576] = 0x0000, /* R576 - Interrupt Control */ - - [584] = 0x002D, /* R584 - IRQ Debounce */ - - [586] = 0x0000, /* R586 - MICINT Source Pol */ - - [768] = 0x1C00, /* R768 - DSP2 Power Management */ - - [1037] = 0x0000, /* R1037 - DSP2_ExecControl */ - - [8192] = 0x0000, /* R8192 - DSP2 Instruction RAM 0 */ - - [9216] = 0x0030, /* R9216 - DSP2 Address RAM 2 */ - [9217] = 0x0000, /* R9217 - DSP2 Address RAM 1 */ - [9218] = 0x0000, /* R9218 - DSP2 Address RAM 0 */ - - [12288] = 0x0000, /* R12288 - DSP2 Data1 RAM 1 */ - [12289] = 0x0000, /* R12289 - DSP2 Data1 RAM 0 */ - - [13312] = 0x0000, /* R13312 - DSP2 Data2 RAM 1 */ - [13313] = 0x0000, /* R13313 - DSP2 Data2 RAM 0 */ - - [14336] = 0x0000, /* R14336 - DSP2 Data3 RAM 1 */ - [14337] = 0x0000, /* R14337 - DSP2 Data3 RAM 0 */ - - [15360] = 0x000A, /* R15360 - DSP2 Coeff RAM 0 */ - - [16384] = 0x0000, /* R16384 - RETUNEADC_SHARED_COEFF_1 */ - [16385] = 0x0000, /* R16385 - RETUNEADC_SHARED_COEFF_0 */ - [16386] = 0x0000, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */ - [16387] = 0x0000, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */ - [16388] = 0x0000, /* R16388 - SOUNDSTAGE_ENABLES_1 */ - [16389] = 0x0000, /* R16389 - SOUNDSTAGE_ENABLES_0 */ - - [16896] = 0x0002, /* R16896 - HDBASS_AI_1 */ - [16897] = 0xBD12, /* R16897 - HDBASS_AI_0 */ - [16898] = 0x007C, /* R16898 - HDBASS_AR_1 */ - [16899] = 0x586C, /* R16899 - HDBASS_AR_0 */ - [16900] = 0x0053, /* R16900 - HDBASS_B_1 */ - [16901] = 0x8121, /* R16901 - HDBASS_B_0 */ - [16902] = 0x003F, /* R16902 - HDBASS_K_1 */ - [16903] = 0x8BD8, /* R16903 - HDBASS_K_0 */ - [16904] = 0x0032, /* R16904 - HDBASS_N1_1 */ - [16905] = 0xF52D, /* R16905 - HDBASS_N1_0 */ - [16906] = 0x0065, /* R16906 - HDBASS_N2_1 */ - [16907] = 0xAC8C, /* R16907 - HDBASS_N2_0 */ - [16908] = 0x006B, /* R16908 - HDBASS_N3_1 */ - [16909] = 0xE087, /* R16909 - HDBASS_N3_0 */ - [16910] = 0x0072, /* R16910 - HDBASS_N4_1 */ - [16911] = 0x1483, /* R16911 - HDBASS_N4_0 */ - [16912] = 0x0072, /* R16912 - HDBASS_N5_1 */ - [16913] = 0x1483, /* R16913 - HDBASS_N5_0 */ - [16914] = 0x0043, /* R16914 - HDBASS_X1_1 */ - [16915] = 0x3525, /* R16915 - HDBASS_X1_0 */ - [16916] = 0x0006, /* R16916 - HDBASS_X2_1 */ - [16917] = 0x6A4A, /* R16917 - HDBASS_X2_0 */ - [16918] = 0x0043, /* R16918 - HDBASS_X3_1 */ - [16919] = 0x6079, /* R16919 - HDBASS_X3_0 */ - [16920] = 0x0008, /* R16920 - HDBASS_ATK_1 */ - [16921] = 0x0000, /* R16921 - HDBASS_ATK_0 */ - [16922] = 0x0001, /* R16922 - HDBASS_DCY_1 */ - [16923] = 0x0000, /* R16923 - HDBASS_DCY_0 */ - [16924] = 0x0059, /* R16924 - HDBASS_PG_1 */ - [16925] = 0x999A, /* R16925 - HDBASS_PG_0 */ - - [17048] = 0x0083, /* R17408 - HPF_C_1 */ - [17049] = 0x98AD, /* R17409 - HPF_C_0 */ - - [17920] = 0x007F, /* R17920 - ADCL_RETUNE_C1_1 */ - [17921] = 0xFFFF, /* R17921 - ADCL_RETUNE_C1_0 */ - [17922] = 0x0000, /* R17922 - ADCL_RETUNE_C2_1 */ - [17923] = 0x0000, /* R17923 - ADCL_RETUNE_C2_0 */ - [17924] = 0x0000, /* R17924 - ADCL_RETUNE_C3_1 */ - [17925] = 0x0000, /* R17925 - ADCL_RETUNE_C3_0 */ - [17926] = 0x0000, /* R17926 - ADCL_RETUNE_C4_1 */ - [17927] = 0x0000, /* R17927 - ADCL_RETUNE_C4_0 */ - [17928] = 0x0000, /* R17928 - ADCL_RETUNE_C5_1 */ - [17929] = 0x0000, /* R17929 - ADCL_RETUNE_C5_0 */ - [17930] = 0x0000, /* R17930 - ADCL_RETUNE_C6_1 */ - [17931] = 0x0000, /* R17931 - ADCL_RETUNE_C6_0 */ - [17932] = 0x0000, /* R17932 - ADCL_RETUNE_C7_1 */ - [17933] = 0x0000, /* R17933 - ADCL_RETUNE_C7_0 */ - [17934] = 0x0000, /* R17934 - ADCL_RETUNE_C8_1 */ - [17935] = 0x0000, /* R17935 - ADCL_RETUNE_C8_0 */ - [17936] = 0x0000, /* R17936 - ADCL_RETUNE_C9_1 */ - [17937] = 0x0000, /* R17937 - ADCL_RETUNE_C9_0 */ - [17938] = 0x0000, /* R17938 - ADCL_RETUNE_C10_1 */ - [17939] = 0x0000, /* R17939 - ADCL_RETUNE_C10_0 */ - [17940] = 0x0000, /* R17940 - ADCL_RETUNE_C11_1 */ - [17941] = 0x0000, /* R17941 - ADCL_RETUNE_C11_0 */ - [17942] = 0x0000, /* R17942 - ADCL_RETUNE_C12_1 */ - [17943] = 0x0000, /* R17943 - ADCL_RETUNE_C12_0 */ - [17944] = 0x0000, /* R17944 - ADCL_RETUNE_C13_1 */ - [17945] = 0x0000, /* R17945 - ADCL_RETUNE_C13_0 */ - [17946] = 0x0000, /* R17946 - ADCL_RETUNE_C14_1 */ - [17947] = 0x0000, /* R17947 - ADCL_RETUNE_C14_0 */ - [17948] = 0x0000, /* R17948 - ADCL_RETUNE_C15_1 */ - [17949] = 0x0000, /* R17949 - ADCL_RETUNE_C15_0 */ - [17950] = 0x0000, /* R17950 - ADCL_RETUNE_C16_1 */ - [17951] = 0x0000, /* R17951 - ADCL_RETUNE_C16_0 */ - [17952] = 0x0000, /* R17952 - ADCL_RETUNE_C17_1 */ - [17953] = 0x0000, /* R17953 - ADCL_RETUNE_C17_0 */ - [17954] = 0x0000, /* R17954 - ADCL_RETUNE_C18_1 */ - [17955] = 0x0000, /* R17955 - ADCL_RETUNE_C18_0 */ - [17956] = 0x0000, /* R17956 - ADCL_RETUNE_C19_1 */ - [17957] = 0x0000, /* R17957 - ADCL_RETUNE_C19_0 */ - [17958] = 0x0000, /* R17958 - ADCL_RETUNE_C20_1 */ - [17959] = 0x0000, /* R17959 - ADCL_RETUNE_C20_0 */ - [17960] = 0x0000, /* R17960 - ADCL_RETUNE_C21_1 */ - [17961] = 0x0000, /* R17961 - ADCL_RETUNE_C21_0 */ - [17962] = 0x0000, /* R17962 - ADCL_RETUNE_C22_1 */ - [17963] = 0x0000, /* R17963 - ADCL_RETUNE_C22_0 */ - [17964] = 0x0000, /* R17964 - ADCL_RETUNE_C23_1 */ - [17965] = 0x0000, /* R17965 - ADCL_RETUNE_C23_0 */ - [17966] = 0x0000, /* R17966 - ADCL_RETUNE_C24_1 */ - [17967] = 0x0000, /* R17967 - ADCL_RETUNE_C24_0 */ - [17968] = 0x0000, /* R17968 - ADCL_RETUNE_C25_1 */ - [17969] = 0x0000, /* R17969 - ADCL_RETUNE_C25_0 */ - [17970] = 0x0000, /* R17970 - ADCL_RETUNE_C26_1 */ - [17971] = 0x0000, /* R17971 - ADCL_RETUNE_C26_0 */ - [17972] = 0x0000, /* R17972 - ADCL_RETUNE_C27_1 */ - [17973] = 0x0000, /* R17973 - ADCL_RETUNE_C27_0 */ - [17974] = 0x0000, /* R17974 - ADCL_RETUNE_C28_1 */ - [17975] = 0x0000, /* R17975 - ADCL_RETUNE_C28_0 */ - [17976] = 0x0000, /* R17976 - ADCL_RETUNE_C29_1 */ - [17977] = 0x0000, /* R17977 - ADCL_RETUNE_C29_0 */ - [17978] = 0x0000, /* R17978 - ADCL_RETUNE_C30_1 */ - [17979] = 0x0000, /* R17979 - ADCL_RETUNE_C30_0 */ - [17980] = 0x0000, /* R17980 - ADCL_RETUNE_C31_1 */ - [17981] = 0x0000, /* R17981 - ADCL_RETUNE_C31_0 */ - [17982] = 0x0000, /* R17982 - ADCL_RETUNE_C32_1 */ - [17983] = 0x0000, /* R17983 - ADCL_RETUNE_C32_0 */ - - [18432] = 0x0020, /* R18432 - RETUNEADC_PG2_1 */ - [18433] = 0x0000, /* R18433 - RETUNEADC_PG2_0 */ - [18434] = 0x0040, /* R18434 - RETUNEADC_PG_1 */ - [18435] = 0x0000, /* R18435 - RETUNEADC_PG_0 */ - - [18944] = 0x007F, /* R18944 - ADCR_RETUNE_C1_1 */ - [18945] = 0xFFFF, /* R18945 - ADCR_RETUNE_C1_0 */ - [18946] = 0x0000, /* R18946 - ADCR_RETUNE_C2_1 */ - [18947] = 0x0000, /* R18947 - ADCR_RETUNE_C2_0 */ - [18948] = 0x0000, /* R18948 - ADCR_RETUNE_C3_1 */ - [18949] = 0x0000, /* R18949 - ADCR_RETUNE_C3_0 */ - [18950] = 0x0000, /* R18950 - ADCR_RETUNE_C4_1 */ - [18951] = 0x0000, /* R18951 - ADCR_RETUNE_C4_0 */ - [18952] = 0x0000, /* R18952 - ADCR_RETUNE_C5_1 */ - [18953] = 0x0000, /* R18953 - ADCR_RETUNE_C5_0 */ - [18954] = 0x0000, /* R18954 - ADCR_RETUNE_C6_1 */ - [18955] = 0x0000, /* R18955 - ADCR_RETUNE_C6_0 */ - [18956] = 0x0000, /* R18956 - ADCR_RETUNE_C7_1 */ - [18957] = 0x0000, /* R18957 - ADCR_RETUNE_C7_0 */ - [18958] = 0x0000, /* R18958 - ADCR_RETUNE_C8_1 */ - [18959] = 0x0000, /* R18959 - ADCR_RETUNE_C8_0 */ - [18960] = 0x0000, /* R18960 - ADCR_RETUNE_C9_1 */ - [18961] = 0x0000, /* R18961 - ADCR_RETUNE_C9_0 */ - [18962] = 0x0000, /* R18962 - ADCR_RETUNE_C10_1 */ - [18963] = 0x0000, /* R18963 - ADCR_RETUNE_C10_0 */ - [18964] = 0x0000, /* R18964 - ADCR_RETUNE_C11_1 */ - [18965] = 0x0000, /* R18965 - ADCR_RETUNE_C11_0 */ - [18966] = 0x0000, /* R18966 - ADCR_RETUNE_C12_1 */ - [18967] = 0x0000, /* R18967 - ADCR_RETUNE_C12_0 */ - [18968] = 0x0000, /* R18968 - ADCR_RETUNE_C13_1 */ - [18969] = 0x0000, /* R18969 - ADCR_RETUNE_C13_0 */ - [18970] = 0x0000, /* R18970 - ADCR_RETUNE_C14_1 */ - [18971] = 0x0000, /* R18971 - ADCR_RETUNE_C14_0 */ - [18972] = 0x0000, /* R18972 - ADCR_RETUNE_C15_1 */ - [18973] = 0x0000, /* R18973 - ADCR_RETUNE_C15_0 */ - [18974] = 0x0000, /* R18974 - ADCR_RETUNE_C16_1 */ - [18975] = 0x0000, /* R18975 - ADCR_RETUNE_C16_0 */ - [18976] = 0x0000, /* R18976 - ADCR_RETUNE_C17_1 */ - [18977] = 0x0000, /* R18977 - ADCR_RETUNE_C17_0 */ - [18978] = 0x0000, /* R18978 - ADCR_RETUNE_C18_1 */ - [18979] = 0x0000, /* R18979 - ADCR_RETUNE_C18_0 */ - [18980] = 0x0000, /* R18980 - ADCR_RETUNE_C19_1 */ - [18981] = 0x0000, /* R18981 - ADCR_RETUNE_C19_0 */ - [18982] = 0x0000, /* R18982 - ADCR_RETUNE_C20_1 */ - [18983] = 0x0000, /* R18983 - ADCR_RETUNE_C20_0 */ - [18984] = 0x0000, /* R18984 - ADCR_RETUNE_C21_1 */ - [18985] = 0x0000, /* R18985 - ADCR_RETUNE_C21_0 */ - [18986] = 0x0000, /* R18986 - ADCR_RETUNE_C22_1 */ - [18987] = 0x0000, /* R18987 - ADCR_RETUNE_C22_0 */ - [18988] = 0x0000, /* R18988 - ADCR_RETUNE_C23_1 */ - [18989] = 0x0000, /* R18989 - ADCR_RETUNE_C23_0 */ - [18990] = 0x0000, /* R18990 - ADCR_RETUNE_C24_1 */ - [18991] = 0x0000, /* R18991 - ADCR_RETUNE_C24_0 */ - [18992] = 0x0000, /* R18992 - ADCR_RETUNE_C25_1 */ - [18993] = 0x0000, /* R18993 - ADCR_RETUNE_C25_0 */ - [18994] = 0x0000, /* R18994 - ADCR_RETUNE_C26_1 */ - [18995] = 0x0000, /* R18995 - ADCR_RETUNE_C26_0 */ - [18996] = 0x0000, /* R18996 - ADCR_RETUNE_C27_1 */ - [18997] = 0x0000, /* R18997 - ADCR_RETUNE_C27_0 */ - [18998] = 0x0000, /* R18998 - ADCR_RETUNE_C28_1 */ - [18999] = 0x0000, /* R18999 - ADCR_RETUNE_C28_0 */ - [19000] = 0x0000, /* R19000 - ADCR_RETUNE_C29_1 */ - [19001] = 0x0000, /* R19001 - ADCR_RETUNE_C29_0 */ - [19002] = 0x0000, /* R19002 - ADCR_RETUNE_C30_1 */ - [19003] = 0x0000, /* R19003 - ADCR_RETUNE_C30_0 */ - [19004] = 0x0000, /* R19004 - ADCR_RETUNE_C31_1 */ - [19005] = 0x0000, /* R19005 - ADCR_RETUNE_C31_0 */ - [19006] = 0x0000, /* R19006 - ADCR_RETUNE_C32_1 */ - [19007] = 0x0000, /* R19007 - ADCR_RETUNE_C32_0 */ - - [19456] = 0x007F, /* R19456 - DACL_RETUNE_C1_1 */ - [19457] = 0xFFFF, /* R19457 - DACL_RETUNE_C1_0 */ - [19458] = 0x0000, /* R19458 - DACL_RETUNE_C2_1 */ - [19459] = 0x0000, /* R19459 - DACL_RETUNE_C2_0 */ - [19460] = 0x0000, /* R19460 - DACL_RETUNE_C3_1 */ - [19461] = 0x0000, /* R19461 - DACL_RETUNE_C3_0 */ - [19462] = 0x0000, /* R19462 - DACL_RETUNE_C4_1 */ - [19463] = 0x0000, /* R19463 - DACL_RETUNE_C4_0 */ - [19464] = 0x0000, /* R19464 - DACL_RETUNE_C5_1 */ - [19465] = 0x0000, /* R19465 - DACL_RETUNE_C5_0 */ - [19466] = 0x0000, /* R19466 - DACL_RETUNE_C6_1 */ - [19467] = 0x0000, /* R19467 - DACL_RETUNE_C6_0 */ - [19468] = 0x0000, /* R19468 - DACL_RETUNE_C7_1 */ - [19469] = 0x0000, /* R19469 - DACL_RETUNE_C7_0 */ - [19470] = 0x0000, /* R19470 - DACL_RETUNE_C8_1 */ - [19471] = 0x0000, /* R19471 - DACL_RETUNE_C8_0 */ - [19472] = 0x0000, /* R19472 - DACL_RETUNE_C9_1 */ - [19473] = 0x0000, /* R19473 - DACL_RETUNE_C9_0 */ - [19474] = 0x0000, /* R19474 - DACL_RETUNE_C10_1 */ - [19475] = 0x0000, /* R19475 - DACL_RETUNE_C10_0 */ - [19476] = 0x0000, /* R19476 - DACL_RETUNE_C11_1 */ - [19477] = 0x0000, /* R19477 - DACL_RETUNE_C11_0 */ - [19478] = 0x0000, /* R19478 - DACL_RETUNE_C12_1 */ - [19479] = 0x0000, /* R19479 - DACL_RETUNE_C12_0 */ - [19480] = 0x0000, /* R19480 - DACL_RETUNE_C13_1 */ - [19481] = 0x0000, /* R19481 - DACL_RETUNE_C13_0 */ - [19482] = 0x0000, /* R19482 - DACL_RETUNE_C14_1 */ - [19483] = 0x0000, /* R19483 - DACL_RETUNE_C14_0 */ - [19484] = 0x0000, /* R19484 - DACL_RETUNE_C15_1 */ - [19485] = 0x0000, /* R19485 - DACL_RETUNE_C15_0 */ - [19486] = 0x0000, /* R19486 - DACL_RETUNE_C16_1 */ - [19487] = 0x0000, /* R19487 - DACL_RETUNE_C16_0 */ - [19488] = 0x0000, /* R19488 - DACL_RETUNE_C17_1 */ - [19489] = 0x0000, /* R19489 - DACL_RETUNE_C17_0 */ - [19490] = 0x0000, /* R19490 - DACL_RETUNE_C18_1 */ - [19491] = 0x0000, /* R19491 - DACL_RETUNE_C18_0 */ - [19492] = 0x0000, /* R19492 - DACL_RETUNE_C19_1 */ - [19493] = 0x0000, /* R19493 - DACL_RETUNE_C19_0 */ - [19494] = 0x0000, /* R19494 - DACL_RETUNE_C20_1 */ - [19495] = 0x0000, /* R19495 - DACL_RETUNE_C20_0 */ - [19496] = 0x0000, /* R19496 - DACL_RETUNE_C21_1 */ - [19497] = 0x0000, /* R19497 - DACL_RETUNE_C21_0 */ - [19498] = 0x0000, /* R19498 - DACL_RETUNE_C22_1 */ - [19499] = 0x0000, /* R19499 - DACL_RETUNE_C22_0 */ - [19500] = 0x0000, /* R19500 - DACL_RETUNE_C23_1 */ - [19501] = 0x0000, /* R19501 - DACL_RETUNE_C23_0 */ - [19502] = 0x0000, /* R19502 - DACL_RETUNE_C24_1 */ - [19503] = 0x0000, /* R19503 - DACL_RETUNE_C24_0 */ - [19504] = 0x0000, /* R19504 - DACL_RETUNE_C25_1 */ - [19505] = 0x0000, /* R19505 - DACL_RETUNE_C25_0 */ - [19506] = 0x0000, /* R19506 - DACL_RETUNE_C26_1 */ - [19507] = 0x0000, /* R19507 - DACL_RETUNE_C26_0 */ - [19508] = 0x0000, /* R19508 - DACL_RETUNE_C27_1 */ - [19509] = 0x0000, /* R19509 - DACL_RETUNE_C27_0 */ - [19510] = 0x0000, /* R19510 - DACL_RETUNE_C28_1 */ - [19511] = 0x0000, /* R19511 - DACL_RETUNE_C28_0 */ - [19512] = 0x0000, /* R19512 - DACL_RETUNE_C29_1 */ - [19513] = 0x0000, /* R19513 - DACL_RETUNE_C29_0 */ - [19514] = 0x0000, /* R19514 - DACL_RETUNE_C30_1 */ - [19515] = 0x0000, /* R19515 - DACL_RETUNE_C30_0 */ - [19516] = 0x0000, /* R19516 - DACL_RETUNE_C31_1 */ - [19517] = 0x0000, /* R19517 - DACL_RETUNE_C31_0 */ - [19518] = 0x0000, /* R19518 - DACL_RETUNE_C32_1 */ - [19519] = 0x0000, /* R19519 - DACL_RETUNE_C32_0 */ - - [19968] = 0x0020, /* R19968 - RETUNEDAC_PG2_1 */ - [19969] = 0x0000, /* R19969 - RETUNEDAC_PG2_0 */ - [19970] = 0x0040, /* R19970 - RETUNEDAC_PG_1 */ - [19971] = 0x0000, /* R19971 - RETUNEDAC_PG_0 */ - - [20480] = 0x007F, /* R20480 - DACR_RETUNE_C1_1 */ - [20481] = 0xFFFF, /* R20481 - DACR_RETUNE_C1_0 */ - [20482] = 0x0000, /* R20482 - DACR_RETUNE_C2_1 */ - [20483] = 0x0000, /* R20483 - DACR_RETUNE_C2_0 */ - [20484] = 0x0000, /* R20484 - DACR_RETUNE_C3_1 */ - [20485] = 0x0000, /* R20485 - DACR_RETUNE_C3_0 */ - [20486] = 0x0000, /* R20486 - DACR_RETUNE_C4_1 */ - [20487] = 0x0000, /* R20487 - DACR_RETUNE_C4_0 */ - [20488] = 0x0000, /* R20488 - DACR_RETUNE_C5_1 */ - [20489] = 0x0000, /* R20489 - DACR_RETUNE_C5_0 */ - [20490] = 0x0000, /* R20490 - DACR_RETUNE_C6_1 */ - [20491] = 0x0000, /* R20491 - DACR_RETUNE_C6_0 */ - [20492] = 0x0000, /* R20492 - DACR_RETUNE_C7_1 */ - [20493] = 0x0000, /* R20493 - DACR_RETUNE_C7_0 */ - [20494] = 0x0000, /* R20494 - DACR_RETUNE_C8_1 */ - [20495] = 0x0000, /* R20495 - DACR_RETUNE_C8_0 */ - [20496] = 0x0000, /* R20496 - DACR_RETUNE_C9_1 */ - [20497] = 0x0000, /* R20497 - DACR_RETUNE_C9_0 */ - [20498] = 0x0000, /* R20498 - DACR_RETUNE_C10_1 */ - [20499] = 0x0000, /* R20499 - DACR_RETUNE_C10_0 */ - [20500] = 0x0000, /* R20500 - DACR_RETUNE_C11_1 */ - [20501] = 0x0000, /* R20501 - DACR_RETUNE_C11_0 */ - [20502] = 0x0000, /* R20502 - DACR_RETUNE_C12_1 */ - [20503] = 0x0000, /* R20503 - DACR_RETUNE_C12_0 */ - [20504] = 0x0000, /* R20504 - DACR_RETUNE_C13_1 */ - [20505] = 0x0000, /* R20505 - DACR_RETUNE_C13_0 */ - [20506] = 0x0000, /* R20506 - DACR_RETUNE_C14_1 */ - [20507] = 0x0000, /* R20507 - DACR_RETUNE_C14_0 */ - [20508] = 0x0000, /* R20508 - DACR_RETUNE_C15_1 */ - [20509] = 0x0000, /* R20509 - DACR_RETUNE_C15_0 */ - [20510] = 0x0000, /* R20510 - DACR_RETUNE_C16_1 */ - [20511] = 0x0000, /* R20511 - DACR_RETUNE_C16_0 */ - [20512] = 0x0000, /* R20512 - DACR_RETUNE_C17_1 */ - [20513] = 0x0000, /* R20513 - DACR_RETUNE_C17_0 */ - [20514] = 0x0000, /* R20514 - DACR_RETUNE_C18_1 */ - [20515] = 0x0000, /* R20515 - DACR_RETUNE_C18_0 */ - [20516] = 0x0000, /* R20516 - DACR_RETUNE_C19_1 */ - [20517] = 0x0000, /* R20517 - DACR_RETUNE_C19_0 */ - [20518] = 0x0000, /* R20518 - DACR_RETUNE_C20_1 */ - [20519] = 0x0000, /* R20519 - DACR_RETUNE_C20_0 */ - [20520] = 0x0000, /* R20520 - DACR_RETUNE_C21_1 */ - [20521] = 0x0000, /* R20521 - DACR_RETUNE_C21_0 */ - [20522] = 0x0000, /* R20522 - DACR_RETUNE_C22_1 */ - [20523] = 0x0000, /* R20523 - DACR_RETUNE_C22_0 */ - [20524] = 0x0000, /* R20524 - DACR_RETUNE_C23_1 */ - [20525] = 0x0000, /* R20525 - DACR_RETUNE_C23_0 */ - [20526] = 0x0000, /* R20526 - DACR_RETUNE_C24_1 */ - [20527] = 0x0000, /* R20527 - DACR_RETUNE_C24_0 */ - [20528] = 0x0000, /* R20528 - DACR_RETUNE_C25_1 */ - [20529] = 0x0000, /* R20529 - DACR_RETUNE_C25_0 */ - [20530] = 0x0000, /* R20530 - DACR_RETUNE_C26_1 */ - [20531] = 0x0000, /* R20531 - DACR_RETUNE_C26_0 */ - [20532] = 0x0000, /* R20532 - DACR_RETUNE_C27_1 */ - [20533] = 0x0000, /* R20533 - DACR_RETUNE_C27_0 */ - [20534] = 0x0000, /* R20534 - DACR_RETUNE_C28_1 */ - [20535] = 0x0000, /* R20535 - DACR_RETUNE_C28_0 */ - [20536] = 0x0000, /* R20536 - DACR_RETUNE_C29_1 */ - [20537] = 0x0000, /* R20537 - DACR_RETUNE_C29_0 */ - [20538] = 0x0000, /* R20538 - DACR_RETUNE_C30_1 */ - [20539] = 0x0000, /* R20539 - DACR_RETUNE_C30_0 */ - [20540] = 0x0000, /* R20540 - DACR_RETUNE_C31_1 */ - [20541] = 0x0000, /* R20541 - DACR_RETUNE_C31_0 */ - [20542] = 0x0000, /* R20542 - DACR_RETUNE_C32_1 */ - [20543] = 0x0000, /* R20543 - DACR_RETUNE_C32_0 */ - - [20992] = 0x008C, /* R20992 - VSS_XHD2_1 */ - [20993] = 0x0200, /* R20993 - VSS_XHD2_0 */ - [20994] = 0x0035, /* R20994 - VSS_XHD3_1 */ - [20995] = 0x0700, /* R20995 - VSS_XHD3_0 */ - [20996] = 0x003A, /* R20996 - VSS_XHN1_1 */ - [20997] = 0x4100, /* R20997 - VSS_XHN1_0 */ - [20998] = 0x008B, /* R20998 - VSS_XHN2_1 */ - [20999] = 0x7D00, /* R20999 - VSS_XHN2_0 */ - [21000] = 0x003A, /* R21000 - VSS_XHN3_1 */ - [21001] = 0x4100, /* R21001 - VSS_XHN3_0 */ - [21002] = 0x008C, /* R21002 - VSS_XLA_1 */ - [21003] = 0xFEE8, /* R21003 - VSS_XLA_0 */ - [21004] = 0x0078, /* R21004 - VSS_XLB_1 */ - [21005] = 0x0000, /* R21005 - VSS_XLB_0 */ - [21006] = 0x003F, /* R21006 - VSS_XLG_1 */ - [21007] = 0xB260, /* R21007 - VSS_XLG_0 */ - [21008] = 0x002D, /* R21008 - VSS_PG2_1 */ - [21009] = 0x1818, /* R21009 - VSS_PG2_0 */ - [21010] = 0x0020, /* R21010 - VSS_PG_1 */ - [21011] = 0x0000, /* R21011 - VSS_PG_0 */ - [21012] = 0x00F1, /* R21012 - VSS_XTD1_1 */ - [21013] = 0x8340, /* R21013 - VSS_XTD1_0 */ - [21014] = 0x00FB, /* R21014 - VSS_XTD2_1 */ - [21015] = 0x8300, /* R21015 - VSS_XTD2_0 */ - [21016] = 0x00EE, /* R21016 - VSS_XTD3_1 */ - [21017] = 0xAEC0, /* R21017 - VSS_XTD3_0 */ - [21018] = 0x00FB, /* R21018 - VSS_XTD4_1 */ - [21019] = 0xAC40, /* R21019 - VSS_XTD4_0 */ - [21020] = 0x00F1, /* R21020 - VSS_XTD5_1 */ - [21021] = 0x7F80, /* R21021 - VSS_XTD5_0 */ - [21022] = 0x00F4, /* R21022 - VSS_XTD6_1 */ - [21023] = 0x3B40, /* R21023 - VSS_XTD6_0 */ - [21024] = 0x00F5, /* R21024 - VSS_XTD7_1 */ - [21025] = 0xFB00, /* R21025 - VSS_XTD7_0 */ - [21026] = 0x00EA, /* R21026 - VSS_XTD8_1 */ - [21027] = 0x10C0, /* R21027 - VSS_XTD8_0 */ - [21028] = 0x00FC, /* R21028 - VSS_XTD9_1 */ - [21029] = 0xC580, /* R21029 - VSS_XTD9_0 */ - [21030] = 0x00E2, /* R21030 - VSS_XTD10_1 */ - [21031] = 0x75C0, /* R21031 - VSS_XTD10_0 */ - [21032] = 0x0004, /* R21032 - VSS_XTD11_1 */ - [21033] = 0xB480, /* R21033 - VSS_XTD11_0 */ - [21034] = 0x00D4, /* R21034 - VSS_XTD12_1 */ - [21035] = 0xF980, /* R21035 - VSS_XTD12_0 */ - [21036] = 0x0004, /* R21036 - VSS_XTD13_1 */ - [21037] = 0x9140, /* R21037 - VSS_XTD13_0 */ - [21038] = 0x00D8, /* R21038 - VSS_XTD14_1 */ - [21039] = 0xA480, /* R21039 - VSS_XTD14_0 */ - [21040] = 0x0002, /* R21040 - VSS_XTD15_1 */ - [21041] = 0x3DC0, /* R21041 - VSS_XTD15_0 */ - [21042] = 0x00CF, /* R21042 - VSS_XTD16_1 */ - [21043] = 0x7A80, /* R21043 - VSS_XTD16_0 */ - [21044] = 0x00DC, /* R21044 - VSS_XTD17_1 */ - [21045] = 0x0600, /* R21045 - VSS_XTD17_0 */ - [21046] = 0x00F2, /* R21046 - VSS_XTD18_1 */ - [21047] = 0xDAC0, /* R21047 - VSS_XTD18_0 */ - [21048] = 0x00BA, /* R21048 - VSS_XTD19_1 */ - [21049] = 0xF340, /* R21049 - VSS_XTD19_0 */ - [21050] = 0x000A, /* R21050 - VSS_XTD20_1 */ - [21051] = 0x7940, /* R21051 - VSS_XTD20_0 */ - [21052] = 0x001C, /* R21052 - VSS_XTD21_1 */ - [21053] = 0x0680, /* R21053 - VSS_XTD21_0 */ - [21054] = 0x00FD, /* R21054 - VSS_XTD22_1 */ - [21055] = 0x2D00, /* R21055 - VSS_XTD22_0 */ - [21056] = 0x001C, /* R21056 - VSS_XTD23_1 */ - [21057] = 0xE840, /* R21057 - VSS_XTD23_0 */ - [21058] = 0x000D, /* R21058 - VSS_XTD24_1 */ - [21059] = 0xDC40, /* R21059 - VSS_XTD24_0 */ - [21060] = 0x00FC, /* R21060 - VSS_XTD25_1 */ - [21061] = 0x9D00, /* R21061 - VSS_XTD25_0 */ - [21062] = 0x0009, /* R21062 - VSS_XTD26_1 */ - [21063] = 0x5580, /* R21063 - VSS_XTD26_0 */ - [21064] = 0x00FE, /* R21064 - VSS_XTD27_1 */ - [21065] = 0x7E80, /* R21065 - VSS_XTD27_0 */ - [21066] = 0x000E, /* R21066 - VSS_XTD28_1 */ - [21067] = 0xAB40, /* R21067 - VSS_XTD28_0 */ - [21068] = 0x00F9, /* R21068 - VSS_XTD29_1 */ - [21069] = 0x9880, /* R21069 - VSS_XTD29_0 */ - [21070] = 0x0009, /* R21070 - VSS_XTD30_1 */ - [21071] = 0x87C0, /* R21071 - VSS_XTD30_0 */ - [21072] = 0x00FD, /* R21072 - VSS_XTD31_1 */ - [21073] = 0x2C40, /* R21073 - VSS_XTD31_0 */ - [21074] = 0x0009, /* R21074 - VSS_XTD32_1 */ - [21075] = 0x4800, /* R21075 - VSS_XTD32_0 */ - [21076] = 0x0003, /* R21076 - VSS_XTS1_1 */ - [21077] = 0x5F40, /* R21077 - VSS_XTS1_0 */ - [21078] = 0x0000, /* R21078 - VSS_XTS2_1 */ - [21079] = 0x8700, /* R21079 - VSS_XTS2_0 */ - [21080] = 0x00FA, /* R21080 - VSS_XTS3_1 */ - [21081] = 0xE4C0, /* R21081 - VSS_XTS3_0 */ - [21082] = 0x0000, /* R21082 - VSS_XTS4_1 */ - [21083] = 0x0B40, /* R21083 - VSS_XTS4_0 */ - [21084] = 0x0004, /* R21084 - VSS_XTS5_1 */ - [21085] = 0xE180, /* R21085 - VSS_XTS5_0 */ - [21086] = 0x0001, /* R21086 - VSS_XTS6_1 */ - [21087] = 0x1F40, /* R21087 - VSS_XTS6_0 */ - [21088] = 0x00F8, /* R21088 - VSS_XTS7_1 */ - [21089] = 0xB000, /* R21089 - VSS_XTS7_0 */ - [21090] = 0x00FB, /* R21090 - VSS_XTS8_1 */ - [21091] = 0xCBC0, /* R21091 - VSS_XTS8_0 */ - [21092] = 0x0004, /* R21092 - VSS_XTS9_1 */ - [21093] = 0xF380, /* R21093 - VSS_XTS9_0 */ - [21094] = 0x0007, /* R21094 - VSS_XTS10_1 */ - [21095] = 0xDF40, /* R21095 - VSS_XTS10_0 */ - [21096] = 0x00FF, /* R21096 - VSS_XTS11_1 */ - [21097] = 0x0700, /* R21097 - VSS_XTS11_0 */ - [21098] = 0x00EF, /* R21098 - VSS_XTS12_1 */ - [21099] = 0xD700, /* R21099 - VSS_XTS12_0 */ - [21100] = 0x00FB, /* R21100 - VSS_XTS13_1 */ - [21101] = 0xAF40, /* R21101 - VSS_XTS13_0 */ - [21102] = 0x0010, /* R21102 - VSS_XTS14_1 */ - [21103] = 0x8A80, /* R21103 - VSS_XTS14_0 */ - [21104] = 0x0011, /* R21104 - VSS_XTS15_1 */ - [21105] = 0x07C0, /* R21105 - VSS_XTS15_0 */ - [21106] = 0x00E0, /* R21106 - VSS_XTS16_1 */ - [21107] = 0x0800, /* R21107 - VSS_XTS16_0 */ - [21108] = 0x00D2, /* R21108 - VSS_XTS17_1 */ - [21109] = 0x7600, /* R21109 - VSS_XTS17_0 */ - [21110] = 0x0020, /* R21110 - VSS_XTS18_1 */ - [21111] = 0xCF40, /* R21111 - VSS_XTS18_0 */ - [21112] = 0x0030, /* R21112 - VSS_XTS19_1 */ - [21113] = 0x2340, /* R21113 - VSS_XTS19_0 */ - [21114] = 0x00FD, /* R21114 - VSS_XTS20_1 */ - [21115] = 0x69C0, /* R21115 - VSS_XTS20_0 */ - [21116] = 0x0028, /* R21116 - VSS_XTS21_1 */ - [21117] = 0x3500, /* R21117 - VSS_XTS21_0 */ - [21118] = 0x0006, /* R21118 - VSS_XTS22_1 */ - [21119] = 0x3300, /* R21119 - VSS_XTS22_0 */ - [21120] = 0x00D9, /* R21120 - VSS_XTS23_1 */ - [21121] = 0xF6C0, /* R21121 - VSS_XTS23_0 */ - [21122] = 0x00F3, /* R21122 - VSS_XTS24_1 */ - [21123] = 0x3340, /* R21123 - VSS_XTS24_0 */ - [21124] = 0x000F, /* R21124 - VSS_XTS25_1 */ - [21125] = 0x4200, /* R21125 - VSS_XTS25_0 */ - [21126] = 0x0004, /* R21126 - VSS_XTS26_1 */ - [21127] = 0x0C80, /* R21127 - VSS_XTS26_0 */ - [21128] = 0x00FB, /* R21128 - VSS_XTS27_1 */ - [21129] = 0x3F80, /* R21129 - VSS_XTS27_0 */ - [21130] = 0x00F7, /* R21130 - VSS_XTS28_1 */ - [21131] = 0x57C0, /* R21131 - VSS_XTS28_0 */ - [21132] = 0x0003, /* R21132 - VSS_XTS29_1 */ - [21133] = 0x5400, /* R21133 - VSS_XTS29_0 */ - [21134] = 0x0000, /* R21134 - VSS_XTS30_1 */ - [21135] = 0xC6C0, /* R21135 - VSS_XTS30_0 */ - [21136] = 0x0003, /* R21136 - VSS_XTS31_1 */ - [21137] = 0x12C0, /* R21137 - VSS_XTS31_0 */ - [21138] = 0x00FD, /* R21138 - VSS_XTS32_1 */ - [21139] = 0x8580, /* R21139 - VSS_XTS32_0 */ +static struct reg_default wm8962_reg[] = { + { 0, 0x009F }, /* R0 - Left Input volume */ + { 1, 0x049F }, /* R1 - Right Input volume */ + { 2, 0x0000 }, /* R2 - HPOUTL volume */ + { 3, 0x0000 }, /* R3 - HPOUTR volume */ + { 4, 0x0020 }, /* R4 - Clocking1 */ + { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ + { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ + { 7, 0x000A }, /* R7 - Audio Interface 0 */ + { 8, 0x01E4 }, /* R8 - Clocking2 */ + { 9, 0x0300 }, /* R9 - Audio Interface 1 */ + { 10, 0x00C0 }, /* R10 - Left DAC volume */ + { 11, 0x00C0 }, /* R11 - Right DAC volume */ + + { 14, 0x0040 }, /* R14 - Audio Interface 2 */ + { 15, 0x6243 }, /* R15 - Software Reset */ + + { 17, 0x007B }, /* R17 - ALC1 */ + { 18, 0x0000 }, /* R18 - ALC2 */ + { 19, 0x1C32 }, /* R19 - ALC3 */ + { 20, 0x3200 }, /* R20 - Noise Gate */ + { 21, 0x00C0 }, /* R21 - Left ADC volume */ + { 22, 0x00C0 }, /* R22 - Right ADC volume */ + { 23, 0x0160 }, /* R23 - Additional control(1) */ + { 24, 0x0000 }, /* R24 - Additional control(2) */ + { 25, 0x0000 }, /* R25 - Pwr Mgmt (1) */ + { 26, 0x0000 }, /* R26 - Pwr Mgmt (2) */ + { 27, 0x0010 }, /* R27 - Additional Control (3) */ + { 28, 0x0000 }, /* R28 - Anti-pop */ + + { 30, 0x005E }, /* R30 - Clocking 3 */ + { 31, 0x0000 }, /* R31 - Input mixer control (1) */ + { 32, 0x0145 }, /* R32 - Left input mixer volume */ + { 33, 0x0145 }, /* R33 - Right input mixer volume */ + { 34, 0x0009 }, /* R34 - Input mixer control (2) */ + { 35, 0x0003 }, /* R35 - Input bias control */ + { 37, 0x0008 }, /* R37 - Left input PGA control */ + { 38, 0x0008 }, /* R38 - Right input PGA control */ + + { 40, 0x0000 }, /* R40 - SPKOUTL volume */ + { 41, 0x0000 }, /* R41 - SPKOUTR volume */ + + { 47, 0x0000 }, /* R47 - Thermal Shutdown Status */ + { 48, 0x8027 }, /* R48 - Additional Control (4) */ + { 49, 0x0010 }, /* R49 - Class D Control 1 */ + + { 51, 0x0003 }, /* R51 - Class D Control 2 */ + + { 56, 0x0506 }, /* R56 - Clocking 4 */ + { 57, 0x0000 }, /* R57 - DAC DSP Mixing (1) */ + { 58, 0x0000 }, /* R58 - DAC DSP Mixing (2) */ + + { 60, 0x0300 }, /* R60 - DC Servo 0 */ + { 61, 0x0300 }, /* R61 - DC Servo 1 */ + + { 64, 0x0810 }, /* R64 - DC Servo 4 */ + + { 66, 0x0000 }, /* R66 - DC Servo 6 */ + + { 68, 0x001B }, /* R68 - Analogue PGA Bias */ + { 69, 0x0000 }, /* R69 - Analogue HP 0 */ + + { 71, 0x01FB }, /* R71 - Analogue HP 2 */ + { 72, 0x0000 }, /* R72 - Charge Pump 1 */ + + { 82, 0x0004 }, /* R82 - Charge Pump B */ + + { 87, 0x0000 }, /* R87 - Write Sequencer Control 1 */ + + { 90, 0x0000 }, /* R90 - Write Sequencer Control 2 */ + + { 93, 0x0000 }, /* R93 - Write Sequencer Control 3 */ + { 94, 0x0000 }, /* R94 - Control Interface */ + + { 99, 0x0000 }, /* R99 - Mixer Enables */ + { 100, 0x0000 }, /* R100 - Headphone Mixer (1) */ + { 101, 0x0000 }, /* R101 - Headphone Mixer (2) */ + { 102, 0x013F }, /* R102 - Headphone Mixer (3) */ + { 103, 0x013F }, /* R103 - Headphone Mixer (4) */ + + { 105, 0x0000 }, /* R105 - Speaker Mixer (1) */ + { 106, 0x0000 }, /* R106 - Speaker Mixer (2) */ + { 107, 0x013F }, /* R107 - Speaker Mixer (3) */ + { 108, 0x013F }, /* R108 - Speaker Mixer (4) */ + { 109, 0x0003 }, /* R109 - Speaker Mixer (5) */ + { 110, 0x0002 }, /* R110 - Beep Generator (1) */ + + { 115, 0x0006 }, /* R115 - Oscillator Trim (3) */ + { 116, 0x0026 }, /* R116 - Oscillator Trim (4) */ + + { 119, 0x0000 }, /* R119 - Oscillator Trim (7) */ + + { 124, 0x0011 }, /* R124 - Analogue Clocking1 */ + { 125, 0x004B }, /* R125 - Analogue Clocking2 */ + { 126, 0x000D }, /* R126 - Analogue Clocking3 */ + { 127, 0x0000 }, /* R127 - PLL Software Reset */ + + { 129, 0x0000 }, /* R129 - PLL2 */ + + { 131, 0x0000 }, /* R131 - PLL 4 */ + + { 136, 0x0067 }, /* R136 - PLL 9 */ + { 137, 0x001C }, /* R137 - PLL 10 */ + { 138, 0x0071 }, /* R138 - PLL 11 */ + { 139, 0x00C7 }, /* R139 - PLL 12 */ + { 140, 0x0067 }, /* R140 - PLL 13 */ + { 141, 0x0048 }, /* R141 - PLL 14 */ + { 142, 0x0022 }, /* R142 - PLL 15 */ + { 143, 0x0097 }, /* R143 - PLL 16 */ + + { 155, 0x000C }, /* R155 - FLL Control (1) */ + { 156, 0x0039 }, /* R156 - FLL Control (2) */ + { 157, 0x0180 }, /* R157 - FLL Control (3) */ + + { 159, 0x0032 }, /* R159 - FLL Control (5) */ + { 160, 0x0018 }, /* R160 - FLL Control (6) */ + { 161, 0x007D }, /* R161 - FLL Control (7) */ + { 162, 0x0008 }, /* R162 - FLL Control (8) */ + + { 252, 0x0005 }, /* R252 - General test 1 */ + + { 256, 0x0000 }, /* R256 - DF1 */ + { 257, 0x0000 }, /* R257 - DF2 */ + { 258, 0x0000 }, /* R258 - DF3 */ + { 259, 0x0000 }, /* R259 - DF4 */ + { 260, 0x0000 }, /* R260 - DF5 */ + { 261, 0x0000 }, /* R261 - DF6 */ + { 262, 0x0000 }, /* R262 - DF7 */ + + { 264, 0x0000 }, /* R264 - LHPF1 */ + { 265, 0x0000 }, /* R265 - LHPF2 */ + + { 268, 0x0000 }, /* R268 - THREED1 */ + { 269, 0x0000 }, /* R269 - THREED2 */ + { 270, 0x0000 }, /* R270 - THREED3 */ + { 271, 0x0000 }, /* R271 - THREED4 */ + + { 276, 0x000C }, /* R276 - DRC 1 */ + { 277, 0x0925 }, /* R277 - DRC 2 */ + { 278, 0x0000 }, /* R278 - DRC 3 */ + { 279, 0x0000 }, /* R279 - DRC 4 */ + { 280, 0x0000 }, /* R280 - DRC 5 */ + + { 285, 0x0000 }, /* R285 - Tloopback */ + + { 335, 0x0004 }, /* R335 - EQ1 */ + { 336, 0x6318 }, /* R336 - EQ2 */ + { 337, 0x6300 }, /* R337 - EQ3 */ + { 338, 0x0FCA }, /* R338 - EQ4 */ + { 339, 0x0400 }, /* R339 - EQ5 */ + { 340, 0x00D8 }, /* R340 - EQ6 */ + { 341, 0x1EB5 }, /* R341 - EQ7 */ + { 342, 0xF145 }, /* R342 - EQ8 */ + { 343, 0x0B75 }, /* R343 - EQ9 */ + { 344, 0x01C5 }, /* R344 - EQ10 */ + { 345, 0x1C58 }, /* R345 - EQ11 */ + { 346, 0xF373 }, /* R346 - EQ12 */ + { 347, 0x0A54 }, /* R347 - EQ13 */ + { 348, 0x0558 }, /* R348 - EQ14 */ + { 349, 0x168E }, /* R349 - EQ15 */ + { 350, 0xF829 }, /* R350 - EQ16 */ + { 351, 0x07AD }, /* R351 - EQ17 */ + { 352, 0x1103 }, /* R352 - EQ18 */ + { 353, 0x0564 }, /* R353 - EQ19 */ + { 354, 0x0559 }, /* R354 - EQ20 */ + { 355, 0x4000 }, /* R355 - EQ21 */ + { 356, 0x6318 }, /* R356 - EQ22 */ + { 357, 0x6300 }, /* R357 - EQ23 */ + { 358, 0x0FCA }, /* R358 - EQ24 */ + { 359, 0x0400 }, /* R359 - EQ25 */ + { 360, 0x00D8 }, /* R360 - EQ26 */ + { 361, 0x1EB5 }, /* R361 - EQ27 */ + { 362, 0xF145 }, /* R362 - EQ28 */ + { 363, 0x0B75 }, /* R363 - EQ29 */ + { 364, 0x01C5 }, /* R364 - EQ30 */ + { 365, 0x1C58 }, /* R365 - EQ31 */ + { 366, 0xF373 }, /* R366 - EQ32 */ + { 367, 0x0A54 }, /* R367 - EQ33 */ + { 368, 0x0558 }, /* R368 - EQ34 */ + { 369, 0x168E }, /* R369 - EQ35 */ + { 370, 0xF829 }, /* R370 - EQ36 */ + { 371, 0x07AD }, /* R371 - EQ37 */ + { 372, 0x1103 }, /* R372 - EQ38 */ + { 373, 0x0564 }, /* R373 - EQ39 */ + { 374, 0x0559 }, /* R374 - EQ40 */ + { 375, 0x4000 }, /* R375 - EQ41 */ + + { 513, 0x0000 }, /* R513 - GPIO 2 */ + { 514, 0x0000 }, /* R514 - GPIO 3 */ + + { 516, 0x8100 }, /* R516 - GPIO 5 */ + { 517, 0x8100 }, /* R517 - GPIO 6 */ + + { 560, 0x0000 }, /* R560 - Interrupt Status 1 */ + { 561, 0x0000 }, /* R561 - Interrupt Status 2 */ + + { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */ + { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */ + + { 576, 0x0000 }, /* R576 - Interrupt Control */ + + { 584, 0x002D }, /* R584 - IRQ Debounce */ + + { 586, 0x0000 }, /* R586 - MICINT Source Pol */ + + { 768, 0x1C00 }, /* R768 - DSP2 Power Management */ + + { 1037, 0x0000 }, /* R1037 - DSP2_ExecControl */ + + { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ + + { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */ + { 9217, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */ + { 9218, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */ + + { 12288, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */ + { 12289, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */ + + { 13312, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */ + { 13313, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */ + + { 14336, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */ + { 14337, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */ + + { 15360, 0x000A }, /* R15360 - DSP2 Coeff RAM 0 */ + + { 16384, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */ + { 16385, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */ + { 16386, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */ + { 16387, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */ + { 16388, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */ + { 16389, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */ + + { 16896, 0x0002 }, /* R16896 - HDBASS_AI_1 */ + { 16897, 0xBD12 }, /* R16897 - HDBASS_AI_0 */ + { 16898, 0x007C }, /* R16898 - HDBASS_AR_1 */ + { 16899, 0x586C }, /* R16899 - HDBASS_AR_0 */ + { 16900, 0x0053 }, /* R16900 - HDBASS_B_1 */ + { 16901, 0x8121 }, /* R16901 - HDBASS_B_0 */ + { 16902, 0x003F }, /* R16902 - HDBASS_K_1 */ + { 16903, 0x8BD8 }, /* R16903 - HDBASS_K_0 */ + { 16904, 0x0032 }, /* R16904 - HDBASS_N1_1 */ + { 16905, 0xF52D }, /* R16905 - HDBASS_N1_0 */ + { 16906, 0x0065 }, /* R16906 - HDBASS_N2_1 */ + { 16907, 0xAC8C }, /* R16907 - HDBASS_N2_0 */ + { 16908, 0x006B }, /* R16908 - HDBASS_N3_1 */ + { 16909, 0xE087 }, /* R16909 - HDBASS_N3_0 */ + { 16910, 0x0072 }, /* R16910 - HDBASS_N4_1 */ + { 16911, 0x1483 }, /* R16911 - HDBASS_N4_0 */ + { 16912, 0x0072 }, /* R16912 - HDBASS_N5_1 */ + { 16913, 0x1483 }, /* R16913 - HDBASS_N5_0 */ + { 16914, 0x0043 }, /* R16914 - HDBASS_X1_1 */ + { 16915, 0x3525 }, /* R16915 - HDBASS_X1_0 */ + { 16916, 0x0006 }, /* R16916 - HDBASS_X2_1 */ + { 16917, 0x6A4A }, /* R16917 - HDBASS_X2_0 */ + { 16918, 0x0043 }, /* R16918 - HDBASS_X3_1 */ + { 16919, 0x6079 }, /* R16919 - HDBASS_X3_0 */ + { 16920, 0x0008 }, /* R16920 - HDBASS_ATK_1 */ + { 16921, 0x0000 }, /* R16921 - HDBASS_ATK_0 */ + { 16922, 0x0001 }, /* R16922 - HDBASS_DCY_1 */ + { 16923, 0x0000 }, /* R16923 - HDBASS_DCY_0 */ + { 16924, 0x0059 }, /* R16924 - HDBASS_PG_1 */ + { 16925, 0x999A }, /* R16925 - HDBASS_PG_0 */ + + { 17048, 0x0083 }, /* R17408 - HPF_C_1 */ + { 17049, 0x98AD }, /* R17409 - HPF_C_0 */ + + { 17920, 0x007F }, /* R17920 - ADCL_RETUNE_C1_1 */ + { 17921, 0xFFFF }, /* R17921 - ADCL_RETUNE_C1_0 */ + { 17922, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */ + { 17923, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */ + { 17924, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */ + { 17925, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */ + { 17926, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */ + { 17927, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */ + { 17928, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */ + { 17929, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */ + { 17930, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */ + { 17931, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */ + { 17932, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */ + { 17933, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */ + { 17934, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */ + { 17935, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */ + { 17936, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */ + { 17937, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */ + { 17938, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */ + { 17939, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */ + { 17940, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */ + { 17941, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */ + { 17942, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */ + { 17943, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */ + { 17944, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */ + { 17945, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */ + { 17946, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */ + { 17947, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */ + { 17948, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */ + { 17949, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */ + { 17950, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */ + { 17951, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */ + { 17952, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */ + { 17953, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */ + { 17954, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */ + { 17955, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */ + { 17956, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */ + { 17957, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */ + { 17958, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */ + { 17959, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */ + { 17960, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */ + { 17961, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */ + { 17962, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */ + { 17963, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */ + { 17964, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */ + { 17965, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */ + { 17966, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */ + { 17967, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */ + { 17968, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */ + { 17969, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */ + { 17970, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */ + { 17971, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */ + { 17972, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */ + { 17973, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */ + { 17974, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */ + { 17975, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */ + { 17976, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */ + { 17977, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */ + { 17978, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */ + { 17979, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */ + { 17980, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */ + { 17981, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */ + { 17982, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */ + { 17983, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */ + + { 18432, 0x0020 }, /* R18432 - RETUNEADC_PG2_1 */ + { 18433, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */ + { 18434, 0x0040 }, /* R18434 - RETUNEADC_PG_1 */ + { 18435, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */ + + { 18944, 0x007F }, /* R18944 - ADCR_RETUNE_C1_1 */ + { 18945, 0xFFFF }, /* R18945 - ADCR_RETUNE_C1_0 */ + { 18946, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */ + { 18947, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */ + { 18948, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */ + { 18949, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */ + { 18950, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */ + { 18951, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */ + { 18952, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */ + { 18953, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */ + { 18954, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */ + { 18955, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */ + { 18956, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */ + { 18957, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */ + { 18958, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */ + { 18959, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */ + { 18960, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */ + { 18961, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */ + { 18962, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */ + { 18963, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */ + { 18964, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */ + { 18965, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */ + { 18966, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */ + { 18967, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */ + { 18968, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */ + { 18969, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */ + { 18970, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */ + { 18971, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */ + { 18972, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */ + { 18973, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */ + { 18974, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */ + { 18975, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */ + { 18976, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */ + { 18977, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */ + { 18978, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */ + { 18979, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */ + { 18980, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */ + { 18981, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */ + { 18982, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */ + { 18983, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */ + { 18984, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */ + { 18985, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */ + { 18986, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */ + { 18987, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */ + { 18988, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */ + { 18989, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */ + { 18990, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */ + { 18991, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */ + { 18992, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */ + { 18993, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */ + { 18994, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */ + { 18995, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */ + { 18996, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */ + { 18997, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */ + { 18998, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */ + { 18999, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */ + { 19000, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */ + { 19001, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */ + { 19002, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */ + { 19003, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */ + { 19004, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */ + { 19005, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */ + { 19006, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */ + { 19007, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */ + + { 19456, 0x007F }, /* R19456 - DACL_RETUNE_C1_1 */ + { 19457, 0xFFFF }, /* R19457 - DACL_RETUNE_C1_0 */ + { 19458, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */ + { 19459, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */ + { 19460, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */ + { 19461, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */ + { 19462, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */ + { 19463, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */ + { 19464, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */ + { 19465, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */ + { 19466, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */ + { 19467, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */ + { 19468, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */ + { 19469, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */ + { 19470, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */ + { 19471, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */ + { 19472, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */ + { 19473, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */ + { 19474, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */ + { 19475, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */ + { 19476, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */ + { 19477, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */ + { 19478, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */ + { 19479, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */ + { 19480, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */ + { 19481, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */ + { 19482, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */ + { 19483, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */ + { 19484, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */ + { 19485, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */ + { 19486, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */ + { 19487, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */ + { 19488, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */ + { 19489, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */ + { 19490, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */ + { 19491, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */ + { 19492, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */ + { 19493, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */ + { 19494, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */ + { 19495, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */ + { 19496, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */ + { 19497, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */ + { 19498, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */ + { 19499, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */ + { 19500, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */ + { 19501, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */ + { 19502, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */ + { 19503, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */ + { 19504, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */ + { 19505, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */ + { 19506, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */ + { 19507, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */ + { 19508, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */ + { 19509, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */ + { 19510, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */ + { 19511, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */ + { 19512, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */ + { 19513, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */ + { 19514, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */ + { 19515, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */ + { 19516, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */ + { 19517, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */ + { 19518, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */ + { 19519, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */ + + { 19968, 0x0020 }, /* R19968 - RETUNEDAC_PG2_1 */ + { 19969, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */ + { 19970, 0x0040 }, /* R19970 - RETUNEDAC_PG_1 */ + { 19971, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */ + + { 20480, 0x007F }, /* R20480 - DACR_RETUNE_C1_1 */ + { 20481, 0xFFFF }, /* R20481 - DACR_RETUNE_C1_0 */ + { 20482, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */ + { 20483, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */ + { 20484, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */ + { 20485, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */ + { 20486, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */ + { 20487, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */ + { 20488, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */ + { 20489, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */ + { 20490, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */ + { 20491, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */ + { 20492, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */ + { 20493, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */ + { 20494, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */ + { 20495, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */ + { 20496, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */ + { 20497, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */ + { 20498, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */ + { 20499, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */ + { 20500, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */ + { 20501, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */ + { 20502, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */ + { 20503, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */ + { 20504, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */ + { 20505, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */ + { 20506, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */ + { 20507, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */ + { 20508, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */ + { 20509, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */ + { 20510, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */ + { 20511, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */ + { 20512, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */ + { 20513, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */ + { 20514, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */ + { 20515, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */ + { 20516, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */ + { 20517, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */ + { 20518, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */ + { 20519, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */ + { 20520, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */ + { 20521, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */ + { 20522, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */ + { 20523, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */ + { 20524, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */ + { 20525, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */ + { 20526, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */ + { 20527, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */ + { 20528, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */ + { 20529, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */ + { 20530, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */ + { 20531, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */ + { 20532, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */ + { 20533, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */ + { 20534, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */ + { 20535, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */ + { 20536, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */ + { 20537, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */ + { 20538, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */ + { 20539, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */ + { 20540, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */ + { 20541, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */ + { 20542, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */ + { 20543, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */ + + { 20992, 0x008C }, /* R20992 - VSS_XHD2_1 */ + { 20993, 0x0200 }, /* R20993 - VSS_XHD2_0 */ + { 20994, 0x0035 }, /* R20994 - VSS_XHD3_1 */ + { 20995, 0x0700 }, /* R20995 - VSS_XHD3_0 */ + { 20996, 0x003A }, /* R20996 - VSS_XHN1_1 */ + { 20997, 0x4100 }, /* R20997 - VSS_XHN1_0 */ + { 20998, 0x008B }, /* R20998 - VSS_XHN2_1 */ + { 20999, 0x7D00 }, /* R20999 - VSS_XHN2_0 */ + { 21000, 0x003A }, /* R21000 - VSS_XHN3_1 */ + { 21001, 0x4100 }, /* R21001 - VSS_XHN3_0 */ + { 21002, 0x008C }, /* R21002 - VSS_XLA_1 */ + { 21003, 0xFEE8 }, /* R21003 - VSS_XLA_0 */ + { 21004, 0x0078 }, /* R21004 - VSS_XLB_1 */ + { 21005, 0x0000 }, /* R21005 - VSS_XLB_0 */ + { 21006, 0x003F }, /* R21006 - VSS_XLG_1 */ + { 21007, 0xB260 }, /* R21007 - VSS_XLG_0 */ + { 21008, 0x002D }, /* R21008 - VSS_PG2_1 */ + { 21009, 0x1818 }, /* R21009 - VSS_PG2_0 */ + { 21010, 0x0020 }, /* R21010 - VSS_PG_1 */ + { 21011, 0x0000 }, /* R21011 - VSS_PG_0 */ + { 21012, 0x00F1 }, /* R21012 - VSS_XTD1_1 */ + { 21013, 0x8340 }, /* R21013 - VSS_XTD1_0 */ + { 21014, 0x00FB }, /* R21014 - VSS_XTD2_1 */ + { 21015, 0x8300 }, /* R21015 - VSS_XTD2_0 */ + { 21016, 0x00EE }, /* R21016 - VSS_XTD3_1 */ + { 21017, 0xAEC0 }, /* R21017 - VSS_XTD3_0 */ + { 21018, 0x00FB }, /* R21018 - VSS_XTD4_1 */ + { 21019, 0xAC40 }, /* R21019 - VSS_XTD4_0 */ + { 21020, 0x00F1 }, /* R21020 - VSS_XTD5_1 */ + { 21021, 0x7F80 }, /* R21021 - VSS_XTD5_0 */ + { 21022, 0x00F4 }, /* R21022 - VSS_XTD6_1 */ + { 21023, 0x3B40 }, /* R21023 - VSS_XTD6_0 */ + { 21024, 0x00F5 }, /* R21024 - VSS_XTD7_1 */ + { 21025, 0xFB00 }, /* R21025 - VSS_XTD7_0 */ + { 21026, 0x00EA }, /* R21026 - VSS_XTD8_1 */ + { 21027, 0x10C0 }, /* R21027 - VSS_XTD8_0 */ + { 21028, 0x00FC }, /* R21028 - VSS_XTD9_1 */ + { 21029, 0xC580 }, /* R21029 - VSS_XTD9_0 */ + { 21030, 0x00E2 }, /* R21030 - VSS_XTD10_1 */ + { 21031, 0x75C0 }, /* R21031 - VSS_XTD10_0 */ + { 21032, 0x0004 }, /* R21032 - VSS_XTD11_1 */ + { 21033, 0xB480 }, /* R21033 - VSS_XTD11_0 */ + { 21034, 0x00D4 }, /* R21034 - VSS_XTD12_1 */ + { 21035, 0xF980 }, /* R21035 - VSS_XTD12_0 */ + { 21036, 0x0004 }, /* R21036 - VSS_XTD13_1 */ + { 21037, 0x9140 }, /* R21037 - VSS_XTD13_0 */ + { 21038, 0x00D8 }, /* R21038 - VSS_XTD14_1 */ + { 21039, 0xA480 }, /* R21039 - VSS_XTD14_0 */ + { 21040, 0x0002 }, /* R21040 - VSS_XTD15_1 */ + { 21041, 0x3DC0 }, /* R21041 - VSS_XTD15_0 */ + { 21042, 0x00CF }, /* R21042 - VSS_XTD16_1 */ + { 21043, 0x7A80 }, /* R21043 - VSS_XTD16_0 */ + { 21044, 0x00DC }, /* R21044 - VSS_XTD17_1 */ + { 21045, 0x0600 }, /* R21045 - VSS_XTD17_0 */ + { 21046, 0x00F2 }, /* R21046 - VSS_XTD18_1 */ + { 21047, 0xDAC0 }, /* R21047 - VSS_XTD18_0 */ + { 21048, 0x00BA }, /* R21048 - VSS_XTD19_1 */ + { 21049, 0xF340 }, /* R21049 - VSS_XTD19_0 */ + { 21050, 0x000A }, /* R21050 - VSS_XTD20_1 */ + { 21051, 0x7940 }, /* R21051 - VSS_XTD20_0 */ + { 21052, 0x001C }, /* R21052 - VSS_XTD21_1 */ + { 21053, 0x0680 }, /* R21053 - VSS_XTD21_0 */ + { 21054, 0x00FD }, /* R21054 - VSS_XTD22_1 */ + { 21055, 0x2D00 }, /* R21055 - VSS_XTD22_0 */ + { 21056, 0x001C }, /* R21056 - VSS_XTD23_1 */ + { 21057, 0xE840 }, /* R21057 - VSS_XTD23_0 */ + { 21058, 0x000D }, /* R21058 - VSS_XTD24_1 */ + { 21059, 0xDC40 }, /* R21059 - VSS_XTD24_0 */ + { 21060, 0x00FC }, /* R21060 - VSS_XTD25_1 */ + { 21061, 0x9D00 }, /* R21061 - VSS_XTD25_0 */ + { 21062, 0x0009 }, /* R21062 - VSS_XTD26_1 */ + { 21063, 0x5580 }, /* R21063 - VSS_XTD26_0 */ + { 21064, 0x00FE }, /* R21064 - VSS_XTD27_1 */ + { 21065, 0x7E80 }, /* R21065 - VSS_XTD27_0 */ + { 21066, 0x000E }, /* R21066 - VSS_XTD28_1 */ + { 21067, 0xAB40 }, /* R21067 - VSS_XTD28_0 */ + { 21068, 0x00F9 }, /* R21068 - VSS_XTD29_1 */ + { 21069, 0x9880 }, /* R21069 - VSS_XTD29_0 */ + { 21070, 0x0009 }, /* R21070 - VSS_XTD30_1 */ + { 21071, 0x87C0 }, /* R21071 - VSS_XTD30_0 */ + { 21072, 0x00FD }, /* R21072 - VSS_XTD31_1 */ + { 21073, 0x2C40 }, /* R21073 - VSS_XTD31_0 */ + { 21074, 0x0009 }, /* R21074 - VSS_XTD32_1 */ + { 21075, 0x4800 }, /* R21075 - VSS_XTD32_0 */ + { 21076, 0x0003 }, /* R21076 - VSS_XTS1_1 */ + { 21077, 0x5F40 }, /* R21077 - VSS_XTS1_0 */ + { 21078, 0x0000 }, /* R21078 - VSS_XTS2_1 */ + { 21079, 0x8700 }, /* R21079 - VSS_XTS2_0 */ + { 21080, 0x00FA }, /* R21080 - VSS_XTS3_1 */ + { 21081, 0xE4C0 }, /* R21081 - VSS_XTS3_0 */ + { 21082, 0x0000 }, /* R21082 - VSS_XTS4_1 */ + { 21083, 0x0B40 }, /* R21083 - VSS_XTS4_0 */ + { 21084, 0x0004 }, /* R21084 - VSS_XTS5_1 */ + { 21085, 0xE180 }, /* R21085 - VSS_XTS5_0 */ + { 21086, 0x0001 }, /* R21086 - VSS_XTS6_1 */ + { 21087, 0x1F40 }, /* R21087 - VSS_XTS6_0 */ + { 21088, 0x00F8 }, /* R21088 - VSS_XTS7_1 */ + { 21089, 0xB000 }, /* R21089 - VSS_XTS7_0 */ + { 21090, 0x00FB }, /* R21090 - VSS_XTS8_1 */ + { 21091, 0xCBC0 }, /* R21091 - VSS_XTS8_0 */ + { 21092, 0x0004 }, /* R21092 - VSS_XTS9_1 */ + { 21093, 0xF380 }, /* R21093 - VSS_XTS9_0 */ + { 21094, 0x0007 }, /* R21094 - VSS_XTS10_1 */ + { 21095, 0xDF40 }, /* R21095 - VSS_XTS10_0 */ + { 21096, 0x00FF }, /* R21096 - VSS_XTS11_1 */ + { 21097, 0x0700 }, /* R21097 - VSS_XTS11_0 */ + { 21098, 0x00EF }, /* R21098 - VSS_XTS12_1 */ + { 21099, 0xD700 }, /* R21099 - VSS_XTS12_0 */ + { 21100, 0x00FB }, /* R21100 - VSS_XTS13_1 */ + { 21101, 0xAF40 }, /* R21101 - VSS_XTS13_0 */ + { 21102, 0x0010 }, /* R21102 - VSS_XTS14_1 */ + { 21103, 0x8A80 }, /* R21103 - VSS_XTS14_0 */ + { 21104, 0x0011 }, /* R21104 - VSS_XTS15_1 */ + { 21105, 0x07C0 }, /* R21105 - VSS_XTS15_0 */ + { 21106, 0x00E0 }, /* R21106 - VSS_XTS16_1 */ + { 21107, 0x0800 }, /* R21107 - VSS_XTS16_0 */ + { 21108, 0x00D2 }, /* R21108 - VSS_XTS17_1 */ + { 21109, 0x7600 }, /* R21109 - VSS_XTS17_0 */ + { 21110, 0x0020 }, /* R21110 - VSS_XTS18_1 */ + { 21111, 0xCF40 }, /* R21111 - VSS_XTS18_0 */ + { 21112, 0x0030 }, /* R21112 - VSS_XTS19_1 */ + { 21113, 0x2340 }, /* R21113 - VSS_XTS19_0 */ + { 21114, 0x00FD }, /* R21114 - VSS_XTS20_1 */ + { 21115, 0x69C0 }, /* R21115 - VSS_XTS20_0 */ + { 21116, 0x0028 }, /* R21116 - VSS_XTS21_1 */ + { 21117, 0x3500 }, /* R21117 - VSS_XTS21_0 */ + { 21118, 0x0006 }, /* R21118 - VSS_XTS22_1 */ + { 21119, 0x3300 }, /* R21119 - VSS_XTS22_0 */ + { 21120, 0x00D9 }, /* R21120 - VSS_XTS23_1 */ + { 21121, 0xF6C0 }, /* R21121 - VSS_XTS23_0 */ + { 21122, 0x00F3 }, /* R21122 - VSS_XTS24_1 */ + { 21123, 0x3340 }, /* R21123 - VSS_XTS24_0 */ + { 21124, 0x000F }, /* R21124 - VSS_XTS25_1 */ + { 21125, 0x4200 }, /* R21125 - VSS_XTS25_0 */ + { 21126, 0x0004 }, /* R21126 - VSS_XTS26_1 */ + { 21127, 0x0C80 }, /* R21127 - VSS_XTS26_0 */ + { 21128, 0x00FB }, /* R21128 - VSS_XTS27_1 */ + { 21129, 0x3F80 }, /* R21129 - VSS_XTS27_0 */ + { 21130, 0x00F7 }, /* R21130 - VSS_XTS28_1 */ + { 21131, 0x57C0 }, /* R21131 - VSS_XTS28_0 */ + { 21132, 0x0003 }, /* R21132 - VSS_XTS29_1 */ + { 21133, 0x5400 }, /* R21133 - VSS_XTS29_0 */ + { 21134, 0x0000 }, /* R21134 - VSS_XTS30_1 */ + { 21135, 0xC6C0 }, /* R21135 - VSS_XTS30_0 */ + { 21136, 0x0003 }, /* R21136 - VSS_XTS31_1 */ + { 21137, 0x12C0 }, /* R21137 - VSS_XTS31_0 */ + { 21138, 0x00FD }, /* R21138 - VSS_XTS32_1 */ + { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */ }; static const struct wm8962_reg_access { @@ -802,7 +803,7 @@ static const struct wm8962_reg_access { u16 vol; } wm8962_reg_access[WM8962_MAX_REGISTER + 1] = { [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */ - [1] = { 0xFEFF, 0x01FF, 0xFFFF }, /* R1 - Right Input volume */ + [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1 - Right Input volume */ [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */ [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */ [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */ @@ -1943,7 +1944,7 @@ static const struct wm8962_reg_access { [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ }; -static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8962_volatile_register(struct device *dev, unsigned int reg) { if (wm8962_reg_access[reg].vol) return 1; @@ -1951,7 +1952,7 @@ static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int re return 0; } -static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8962_readable_register(struct device *dev, unsigned int reg) { if (wm8962_reg_access[reg].read) return 1; @@ -1959,21 +1960,21 @@ static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re return 0; } -static int wm8962_reset(struct snd_soc_codec *codec) +static int wm8962_reset(struct wm8962_priv *wm8962) { int ret; - ret = snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); + ret = regmap_write(wm8962->regmap, WM8962_SOFTWARE_RESET, 0x6243); if (ret != 0) return ret; - return snd_soc_write(codec, WM8962_PLL_SOFTWARE_RESET, 0); + return regmap_write(wm8962->regmap, WM8962_PLL_SOFTWARE_RESET, 0); } static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); static const unsigned int mixinpga_tlv[] = { - TLV_DB_RANGE_HEAD(7), + TLV_DB_RANGE_HEAD(5), 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), @@ -1988,7 +1989,7 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0); static const unsigned int classd_tlv[] = { - TLV_DB_RANGE_HEAD(7), + TLV_DB_RANGE_HEAD(2), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; @@ -2345,6 +2346,10 @@ static int sysclk_event(struct snd_soc_dapm_widget *w, int src; int fll; + /* Ignore attempts to run the event during startup */ + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) + return 0; + src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; switch (src) { @@ -2670,7 +2675,7 @@ SND_SOC_DAPM_INPUT("IN3L"), SND_SOC_DAPM_INPUT("IN3R"), SND_SOC_DAPM_INPUT("IN4L"), SND_SOC_DAPM_INPUT("IN4R"), -SND_SOC_DAPM_INPUT("Beep"), +SND_SOC_DAPM_SIGGEN("Beep"), SND_SOC_DAPM_INPUT("DMICDAT"), SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), @@ -2684,6 +2689,8 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_SUPPLY("TEMP_HP", WM8962_ADDITIONAL_CONTROL_4, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("TEMP_SPK", WM8962_ADDITIONAL_CONTROL_4, 1, 0, NULL, 0), SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, inpgal, ARRAY_SIZE(inpgal)), @@ -2839,6 +2846,9 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = { { "HPOUTL", NULL, "HPOUT" }, { "HPOUTR", NULL, "HPOUT" }, + + { "HPOUTL", NULL, "TEMP_HP" }, + { "HPOUTR", NULL, "TEMP_HP" }, }; static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = { @@ -2855,6 +2865,7 @@ static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = { { "Speaker Output", NULL, "Speaker PGA" }, { "Speaker Output", NULL, "SYSCLK" }, { "Speaker Output", NULL, "TOCLK" }, + { "Speaker Output", NULL, "TEMP_SPK" }, { "SPKOUT", NULL, "Speaker Output" }, }; @@ -2883,10 +2894,12 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = { { "SPKOUTL Output", NULL, "SPKOUTL PGA" }, { "SPKOUTL Output", NULL, "SYSCLK" }, { "SPKOUTL Output", NULL, "TOCLK" }, + { "SPKOUTL Output", NULL, "TEMP_SPK" }, { "SPKOUTR Output", NULL, "SPKOUTR PGA" }, { "SPKOUTR Output", NULL, "SYSCLK" }, { "SPKOUTR Output", NULL, "TOCLK" }, + { "SPKOUTR Output", NULL, "TEMP_SPK" }, { "SPKOUTL", NULL, "SPKOUTL Output" }, { "SPKOUTR", NULL, "SPKOUTR Output" }, @@ -2931,33 +2944,6 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) return 0; } -static void wm8962_sync_cache(struct snd_soc_codec *codec) -{ - u16 *reg_cache = codec->reg_cache; - int i; - - if (!codec->cache_sync) - return; - - dev_dbg(codec->dev, "Syncing cache\n"); - - codec->cache_only = 0; - - /* Sync back cached values if they're different from the - * hardware default. - */ - for (i = 1; i < codec->driver->reg_cache_size; i++) { - if (i == WM8962_SOFTWARE_RESET) - continue; - if (reg_cache[i] == wm8962_reg[i]) - continue; - - snd_soc_write(codec, i, reg_cache[i]); - } - - codec->cache_sync = 0; -} - /* -1 for reserved values */ static const int bclk_divs[] = { 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32 @@ -3085,7 +3071,8 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, return ret; } - wm8962_sync_cache(codec); + regcache_cache_only(wm8962->regmap, false); + regcache_sync(wm8962->regmap); snd_soc_update_bits(codec, WM8962_ANTI_POP, WM8962_STARTUP_BIAS_ENA | @@ -3399,6 +3386,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, unsigned long timeout; int ret; int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; + int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA; /* Any change? */ if (source == wm8962->fll_src && Fref == wm8962->fll_fref && @@ -3459,6 +3447,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, try_wait_for_completion(&wm8962->fll_lock); + if (sysclk) + fll1 |= WM8962_FLL_ENA; + snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | WM8962_FLL_ENA, fll1); @@ -3511,7 +3502,7 @@ static int wm8962_mute(struct snd_soc_dai *dai, int mute) #define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8962_dai_ops = { +static const struct snd_soc_dai_ops wm8962_dai_ops = { .hw_params = wm8962_hw_params, .set_sysclk = wm8962_set_dai_sysclk, .set_fmt = wm8962_set_dai_fmt, @@ -3662,6 +3653,14 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) snd_soc_jack_report(wm8962->jack, 0, SND_JACK_MICROPHONE | SND_JACK_BTN_0); + if (jack) { + snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); + snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS"); + } else { + snd_soc_dapm_disable_pin(&codec->dapm, "SYSCLK"); + snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS"); + } + return 0; } EXPORT_SYMBOL_GPL(wm8962_mic_detect); @@ -3879,13 +3878,17 @@ static int wm8962_gpio_direction_out(struct gpio_chip *chip, { struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); struct snd_soc_codec *codec = wm8962->codec; - int val; + int ret, val; /* Force function 1 (logic output) */ val = (1 << WM8962_GP2_FN_SHIFT) | (value << WM8962_GP2_LVL_SHIFT); - return snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, - WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val); + ret = snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, + WM8962_GP2_FN_MASK | WM8962_GP2_LVL, val); + if (ret < 0) + return ret; + + return 0; } static struct gpio_chip wm8962_template_chip = { @@ -3946,26 +3949,12 @@ static int wm8962_probe(struct snd_soc_codec *codec) bool dmicclk, dmicdat; wm8962->codec = codec; - INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); - init_completion(&wm8962->fll_lock); - - codec->cache_sync = 1; - codec->dapm.idle_bias_off = 1; + codec->control_data = wm8962->regmap; - ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - goto err; - } - - for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) - wm8962->supplies[i].supply = wm8962_supply_names[i]; - - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8962->supplies), - wm8962->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - goto err; + return ret; } wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0; @@ -3988,43 +3977,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) } } - ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), - wm8962->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; - } - - ret = snd_soc_read(codec, WM8962_SOFTWARE_RESET); - if (ret < 0) { - dev_err(codec->dev, "Failed to read ID register\n"); - goto err_enable; - } - if (ret != wm8962_reg[WM8962_SOFTWARE_RESET]) { - dev_err(codec->dev, "Device is not a WM8962, ID %x != %x\n", - ret, wm8962_reg[WM8962_SOFTWARE_RESET]); - ret = -EINVAL; - goto err_enable; - } - - ret = snd_soc_read(codec, WM8962_RIGHT_INPUT_VOLUME); - if (ret < 0) { - dev_err(codec->dev, "Failed to read device revision: %d\n", - ret); - goto err_enable; - } - - dev_info(codec->dev, "customer id %x revision %c\n", - (ret & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT, - ((ret & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT) - + 'A'); - - ret = wm8962_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_enable; - } - /* SYSCLK defaults to on; make sure it is off so we can safely * write to registers if the device is declocked. */ @@ -4039,8 +3991,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) WM8962_OSC_ENA | WM8962_PLL2_ENA | WM8962_PLL3_ENA, 0); - regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); - if (pdata) { /* Apply static configuration for GPIOs */ for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++) @@ -4091,6 +4041,12 @@ static int wm8962_probe(struct snd_soc_codec *codec) /* Stereo control for EQ */ snd_soc_update_bits(codec, WM8962_EQ1, WM8962_EQ_SHARED_COEFF, 0); + /* Don't debouce interrupts so we don't need SYSCLK */ + snd_soc_update_bits(codec, WM8962_IRQ_DEBOUNCE, + WM8962_FLL_LOCK_DB | WM8962_PLL3_LOCK_DB | + WM8962_PLL2_LOCK_DB | WM8962_TEMP_SHUT_DB, + 0); + wm8962_add_widgets(codec); /* Save boards having to disable DMIC when not in use */ @@ -4150,13 +4106,6 @@ static int wm8962_probe(struct snd_soc_codec *codec) } return 0; - -err_enable: - regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); -err: - return ret; } static int wm8962_remove(struct snd_soc_codec *codec) @@ -4174,21 +4123,36 @@ static int wm8962_remove(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) regulator_unregister_notifier(wm8962->supplies[i].consumer, &wm8962->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); return 0; } +static int wm8962_soc_volatile(struct snd_soc_codec *codec, + unsigned int reg) +{ + return true; +} + + static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { .probe = wm8962_probe, .remove = wm8962_remove, .set_bias_level = wm8962_set_bias_level, - .reg_cache_size = WM8962_MAX_REGISTER + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8962_reg, - .volatile_register = wm8962_volatile_register, - .readable_register = wm8962_readable_register, .set_pll = wm8962_set_fll, + .reg_cache_size = WM8962_MAX_REGISTER, + .volatile_register = wm8962_soc_volatile, +}; + +static const struct regmap_config wm8962_regmap = { + .reg_bits = 16, + .val_bits = 16, + + .max_register = WM8962_MAX_REGISTER, + .reg_defaults = wm8962_reg, + .num_reg_defaults = ARRAY_SIZE(wm8962_reg), + .volatile_reg = wm8962_volatile_register, + .readable_reg = wm8962_readable_register, + .cache_type = REGCACHE_RBTREE, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) @@ -4196,28 +4160,112 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8962_priv *wm8962; - int ret; + unsigned int reg; + int ret, i; - wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL); + wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv), + GFP_KERNEL); if (wm8962 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, wm8962); + INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); + init_completion(&wm8962->fll_lock); wm8962->irq = i2c->irq; + for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) + wm8962->supplies[i].supply = wm8962_supply_names[i]; + + ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8962->supplies), + wm8962->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), + wm8962->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + wm8962->regmap = regmap_init_i2c(i2c, &wm8962_regmap); + if (IS_ERR(wm8962->regmap)) { + ret = PTR_ERR(wm8962->regmap); + dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); + goto err_enable; + } + + /* + * We haven't marked the chip revision as volatile due to + * sharing a register with the right input volume; explicitly + * bypass the cache to read it. + */ + regcache_cache_bypass(wm8962->regmap, true); + + ret = regmap_read(wm8962->regmap, WM8962_SOFTWARE_RESET, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register\n"); + goto err_regmap; + } + if (reg != 0x6243) { + dev_err(&i2c->dev, + "Device is not a WM8962, ID %x != 0x6243\n", ret); + ret = -EINVAL; + goto err_regmap; + } + + ret = regmap_read(wm8962->regmap, WM8962_RIGHT_INPUT_VOLUME, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read device revision: %d\n", + ret); + goto err_regmap; + } + + dev_info(&i2c->dev, "customer id %x revision %c\n", + (reg & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT, + ((reg & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT) + + 'A'); + + regcache_cache_bypass(wm8962->regmap, false); + + ret = wm8962_reset(wm8962); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset\n"); + goto err_regmap; + } + + regcache_cache_only(wm8962->regmap, true); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8962, &wm8962_dai, 1); if (ret < 0) - kfree(wm8962); + goto err_regmap; + + /* The drivers should power up as needed */ + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); + + return 0; +err_regmap: + regmap_exit(wm8962->regmap); +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); +err: return ret; } static __devexit int wm8962_i2c_remove(struct i2c_client *client) { + struct wm8962_priv *wm8962 = dev_get_drvdata(&client->dev); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm8962->regmap); + regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); return 0; } diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index b444b297d0b..4af893601f0 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -19,7 +19,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -224,7 +223,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = { SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8971_PWR2, 8, 0), SND_SOC_DAPM_PGA("Mono Out 1", WM8971_PWR2, 2, 0, NULL, 0), - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8971_PWR1, 1, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias", WM8971_PWR1, 1, 0, NULL, 0), SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8971_PWR1, 2, 0), SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8971_PWR1, 3, 0), @@ -567,7 +566,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec, #define WM8971_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8971_dai_ops = { +static const struct snd_soc_dai_ops wm8971_dai_ops = { .hw_params = wm8971_pcm_hw_params, .digital_mute = wm8971_mute, .set_fmt = wm8971_set_dai_fmt, @@ -600,7 +599,7 @@ static void wm8971_work(struct work_struct *work) wm8971_set_bias_level(codec, codec->dapm.bias_level); } -static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8971_suspend(struct snd_soc_codec *codec) { wm8971_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -725,7 +724,7 @@ MODULE_DEVICE_TABLE(i2c, wm8971_i2c_id); static struct i2c_driver wm8971_i2c_driver = { .driver = { - .name = "wm8971-codec", + .name = "wm8971", .owner = THIS_MODULE, }, .probe = wm8971_i2c_probe, diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 9352f1e088d..4a6a7b5a61b 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -226,7 +225,7 @@ SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, wm8974_inpga, SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0, wm8974_boost_mixer, ARRAY_SIZE(wm8974_boost_mixer)), -SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0), +SND_SOC_DAPM_SUPPLY("Mic Bias", WM8974_POWER1, 4, 0, NULL, 0), SND_SOC_DAPM_INPUT("MICN"), SND_SOC_DAPM_INPUT("MICP"), @@ -557,7 +556,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, #define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8974_ops = { +static const struct snd_soc_dai_ops wm8974_ops = { .hw_params = wm8974_pcm_hw_params, .digital_mute = wm8974_mute, .set_fmt = wm8974_set_dai_fmt, @@ -583,7 +582,7 @@ static struct snd_soc_dai_driver wm8974_dai = { .symmetric_rates = 1, }; -static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8974_suspend(struct snd_soc_codec *codec) { wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -672,7 +671,7 @@ MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id); static struct i2c_driver wm8974_i2c_driver = { .driver = { - .name = "wm8974-codec", + .name = "wm8974", .owner = THIS_MODULE, }, .probe = wm8974_i2c_probe, diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 41ca4d9ac20..85d514d63a4 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -865,7 +864,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec, #define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8978_dai_ops = { +static const struct snd_soc_dai_ops wm8978_dai_ops = { .hw_params = wm8978_hw_params, .digital_mute = wm8978_mute, .set_fmt = wm8978_set_dai_fmt, @@ -893,7 +892,7 @@ static struct snd_soc_dai_driver wm8978_dai = { .ops = &wm8978_dai_ops, }; -static int wm8978_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8978_suspend(struct snd_soc_codec *codec) { wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); /* Also switch PLL off */ diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 93ee28439be..cebde568d19 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -481,7 +481,8 @@ static const struct snd_soc_dapm_widget wm8983_dapm_widgets[] = { SND_SOC_DAPM_PGA("OUT4 Out", WM8983_POWER_MANAGEMENT_3, 8, 0, NULL, 0), - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias", WM8983_POWER_MANAGEMENT_1, 4, 0, + NULL, 0), SND_SOC_DAPM_INPUT("LIN"), SND_SOC_DAPM_INPUT("LIP"), @@ -973,7 +974,7 @@ static int wm8983_set_bias_level(struct snd_soc_codec *codec, } #ifdef CONFIG_PM -static int wm8983_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8983_suspend(struct snd_soc_codec *codec) { wm8983_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1034,7 +1035,7 @@ static int wm8983_probe(struct snd_soc_codec *codec) return 0; } -static struct snd_soc_dai_ops wm8983_dai_ops = { +static const struct snd_soc_dai_ops wm8983_dai_ops = { .digital_mute = wm8983_dac_mute, .hw_params = wm8983_hw_params, .set_fmt = wm8983_set_fmt, diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index bae510acdec..c0c86b3c6ad 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -411,7 +411,8 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = { SND_SOC_DAPM_PGA("Right Speaker Out", WM8985_POWER_MANAGEMENT_3, 6, 0, NULL, 0), - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias", WM8985_POWER_MANAGEMENT_1, 4, 0, + NULL, 0), SND_SOC_DAPM_INPUT("LIN"), SND_SOC_DAPM_INPUT("LIP"), @@ -944,7 +945,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, } #ifdef CONFIG_PM -static int wm8985_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8985_suspend(struct snd_soc_codec *codec) { wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1030,7 +1031,7 @@ err_reg_get: return ret; } -static struct snd_soc_dai_ops wm8985_dai_ops = { +static const struct snd_soc_dai_ops wm8985_dai_ops = { .digital_mute = wm8985_dac_mute, .hw_params = wm8985_hw_params, .set_fmt = wm8985_set_fmt, diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 2e9eba717d1..ab52963dd04 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -18,7 +18,6 @@ #include <linux/pm.h> #include <linux/i2c.h> #include <linux/spi/spi.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -267,7 +266,7 @@ static const struct snd_kcontrol_new wm8988_monomux_controls = SOC_DAPM_ENUM("Route", monomux); static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias", WM8988_PWR1, 1, 0, NULL, 0), SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, &wm8988_diffmux_controls), @@ -701,7 +700,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, #define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8988_ops = { +static const struct snd_soc_dai_ops wm8988_ops = { .startup = wm8988_pcm_startup, .hw_params = wm8988_pcm_hw_params, .set_fmt = wm8988_set_dai_fmt, @@ -729,7 +728,7 @@ static struct snd_soc_dai_driver wm8988_dai = { .symmetric_rates = 1, }; -static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8988_suspend(struct snd_soc_codec *codec) { wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -823,7 +822,7 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi) static struct spi_driver wm8988_spi_driver = { .driver = { - .name = "wm8988-codec", + .name = "wm8988", .owner = THIS_MODULE, }, .probe = wm8988_spi_probe, diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index d29a9622964..e538edaae1f 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -776,8 +775,8 @@ SND_SOC_DAPM_PGA("ROPGA", WM8990_POWER_MANAGEMENT_3, WM8990_ROPGA_ENA_BIT, 0, NULL, 0), /* MICBIAS */ -SND_SOC_DAPM_MICBIAS("MICBIAS", WM8990_POWER_MANAGEMENT_1, - WM8990_MICBIAS_ENA_BIT, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS", WM8990_POWER_MANAGEMENT_1, + WM8990_MICBIAS_ENA_BIT, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("LON"), SND_SOC_DAPM_OUTPUT("LOP"), @@ -1287,7 +1286,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, * 1. ADC/DAC on Primary Interface * 2. ADC on Primary Interface/DAC on secondary */ -static struct snd_soc_dai_ops wm8990_dai_ops = { +static const struct snd_soc_dai_ops wm8990_dai_ops = { .hw_params = wm8990_hw_params, .digital_mute = wm8990_mute, .set_fmt = wm8990_set_dai_fmt, @@ -1314,7 +1313,7 @@ static struct snd_soc_dai_driver wm8990_dai = { .ops = &wm8990_dai_ops, }; -static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8990_suspend(struct snd_soc_codec *codec) { wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1418,7 +1417,7 @@ MODULE_DEVICE_TABLE(i2c, wm8990_i2c_id); static struct i2c_driver wm8990_i2c_driver = { .driver = { - .name = "wm8990-codec", + .name = "wm8990", .owner = THIS_MODULE, }, .probe = wm8990_i2c_probe, diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index c9ab3ba9bce..7ee40da8dbb 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -18,7 +18,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -770,8 +769,8 @@ static const struct snd_soc_dapm_widget wm8991_dapm_widgets[] = { NULL, 0), /* MICBIAS */ - SND_SOC_DAPM_MICBIAS("MICBIAS", WM8991_POWER_MANAGEMENT_1, - WM8991_MICBIAS_ENA_BIT, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS", WM8991_POWER_MANAGEMENT_1, + WM8991_MICBIAS_ENA_BIT, 0, NULL, 0), SND_SOC_DAPM_OUTPUT("LON"), SND_SOC_DAPM_OUTPUT("LOP"), @@ -1241,7 +1240,7 @@ static int wm8991_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm8991_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8991_suspend(struct snd_soc_codec *codec) { wm8991_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1311,7 +1310,7 @@ static int wm8991_probe(struct snd_soc_codec *codec) #define WM8991_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops wm8991_ops = { +static const struct snd_soc_dai_ops wm8991_ops = { .hw_params = wm8991_hw_params, .digital_mute = wm8991_mute, .set_fmt = wm8991_set_dai_fmt, diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index eec8e143511..2b40c93601e 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -512,7 +512,7 @@ static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0); static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0); static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); static const unsigned int drc_max_tlv[] = { - TLV_DB_RANGE_HEAD(4), + TLV_DB_RANGE_HEAD(2), 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0), 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0), }; @@ -934,28 +934,6 @@ static const struct snd_soc_dapm_route routes[] = { { "Right Headphone Mux", "DAC", "DACR" }, }; -static void wm8993_cache_restore(struct snd_soc_codec *codec) -{ - u16 *cache = codec->reg_cache; - int i; - - if (!codec->cache_sync) - return; - - /* Reenable hardware writes */ - codec->cache_only = 0; - - /* Restore the register settings */ - for (i = 1; i < WM8993_MAX_REGISTER; i++) { - if (cache[i] == wm8993_reg_defaults[i]) - continue; - snd_soc_write(codec, i, cache[i]); - } - - /* We're in sync again */ - codec->cache_sync = 0; -} - static int wm8993_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { @@ -979,7 +957,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, if (ret != 0) return ret; - wm8993_cache_restore(codec); + snd_soc_cache_sync(codec); /* Tune DC servo configuration */ snd_soc_write(codec, 0x44, 3); @@ -1394,7 +1372,7 @@ out: return 0; } -static struct snd_soc_dai_ops wm8993_ops = { +static const struct snd_soc_dai_ops wm8993_ops = { .set_sysclk = wm8993_set_sysclk, .set_fmt = wm8993_set_dai_fmt, .hw_params = wm8993_hw_params, @@ -1544,7 +1522,7 @@ static int wm8993_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int wm8993_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8993_suspend(struct snd_soc_codec *codec) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); int fll_fout = wm8993->fll_fout; @@ -1613,7 +1591,8 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, struct wm8993_priv *wm8993; int ret; - wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL); + wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), + GFP_KERNEL); if (wm8993 == NULL) return -ENOMEM; @@ -1621,8 +1600,6 @@ static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8993, &wm8993_dai, 1); - if (ret < 0) - kfree(wm8993); return ret; } @@ -1641,7 +1618,7 @@ MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id); static struct i2c_driver wm8993_i2c_driver = { .driver = { - .name = "wm8993-codec", + .name = "wm8993", .owner = THIS_MODULE, }, .probe = wm8993_i2c_probe, diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c deleted file mode 100644 index df5a8b9a250..00000000000 --- a/sound/soc/codecs/wm8994-tables.c +++ /dev/null @@ -1,3147 +0,0 @@ -#include "wm8994.h" - -const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { - { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */ - { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */ - { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */ - { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */ - { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */ - { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */ - { 0x003F, 0x003F }, /* R6 - Power Management (6) */ - { 0x0000, 0x0000 }, /* R7 */ - { 0x0000, 0x0000 }, /* R8 */ - { 0x0000, 0x0000 }, /* R9 */ - { 0x0000, 0x0000 }, /* R10 */ - { 0x0000, 0x0000 }, /* R11 */ - { 0x0000, 0x0000 }, /* R12 */ - { 0x0000, 0x0000 }, /* R13 */ - { 0x0000, 0x0000 }, /* R14 */ - { 0x0000, 0x0000 }, /* R15 */ - { 0x0000, 0x0000 }, /* R16 */ - { 0x0000, 0x0000 }, /* R17 */ - { 0x0000, 0x0000 }, /* R18 */ - { 0x0000, 0x0000 }, /* R19 */ - { 0x0000, 0x0000 }, /* R20 */ - { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */ - { 0x0000, 0x0000 }, /* R22 */ - { 0x0000, 0x0000 }, /* R23 */ - { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */ - { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */ - { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */ - { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */ - { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */ - { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */ - { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */ - { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */ - { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */ - { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */ - { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */ - { 0x003F, 0x003F }, /* R37 - ClassD */ - { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */ - { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */ - { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */ - { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */ - { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */ - { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */ - { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */ - { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */ - { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */ - { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */ - { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */ - { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */ - { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */ - { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */ - { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */ - { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */ - { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */ - { 0x00C1, 0x00C1 }, /* R55 - Additional Control */ - { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */ - { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */ - { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ - { 0x000F, 0x000F }, /* R59 - LDO 1 */ - { 0x0007, 0x0007 }, /* R60 - LDO 2 */ - { 0xFFFF, 0xFFFF }, /* R61 */ - { 0xFFFF, 0xFFFF }, /* R62 */ - { 0x0000, 0x0000 }, /* R63 */ - { 0x0000, 0x0000 }, /* R64 */ - { 0x0000, 0x0000 }, /* R65 */ - { 0x0000, 0x0000 }, /* R66 */ - { 0x0000, 0x0000 }, /* R67 */ - { 0x0000, 0x0000 }, /* R68 */ - { 0x0000, 0x0000 }, /* R69 */ - { 0x0000, 0x0000 }, /* R70 */ - { 0x0000, 0x0000 }, /* R71 */ - { 0x0000, 0x0000 }, /* R72 */ - { 0x0000, 0x0000 }, /* R73 */ - { 0x0000, 0x0000 }, /* R74 */ - { 0x0000, 0x0000 }, /* R75 */ - { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ - { 0x0000, 0x0000 }, /* R77 */ - { 0x0000, 0x0000 }, /* R78 */ - { 0x0000, 0x0000 }, /* R79 */ - { 0x0000, 0x0000 }, /* R80 */ - { 0x0301, 0x0301 }, /* R81 - Class W (1) */ - { 0x0000, 0x0000 }, /* R82 */ - { 0x0000, 0x0000 }, /* R83 */ - { 0x333F, 0x333F }, /* R84 - DC Servo (1) */ - { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */ - { 0x0000, 0x0000 }, /* R86 */ - { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */ - { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */ - { 0x0000, 0x0000 }, /* R89 */ - { 0x0000, 0x0000 }, /* R90 */ - { 0x0000, 0x0000 }, /* R91 */ - { 0x0000, 0x0000 }, /* R92 */ - { 0x0000, 0x0000 }, /* R93 */ - { 0x0000, 0x0000 }, /* R94 */ - { 0x0000, 0x0000 }, /* R95 */ - { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */ - { 0x0000, 0x0000 }, /* R97 */ - { 0x0000, 0x0000 }, /* R98 */ - { 0x0000, 0x0000 }, /* R99 */ - { 0x0000, 0x0000 }, /* R100 */ - { 0x0000, 0x0000 }, /* R101 */ - { 0x0000, 0x0000 }, /* R102 */ - { 0x0000, 0x0000 }, /* R103 */ - { 0x0000, 0x0000 }, /* R104 */ - { 0x0000, 0x0000 }, /* R105 */ - { 0x0000, 0x0000 }, /* R106 */ - { 0x0000, 0x0000 }, /* R107 */ - { 0x0000, 0x0000 }, /* R108 */ - { 0x0000, 0x0000 }, /* R109 */ - { 0x0000, 0x0000 }, /* R110 */ - { 0x0000, 0x0000 }, /* R111 */ - { 0x0000, 0x0000 }, /* R112 */ - { 0x0000, 0x0000 }, /* R113 */ - { 0x0000, 0x0000 }, /* R114 */ - { 0x0000, 0x0000 }, /* R115 */ - { 0x0000, 0x0000 }, /* R116 */ - { 0x0000, 0x0000 }, /* R117 */ - { 0x0000, 0x0000 }, /* R118 */ - { 0x0000, 0x0000 }, /* R119 */ - { 0x0000, 0x0000 }, /* R120 */ - { 0x0000, 0x0000 }, /* R121 */ - { 0x0000, 0x0000 }, /* R122 */ - { 0x0000, 0x0000 }, /* R123 */ - { 0x0000, 0x0000 }, /* R124 */ - { 0x0000, 0x0000 }, /* R125 */ - { 0x0000, 0x0000 }, /* R126 */ - { 0x0000, 0x0000 }, /* R127 */ - { 0x0000, 0x0000 }, /* R128 */ - { 0x0000, 0x0000 }, /* R129 */ - { 0x0000, 0x0000 }, /* R130 */ - { 0x0000, 0x0000 }, /* R131 */ - { 0x0000, 0x0000 }, /* R132 */ - { 0x0000, 0x0000 }, /* R133 */ - { 0x0000, 0x0000 }, /* R134 */ - { 0x0000, 0x0000 }, /* R135 */ - { 0x0000, 0x0000 }, /* R136 */ - { 0x0000, 0x0000 }, /* R137 */ - { 0x0000, 0x0000 }, /* R138 */ - { 0x0000, 0x0000 }, /* R139 */ - { 0x0000, 0x0000 }, /* R140 */ - { 0x0000, 0x0000 }, /* R141 */ - { 0x0000, 0x0000 }, /* R142 */ - { 0x0000, 0x0000 }, /* R143 */ - { 0x0000, 0x0000 }, /* R144 */ - { 0x0000, 0x0000 }, /* R145 */ - { 0x0000, 0x0000 }, /* R146 */ - { 0x0000, 0x0000 }, /* R147 */ - { 0x0000, 0x0000 }, /* R148 */ - { 0x0000, 0x0000 }, /* R149 */ - { 0x0000, 0x0000 }, /* R150 */ - { 0x0000, 0x0000 }, /* R151 */ - { 0x0000, 0x0000 }, /* R152 */ - { 0x0000, 0x0000 }, /* R153 */ - { 0x0000, 0x0000 }, /* R154 */ - { 0x0000, 0x0000 }, /* R155 */ - { 0x0000, 0x0000 }, /* R156 */ - { 0x0000, 0x0000 }, /* R157 */ - { 0x0000, 0x0000 }, /* R158 */ - { 0x0000, 0x0000 }, /* R159 */ - { 0x0000, 0x0000 }, /* R160 */ - { 0x0000, 0x0000 }, /* R161 */ - { 0x0000, 0x0000 }, /* R162 */ - { 0x0000, 0x0000 }, /* R163 */ - { 0x0000, 0x0000 }, /* R164 */ - { 0x0000, 0x0000 }, /* R165 */ - { 0x0000, 0x0000 }, /* R166 */ - { 0x0000, 0x0000 }, /* R167 */ - { 0x0000, 0x0000 }, /* R168 */ - { 0x0000, 0x0000 }, /* R169 */ - { 0x0000, 0x0000 }, /* R170 */ - { 0x0000, 0x0000 }, /* R171 */ - { 0x0000, 0x0000 }, /* R172 */ - { 0x0000, 0x0000 }, /* R173 */ - { 0x0000, 0x0000 }, /* R174 */ - { 0x0000, 0x0000 }, /* R175 */ - { 0x0000, 0x0000 }, /* R176 */ - { 0x0000, 0x0000 }, /* R177 */ - { 0x0000, 0x0000 }, /* R178 */ - { 0x0000, 0x0000 }, /* R179 */ - { 0x0000, 0x0000 }, /* R180 */ - { 0x0000, 0x0000 }, /* R181 */ - { 0x0000, 0x0000 }, /* R182 */ - { 0x0000, 0x0000 }, /* R183 */ - { 0x0000, 0x0000 }, /* R184 */ - { 0x0000, 0x0000 }, /* R185 */ - { 0x0000, 0x0000 }, /* R186 */ - { 0x0000, 0x0000 }, /* R187 */ - { 0x0000, 0x0000 }, /* R188 */ - { 0x0000, 0x0000 }, /* R189 */ - { 0x0000, 0x0000 }, /* R190 */ - { 0x0000, 0x0000 }, /* R191 */ - { 0x0000, 0x0000 }, /* R192 */ - { 0x0000, 0x0000 }, /* R193 */ - { 0x0000, 0x0000 }, /* R194 */ - { 0x0000, 0x0000 }, /* R195 */ - { 0x0000, 0x0000 }, /* R196 */ - { 0x0000, 0x0000 }, /* R197 */ - { 0x0000, 0x0000 }, /* R198 */ - { 0x0000, 0x0000 }, /* R199 */ - { 0x0000, 0x0000 }, /* R200 */ - { 0x0000, 0x0000 }, /* R201 */ - { 0x0000, 0x0000 }, /* R202 */ - { 0x0000, 0x0000 }, /* R203 */ - { 0x0000, 0x0000 }, /* R204 */ - { 0x0000, 0x0000 }, /* R205 */ - { 0x0000, 0x0000 }, /* R206 */ - { 0x0000, 0x0000 }, /* R207 */ - { 0xFFFF, 0xFFFF }, /* R208 */ - { 0xFFFF, 0xFFFF }, /* R209 */ - { 0xFFFF, 0xFFFF }, /* R210 */ - { 0x0000, 0x0000 }, /* R211 */ - { 0x0000, 0x0000 }, /* R212 */ - { 0x0000, 0x0000 }, /* R213 */ - { 0x0000, 0x0000 }, /* R214 */ - { 0x0000, 0x0000 }, /* R215 */ - { 0x0000, 0x0000 }, /* R216 */ - { 0x0000, 0x0000 }, /* R217 */ - { 0x0000, 0x0000 }, /* R218 */ - { 0x0000, 0x0000 }, /* R219 */ - { 0x0000, 0x0000 }, /* R220 */ - { 0x0000, 0x0000 }, /* R221 */ - { 0x0000, 0x0000 }, /* R222 */ - { 0x0000, 0x0000 }, /* R223 */ - { 0x0000, 0x0000 }, /* R224 */ - { 0x0000, 0x0000 }, /* R225 */ - { 0x0000, 0x0000 }, /* R226 */ - { 0x0000, 0x0000 }, /* R227 */ - { 0x0000, 0x0000 }, /* R228 */ - { 0x0000, 0x0000 }, /* R229 */ - { 0x0000, 0x0000 }, /* R230 */ - { 0x0000, 0x0000 }, /* R231 */ - { 0x0000, 0x0000 }, /* R232 */ - { 0x0000, 0x0000 }, /* R233 */ - { 0x0000, 0x0000 }, /* R234 */ - { 0x0000, 0x0000 }, /* R235 */ - { 0x0000, 0x0000 }, /* R236 */ - { 0x0000, 0x0000 }, /* R237 */ - { 0x0000, 0x0000 }, /* R238 */ - { 0x0000, 0x0000 }, /* R239 */ - { 0x0000, 0x0000 }, /* R240 */ - { 0x0000, 0x0000 }, /* R241 */ - { 0x0000, 0x0000 }, /* R242 */ - { 0x0000, 0x0000 }, /* R243 */ - { 0x0000, 0x0000 }, /* R244 */ - { 0x0000, 0x0000 }, /* R245 */ - { 0x0000, 0x0000 }, /* R246 */ - { 0x0000, 0x0000 }, /* R247 */ - { 0x0000, 0x0000 }, /* R248 */ - { 0x0000, 0x0000 }, /* R249 */ - { 0x0000, 0x0000 }, /* R250 */ - { 0x0000, 0x0000 }, /* R251 */ - { 0x0000, 0x0000 }, /* R252 */ - { 0x0000, 0x0000 }, /* R253 */ - { 0x0000, 0x0000 }, /* R254 */ - { 0x0000, 0x0000 }, /* R255 */ - { 0x000F, 0x0000 }, /* R256 - Chip Revision */ - { 0x0074, 0x0074 }, /* R257 - Control Interface */ - { 0x0000, 0x0000 }, /* R258 */ - { 0x0000, 0x0000 }, /* R259 */ - { 0x0000, 0x0000 }, /* R260 */ - { 0x0000, 0x0000 }, /* R261 */ - { 0x0000, 0x0000 }, /* R262 */ - { 0x0000, 0x0000 }, /* R263 */ - { 0x0000, 0x0000 }, /* R264 */ - { 0x0000, 0x0000 }, /* R265 */ - { 0x0000, 0x0000 }, /* R266 */ - { 0x0000, 0x0000 }, /* R267 */ - { 0x0000, 0x0000 }, /* R268 */ - { 0x0000, 0x0000 }, /* R269 */ - { 0x0000, 0x0000 }, /* R270 */ - { 0x0000, 0x0000 }, /* R271 */ - { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */ - { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ - { 0x0000, 0x0000 }, /* R274 */ - { 0x0000, 0x0000 }, /* R275 */ - { 0x0000, 0x0000 }, /* R276 */ - { 0x0000, 0x0000 }, /* R277 */ - { 0x0000, 0x0000 }, /* R278 */ - { 0x0000, 0x0000 }, /* R279 */ - { 0x0000, 0x0000 }, /* R280 */ - { 0x0000, 0x0000 }, /* R281 */ - { 0x0000, 0x0000 }, /* R282 */ - { 0x0000, 0x0000 }, /* R283 */ - { 0x0000, 0x0000 }, /* R284 */ - { 0x0000, 0x0000 }, /* R285 */ - { 0x0000, 0x0000 }, /* R286 */ - { 0x0000, 0x0000 }, /* R287 */ - { 0x0000, 0x0000 }, /* R288 */ - { 0x0000, 0x0000 }, /* R289 */ - { 0x0000, 0x0000 }, /* R290 */ - { 0x0000, 0x0000 }, /* R291 */ - { 0x0000, 0x0000 }, /* R292 */ - { 0x0000, 0x0000 }, /* R293 */ - { 0x0000, 0x0000 }, /* R294 */ - { 0x0000, 0x0000 }, /* R295 */ - { 0x0000, 0x0000 }, /* R296 */ - { 0x0000, 0x0000 }, /* R297 */ - { 0x0000, 0x0000 }, /* R298 */ - { 0x0000, 0x0000 }, /* R299 */ - { 0x0000, 0x0000 }, /* R300 */ - { 0x0000, 0x0000 }, /* R301 */ - { 0x0000, 0x0000 }, /* R302 */ - { 0x0000, 0x0000 }, /* R303 */ - { 0x0000, 0x0000 }, /* R304 */ - { 0x0000, 0x0000 }, /* R305 */ - { 0x0000, 0x0000 }, /* R306 */ - { 0x0000, 0x0000 }, /* R307 */ - { 0x0000, 0x0000 }, /* R308 */ - { 0x0000, 0x0000 }, /* R309 */ - { 0x0000, 0x0000 }, /* R310 */ - { 0x0000, 0x0000 }, /* R311 */ - { 0x0000, 0x0000 }, /* R312 */ - { 0x0000, 0x0000 }, /* R313 */ - { 0x0000, 0x0000 }, /* R314 */ - { 0x0000, 0x0000 }, /* R315 */ - { 0x0000, 0x0000 }, /* R316 */ - { 0x0000, 0x0000 }, /* R317 */ - { 0x0000, 0x0000 }, /* R318 */ - { 0x0000, 0x0000 }, /* R319 */ - { 0x0000, 0x0000 }, /* R320 */ - { 0x0000, 0x0000 }, /* R321 */ - { 0x0000, 0x0000 }, /* R322 */ - { 0x0000, 0x0000 }, /* R323 */ - { 0x0000, 0x0000 }, /* R324 */ - { 0x0000, 0x0000 }, /* R325 */ - { 0x0000, 0x0000 }, /* R326 */ - { 0x0000, 0x0000 }, /* R327 */ - { 0x0000, 0x0000 }, /* R328 */ - { 0x0000, 0x0000 }, /* R329 */ - { 0x0000, 0x0000 }, /* R330 */ - { 0x0000, 0x0000 }, /* R331 */ - { 0x0000, 0x0000 }, /* R332 */ - { 0x0000, 0x0000 }, /* R333 */ - { 0x0000, 0x0000 }, /* R334 */ - { 0x0000, 0x0000 }, /* R335 */ - { 0x0000, 0x0000 }, /* R336 */ - { 0x0000, 0x0000 }, /* R337 */ - { 0x0000, 0x0000 }, /* R338 */ - { 0x0000, 0x0000 }, /* R339 */ - { 0x0000, 0x0000 }, /* R340 */ - { 0x0000, 0x0000 }, /* R341 */ - { 0x0000, 0x0000 }, /* R342 */ - { 0x0000, 0x0000 }, /* R343 */ - { 0x0000, 0x0000 }, /* R344 */ - { 0x0000, 0x0000 }, /* R345 */ - { 0x0000, 0x0000 }, /* R346 */ - { 0x0000, 0x0000 }, /* R347 */ - { 0x0000, 0x0000 }, /* R348 */ - { 0x0000, 0x0000 }, /* R349 */ - { 0x0000, 0x0000 }, /* R350 */ - { 0x0000, 0x0000 }, /* R351 */ - { 0x0000, 0x0000 }, /* R352 */ - { 0x0000, 0x0000 }, /* R353 */ - { 0x0000, 0x0000 }, /* R354 */ - { 0x0000, 0x0000 }, /* R355 */ - { 0x0000, 0x0000 }, /* R356 */ - { 0x0000, 0x0000 }, /* R357 */ - { 0x0000, 0x0000 }, /* R358 */ - { 0x0000, 0x0000 }, /* R359 */ - { 0x0000, 0x0000 }, /* R360 */ - { 0x0000, 0x0000 }, /* R361 */ - { 0x0000, 0x0000 }, /* R362 */ - { 0x0000, 0x0000 }, /* R363 */ - { 0x0000, 0x0000 }, /* R364 */ - { 0x0000, 0x0000 }, /* R365 */ - { 0x0000, 0x0000 }, /* R366 */ - { 0x0000, 0x0000 }, /* R367 */ - { 0x0000, 0x0000 }, /* R368 */ - { 0x0000, 0x0000 }, /* R369 */ - { 0x0000, 0x0000 }, /* R370 */ - { 0x0000, 0x0000 }, /* R371 */ - { 0x0000, 0x0000 }, /* R372 */ - { 0x0000, 0x0000 }, /* R373 */ - { 0x0000, 0x0000 }, /* R374 */ - { 0x0000, 0x0000 }, /* R375 */ - { 0x0000, 0x0000 }, /* R376 */ - { 0x0000, 0x0000 }, /* R377 */ - { 0x0000, 0x0000 }, /* R378 */ - { 0x0000, 0x0000 }, /* R379 */ - { 0x0000, 0x0000 }, /* R380 */ - { 0x0000, 0x0000 }, /* R381 */ - { 0x0000, 0x0000 }, /* R382 */ - { 0x0000, 0x0000 }, /* R383 */ - { 0x0000, 0x0000 }, /* R384 */ - { 0x0000, 0x0000 }, /* R385 */ - { 0x0000, 0x0000 }, /* R386 */ - { 0x0000, 0x0000 }, /* R387 */ - { 0x0000, 0x0000 }, /* R388 */ - { 0x0000, 0x0000 }, /* R389 */ - { 0x0000, 0x0000 }, /* R390 */ - { 0x0000, 0x0000 }, /* R391 */ - { 0x0000, 0x0000 }, /* R392 */ - { 0x0000, 0x0000 }, /* R393 */ - { 0x0000, 0x0000 }, /* R394 */ - { 0x0000, 0x0000 }, /* R395 */ - { 0x0000, 0x0000 }, /* R396 */ - { 0x0000, 0x0000 }, /* R397 */ - { 0x0000, 0x0000 }, /* R398 */ - { 0x0000, 0x0000 }, /* R399 */ - { 0x0000, 0x0000 }, /* R400 */ - { 0x0000, 0x0000 }, /* R401 */ - { 0x0000, 0x0000 }, /* R402 */ - { 0x0000, 0x0000 }, /* R403 */ - { 0x0000, 0x0000 }, /* R404 */ - { 0x0000, 0x0000 }, /* R405 */ - { 0x0000, 0x0000 }, /* R406 */ - { 0x0000, 0x0000 }, /* R407 */ - { 0x0000, 0x0000 }, /* R408 */ - { 0x0000, 0x0000 }, /* R409 */ - { 0x0000, 0x0000 }, /* R410 */ - { 0x0000, 0x0000 }, /* R411 */ - { 0x0000, 0x0000 }, /* R412 */ - { 0x0000, 0x0000 }, /* R413 */ - { 0x0000, 0x0000 }, /* R414 */ - { 0x0000, 0x0000 }, /* R415 */ - { 0x0000, 0x0000 }, /* R416 */ - { 0x0000, 0x0000 }, /* R417 */ - { 0x0000, 0x0000 }, /* R418 */ - { 0x0000, 0x0000 }, /* R419 */ - { 0x0000, 0x0000 }, /* R420 */ - { 0x0000, 0x0000 }, /* R421 */ - { 0x0000, 0x0000 }, /* R422 */ - { 0x0000, 0x0000 }, /* R423 */ - { 0x0000, 0x0000 }, /* R424 */ - { 0x0000, 0x0000 }, /* R425 */ - { 0x0000, 0x0000 }, /* R426 */ - { 0x0000, 0x0000 }, /* R427 */ - { 0x0000, 0x0000 }, /* R428 */ - { 0x0000, 0x0000 }, /* R429 */ - { 0x0000, 0x0000 }, /* R430 */ - { 0x0000, 0x0000 }, /* R431 */ - { 0x0000, 0x0000 }, /* R432 */ - { 0x0000, 0x0000 }, /* R433 */ - { 0x0000, 0x0000 }, /* R434 */ - { 0x0000, 0x0000 }, /* R435 */ - { 0x0000, 0x0000 }, /* R436 */ - { 0x0000, 0x0000 }, /* R437 */ - { 0x0000, 0x0000 }, /* R438 */ - { 0x0000, 0x0000 }, /* R439 */ - { 0x0000, 0x0000 }, /* R440 */ - { 0x0000, 0x0000 }, /* R441 */ - { 0x0000, 0x0000 }, /* R442 */ - { 0x0000, 0x0000 }, /* R443 */ - { 0x0000, 0x0000 }, /* R444 */ - { 0x0000, 0x0000 }, /* R445 */ - { 0x0000, 0x0000 }, /* R446 */ - { 0x0000, 0x0000 }, /* R447 */ - { 0x0000, 0x0000 }, /* R448 */ - { 0x0000, 0x0000 }, /* R449 */ - { 0x0000, 0x0000 }, /* R450 */ - { 0x0000, 0x0000 }, /* R451 */ - { 0x0000, 0x0000 }, /* R452 */ - { 0x0000, 0x0000 }, /* R453 */ - { 0x0000, 0x0000 }, /* R454 */ - { 0x0000, 0x0000 }, /* R455 */ - { 0x0000, 0x0000 }, /* R456 */ - { 0x0000, 0x0000 }, /* R457 */ - { 0x0000, 0x0000 }, /* R458 */ - { 0x0000, 0x0000 }, /* R459 */ - { 0x0000, 0x0000 }, /* R460 */ - { 0x0000, 0x0000 }, /* R461 */ - { 0x0000, 0x0000 }, /* R462 */ - { 0x0000, 0x0000 }, /* R463 */ - { 0x0000, 0x0000 }, /* R464 */ - { 0x0000, 0x0000 }, /* R465 */ - { 0x0000, 0x0000 }, /* R466 */ - { 0x0000, 0x0000 }, /* R467 */ - { 0x0000, 0x0000 }, /* R468 */ - { 0x0000, 0x0000 }, /* R469 */ - { 0x0000, 0x0000 }, /* R470 */ - { 0x0000, 0x0000 }, /* R471 */ - { 0x0000, 0x0000 }, /* R472 */ - { 0x0000, 0x0000 }, /* R473 */ - { 0x0000, 0x0000 }, /* R474 */ - { 0x0000, 0x0000 }, /* R475 */ - { 0x0000, 0x0000 }, /* R476 */ - { 0x0000, 0x0000 }, /* R477 */ - { 0x0000, 0x0000 }, /* R478 */ - { 0x0000, 0x0000 }, /* R479 */ - { 0x0000, 0x0000 }, /* R480 */ - { 0x0000, 0x0000 }, /* R481 */ - { 0x0000, 0x0000 }, /* R482 */ - { 0x0000, 0x0000 }, /* R483 */ - { 0x0000, 0x0000 }, /* R484 */ - { 0x0000, 0x0000 }, /* R485 */ - { 0x0000, 0x0000 }, /* R486 */ - { 0x0000, 0x0000 }, /* R487 */ - { 0x0000, 0x0000 }, /* R488 */ - { 0x0000, 0x0000 }, /* R489 */ - { 0x0000, 0x0000 }, /* R490 */ - { 0x0000, 0x0000 }, /* R491 */ - { 0x0000, 0x0000 }, /* R492 */ - { 0x0000, 0x0000 }, /* R493 */ - { 0x0000, 0x0000 }, /* R494 */ - { 0x0000, 0x0000 }, /* R495 */ - { 0x0000, 0x0000 }, /* R496 */ - { 0x0000, 0x0000 }, /* R497 */ - { 0x0000, 0x0000 }, /* R498 */ - { 0x0000, 0x0000 }, /* R499 */ - { 0x0000, 0x0000 }, /* R500 */ - { 0x0000, 0x0000 }, /* R501 */ - { 0x0000, 0x0000 }, /* R502 */ - { 0x0000, 0x0000 }, /* R503 */ - { 0x0000, 0x0000 }, /* R504 */ - { 0x0000, 0x0000 }, /* R505 */ - { 0x0000, 0x0000 }, /* R506 */ - { 0x0000, 0x0000 }, /* R507 */ - { 0x0000, 0x0000 }, /* R508 */ - { 0x0000, 0x0000 }, /* R509 */ - { 0x0000, 0x0000 }, /* R510 */ - { 0x0000, 0x0000 }, /* R511 */ - { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */ - { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */ - { 0x0000, 0x0000 }, /* R514 */ - { 0x0000, 0x0000 }, /* R515 */ - { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */ - { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */ - { 0x0000, 0x0000 }, /* R518 */ - { 0x0000, 0x0000 }, /* R519 */ - { 0x001F, 0x001F }, /* R520 - Clocking (1) */ - { 0x0777, 0x0777 }, /* R521 - Clocking (2) */ - { 0x0000, 0x0000 }, /* R522 */ - { 0x0000, 0x0000 }, /* R523 */ - { 0x0000, 0x0000 }, /* R524 */ - { 0x0000, 0x0000 }, /* R525 */ - { 0x0000, 0x0000 }, /* R526 */ - { 0x0000, 0x0000 }, /* R527 */ - { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */ - { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */ - { 0x000F, 0x0000 }, /* R530 - Rate Status */ - { 0x0000, 0x0000 }, /* R531 */ - { 0x0000, 0x0000 }, /* R532 */ - { 0x0000, 0x0000 }, /* R533 */ - { 0x0000, 0x0000 }, /* R534 */ - { 0x0000, 0x0000 }, /* R535 */ - { 0x0000, 0x0000 }, /* R536 */ - { 0x0000, 0x0000 }, /* R537 */ - { 0x0000, 0x0000 }, /* R538 */ - { 0x0000, 0x0000 }, /* R539 */ - { 0x0000, 0x0000 }, /* R540 */ - { 0x0000, 0x0000 }, /* R541 */ - { 0x0000, 0x0000 }, /* R542 */ - { 0x0000, 0x0000 }, /* R543 */ - { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */ - { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */ - { 0x0000, 0x0000 }, /* R549 */ - { 0x0000, 0x0000 }, /* R550 */ - { 0x0000, 0x0000 }, /* R551 */ - { 0x0000, 0x0000 }, /* R552 */ - { 0x0000, 0x0000 }, /* R553 */ - { 0x0000, 0x0000 }, /* R554 */ - { 0x0000, 0x0000 }, /* R555 */ - { 0x0000, 0x0000 }, /* R556 */ - { 0x0000, 0x0000 }, /* R557 */ - { 0x0000, 0x0000 }, /* R558 */ - { 0x0000, 0x0000 }, /* R559 */ - { 0x0000, 0x0000 }, /* R560 */ - { 0x0000, 0x0000 }, /* R561 */ - { 0x0000, 0x0000 }, /* R562 */ - { 0x0000, 0x0000 }, /* R563 */ - { 0x0000, 0x0000 }, /* R564 */ - { 0x0000, 0x0000 }, /* R565 */ - { 0x0000, 0x0000 }, /* R566 */ - { 0x0000, 0x0000 }, /* R567 */ - { 0x0000, 0x0000 }, /* R568 */ - { 0x0000, 0x0000 }, /* R569 */ - { 0x0000, 0x0000 }, /* R570 */ - { 0x0000, 0x0000 }, /* R571 */ - { 0x0000, 0x0000 }, /* R572 */ - { 0x0000, 0x0000 }, /* R573 */ - { 0x0000, 0x0000 }, /* R574 */ - { 0x0000, 0x0000 }, /* R575 */ - { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */ - { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */ - { 0x0000, 0x0000 }, /* R581 */ - { 0x0000, 0x0000 }, /* R582 */ - { 0x0000, 0x0000 }, /* R583 */ - { 0x0000, 0x0000 }, /* R584 */ - { 0x0000, 0x0000 }, /* R585 */ - { 0x0000, 0x0000 }, /* R586 */ - { 0x0000, 0x0000 }, /* R587 */ - { 0x0000, 0x0000 }, /* R588 */ - { 0x0000, 0x0000 }, /* R589 */ - { 0x0000, 0x0000 }, /* R590 */ - { 0x0000, 0x0000 }, /* R591 */ - { 0x0000, 0x0000 }, /* R592 */ - { 0x0000, 0x0000 }, /* R593 */ - { 0x0000, 0x0000 }, /* R594 */ - { 0x0000, 0x0000 }, /* R595 */ - { 0x0000, 0x0000 }, /* R596 */ - { 0x0000, 0x0000 }, /* R597 */ - { 0x0000, 0x0000 }, /* R598 */ - { 0x0000, 0x0000 }, /* R599 */ - { 0x0000, 0x0000 }, /* R600 */ - { 0x0000, 0x0000 }, /* R601 */ - { 0x0000, 0x0000 }, /* R602 */ - { 0x0000, 0x0000 }, /* R603 */ - { 0x0000, 0x0000 }, /* R604 */ - { 0x0000, 0x0000 }, /* R605 */ - { 0x0000, 0x0000 }, /* R606 */ - { 0x0000, 0x0000 }, /* R607 */ - { 0x0000, 0x0000 }, /* R608 */ - { 0x0000, 0x0000 }, /* R609 */ - { 0x0000, 0x0000 }, /* R610 */ - { 0x0000, 0x0000 }, /* R611 */ - { 0x0000, 0x0000 }, /* R612 */ - { 0x0000, 0x0000 }, /* R613 */ - { 0x0000, 0x0000 }, /* R614 */ - { 0x0000, 0x0000 }, /* R615 */ - { 0x0000, 0x0000 }, /* R616 */ - { 0x0000, 0x0000 }, /* R617 */ - { 0x0000, 0x0000 }, /* R618 */ - { 0x0000, 0x0000 }, /* R619 */ - { 0x0000, 0x0000 }, /* R620 */ - { 0x0000, 0x0000 }, /* R621 */ - { 0x0000, 0x0000 }, /* R622 */ - { 0x0000, 0x0000 }, /* R623 */ - { 0x0000, 0x0000 }, /* R624 */ - { 0x0000, 0x0000 }, /* R625 */ - { 0x0000, 0x0000 }, /* R626 */ - { 0x0000, 0x0000 }, /* R627 */ - { 0x0000, 0x0000 }, /* R628 */ - { 0x0000, 0x0000 }, /* R629 */ - { 0x0000, 0x0000 }, /* R630 */ - { 0x0000, 0x0000 }, /* R631 */ - { 0x0000, 0x0000 }, /* R632 */ - { 0x0000, 0x0000 }, /* R633 */ - { 0x0000, 0x0000 }, /* R634 */ - { 0x0000, 0x0000 }, /* R635 */ - { 0x0000, 0x0000 }, /* R636 */ - { 0x0000, 0x0000 }, /* R637 */ - { 0x0000, 0x0000 }, /* R638 */ - { 0x0000, 0x0000 }, /* R639 */ - { 0x0000, 0x0000 }, /* R640 */ - { 0x0000, 0x0000 }, /* R641 */ - { 0x0000, 0x0000 }, /* R642 */ - { 0x0000, 0x0000 }, /* R643 */ - { 0x0000, 0x0000 }, /* R644 */ - { 0x0000, 0x0000 }, /* R645 */ - { 0x0000, 0x0000 }, /* R646 */ - { 0x0000, 0x0000 }, /* R647 */ - { 0x0000, 0x0000 }, /* R648 */ - { 0x0000, 0x0000 }, /* R649 */ - { 0x0000, 0x0000 }, /* R650 */ - { 0x0000, 0x0000 }, /* R651 */ - { 0x0000, 0x0000 }, /* R652 */ - { 0x0000, 0x0000 }, /* R653 */ - { 0x0000, 0x0000 }, /* R654 */ - { 0x0000, 0x0000 }, /* R655 */ - { 0x0000, 0x0000 }, /* R656 */ - { 0x0000, 0x0000 }, /* R657 */ - { 0x0000, 0x0000 }, /* R658 */ - { 0x0000, 0x0000 }, /* R659 */ - { 0x0000, 0x0000 }, /* R660 */ - { 0x0000, 0x0000 }, /* R661 */ - { 0x0000, 0x0000 }, /* R662 */ - { 0x0000, 0x0000 }, /* R663 */ - { 0x0000, 0x0000 }, /* R664 */ - { 0x0000, 0x0000 }, /* R665 */ - { 0x0000, 0x0000 }, /* R666 */ - { 0x0000, 0x0000 }, /* R667 */ - { 0x0000, 0x0000 }, /* R668 */ - { 0x0000, 0x0000 }, /* R669 */ - { 0x0000, 0x0000 }, /* R670 */ - { 0x0000, 0x0000 }, /* R671 */ - { 0x0000, 0x0000 }, /* R672 */ - { 0x0000, 0x0000 }, /* R673 */ - { 0x0000, 0x0000 }, /* R674 */ - { 0x0000, 0x0000 }, /* R675 */ - { 0x0000, 0x0000 }, /* R676 */ - { 0x0000, 0x0000 }, /* R677 */ - { 0x0000, 0x0000 }, /* R678 */ - { 0x0000, 0x0000 }, /* R679 */ - { 0x0000, 0x0000 }, /* R680 */ - { 0x0000, 0x0000 }, /* R681 */ - { 0x0000, 0x0000 }, /* R682 */ - { 0x0000, 0x0000 }, /* R683 */ - { 0x0000, 0x0000 }, /* R684 */ - { 0x0000, 0x0000 }, /* R685 */ - { 0x0000, 0x0000 }, /* R686 */ - { 0x0000, 0x0000 }, /* R687 */ - { 0x0000, 0x0000 }, /* R688 */ - { 0x0000, 0x0000 }, /* R689 */ - { 0x0000, 0x0000 }, /* R690 */ - { 0x0000, 0x0000 }, /* R691 */ - { 0x0000, 0x0000 }, /* R692 */ - { 0x0000, 0x0000 }, /* R693 */ - { 0x0000, 0x0000 }, /* R694 */ - { 0x0000, 0x0000 }, /* R695 */ - { 0x0000, 0x0000 }, /* R696 */ - { 0x0000, 0x0000 }, /* R697 */ - { 0x0000, 0x0000 }, /* R698 */ - { 0x0000, 0x0000 }, /* R699 */ - { 0x0000, 0x0000 }, /* R700 */ - { 0x0000, 0x0000 }, /* R701 */ - { 0x0000, 0x0000 }, /* R702 */ - { 0x0000, 0x0000 }, /* R703 */ - { 0x0000, 0x0000 }, /* R704 */ - { 0x0000, 0x0000 }, /* R705 */ - { 0x0000, 0x0000 }, /* R706 */ - { 0x0000, 0x0000 }, /* R707 */ - { 0x0000, 0x0000 }, /* R708 */ - { 0x0000, 0x0000 }, /* R709 */ - { 0x0000, 0x0000 }, /* R710 */ - { 0x0000, 0x0000 }, /* R711 */ - { 0x0000, 0x0000 }, /* R712 */ - { 0x0000, 0x0000 }, /* R713 */ - { 0x0000, 0x0000 }, /* R714 */ - { 0x0000, 0x0000 }, /* R715 */ - { 0x0000, 0x0000 }, /* R716 */ - { 0x0000, 0x0000 }, /* R717 */ - { 0x0000, 0x0000 }, /* R718 */ - { 0x0000, 0x0000 }, /* R719 */ - { 0x0000, 0x0000 }, /* R720 */ - { 0x0000, 0x0000 }, /* R721 */ - { 0x0000, 0x0000 }, /* R722 */ - { 0x0000, 0x0000 }, /* R723 */ - { 0x0000, 0x0000 }, /* R724 */ - { 0x0000, 0x0000 }, /* R725 */ - { 0x0000, 0x0000 }, /* R726 */ - { 0x0000, 0x0000 }, /* R727 */ - { 0x0000, 0x0000 }, /* R728 */ - { 0x0000, 0x0000 }, /* R729 */ - { 0x0000, 0x0000 }, /* R730 */ - { 0x0000, 0x0000 }, /* R731 */ - { 0x0000, 0x0000 }, /* R732 */ - { 0x0000, 0x0000 }, /* R733 */ - { 0x0000, 0x0000 }, /* R734 */ - { 0x0000, 0x0000 }, /* R735 */ - { 0x0000, 0x0000 }, /* R736 */ - { 0x0000, 0x0000 }, /* R737 */ - { 0x0000, 0x0000 }, /* R738 */ - { 0x0000, 0x0000 }, /* R739 */ - { 0x0000, 0x0000 }, /* R740 */ - { 0x0000, 0x0000 }, /* R741 */ - { 0x0000, 0x0000 }, /* R742 */ - { 0x0000, 0x0000 }, /* R743 */ - { 0x0000, 0x0000 }, /* R744 */ - { 0x0000, 0x0000 }, /* R745 */ - { 0x0000, 0x0000 }, /* R746 */ - { 0x0000, 0x0000 }, /* R747 */ - { 0x0000, 0x0000 }, /* R748 */ - { 0x0000, 0x0000 }, /* R749 */ - { 0x0000, 0x0000 }, /* R750 */ - { 0x0000, 0x0000 }, /* R751 */ - { 0x0000, 0x0000 }, /* R752 */ - { 0x0000, 0x0000 }, /* R753 */ - { 0x0000, 0x0000 }, /* R754 */ - { 0x0000, 0x0000 }, /* R755 */ - { 0x0000, 0x0000 }, /* R756 */ - { 0x0000, 0x0000 }, /* R757 */ - { 0x0000, 0x0000 }, /* R758 */ - { 0x0000, 0x0000 }, /* R759 */ - { 0x0000, 0x0000 }, /* R760 */ - { 0x0000, 0x0000 }, /* R761 */ - { 0x0000, 0x0000 }, /* R762 */ - { 0x0000, 0x0000 }, /* R763 */ - { 0x0000, 0x0000 }, /* R764 */ - { 0x0000, 0x0000 }, /* R765 */ - { 0x0000, 0x0000 }, /* R766 */ - { 0x0000, 0x0000 }, /* R767 */ - { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */ - { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */ - { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */ - { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */ - { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */ - { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */ - { 0x0000, 0x0000 }, /* R776 */ - { 0x0000, 0x0000 }, /* R777 */ - { 0x0000, 0x0000 }, /* R778 */ - { 0x0000, 0x0000 }, /* R779 */ - { 0x0000, 0x0000 }, /* R780 */ - { 0x0000, 0x0000 }, /* R781 */ - { 0x0000, 0x0000 }, /* R782 */ - { 0x0000, 0x0000 }, /* R783 */ - { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */ - { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */ - { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */ - { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */ - { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */ - { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */ - { 0x0000, 0x0000 }, /* R792 */ - { 0x0000, 0x0000 }, /* R793 */ - { 0x0000, 0x0000 }, /* R794 */ - { 0x0000, 0x0000 }, /* R795 */ - { 0x0000, 0x0000 }, /* R796 */ - { 0x0000, 0x0000 }, /* R797 */ - { 0x0000, 0x0000 }, /* R798 */ - { 0x0000, 0x0000 }, /* R799 */ - { 0x0000, 0x0000 }, /* R800 */ - { 0x0000, 0x0000 }, /* R801 */ - { 0x0000, 0x0000 }, /* R802 */ - { 0x0000, 0x0000 }, /* R803 */ - { 0x0000, 0x0000 }, /* R804 */ - { 0x0000, 0x0000 }, /* R805 */ - { 0x0000, 0x0000 }, /* R806 */ - { 0x0000, 0x0000 }, /* R807 */ - { 0x0000, 0x0000 }, /* R808 */ - { 0x0000, 0x0000 }, /* R809 */ - { 0x0000, 0x0000 }, /* R810 */ - { 0x0000, 0x0000 }, /* R811 */ - { 0x0000, 0x0000 }, /* R812 */ - { 0x0000, 0x0000 }, /* R813 */ - { 0x0000, 0x0000 }, /* R814 */ - { 0x0000, 0x0000 }, /* R815 */ - { 0x0000, 0x0000 }, /* R816 */ - { 0x0000, 0x0000 }, /* R817 */ - { 0x0000, 0x0000 }, /* R818 */ - { 0x0000, 0x0000 }, /* R819 */ - { 0x0000, 0x0000 }, /* R820 */ - { 0x0000, 0x0000 }, /* R821 */ - { 0x0000, 0x0000 }, /* R822 */ - { 0x0000, 0x0000 }, /* R823 */ - { 0x0000, 0x0000 }, /* R824 */ - { 0x0000, 0x0000 }, /* R825 */ - { 0x0000, 0x0000 }, /* R826 */ - { 0x0000, 0x0000 }, /* R827 */ - { 0x0000, 0x0000 }, /* R828 */ - { 0x0000, 0x0000 }, /* R829 */ - { 0x0000, 0x0000 }, /* R830 */ - { 0x0000, 0x0000 }, /* R831 */ - { 0x0000, 0x0000 }, /* R832 */ - { 0x0000, 0x0000 }, /* R833 */ - { 0x0000, 0x0000 }, /* R834 */ - { 0x0000, 0x0000 }, /* R835 */ - { 0x0000, 0x0000 }, /* R836 */ - { 0x0000, 0x0000 }, /* R837 */ - { 0x0000, 0x0000 }, /* R838 */ - { 0x0000, 0x0000 }, /* R839 */ - { 0x0000, 0x0000 }, /* R840 */ - { 0x0000, 0x0000 }, /* R841 */ - { 0x0000, 0x0000 }, /* R842 */ - { 0x0000, 0x0000 }, /* R843 */ - { 0x0000, 0x0000 }, /* R844 */ - { 0x0000, 0x0000 }, /* R845 */ - { 0x0000, 0x0000 }, /* R846 */ - { 0x0000, 0x0000 }, /* R847 */ - { 0x0000, 0x0000 }, /* R848 */ - { 0x0000, 0x0000 }, /* R849 */ - { 0x0000, 0x0000 }, /* R850 */ - { 0x0000, 0x0000 }, /* R851 */ - { 0x0000, 0x0000 }, /* R852 */ - { 0x0000, 0x0000 }, /* R853 */ - { 0x0000, 0x0000 }, /* R854 */ - { 0x0000, 0x0000 }, /* R855 */ - { 0x0000, 0x0000 }, /* R856 */ - { 0x0000, 0x0000 }, /* R857 */ - { 0x0000, 0x0000 }, /* R858 */ - { 0x0000, 0x0000 }, /* R859 */ - { 0x0000, 0x0000 }, /* R860 */ - { 0x0000, 0x0000 }, /* R861 */ - { 0x0000, 0x0000 }, /* R862 */ - { 0x0000, 0x0000 }, /* R863 */ - { 0x0000, 0x0000 }, /* R864 */ - { 0x0000, 0x0000 }, /* R865 */ - { 0x0000, 0x0000 }, /* R866 */ - { 0x0000, 0x0000 }, /* R867 */ - { 0x0000, 0x0000 }, /* R868 */ - { 0x0000, 0x0000 }, /* R869 */ - { 0x0000, 0x0000 }, /* R870 */ - { 0x0000, 0x0000 }, /* R871 */ - { 0x0000, 0x0000 }, /* R872 */ - { 0x0000, 0x0000 }, /* R873 */ - { 0x0000, 0x0000 }, /* R874 */ - { 0x0000, 0x0000 }, /* R875 */ - { 0x0000, 0x0000 }, /* R876 */ - { 0x0000, 0x0000 }, /* R877 */ - { 0x0000, 0x0000 }, /* R878 */ - { 0x0000, 0x0000 }, /* R879 */ - { 0x0000, 0x0000 }, /* R880 */ - { 0x0000, 0x0000 }, /* R881 */ - { 0x0000, 0x0000 }, /* R882 */ - { 0x0000, 0x0000 }, /* R883 */ - { 0x0000, 0x0000 }, /* R884 */ - { 0x0000, 0x0000 }, /* R885 */ - { 0x0000, 0x0000 }, /* R886 */ - { 0x0000, 0x0000 }, /* R887 */ - { 0x0000, 0x0000 }, /* R888 */ - { 0x0000, 0x0000 }, /* R889 */ - { 0x0000, 0x0000 }, /* R890 */ - { 0x0000, 0x0000 }, /* R891 */ - { 0x0000, 0x0000 }, /* R892 */ - { 0x0000, 0x0000 }, /* R893 */ - { 0x0000, 0x0000 }, /* R894 */ - { 0x0000, 0x0000 }, /* R895 */ - { 0x0000, 0x0000 }, /* R896 */ - { 0x0000, 0x0000 }, /* R897 */ - { 0x0000, 0x0000 }, /* R898 */ - { 0x0000, 0x0000 }, /* R899 */ - { 0x0000, 0x0000 }, /* R900 */ - { 0x0000, 0x0000 }, /* R901 */ - { 0x0000, 0x0000 }, /* R902 */ - { 0x0000, 0x0000 }, /* R903 */ - { 0x0000, 0x0000 }, /* R904 */ - { 0x0000, 0x0000 }, /* R905 */ - { 0x0000, 0x0000 }, /* R906 */ - { 0x0000, 0x0000 }, /* R907 */ - { 0x0000, 0x0000 }, /* R908 */ - { 0x0000, 0x0000 }, /* R909 */ - { 0x0000, 0x0000 }, /* R910 */ - { 0x0000, 0x0000 }, /* R911 */ - { 0x0000, 0x0000 }, /* R912 */ - { 0x0000, 0x0000 }, /* R913 */ - { 0x0000, 0x0000 }, /* R914 */ - { 0x0000, 0x0000 }, /* R915 */ - { 0x0000, 0x0000 }, /* R916 */ - { 0x0000, 0x0000 }, /* R917 */ - { 0x0000, 0x0000 }, /* R918 */ - { 0x0000, 0x0000 }, /* R919 */ - { 0x0000, 0x0000 }, /* R920 */ - { 0x0000, 0x0000 }, /* R921 */ - { 0x0000, 0x0000 }, /* R922 */ - { 0x0000, 0x0000 }, /* R923 */ - { 0x0000, 0x0000 }, /* R924 */ - { 0x0000, 0x0000 }, /* R925 */ - { 0x0000, 0x0000 }, /* R926 */ - { 0x0000, 0x0000 }, /* R927 */ - { 0x0000, 0x0000 }, /* R928 */ - { 0x0000, 0x0000 }, /* R929 */ - { 0x0000, 0x0000 }, /* R930 */ - { 0x0000, 0x0000 }, /* R931 */ - { 0x0000, 0x0000 }, /* R932 */ - { 0x0000, 0x0000 }, /* R933 */ - { 0x0000, 0x0000 }, /* R934 */ - { 0x0000, 0x0000 }, /* R935 */ - { 0x0000, 0x0000 }, /* R936 */ - { 0x0000, 0x0000 }, /* R937 */ - { 0x0000, 0x0000 }, /* R938 */ - { 0x0000, 0x0000 }, /* R939 */ - { 0x0000, 0x0000 }, /* R940 */ - { 0x0000, 0x0000 }, /* R941 */ - { 0x0000, 0x0000 }, /* R942 */ - { 0x0000, 0x0000 }, /* R943 */ - { 0x0000, 0x0000 }, /* R944 */ - { 0x0000, 0x0000 }, /* R945 */ - { 0x0000, 0x0000 }, /* R946 */ - { 0x0000, 0x0000 }, /* R947 */ - { 0x0000, 0x0000 }, /* R948 */ - { 0x0000, 0x0000 }, /* R949 */ - { 0x0000, 0x0000 }, /* R950 */ - { 0x0000, 0x0000 }, /* R951 */ - { 0x0000, 0x0000 }, /* R952 */ - { 0x0000, 0x0000 }, /* R953 */ - { 0x0000, 0x0000 }, /* R954 */ - { 0x0000, 0x0000 }, /* R955 */ - { 0x0000, 0x0000 }, /* R956 */ - { 0x0000, 0x0000 }, /* R957 */ - { 0x0000, 0x0000 }, /* R958 */ - { 0x0000, 0x0000 }, /* R959 */ - { 0x0000, 0x0000 }, /* R960 */ - { 0x0000, 0x0000 }, /* R961 */ - { 0x0000, 0x0000 }, /* R962 */ - { 0x0000, 0x0000 }, /* R963 */ - { 0x0000, 0x0000 }, /* R964 */ - { 0x0000, 0x0000 }, /* R965 */ - { 0x0000, 0x0000 }, /* R966 */ - { 0x0000, 0x0000 }, /* R967 */ - { 0x0000, 0x0000 }, /* R968 */ - { 0x0000, 0x0000 }, /* R969 */ - { 0x0000, 0x0000 }, /* R970 */ - { 0x0000, 0x0000 }, /* R971 */ - { 0x0000, 0x0000 }, /* R972 */ - { 0x0000, 0x0000 }, /* R973 */ - { 0x0000, 0x0000 }, /* R974 */ - { 0x0000, 0x0000 }, /* R975 */ - { 0x0000, 0x0000 }, /* R976 */ - { 0x0000, 0x0000 }, /* R977 */ - { 0x0000, 0x0000 }, /* R978 */ - { 0x0000, 0x0000 }, /* R979 */ - { 0x0000, 0x0000 }, /* R980 */ - { 0x0000, 0x0000 }, /* R981 */ - { 0x0000, 0x0000 }, /* R982 */ - { 0x0000, 0x0000 }, /* R983 */ - { 0x0000, 0x0000 }, /* R984 */ - { 0x0000, 0x0000 }, /* R985 */ - { 0x0000, 0x0000 }, /* R986 */ - { 0x0000, 0x0000 }, /* R987 */ - { 0x0000, 0x0000 }, /* R988 */ - { 0x0000, 0x0000 }, /* R989 */ - { 0x0000, 0x0000 }, /* R990 */ - { 0x0000, 0x0000 }, /* R991 */ - { 0x0000, 0x0000 }, /* R992 */ - { 0x0000, 0x0000 }, /* R993 */ - { 0x0000, 0x0000 }, /* R994 */ - { 0x0000, 0x0000 }, /* R995 */ - { 0x0000, 0x0000 }, /* R996 */ - { 0x0000, 0x0000 }, /* R997 */ - { 0x0000, 0x0000 }, /* R998 */ - { 0x0000, 0x0000 }, /* R999 */ - { 0x0000, 0x0000 }, /* R1000 */ - { 0x0000, 0x0000 }, /* R1001 */ - { 0x0000, 0x0000 }, /* R1002 */ - { 0x0000, 0x0000 }, /* R1003 */ - { 0x0000, 0x0000 }, /* R1004 */ - { 0x0000, 0x0000 }, /* R1005 */ - { 0x0000, 0x0000 }, /* R1006 */ - { 0x0000, 0x0000 }, /* R1007 */ - { 0x0000, 0x0000 }, /* R1008 */ - { 0x0000, 0x0000 }, /* R1009 */ - { 0x0000, 0x0000 }, /* R1010 */ - { 0x0000, 0x0000 }, /* R1011 */ - { 0x0000, 0x0000 }, /* R1012 */ - { 0x0000, 0x0000 }, /* R1013 */ - { 0x0000, 0x0000 }, /* R1014 */ - { 0x0000, 0x0000 }, /* R1015 */ - { 0x0000, 0x0000 }, /* R1016 */ - { 0x0000, 0x0000 }, /* R1017 */ - { 0x0000, 0x0000 }, /* R1018 */ - { 0x0000, 0x0000 }, /* R1019 */ - { 0x0000, 0x0000 }, /* R1020 */ - { 0x0000, 0x0000 }, /* R1021 */ - { 0x0000, 0x0000 }, /* R1022 */ - { 0x0000, 0x0000 }, /* R1023 */ - { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */ - { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */ - { 0x0000, 0x0000 }, /* R1032 */ - { 0x0000, 0x0000 }, /* R1033 */ - { 0x0000, 0x0000 }, /* R1034 */ - { 0x0000, 0x0000 }, /* R1035 */ - { 0x0000, 0x0000 }, /* R1036 */ - { 0x0000, 0x0000 }, /* R1037 */ - { 0x0000, 0x0000 }, /* R1038 */ - { 0x0000, 0x0000 }, /* R1039 */ - { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */ - { 0x0000, 0x0000 }, /* R1042 */ - { 0x0000, 0x0000 }, /* R1043 */ - { 0x0000, 0x0000 }, /* R1044 */ - { 0x0000, 0x0000 }, /* R1045 */ - { 0x0000, 0x0000 }, /* R1046 */ - { 0x0000, 0x0000 }, /* R1047 */ - { 0x0000, 0x0000 }, /* R1048 */ - { 0x0000, 0x0000 }, /* R1049 */ - { 0x0000, 0x0000 }, /* R1050 */ - { 0x0000, 0x0000 }, /* R1051 */ - { 0x0000, 0x0000 }, /* R1052 */ - { 0x0000, 0x0000 }, /* R1053 */ - { 0x0000, 0x0000 }, /* R1054 */ - { 0x0000, 0x0000 }, /* R1055 */ - { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */ - { 0x0000, 0x0000 }, /* R1060 */ - { 0x0000, 0x0000 }, /* R1061 */ - { 0x0000, 0x0000 }, /* R1062 */ - { 0x0000, 0x0000 }, /* R1063 */ - { 0x0000, 0x0000 }, /* R1064 */ - { 0x0000, 0x0000 }, /* R1065 */ - { 0x0000, 0x0000 }, /* R1066 */ - { 0x0000, 0x0000 }, /* R1067 */ - { 0x0000, 0x0000 }, /* R1068 */ - { 0x0000, 0x0000 }, /* R1069 */ - { 0x0000, 0x0000 }, /* R1070 */ - { 0x0000, 0x0000 }, /* R1071 */ - { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */ - { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */ - { 0x0000, 0x0000 }, /* R1074 */ - { 0x0000, 0x0000 }, /* R1075 */ - { 0x0000, 0x0000 }, /* R1076 */ - { 0x0000, 0x0000 }, /* R1077 */ - { 0x0000, 0x0000 }, /* R1078 */ - { 0x0000, 0x0000 }, /* R1079 */ - { 0x0000, 0x0000 }, /* R1080 */ - { 0x0000, 0x0000 }, /* R1081 */ - { 0x0000, 0x0000 }, /* R1082 */ - { 0x0000, 0x0000 }, /* R1083 */ - { 0x0000, 0x0000 }, /* R1084 */ - { 0x0000, 0x0000 }, /* R1085 */ - { 0x0000, 0x0000 }, /* R1086 */ - { 0x0000, 0x0000 }, /* R1087 */ - { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */ - { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */ - { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */ - { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */ - { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0000, 0x0000 }, /* R1093 */ - { 0x0000, 0x0000 }, /* R1094 */ - { 0x0000, 0x0000 }, /* R1095 */ - { 0x0000, 0x0000 }, /* R1096 */ - { 0x0000, 0x0000 }, /* R1097 */ - { 0x0000, 0x0000 }, /* R1098 */ - { 0x0000, 0x0000 }, /* R1099 */ - { 0x0000, 0x0000 }, /* R1100 */ - { 0x0000, 0x0000 }, /* R1101 */ - { 0x0000, 0x0000 }, /* R1102 */ - { 0x0000, 0x0000 }, /* R1103 */ - { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */ - { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */ - { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */ - { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */ - { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */ - { 0x0000, 0x0000 }, /* R1109 */ - { 0x0000, 0x0000 }, /* R1110 */ - { 0x0000, 0x0000 }, /* R1111 */ - { 0x0000, 0x0000 }, /* R1112 */ - { 0x0000, 0x0000 }, /* R1113 */ - { 0x0000, 0x0000 }, /* R1114 */ - { 0x0000, 0x0000 }, /* R1115 */ - { 0x0000, 0x0000 }, /* R1116 */ - { 0x0000, 0x0000 }, /* R1117 */ - { 0x0000, 0x0000 }, /* R1118 */ - { 0x0000, 0x0000 }, /* R1119 */ - { 0x0000, 0x0000 }, /* R1120 */ - { 0x0000, 0x0000 }, /* R1121 */ - { 0x0000, 0x0000 }, /* R1122 */ - { 0x0000, 0x0000 }, /* R1123 */ - { 0x0000, 0x0000 }, /* R1124 */ - { 0x0000, 0x0000 }, /* R1125 */ - { 0x0000, 0x0000 }, /* R1126 */ - { 0x0000, 0x0000 }, /* R1127 */ - { 0x0000, 0x0000 }, /* R1128 */ - { 0x0000, 0x0000 }, /* R1129 */ - { 0x0000, 0x0000 }, /* R1130 */ - { 0x0000, 0x0000 }, /* R1131 */ - { 0x0000, 0x0000 }, /* R1132 */ - { 0x0000, 0x0000 }, /* R1133 */ - { 0x0000, 0x0000 }, /* R1134 */ - { 0x0000, 0x0000 }, /* R1135 */ - { 0x0000, 0x0000 }, /* R1136 */ - { 0x0000, 0x0000 }, /* R1137 */ - { 0x0000, 0x0000 }, /* R1138 */ - { 0x0000, 0x0000 }, /* R1139 */ - { 0x0000, 0x0000 }, /* R1140 */ - { 0x0000, 0x0000 }, /* R1141 */ - { 0x0000, 0x0000 }, /* R1142 */ - { 0x0000, 0x0000 }, /* R1143 */ - { 0x0000, 0x0000 }, /* R1144 */ - { 0x0000, 0x0000 }, /* R1145 */ - { 0x0000, 0x0000 }, /* R1146 */ - { 0x0000, 0x0000 }, /* R1147 */ - { 0x0000, 0x0000 }, /* R1148 */ - { 0x0000, 0x0000 }, /* R1149 */ - { 0x0000, 0x0000 }, /* R1150 */ - { 0x0000, 0x0000 }, /* R1151 */ - { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1172 */ - { 0x0000, 0x0000 }, /* R1173 */ - { 0x0000, 0x0000 }, /* R1174 */ - { 0x0000, 0x0000 }, /* R1175 */ - { 0x0000, 0x0000 }, /* R1176 */ - { 0x0000, 0x0000 }, /* R1177 */ - { 0x0000, 0x0000 }, /* R1178 */ - { 0x0000, 0x0000 }, /* R1179 */ - { 0x0000, 0x0000 }, /* R1180 */ - { 0x0000, 0x0000 }, /* R1181 */ - { 0x0000, 0x0000 }, /* R1182 */ - { 0x0000, 0x0000 }, /* R1183 */ - { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1204 */ - { 0x0000, 0x0000 }, /* R1205 */ - { 0x0000, 0x0000 }, /* R1206 */ - { 0x0000, 0x0000 }, /* R1207 */ - { 0x0000, 0x0000 }, /* R1208 */ - { 0x0000, 0x0000 }, /* R1209 */ - { 0x0000, 0x0000 }, /* R1210 */ - { 0x0000, 0x0000 }, /* R1211 */ - { 0x0000, 0x0000 }, /* R1212 */ - { 0x0000, 0x0000 }, /* R1213 */ - { 0x0000, 0x0000 }, /* R1214 */ - { 0x0000, 0x0000 }, /* R1215 */ - { 0x0000, 0x0000 }, /* R1216 */ - { 0x0000, 0x0000 }, /* R1217 */ - { 0x0000, 0x0000 }, /* R1218 */ - { 0x0000, 0x0000 }, /* R1219 */ - { 0x0000, 0x0000 }, /* R1220 */ - { 0x0000, 0x0000 }, /* R1221 */ - { 0x0000, 0x0000 }, /* R1222 */ - { 0x0000, 0x0000 }, /* R1223 */ - { 0x0000, 0x0000 }, /* R1224 */ - { 0x0000, 0x0000 }, /* R1225 */ - { 0x0000, 0x0000 }, /* R1226 */ - { 0x0000, 0x0000 }, /* R1227 */ - { 0x0000, 0x0000 }, /* R1228 */ - { 0x0000, 0x0000 }, /* R1229 */ - { 0x0000, 0x0000 }, /* R1230 */ - { 0x0000, 0x0000 }, /* R1231 */ - { 0x0000, 0x0000 }, /* R1232 */ - { 0x0000, 0x0000 }, /* R1233 */ - { 0x0000, 0x0000 }, /* R1234 */ - { 0x0000, 0x0000 }, /* R1235 */ - { 0x0000, 0x0000 }, /* R1236 */ - { 0x0000, 0x0000 }, /* R1237 */ - { 0x0000, 0x0000 }, /* R1238 */ - { 0x0000, 0x0000 }, /* R1239 */ - { 0x0000, 0x0000 }, /* R1240 */ - { 0x0000, 0x0000 }, /* R1241 */ - { 0x0000, 0x0000 }, /* R1242 */ - { 0x0000, 0x0000 }, /* R1243 */ - { 0x0000, 0x0000 }, /* R1244 */ - { 0x0000, 0x0000 }, /* R1245 */ - { 0x0000, 0x0000 }, /* R1246 */ - { 0x0000, 0x0000 }, /* R1247 */ - { 0x0000, 0x0000 }, /* R1248 */ - { 0x0000, 0x0000 }, /* R1249 */ - { 0x0000, 0x0000 }, /* R1250 */ - { 0x0000, 0x0000 }, /* R1251 */ - { 0x0000, 0x0000 }, /* R1252 */ - { 0x0000, 0x0000 }, /* R1253 */ - { 0x0000, 0x0000 }, /* R1254 */ - { 0x0000, 0x0000 }, /* R1255 */ - { 0x0000, 0x0000 }, /* R1256 */ - { 0x0000, 0x0000 }, /* R1257 */ - { 0x0000, 0x0000 }, /* R1258 */ - { 0x0000, 0x0000 }, /* R1259 */ - { 0x0000, 0x0000 }, /* R1260 */ - { 0x0000, 0x0000 }, /* R1261 */ - { 0x0000, 0x0000 }, /* R1262 */ - { 0x0000, 0x0000 }, /* R1263 */ - { 0x0000, 0x0000 }, /* R1264 */ - { 0x0000, 0x0000 }, /* R1265 */ - { 0x0000, 0x0000 }, /* R1266 */ - { 0x0000, 0x0000 }, /* R1267 */ - { 0x0000, 0x0000 }, /* R1268 */ - { 0x0000, 0x0000 }, /* R1269 */ - { 0x0000, 0x0000 }, /* R1270 */ - { 0x0000, 0x0000 }, /* R1271 */ - { 0x0000, 0x0000 }, /* R1272 */ - { 0x0000, 0x0000 }, /* R1273 */ - { 0x0000, 0x0000 }, /* R1274 */ - { 0x0000, 0x0000 }, /* R1275 */ - { 0x0000, 0x0000 }, /* R1276 */ - { 0x0000, 0x0000 }, /* R1277 */ - { 0x0000, 0x0000 }, /* R1278 */ - { 0x0000, 0x0000 }, /* R1279 */ - { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */ - { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */ - { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */ - { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0000, 0x0000 }, /* R1284 */ - { 0x0000, 0x0000 }, /* R1285 */ - { 0x0000, 0x0000 }, /* R1286 */ - { 0x0000, 0x0000 }, /* R1287 */ - { 0x0000, 0x0000 }, /* R1288 */ - { 0x0000, 0x0000 }, /* R1289 */ - { 0x0000, 0x0000 }, /* R1290 */ - { 0x0000, 0x0000 }, /* R1291 */ - { 0x0000, 0x0000 }, /* R1292 */ - { 0x0000, 0x0000 }, /* R1293 */ - { 0x0000, 0x0000 }, /* R1294 */ - { 0x0000, 0x0000 }, /* R1295 */ - { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */ - { 0x0000, 0x0000 }, /* R1297 */ - { 0x0000, 0x0000 }, /* R1298 */ - { 0x0000, 0x0000 }, /* R1299 */ - { 0x0000, 0x0000 }, /* R1300 */ - { 0x0000, 0x0000 }, /* R1301 */ - { 0x0000, 0x0000 }, /* R1302 */ - { 0x0000, 0x0000 }, /* R1303 */ - { 0x0000, 0x0000 }, /* R1304 */ - { 0x0000, 0x0000 }, /* R1305 */ - { 0x0000, 0x0000 }, /* R1306 */ - { 0x0000, 0x0000 }, /* R1307 */ - { 0x0000, 0x0000 }, /* R1308 */ - { 0x0000, 0x0000 }, /* R1309 */ - { 0x0000, 0x0000 }, /* R1310 */ - { 0x0000, 0x0000 }, /* R1311 */ - { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0000, 0x0000 }, /* R1314 */ - { 0x0000, 0x0000 }, /* R1315 */ - { 0x0000, 0x0000 }, /* R1316 */ - { 0x0000, 0x0000 }, /* R1317 */ - { 0x0000, 0x0000 }, /* R1318 */ - { 0x0000, 0x0000 }, /* R1319 */ - { 0x0000, 0x0000 }, /* R1320 */ - { 0x0000, 0x0000 }, /* R1321 */ - { 0x0000, 0x0000 }, /* R1322 */ - { 0x0000, 0x0000 }, /* R1323 */ - { 0x0000, 0x0000 }, /* R1324 */ - { 0x0000, 0x0000 }, /* R1325 */ - { 0x0000, 0x0000 }, /* R1326 */ - { 0x0000, 0x0000 }, /* R1327 */ - { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */ - { 0x0000, 0x0000 }, /* R1329 */ - { 0x0000, 0x0000 }, /* R1330 */ - { 0x0000, 0x0000 }, /* R1331 */ - { 0x0000, 0x0000 }, /* R1332 */ - { 0x0000, 0x0000 }, /* R1333 */ - { 0x0000, 0x0000 }, /* R1334 */ - { 0x0000, 0x0000 }, /* R1335 */ - { 0x0000, 0x0000 }, /* R1336 */ - { 0x0000, 0x0000 }, /* R1337 */ - { 0x0000, 0x0000 }, /* R1338 */ - { 0x0000, 0x0000 }, /* R1339 */ - { 0x0000, 0x0000 }, /* R1340 */ - { 0x0000, 0x0000 }, /* R1341 */ - { 0x0000, 0x0000 }, /* R1342 */ - { 0x0000, 0x0000 }, /* R1343 */ - { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */ - { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */ - { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */ - { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */ - { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */ - { 0x0000, 0x0000 }, /* R1349 */ - { 0x0000, 0x0000 }, /* R1350 */ - { 0x0000, 0x0000 }, /* R1351 */ - { 0x0000, 0x0000 }, /* R1352 */ - { 0x0000, 0x0000 }, /* R1353 */ - { 0x0000, 0x0000 }, /* R1354 */ - { 0x0000, 0x0000 }, /* R1355 */ - { 0x0000, 0x0000 }, /* R1356 */ - { 0x0000, 0x0000 }, /* R1357 */ - { 0x0000, 0x0000 }, /* R1358 */ - { 0x0000, 0x0000 }, /* R1359 */ - { 0x0000, 0x0000 }, /* R1360 */ - { 0x0000, 0x0000 }, /* R1361 */ - { 0x0000, 0x0000 }, /* R1362 */ - { 0x0000, 0x0000 }, /* R1363 */ - { 0x0000, 0x0000 }, /* R1364 */ - { 0x0000, 0x0000 }, /* R1365 */ - { 0x0000, 0x0000 }, /* R1366 */ - { 0x0000, 0x0000 }, /* R1367 */ - { 0x0000, 0x0000 }, /* R1368 */ - { 0x0000, 0x0000 }, /* R1369 */ - { 0x0000, 0x0000 }, /* R1370 */ - { 0x0000, 0x0000 }, /* R1371 */ - { 0x0000, 0x0000 }, /* R1372 */ - { 0x0000, 0x0000 }, /* R1373 */ - { 0x0000, 0x0000 }, /* R1374 */ - { 0x0000, 0x0000 }, /* R1375 */ - { 0x0000, 0x0000 }, /* R1376 */ - { 0x0000, 0x0000 }, /* R1377 */ - { 0x0000, 0x0000 }, /* R1378 */ - { 0x0000, 0x0000 }, /* R1379 */ - { 0x0000, 0x0000 }, /* R1380 */ - { 0x0000, 0x0000 }, /* R1381 */ - { 0x0000, 0x0000 }, /* R1382 */ - { 0x0000, 0x0000 }, /* R1383 */ - { 0x0000, 0x0000 }, /* R1384 */ - { 0x0000, 0x0000 }, /* R1385 */ - { 0x0000, 0x0000 }, /* R1386 */ - { 0x0000, 0x0000 }, /* R1387 */ - { 0x0000, 0x0000 }, /* R1388 */ - { 0x0000, 0x0000 }, /* R1389 */ - { 0x0000, 0x0000 }, /* R1390 */ - { 0x0000, 0x0000 }, /* R1391 */ - { 0x0000, 0x0000 }, /* R1392 */ - { 0x0000, 0x0000 }, /* R1393 */ - { 0x0000, 0x0000 }, /* R1394 */ - { 0x0000, 0x0000 }, /* R1395 */ - { 0x0000, 0x0000 }, /* R1396 */ - { 0x0000, 0x0000 }, /* R1397 */ - { 0x0000, 0x0000 }, /* R1398 */ - { 0x0000, 0x0000 }, /* R1399 */ - { 0x0000, 0x0000 }, /* R1400 */ - { 0x0000, 0x0000 }, /* R1401 */ - { 0x0000, 0x0000 }, /* R1402 */ - { 0x0000, 0x0000 }, /* R1403 */ - { 0x0000, 0x0000 }, /* R1404 */ - { 0x0000, 0x0000 }, /* R1405 */ - { 0x0000, 0x0000 }, /* R1406 */ - { 0x0000, 0x0000 }, /* R1407 */ - { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1428 */ - { 0x0000, 0x0000 }, /* R1429 */ - { 0x0000, 0x0000 }, /* R1430 */ - { 0x0000, 0x0000 }, /* R1431 */ - { 0x0000, 0x0000 }, /* R1432 */ - { 0x0000, 0x0000 }, /* R1433 */ - { 0x0000, 0x0000 }, /* R1434 */ - { 0x0000, 0x0000 }, /* R1435 */ - { 0x0000, 0x0000 }, /* R1436 */ - { 0x0000, 0x0000 }, /* R1437 */ - { 0x0000, 0x0000 }, /* R1438 */ - { 0x0000, 0x0000 }, /* R1439 */ - { 0x0000, 0x0000 }, /* R1440 */ - { 0x0000, 0x0000 }, /* R1441 */ - { 0x0000, 0x0000 }, /* R1442 */ - { 0x0000, 0x0000 }, /* R1443 */ - { 0x0000, 0x0000 }, /* R1444 */ - { 0x0000, 0x0000 }, /* R1445 */ - { 0x0000, 0x0000 }, /* R1446 */ - { 0x0000, 0x0000 }, /* R1447 */ - { 0x0000, 0x0000 }, /* R1448 */ - { 0x0000, 0x0000 }, /* R1449 */ - { 0x0000, 0x0000 }, /* R1450 */ - { 0x0000, 0x0000 }, /* R1451 */ - { 0x0000, 0x0000 }, /* R1452 */ - { 0x0000, 0x0000 }, /* R1453 */ - { 0x0000, 0x0000 }, /* R1454 */ - { 0x0000, 0x0000 }, /* R1455 */ - { 0x0000, 0x0000 }, /* R1456 */ - { 0x0000, 0x0000 }, /* R1457 */ - { 0x0000, 0x0000 }, /* R1458 */ - { 0x0000, 0x0000 }, /* R1459 */ - { 0x0000, 0x0000 }, /* R1460 */ - { 0x0000, 0x0000 }, /* R1461 */ - { 0x0000, 0x0000 }, /* R1462 */ - { 0x0000, 0x0000 }, /* R1463 */ - { 0x0000, 0x0000 }, /* R1464 */ - { 0x0000, 0x0000 }, /* R1465 */ - { 0x0000, 0x0000 }, /* R1466 */ - { 0x0000, 0x0000 }, /* R1467 */ - { 0x0000, 0x0000 }, /* R1468 */ - { 0x0000, 0x0000 }, /* R1469 */ - { 0x0000, 0x0000 }, /* R1470 */ - { 0x0000, 0x0000 }, /* R1471 */ - { 0x0000, 0x0000 }, /* R1472 */ - { 0x0000, 0x0000 }, /* R1473 */ - { 0x0000, 0x0000 }, /* R1474 */ - { 0x0000, 0x0000 }, /* R1475 */ - { 0x0000, 0x0000 }, /* R1476 */ - { 0x0000, 0x0000 }, /* R1477 */ - { 0x0000, 0x0000 }, /* R1478 */ - { 0x0000, 0x0000 }, /* R1479 */ - { 0x0000, 0x0000 }, /* R1480 */ - { 0x0000, 0x0000 }, /* R1481 */ - { 0x0000, 0x0000 }, /* R1482 */ - { 0x0000, 0x0000 }, /* R1483 */ - { 0x0000, 0x0000 }, /* R1484 */ - { 0x0000, 0x0000 }, /* R1485 */ - { 0x0000, 0x0000 }, /* R1486 */ - { 0x0000, 0x0000 }, /* R1487 */ - { 0x0000, 0x0000 }, /* R1488 */ - { 0x0000, 0x0000 }, /* R1489 */ - { 0x0000, 0x0000 }, /* R1490 */ - { 0x0000, 0x0000 }, /* R1491 */ - { 0x0000, 0x0000 }, /* R1492 */ - { 0x0000, 0x0000 }, /* R1493 */ - { 0x0000, 0x0000 }, /* R1494 */ - { 0x0000, 0x0000 }, /* R1495 */ - { 0x0000, 0x0000 }, /* R1496 */ - { 0x0000, 0x0000 }, /* R1497 */ - { 0x0000, 0x0000 }, /* R1498 */ - { 0x0000, 0x0000 }, /* R1499 */ - { 0x0000, 0x0000 }, /* R1500 */ - { 0x0000, 0x0000 }, /* R1501 */ - { 0x0000, 0x0000 }, /* R1502 */ - { 0x0000, 0x0000 }, /* R1503 */ - { 0x0000, 0x0000 }, /* R1504 */ - { 0x0000, 0x0000 }, /* R1505 */ - { 0x0000, 0x0000 }, /* R1506 */ - { 0x0000, 0x0000 }, /* R1507 */ - { 0x0000, 0x0000 }, /* R1508 */ - { 0x0000, 0x0000 }, /* R1509 */ - { 0x0000, 0x0000 }, /* R1510 */ - { 0x0000, 0x0000 }, /* R1511 */ - { 0x0000, 0x0000 }, /* R1512 */ - { 0x0000, 0x0000 }, /* R1513 */ - { 0x0000, 0x0000 }, /* R1514 */ - { 0x0000, 0x0000 }, /* R1515 */ - { 0x0000, 0x0000 }, /* R1516 */ - { 0x0000, 0x0000 }, /* R1517 */ - { 0x0000, 0x0000 }, /* R1518 */ - { 0x0000, 0x0000 }, /* R1519 */ - { 0x0000, 0x0000 }, /* R1520 */ - { 0x0000, 0x0000 }, /* R1521 */ - { 0x0000, 0x0000 }, /* R1522 */ - { 0x0000, 0x0000 }, /* R1523 */ - { 0x0000, 0x0000 }, /* R1524 */ - { 0x0000, 0x0000 }, /* R1525 */ - { 0x0000, 0x0000 }, /* R1526 */ - { 0x0000, 0x0000 }, /* R1527 */ - { 0x0000, 0x0000 }, /* R1528 */ - { 0x0000, 0x0000 }, /* R1529 */ - { 0x0000, 0x0000 }, /* R1530 */ - { 0x0000, 0x0000 }, /* R1531 */ - { 0x0000, 0x0000 }, /* R1532 */ - { 0x0000, 0x0000 }, /* R1533 */ - { 0x0000, 0x0000 }, /* R1534 */ - { 0x0000, 0x0000 }, /* R1535 */ - { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ - { 0x0000, 0x0000 }, /* R1546 */ - { 0x0000, 0x0000 }, /* R1547 */ - { 0x0000, 0x0000 }, /* R1548 */ - { 0x0000, 0x0000 }, /* R1549 */ - { 0x0000, 0x0000 }, /* R1550 */ - { 0x0000, 0x0000 }, /* R1551 */ - { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */ - { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */ - { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */ - { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */ - { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */ - { 0x0000, 0x0000 }, /* R1557 */ - { 0x0000, 0x0000 }, /* R1558 */ - { 0x0000, 0x0000 }, /* R1559 */ - { 0x0000, 0x0000 }, /* R1560 */ - { 0x0000, 0x0000 }, /* R1561 */ - { 0x0000, 0x0000 }, /* R1562 */ - { 0x0000, 0x0000 }, /* R1563 */ - { 0x0000, 0x0000 }, /* R1564 */ - { 0x0000, 0x0000 }, /* R1565 */ - { 0x0000, 0x0000 }, /* R1566 */ - { 0x0000, 0x0000 }, /* R1567 */ - { 0x0003, 0x0003 }, /* R1568 - Oversampling */ - { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ -}; - -const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { - 0x8994, /* R0 - Software Reset */ - 0x0000, /* R1 - Power Management (1) */ - 0x6000, /* R2 - Power Management (2) */ - 0x0000, /* R3 - Power Management (3) */ - 0x0000, /* R4 - Power Management (4) */ - 0x0000, /* R5 - Power Management (5) */ - 0x0000, /* R6 - Power Management (6) */ - 0x0000, /* R7 */ - 0x0000, /* R8 */ - 0x0000, /* R9 */ - 0x0000, /* R10 */ - 0x0000, /* R11 */ - 0x0000, /* R12 */ - 0x0000, /* R13 */ - 0x0000, /* R14 */ - 0x0000, /* R15 */ - 0x0000, /* R16 */ - 0x0000, /* R17 */ - 0x0000, /* R18 */ - 0x0000, /* R19 */ - 0x0000, /* R20 */ - 0x0000, /* R21 - Input Mixer (1) */ - 0x0000, /* R22 */ - 0x0000, /* R23 */ - 0x008B, /* R24 - Left Line Input 1&2 Volume */ - 0x008B, /* R25 - Left Line Input 3&4 Volume */ - 0x008B, /* R26 - Right Line Input 1&2 Volume */ - 0x008B, /* R27 - Right Line Input 3&4 Volume */ - 0x006D, /* R28 - Left Output Volume */ - 0x006D, /* R29 - Right Output Volume */ - 0x0066, /* R30 - Line Outputs Volume */ - 0x0020, /* R31 - HPOUT2 Volume */ - 0x0079, /* R32 - Left OPGA Volume */ - 0x0079, /* R33 - Right OPGA Volume */ - 0x0003, /* R34 - SPKMIXL Attenuation */ - 0x0003, /* R35 - SPKMIXR Attenuation */ - 0x0011, /* R36 - SPKOUT Mixers */ - 0x0140, /* R37 - ClassD */ - 0x0079, /* R38 - Speaker Volume Left */ - 0x0079, /* R39 - Speaker Volume Right */ - 0x0000, /* R40 - Input Mixer (2) */ - 0x0000, /* R41 - Input Mixer (3) */ - 0x0000, /* R42 - Input Mixer (4) */ - 0x0000, /* R43 - Input Mixer (5) */ - 0x0000, /* R44 - Input Mixer (6) */ - 0x0000, /* R45 - Output Mixer (1) */ - 0x0000, /* R46 - Output Mixer (2) */ - 0x0000, /* R47 - Output Mixer (3) */ - 0x0000, /* R48 - Output Mixer (4) */ - 0x0000, /* R49 - Output Mixer (5) */ - 0x0000, /* R50 - Output Mixer (6) */ - 0x0000, /* R51 - HPOUT2 Mixer */ - 0x0000, /* R52 - Line Mixer (1) */ - 0x0000, /* R53 - Line Mixer (2) */ - 0x0000, /* R54 - Speaker Mixer */ - 0x0000, /* R55 - Additional Control */ - 0x0000, /* R56 - AntiPOP (1) */ - 0x0000, /* R57 - AntiPOP (2) */ - 0x0000, /* R58 - MICBIAS */ - 0x000D, /* R59 - LDO 1 */ - 0x0003, /* R60 - LDO 2 */ - 0x0039, /* R61 - MICBIAS1 */ - 0x0039, /* R62 - MICBIAS2 */ - 0x0000, /* R63 */ - 0x0000, /* R64 */ - 0x0000, /* R65 */ - 0x0000, /* R66 */ - 0x0000, /* R67 */ - 0x0000, /* R68 */ - 0x0000, /* R69 */ - 0x0000, /* R70 */ - 0x0000, /* R71 */ - 0x0000, /* R72 */ - 0x0000, /* R73 */ - 0x0000, /* R74 */ - 0x0000, /* R75 */ - 0x1F25, /* R76 - Charge Pump (1) */ - 0x0000, /* R77 */ - 0x0000, /* R78 */ - 0x0000, /* R79 */ - 0x0000, /* R80 */ - 0x0004, /* R81 - Class W (1) */ - 0x0000, /* R82 */ - 0x0000, /* R83 */ - 0x0000, /* R84 - DC Servo (1) */ - 0x054A, /* R85 - DC Servo (2) */ - 0x0000, /* R86 */ - 0x0000, /* R87 - DC Servo (4) */ - 0x0000, /* R88 - DC Servo Readback */ - 0x0000, /* R89 */ - 0x0000, /* R90 */ - 0x0000, /* R91 */ - 0x0000, /* R92 */ - 0x0000, /* R93 */ - 0x0000, /* R94 */ - 0x0000, /* R95 */ - 0x0000, /* R96 - Analogue HP (1) */ - 0x0000, /* R97 */ - 0x0000, /* R98 */ - 0x0000, /* R99 */ - 0x0000, /* R100 */ - 0x0000, /* R101 */ - 0x0000, /* R102 */ - 0x0000, /* R103 */ - 0x0000, /* R104 */ - 0x0000, /* R105 */ - 0x0000, /* R106 */ - 0x0000, /* R107 */ - 0x0000, /* R108 */ - 0x0000, /* R109 */ - 0x0000, /* R110 */ - 0x0000, /* R111 */ - 0x0000, /* R112 */ - 0x0000, /* R113 */ - 0x0000, /* R114 */ - 0x0000, /* R115 */ - 0x0000, /* R116 */ - 0x0000, /* R117 */ - 0x0000, /* R118 */ - 0x0000, /* R119 */ - 0x0000, /* R120 */ - 0x0000, /* R121 */ - 0x0000, /* R122 */ - 0x0000, /* R123 */ - 0x0000, /* R124 */ - 0x0000, /* R125 */ - 0x0000, /* R126 */ - 0x0000, /* R127 */ - 0x0000, /* R128 */ - 0x0000, /* R129 */ - 0x0000, /* R130 */ - 0x0000, /* R131 */ - 0x0000, /* R132 */ - 0x0000, /* R133 */ - 0x0000, /* R134 */ - 0x0000, /* R135 */ - 0x0000, /* R136 */ - 0x0000, /* R137 */ - 0x0000, /* R138 */ - 0x0000, /* R139 */ - 0x0000, /* R140 */ - 0x0000, /* R141 */ - 0x0000, /* R142 */ - 0x0000, /* R143 */ - 0x0000, /* R144 */ - 0x0000, /* R145 */ - 0x0000, /* R146 */ - 0x0000, /* R147 */ - 0x0000, /* R148 */ - 0x0000, /* R149 */ - 0x0000, /* R150 */ - 0x0000, /* R151 */ - 0x0000, /* R152 */ - 0x0000, /* R153 */ - 0x0000, /* R154 */ - 0x0000, /* R155 */ - 0x0000, /* R156 */ - 0x0000, /* R157 */ - 0x0000, /* R158 */ - 0x0000, /* R159 */ - 0x0000, /* R160 */ - 0x0000, /* R161 */ - 0x0000, /* R162 */ - 0x0000, /* R163 */ - 0x0000, /* R164 */ - 0x0000, /* R165 */ - 0x0000, /* R166 */ - 0x0000, /* R167 */ - 0x0000, /* R168 */ - 0x0000, /* R169 */ - 0x0000, /* R170 */ - 0x0000, /* R171 */ - 0x0000, /* R172 */ - 0x0000, /* R173 */ - 0x0000, /* R174 */ - 0x0000, /* R175 */ - 0x0000, /* R176 */ - 0x0000, /* R177 */ - 0x0000, /* R178 */ - 0x0000, /* R179 */ - 0x0000, /* R180 */ - 0x0000, /* R181 */ - 0x0000, /* R182 */ - 0x0000, /* R183 */ - 0x0000, /* R184 */ - 0x0000, /* R185 */ - 0x0000, /* R186 */ - 0x0000, /* R187 */ - 0x0000, /* R188 */ - 0x0000, /* R189 */ - 0x0000, /* R190 */ - 0x0000, /* R191 */ - 0x0000, /* R192 */ - 0x0000, /* R193 */ - 0x0000, /* R194 */ - 0x0000, /* R195 */ - 0x0000, /* R196 */ - 0x0000, /* R197 */ - 0x0000, /* R198 */ - 0x0000, /* R199 */ - 0x0000, /* R200 */ - 0x0000, /* R201 */ - 0x0000, /* R202 */ - 0x0000, /* R203 */ - 0x0000, /* R204 */ - 0x0000, /* R205 */ - 0x0000, /* R206 */ - 0x0000, /* R207 */ - 0x0000, /* R208 */ - 0x0000, /* R209 */ - 0x0000, /* R210 */ - 0x0000, /* R211 */ - 0x0000, /* R212 */ - 0x0000, /* R213 */ - 0x0000, /* R214 */ - 0x0000, /* R215 */ - 0x0000, /* R216 */ - 0x0000, /* R217 */ - 0x0000, /* R218 */ - 0x0000, /* R219 */ - 0x0000, /* R220 */ - 0x0000, /* R221 */ - 0x0000, /* R222 */ - 0x0000, /* R223 */ - 0x0000, /* R224 */ - 0x0000, /* R225 */ - 0x0000, /* R226 */ - 0x0000, /* R227 */ - 0x0000, /* R228 */ - 0x0000, /* R229 */ - 0x0000, /* R230 */ - 0x0000, /* R231 */ - 0x0000, /* R232 */ - 0x0000, /* R233 */ - 0x0000, /* R234 */ - 0x0000, /* R235 */ - 0x0000, /* R236 */ - 0x0000, /* R237 */ - 0x0000, /* R238 */ - 0x0000, /* R239 */ - 0x0000, /* R240 */ - 0x0000, /* R241 */ - 0x0000, /* R242 */ - 0x0000, /* R243 */ - 0x0000, /* R244 */ - 0x0000, /* R245 */ - 0x0000, /* R246 */ - 0x0000, /* R247 */ - 0x0000, /* R248 */ - 0x0000, /* R249 */ - 0x0000, /* R250 */ - 0x0000, /* R251 */ - 0x0000, /* R252 */ - 0x0000, /* R253 */ - 0x0000, /* R254 */ - 0x0000, /* R255 */ - 0x0003, /* R256 - Chip Revision */ - 0x8004, /* R257 - Control Interface */ - 0x0000, /* R258 */ - 0x0000, /* R259 */ - 0x0000, /* R260 */ - 0x0000, /* R261 */ - 0x0000, /* R262 */ - 0x0000, /* R263 */ - 0x0000, /* R264 */ - 0x0000, /* R265 */ - 0x0000, /* R266 */ - 0x0000, /* R267 */ - 0x0000, /* R268 */ - 0x0000, /* R269 */ - 0x0000, /* R270 */ - 0x0000, /* R271 */ - 0x0000, /* R272 - Write Sequencer Ctrl (1) */ - 0x0000, /* R273 - Write Sequencer Ctrl (2) */ - 0x0000, /* R274 */ - 0x0000, /* R275 */ - 0x0000, /* R276 */ - 0x0000, /* R277 */ - 0x0000, /* R278 */ - 0x0000, /* R279 */ - 0x0000, /* R280 */ - 0x0000, /* R281 */ - 0x0000, /* R282 */ - 0x0000, /* R283 */ - 0x0000, /* R284 */ - 0x0000, /* R285 */ - 0x0000, /* R286 */ - 0x0000, /* R287 */ - 0x0000, /* R288 */ - 0x0000, /* R289 */ - 0x0000, /* R290 */ - 0x0000, /* R291 */ - 0x0000, /* R292 */ - 0x0000, /* R293 */ - 0x0000, /* R294 */ - 0x0000, /* R295 */ - 0x0000, /* R296 */ - 0x0000, /* R297 */ - 0x0000, /* R298 */ - 0x0000, /* R299 */ - 0x0000, /* R300 */ - 0x0000, /* R301 */ - 0x0000, /* R302 */ - 0x0000, /* R303 */ - 0x0000, /* R304 */ - 0x0000, /* R305 */ - 0x0000, /* R306 */ - 0x0000, /* R307 */ - 0x0000, /* R308 */ - 0x0000, /* R309 */ - 0x0000, /* R310 */ - 0x0000, /* R311 */ - 0x0000, /* R312 */ - 0x0000, /* R313 */ - 0x0000, /* R314 */ - 0x0000, /* R315 */ - 0x0000, /* R316 */ - 0x0000, /* R317 */ - 0x0000, /* R318 */ - 0x0000, /* R319 */ - 0x0000, /* R320 */ - 0x0000, /* R321 */ - 0x0000, /* R322 */ - 0x0000, /* R323 */ - 0x0000, /* R324 */ - 0x0000, /* R325 */ - 0x0000, /* R326 */ - 0x0000, /* R327 */ - 0x0000, /* R328 */ - 0x0000, /* R329 */ - 0x0000, /* R330 */ - 0x0000, /* R331 */ - 0x0000, /* R332 */ - 0x0000, /* R333 */ - 0x0000, /* R334 */ - 0x0000, /* R335 */ - 0x0000, /* R336 */ - 0x0000, /* R337 */ - 0x0000, /* R338 */ - 0x0000, /* R339 */ - 0x0000, /* R340 */ - 0x0000, /* R341 */ - 0x0000, /* R342 */ - 0x0000, /* R343 */ - 0x0000, /* R344 */ - 0x0000, /* R345 */ - 0x0000, /* R346 */ - 0x0000, /* R347 */ - 0x0000, /* R348 */ - 0x0000, /* R349 */ - 0x0000, /* R350 */ - 0x0000, /* R351 */ - 0x0000, /* R352 */ - 0x0000, /* R353 */ - 0x0000, /* R354 */ - 0x0000, /* R355 */ - 0x0000, /* R356 */ - 0x0000, /* R357 */ - 0x0000, /* R358 */ - 0x0000, /* R359 */ - 0x0000, /* R360 */ - 0x0000, /* R361 */ - 0x0000, /* R362 */ - 0x0000, /* R363 */ - 0x0000, /* R364 */ - 0x0000, /* R365 */ - 0x0000, /* R366 */ - 0x0000, /* R367 */ - 0x0000, /* R368 */ - 0x0000, /* R369 */ - 0x0000, /* R370 */ - 0x0000, /* R371 */ - 0x0000, /* R372 */ - 0x0000, /* R373 */ - 0x0000, /* R374 */ - 0x0000, /* R375 */ - 0x0000, /* R376 */ - 0x0000, /* R377 */ - 0x0000, /* R378 */ - 0x0000, /* R379 */ - 0x0000, /* R380 */ - 0x0000, /* R381 */ - 0x0000, /* R382 */ - 0x0000, /* R383 */ - 0x0000, /* R384 */ - 0x0000, /* R385 */ - 0x0000, /* R386 */ - 0x0000, /* R387 */ - 0x0000, /* R388 */ - 0x0000, /* R389 */ - 0x0000, /* R390 */ - 0x0000, /* R391 */ - 0x0000, /* R392 */ - 0x0000, /* R393 */ - 0x0000, /* R394 */ - 0x0000, /* R395 */ - 0x0000, /* R396 */ - 0x0000, /* R397 */ - 0x0000, /* R398 */ - 0x0000, /* R399 */ - 0x0000, /* R400 */ - 0x0000, /* R401 */ - 0x0000, /* R402 */ - 0x0000, /* R403 */ - 0x0000, /* R404 */ - 0x0000, /* R405 */ - 0x0000, /* R406 */ - 0x0000, /* R407 */ - 0x0000, /* R408 */ - 0x0000, /* R409 */ - 0x0000, /* R410 */ - 0x0000, /* R411 */ - 0x0000, /* R412 */ - 0x0000, /* R413 */ - 0x0000, /* R414 */ - 0x0000, /* R415 */ - 0x0000, /* R416 */ - 0x0000, /* R417 */ - 0x0000, /* R418 */ - 0x0000, /* R419 */ - 0x0000, /* R420 */ - 0x0000, /* R421 */ - 0x0000, /* R422 */ - 0x0000, /* R423 */ - 0x0000, /* R424 */ - 0x0000, /* R425 */ - 0x0000, /* R426 */ - 0x0000, /* R427 */ - 0x0000, /* R428 */ - 0x0000, /* R429 */ - 0x0000, /* R430 */ - 0x0000, /* R431 */ - 0x0000, /* R432 */ - 0x0000, /* R433 */ - 0x0000, /* R434 */ - 0x0000, /* R435 */ - 0x0000, /* R436 */ - 0x0000, /* R437 */ - 0x0000, /* R438 */ - 0x0000, /* R439 */ - 0x0000, /* R440 */ - 0x0000, /* R441 */ - 0x0000, /* R442 */ - 0x0000, /* R443 */ - 0x0000, /* R444 */ - 0x0000, /* R445 */ - 0x0000, /* R446 */ - 0x0000, /* R447 */ - 0x0000, /* R448 */ - 0x0000, /* R449 */ - 0x0000, /* R450 */ - 0x0000, /* R451 */ - 0x0000, /* R452 */ - 0x0000, /* R453 */ - 0x0000, /* R454 */ - 0x0000, /* R455 */ - 0x0000, /* R456 */ - 0x0000, /* R457 */ - 0x0000, /* R458 */ - 0x0000, /* R459 */ - 0x0000, /* R460 */ - 0x0000, /* R461 */ - 0x0000, /* R462 */ - 0x0000, /* R463 */ - 0x0000, /* R464 */ - 0x0000, /* R465 */ - 0x0000, /* R466 */ - 0x0000, /* R467 */ - 0x0000, /* R468 */ - 0x0000, /* R469 */ - 0x0000, /* R470 */ - 0x0000, /* R471 */ - 0x0000, /* R472 */ - 0x0000, /* R473 */ - 0x0000, /* R474 */ - 0x0000, /* R475 */ - 0x0000, /* R476 */ - 0x0000, /* R477 */ - 0x0000, /* R478 */ - 0x0000, /* R479 */ - 0x0000, /* R480 */ - 0x0000, /* R481 */ - 0x0000, /* R482 */ - 0x0000, /* R483 */ - 0x0000, /* R484 */ - 0x0000, /* R485 */ - 0x0000, /* R486 */ - 0x0000, /* R487 */ - 0x0000, /* R488 */ - 0x0000, /* R489 */ - 0x0000, /* R490 */ - 0x0000, /* R491 */ - 0x0000, /* R492 */ - 0x0000, /* R493 */ - 0x0000, /* R494 */ - 0x0000, /* R495 */ - 0x0000, /* R496 */ - 0x0000, /* R497 */ - 0x0000, /* R498 */ - 0x0000, /* R499 */ - 0x0000, /* R500 */ - 0x0000, /* R501 */ - 0x0000, /* R502 */ - 0x0000, /* R503 */ - 0x0000, /* R504 */ - 0x0000, /* R505 */ - 0x0000, /* R506 */ - 0x0000, /* R507 */ - 0x0000, /* R508 */ - 0x0000, /* R509 */ - 0x0000, /* R510 */ - 0x0000, /* R511 */ - 0x0000, /* R512 - AIF1 Clocking (1) */ - 0x0000, /* R513 - AIF1 Clocking (2) */ - 0x0000, /* R514 */ - 0x0000, /* R515 */ - 0x0000, /* R516 - AIF2 Clocking (1) */ - 0x0000, /* R517 - AIF2 Clocking (2) */ - 0x0000, /* R518 */ - 0x0000, /* R519 */ - 0x0000, /* R520 - Clocking (1) */ - 0x0000, /* R521 - Clocking (2) */ - 0x0000, /* R522 */ - 0x0000, /* R523 */ - 0x0000, /* R524 */ - 0x0000, /* R525 */ - 0x0000, /* R526 */ - 0x0000, /* R527 */ - 0x0083, /* R528 - AIF1 Rate */ - 0x0083, /* R529 - AIF2 Rate */ - 0x0000, /* R530 - Rate Status */ - 0x0000, /* R531 */ - 0x0000, /* R532 */ - 0x0000, /* R533 */ - 0x0000, /* R534 */ - 0x0000, /* R535 */ - 0x0000, /* R536 */ - 0x0000, /* R537 */ - 0x0000, /* R538 */ - 0x0000, /* R539 */ - 0x0000, /* R540 */ - 0x0000, /* R541 */ - 0x0000, /* R542 */ - 0x0000, /* R543 */ - 0x0000, /* R544 - FLL1 Control (1) */ - 0x0000, /* R545 - FLL1 Control (2) */ - 0x0000, /* R546 - FLL1 Control (3) */ - 0x0000, /* R547 - FLL1 Control (4) */ - 0x0C80, /* R548 - FLL1 Control (5) */ - 0x0000, /* R549 */ - 0x0000, /* R550 */ - 0x0000, /* R551 */ - 0x0000, /* R552 */ - 0x0000, /* R553 */ - 0x0000, /* R554 */ - 0x0000, /* R555 */ - 0x0000, /* R556 */ - 0x0000, /* R557 */ - 0x0000, /* R558 */ - 0x0000, /* R559 */ - 0x0000, /* R560 */ - 0x0000, /* R561 */ - 0x0000, /* R562 */ - 0x0000, /* R563 */ - 0x0000, /* R564 */ - 0x0000, /* R565 */ - 0x0000, /* R566 */ - 0x0000, /* R567 */ - 0x0000, /* R568 */ - 0x0000, /* R569 */ - 0x0000, /* R570 */ - 0x0000, /* R571 */ - 0x0000, /* R572 */ - 0x0000, /* R573 */ - 0x0000, /* R574 */ - 0x0000, /* R575 */ - 0x0000, /* R576 - FLL2 Control (1) */ - 0x0000, /* R577 - FLL2 Control (2) */ - 0x0000, /* R578 - FLL2 Control (3) */ - 0x0000, /* R579 - FLL2 Control (4) */ - 0x0C80, /* R580 - FLL2 Control (5) */ - 0x0000, /* R581 */ - 0x0000, /* R582 */ - 0x0000, /* R583 */ - 0x0000, /* R584 */ - 0x0000, /* R585 */ - 0x0000, /* R586 */ - 0x0000, /* R587 */ - 0x0000, /* R588 */ - 0x0000, /* R589 */ - 0x0000, /* R590 */ - 0x0000, /* R591 */ - 0x0000, /* R592 */ - 0x0000, /* R593 */ - 0x0000, /* R594 */ - 0x0000, /* R595 */ - 0x0000, /* R596 */ - 0x0000, /* R597 */ - 0x0000, /* R598 */ - 0x0000, /* R599 */ - 0x0000, /* R600 */ - 0x0000, /* R601 */ - 0x0000, /* R602 */ - 0x0000, /* R603 */ - 0x0000, /* R604 */ - 0x0000, /* R605 */ - 0x0000, /* R606 */ - 0x0000, /* R607 */ - 0x0000, /* R608 */ - 0x0000, /* R609 */ - 0x0000, /* R610 */ - 0x0000, /* R611 */ - 0x0000, /* R612 */ - 0x0000, /* R613 */ - 0x0000, /* R614 */ - 0x0000, /* R615 */ - 0x0000, /* R616 */ - 0x0000, /* R617 */ - 0x0000, /* R618 */ - 0x0000, /* R619 */ - 0x0000, /* R620 */ - 0x0000, /* R621 */ - 0x0000, /* R622 */ - 0x0000, /* R623 */ - 0x0000, /* R624 */ - 0x0000, /* R625 */ - 0x0000, /* R626 */ - 0x0000, /* R627 */ - 0x0000, /* R628 */ - 0x0000, /* R629 */ - 0x0000, /* R630 */ - 0x0000, /* R631 */ - 0x0000, /* R632 */ - 0x0000, /* R633 */ - 0x0000, /* R634 */ - 0x0000, /* R635 */ - 0x0000, /* R636 */ - 0x0000, /* R637 */ - 0x0000, /* R638 */ - 0x0000, /* R639 */ - 0x0000, /* R640 */ - 0x0000, /* R641 */ - 0x0000, /* R642 */ - 0x0000, /* R643 */ - 0x0000, /* R644 */ - 0x0000, /* R645 */ - 0x0000, /* R646 */ - 0x0000, /* R647 */ - 0x0000, /* R648 */ - 0x0000, /* R649 */ - 0x0000, /* R650 */ - 0x0000, /* R651 */ - 0x0000, /* R652 */ - 0x0000, /* R653 */ - 0x0000, /* R654 */ - 0x0000, /* R655 */ - 0x0000, /* R656 */ - 0x0000, /* R657 */ - 0x0000, /* R658 */ - 0x0000, /* R659 */ - 0x0000, /* R660 */ - 0x0000, /* R661 */ - 0x0000, /* R662 */ - 0x0000, /* R663 */ - 0x0000, /* R664 */ - 0x0000, /* R665 */ - 0x0000, /* R666 */ - 0x0000, /* R667 */ - 0x0000, /* R668 */ - 0x0000, /* R669 */ - 0x0000, /* R670 */ - 0x0000, /* R671 */ - 0x0000, /* R672 */ - 0x0000, /* R673 */ - 0x0000, /* R674 */ - 0x0000, /* R675 */ - 0x0000, /* R676 */ - 0x0000, /* R677 */ - 0x0000, /* R678 */ - 0x0000, /* R679 */ - 0x0000, /* R680 */ - 0x0000, /* R681 */ - 0x0000, /* R682 */ - 0x0000, /* R683 */ - 0x0000, /* R684 */ - 0x0000, /* R685 */ - 0x0000, /* R686 */ - 0x0000, /* R687 */ - 0x0000, /* R688 */ - 0x0000, /* R689 */ - 0x0000, /* R690 */ - 0x0000, /* R691 */ - 0x0000, /* R692 */ - 0x0000, /* R693 */ - 0x0000, /* R694 */ - 0x0000, /* R695 */ - 0x0000, /* R696 */ - 0x0000, /* R697 */ - 0x0000, /* R698 */ - 0x0000, /* R699 */ - 0x0000, /* R700 */ - 0x0000, /* R701 */ - 0x0000, /* R702 */ - 0x0000, /* R703 */ - 0x0000, /* R704 */ - 0x0000, /* R705 */ - 0x0000, /* R706 */ - 0x0000, /* R707 */ - 0x0000, /* R708 */ - 0x0000, /* R709 */ - 0x0000, /* R710 */ - 0x0000, /* R711 */ - 0x0000, /* R712 */ - 0x0000, /* R713 */ - 0x0000, /* R714 */ - 0x0000, /* R715 */ - 0x0000, /* R716 */ - 0x0000, /* R717 */ - 0x0000, /* R718 */ - 0x0000, /* R719 */ - 0x0000, /* R720 */ - 0x0000, /* R721 */ - 0x0000, /* R722 */ - 0x0000, /* R723 */ - 0x0000, /* R724 */ - 0x0000, /* R725 */ - 0x0000, /* R726 */ - 0x0000, /* R727 */ - 0x0000, /* R728 */ - 0x0000, /* R729 */ - 0x0000, /* R730 */ - 0x0000, /* R731 */ - 0x0000, /* R732 */ - 0x0000, /* R733 */ - 0x0000, /* R734 */ - 0x0000, /* R735 */ - 0x0000, /* R736 */ - 0x0000, /* R737 */ - 0x0000, /* R738 */ - 0x0000, /* R739 */ - 0x0000, /* R740 */ - 0x0000, /* R741 */ - 0x0000, /* R742 */ - 0x0000, /* R743 */ - 0x0000, /* R744 */ - 0x0000, /* R745 */ - 0x0000, /* R746 */ - 0x0000, /* R747 */ - 0x0000, /* R748 */ - 0x0000, /* R749 */ - 0x0000, /* R750 */ - 0x0000, /* R751 */ - 0x0000, /* R752 */ - 0x0000, /* R753 */ - 0x0000, /* R754 */ - 0x0000, /* R755 */ - 0x0000, /* R756 */ - 0x0000, /* R757 */ - 0x0000, /* R758 */ - 0x0000, /* R759 */ - 0x0000, /* R760 */ - 0x0000, /* R761 */ - 0x0000, /* R762 */ - 0x0000, /* R763 */ - 0x0000, /* R764 */ - 0x0000, /* R765 */ - 0x0000, /* R766 */ - 0x0000, /* R767 */ - 0x4050, /* R768 - AIF1 Control (1) */ - 0x4000, /* R769 - AIF1 Control (2) */ - 0x0000, /* R770 - AIF1 Master/Slave */ - 0x0040, /* R771 - AIF1 BCLK */ - 0x0040, /* R772 - AIF1ADC LRCLK */ - 0x0040, /* R773 - AIF1DAC LRCLK */ - 0x0004, /* R774 - AIF1DAC Data */ - 0x0100, /* R775 - AIF1ADC Data */ - 0x0000, /* R776 */ - 0x0000, /* R777 */ - 0x0000, /* R778 */ - 0x0000, /* R779 */ - 0x0000, /* R780 */ - 0x0000, /* R781 */ - 0x0000, /* R782 */ - 0x0000, /* R783 */ - 0x4050, /* R784 - AIF2 Control (1) */ - 0x4000, /* R785 - AIF2 Control (2) */ - 0x0000, /* R786 - AIF2 Master/Slave */ - 0x0040, /* R787 - AIF2 BCLK */ - 0x0040, /* R788 - AIF2ADC LRCLK */ - 0x0040, /* R789 - AIF2DAC LRCLK */ - 0x0000, /* R790 - AIF2DAC Data */ - 0x0000, /* R791 - AIF2ADC Data */ - 0x0000, /* R792 */ - 0x0000, /* R793 */ - 0x0000, /* R794 */ - 0x0000, /* R795 */ - 0x0000, /* R796 */ - 0x0000, /* R797 */ - 0x0000, /* R798 */ - 0x0000, /* R799 */ - 0x0000, /* R800 */ - 0x0000, /* R801 */ - 0x0000, /* R802 */ - 0x0000, /* R803 */ - 0x0000, /* R804 */ - 0x0000, /* R805 */ - 0x0000, /* R806 */ - 0x0000, /* R807 */ - 0x0000, /* R808 */ - 0x0000, /* R809 */ - 0x0000, /* R810 */ - 0x0000, /* R811 */ - 0x0000, /* R812 */ - 0x0000, /* R813 */ - 0x0000, /* R814 */ - 0x0000, /* R815 */ - 0x0000, /* R816 */ - 0x0000, /* R817 */ - 0x0000, /* R818 */ - 0x0000, /* R819 */ - 0x0000, /* R820 */ - 0x0000, /* R821 */ - 0x0000, /* R822 */ - 0x0000, /* R823 */ - 0x0000, /* R824 */ - 0x0000, /* R825 */ - 0x0000, /* R826 */ - 0x0000, /* R827 */ - 0x0000, /* R828 */ - 0x0000, /* R829 */ - 0x0000, /* R830 */ - 0x0000, /* R831 */ - 0x0000, /* R832 */ - 0x0000, /* R833 */ - 0x0000, /* R834 */ - 0x0000, /* R835 */ - 0x0000, /* R836 */ - 0x0000, /* R837 */ - 0x0000, /* R838 */ - 0x0000, /* R839 */ - 0x0000, /* R840 */ - 0x0000, /* R841 */ - 0x0000, /* R842 */ - 0x0000, /* R843 */ - 0x0000, /* R844 */ - 0x0000, /* R845 */ - 0x0000, /* R846 */ - 0x0000, /* R847 */ - 0x0000, /* R848 */ - 0x0000, /* R849 */ - 0x0000, /* R850 */ - 0x0000, /* R851 */ - 0x0000, /* R852 */ - 0x0000, /* R853 */ - 0x0000, /* R854 */ - 0x0000, /* R855 */ - 0x0000, /* R856 */ - 0x0000, /* R857 */ - 0x0000, /* R858 */ - 0x0000, /* R859 */ - 0x0000, /* R860 */ - 0x0000, /* R861 */ - 0x0000, /* R862 */ - 0x0000, /* R863 */ - 0x0000, /* R864 */ - 0x0000, /* R865 */ - 0x0000, /* R866 */ - 0x0000, /* R867 */ - 0x0000, /* R868 */ - 0x0000, /* R869 */ - 0x0000, /* R870 */ - 0x0000, /* R871 */ - 0x0000, /* R872 */ - 0x0000, /* R873 */ - 0x0000, /* R874 */ - 0x0000, /* R875 */ - 0x0000, /* R876 */ - 0x0000, /* R877 */ - 0x0000, /* R878 */ - 0x0000, /* R879 */ - 0x0000, /* R880 */ - 0x0000, /* R881 */ - 0x0000, /* R882 */ - 0x0000, /* R883 */ - 0x0000, /* R884 */ - 0x0000, /* R885 */ - 0x0000, /* R886 */ - 0x0000, /* R887 */ - 0x0000, /* R888 */ - 0x0000, /* R889 */ - 0x0000, /* R890 */ - 0x0000, /* R891 */ - 0x0000, /* R892 */ - 0x0000, /* R893 */ - 0x0000, /* R894 */ - 0x0000, /* R895 */ - 0x0000, /* R896 */ - 0x0000, /* R897 */ - 0x0000, /* R898 */ - 0x0000, /* R899 */ - 0x0000, /* R900 */ - 0x0000, /* R901 */ - 0x0000, /* R902 */ - 0x0000, /* R903 */ - 0x0000, /* R904 */ - 0x0000, /* R905 */ - 0x0000, /* R906 */ - 0x0000, /* R907 */ - 0x0000, /* R908 */ - 0x0000, /* R909 */ - 0x0000, /* R910 */ - 0x0000, /* R911 */ - 0x0000, /* R912 */ - 0x0000, /* R913 */ - 0x0000, /* R914 */ - 0x0000, /* R915 */ - 0x0000, /* R916 */ - 0x0000, /* R917 */ - 0x0000, /* R918 */ - 0x0000, /* R919 */ - 0x0000, /* R920 */ - 0x0000, /* R921 */ - 0x0000, /* R922 */ - 0x0000, /* R923 */ - 0x0000, /* R924 */ - 0x0000, /* R925 */ - 0x0000, /* R926 */ - 0x0000, /* R927 */ - 0x0000, /* R928 */ - 0x0000, /* R929 */ - 0x0000, /* R930 */ - 0x0000, /* R931 */ - 0x0000, /* R932 */ - 0x0000, /* R933 */ - 0x0000, /* R934 */ - 0x0000, /* R935 */ - 0x0000, /* R936 */ - 0x0000, /* R937 */ - 0x0000, /* R938 */ - 0x0000, /* R939 */ - 0x0000, /* R940 */ - 0x0000, /* R941 */ - 0x0000, /* R942 */ - 0x0000, /* R943 */ - 0x0000, /* R944 */ - 0x0000, /* R945 */ - 0x0000, /* R946 */ - 0x0000, /* R947 */ - 0x0000, /* R948 */ - 0x0000, /* R949 */ - 0x0000, /* R950 */ - 0x0000, /* R951 */ - 0x0000, /* R952 */ - 0x0000, /* R953 */ - 0x0000, /* R954 */ - 0x0000, /* R955 */ - 0x0000, /* R956 */ - 0x0000, /* R957 */ - 0x0000, /* R958 */ - 0x0000, /* R959 */ - 0x0000, /* R960 */ - 0x0000, /* R961 */ - 0x0000, /* R962 */ - 0x0000, /* R963 */ - 0x0000, /* R964 */ - 0x0000, /* R965 */ - 0x0000, /* R966 */ - 0x0000, /* R967 */ - 0x0000, /* R968 */ - 0x0000, /* R969 */ - 0x0000, /* R970 */ - 0x0000, /* R971 */ - 0x0000, /* R972 */ - 0x0000, /* R973 */ - 0x0000, /* R974 */ - 0x0000, /* R975 */ - 0x0000, /* R976 */ - 0x0000, /* R977 */ - 0x0000, /* R978 */ - 0x0000, /* R979 */ - 0x0000, /* R980 */ - 0x0000, /* R981 */ - 0x0000, /* R982 */ - 0x0000, /* R983 */ - 0x0000, /* R984 */ - 0x0000, /* R985 */ - 0x0000, /* R986 */ - 0x0000, /* R987 */ - 0x0000, /* R988 */ - 0x0000, /* R989 */ - 0x0000, /* R990 */ - 0x0000, /* R991 */ - 0x0000, /* R992 */ - 0x0000, /* R993 */ - 0x0000, /* R994 */ - 0x0000, /* R995 */ - 0x0000, /* R996 */ - 0x0000, /* R997 */ - 0x0000, /* R998 */ - 0x0000, /* R999 */ - 0x0000, /* R1000 */ - 0x0000, /* R1001 */ - 0x0000, /* R1002 */ - 0x0000, /* R1003 */ - 0x0000, /* R1004 */ - 0x0000, /* R1005 */ - 0x0000, /* R1006 */ - 0x0000, /* R1007 */ - 0x0000, /* R1008 */ - 0x0000, /* R1009 */ - 0x0000, /* R1010 */ - 0x0000, /* R1011 */ - 0x0000, /* R1012 */ - 0x0000, /* R1013 */ - 0x0000, /* R1014 */ - 0x0000, /* R1015 */ - 0x0000, /* R1016 */ - 0x0000, /* R1017 */ - 0x0000, /* R1018 */ - 0x0000, /* R1019 */ - 0x0000, /* R1020 */ - 0x0000, /* R1021 */ - 0x0000, /* R1022 */ - 0x0000, /* R1023 */ - 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */ - 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */ - 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */ - 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */ - 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */ - 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */ - 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */ - 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */ - 0x0000, /* R1032 */ - 0x0000, /* R1033 */ - 0x0000, /* R1034 */ - 0x0000, /* R1035 */ - 0x0000, /* R1036 */ - 0x0000, /* R1037 */ - 0x0000, /* R1038 */ - 0x0000, /* R1039 */ - 0x0000, /* R1040 - AIF1 ADC1 Filters */ - 0x0000, /* R1041 - AIF1 ADC2 Filters */ - 0x0000, /* R1042 */ - 0x0000, /* R1043 */ - 0x0000, /* R1044 */ - 0x0000, /* R1045 */ - 0x0000, /* R1046 */ - 0x0000, /* R1047 */ - 0x0000, /* R1048 */ - 0x0000, /* R1049 */ - 0x0000, /* R1050 */ - 0x0000, /* R1051 */ - 0x0000, /* R1052 */ - 0x0000, /* R1053 */ - 0x0000, /* R1054 */ - 0x0000, /* R1055 */ - 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */ - 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */ - 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */ - 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */ - 0x0000, /* R1060 */ - 0x0000, /* R1061 */ - 0x0000, /* R1062 */ - 0x0000, /* R1063 */ - 0x0000, /* R1064 */ - 0x0000, /* R1065 */ - 0x0000, /* R1066 */ - 0x0000, /* R1067 */ - 0x0000, /* R1068 */ - 0x0000, /* R1069 */ - 0x0000, /* R1070 */ - 0x0000, /* R1071 */ - 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */ - 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */ - 0x0000, /* R1074 */ - 0x0000, /* R1075 */ - 0x0000, /* R1076 */ - 0x0000, /* R1077 */ - 0x0000, /* R1078 */ - 0x0000, /* R1079 */ - 0x0000, /* R1080 */ - 0x0000, /* R1081 */ - 0x0000, /* R1082 */ - 0x0000, /* R1083 */ - 0x0000, /* R1084 */ - 0x0000, /* R1085 */ - 0x0000, /* R1086 */ - 0x0000, /* R1087 */ - 0x0098, /* R1088 - AIF1 DRC1 (1) */ - 0x0845, /* R1089 - AIF1 DRC1 (2) */ - 0x0000, /* R1090 - AIF1 DRC1 (3) */ - 0x0000, /* R1091 - AIF1 DRC1 (4) */ - 0x0000, /* R1092 - AIF1 DRC1 (5) */ - 0x0000, /* R1093 */ - 0x0000, /* R1094 */ - 0x0000, /* R1095 */ - 0x0000, /* R1096 */ - 0x0000, /* R1097 */ - 0x0000, /* R1098 */ - 0x0000, /* R1099 */ - 0x0000, /* R1100 */ - 0x0000, /* R1101 */ - 0x0000, /* R1102 */ - 0x0000, /* R1103 */ - 0x0098, /* R1104 - AIF1 DRC2 (1) */ - 0x0845, /* R1105 - AIF1 DRC2 (2) */ - 0x0000, /* R1106 - AIF1 DRC2 (3) */ - 0x0000, /* R1107 - AIF1 DRC2 (4) */ - 0x0000, /* R1108 - AIF1 DRC2 (5) */ - 0x0000, /* R1109 */ - 0x0000, /* R1110 */ - 0x0000, /* R1111 */ - 0x0000, /* R1112 */ - 0x0000, /* R1113 */ - 0x0000, /* R1114 */ - 0x0000, /* R1115 */ - 0x0000, /* R1116 */ - 0x0000, /* R1117 */ - 0x0000, /* R1118 */ - 0x0000, /* R1119 */ - 0x0000, /* R1120 */ - 0x0000, /* R1121 */ - 0x0000, /* R1122 */ - 0x0000, /* R1123 */ - 0x0000, /* R1124 */ - 0x0000, /* R1125 */ - 0x0000, /* R1126 */ - 0x0000, /* R1127 */ - 0x0000, /* R1128 */ - 0x0000, /* R1129 */ - 0x0000, /* R1130 */ - 0x0000, /* R1131 */ - 0x0000, /* R1132 */ - 0x0000, /* R1133 */ - 0x0000, /* R1134 */ - 0x0000, /* R1135 */ - 0x0000, /* R1136 */ - 0x0000, /* R1137 */ - 0x0000, /* R1138 */ - 0x0000, /* R1139 */ - 0x0000, /* R1140 */ - 0x0000, /* R1141 */ - 0x0000, /* R1142 */ - 0x0000, /* R1143 */ - 0x0000, /* R1144 */ - 0x0000, /* R1145 */ - 0x0000, /* R1146 */ - 0x0000, /* R1147 */ - 0x0000, /* R1148 */ - 0x0000, /* R1149 */ - 0x0000, /* R1150 */ - 0x0000, /* R1151 */ - 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - 0x0000, /* R1172 */ - 0x0000, /* R1173 */ - 0x0000, /* R1174 */ - 0x0000, /* R1175 */ - 0x0000, /* R1176 */ - 0x0000, /* R1177 */ - 0x0000, /* R1178 */ - 0x0000, /* R1179 */ - 0x0000, /* R1180 */ - 0x0000, /* R1181 */ - 0x0000, /* R1182 */ - 0x0000, /* R1183 */ - 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - 0x0000, /* R1204 */ - 0x0000, /* R1205 */ - 0x0000, /* R1206 */ - 0x0000, /* R1207 */ - 0x0000, /* R1208 */ - 0x0000, /* R1209 */ - 0x0000, /* R1210 */ - 0x0000, /* R1211 */ - 0x0000, /* R1212 */ - 0x0000, /* R1213 */ - 0x0000, /* R1214 */ - 0x0000, /* R1215 */ - 0x0000, /* R1216 */ - 0x0000, /* R1217 */ - 0x0000, /* R1218 */ - 0x0000, /* R1219 */ - 0x0000, /* R1220 */ - 0x0000, /* R1221 */ - 0x0000, /* R1222 */ - 0x0000, /* R1223 */ - 0x0000, /* R1224 */ - 0x0000, /* R1225 */ - 0x0000, /* R1226 */ - 0x0000, /* R1227 */ - 0x0000, /* R1228 */ - 0x0000, /* R1229 */ - 0x0000, /* R1230 */ - 0x0000, /* R1231 */ - 0x0000, /* R1232 */ - 0x0000, /* R1233 */ - 0x0000, /* R1234 */ - 0x0000, /* R1235 */ - 0x0000, /* R1236 */ - 0x0000, /* R1237 */ - 0x0000, /* R1238 */ - 0x0000, /* R1239 */ - 0x0000, /* R1240 */ - 0x0000, /* R1241 */ - 0x0000, /* R1242 */ - 0x0000, /* R1243 */ - 0x0000, /* R1244 */ - 0x0000, /* R1245 */ - 0x0000, /* R1246 */ - 0x0000, /* R1247 */ - 0x0000, /* R1248 */ - 0x0000, /* R1249 */ - 0x0000, /* R1250 */ - 0x0000, /* R1251 */ - 0x0000, /* R1252 */ - 0x0000, /* R1253 */ - 0x0000, /* R1254 */ - 0x0000, /* R1255 */ - 0x0000, /* R1256 */ - 0x0000, /* R1257 */ - 0x0000, /* R1258 */ - 0x0000, /* R1259 */ - 0x0000, /* R1260 */ - 0x0000, /* R1261 */ - 0x0000, /* R1262 */ - 0x0000, /* R1263 */ - 0x0000, /* R1264 */ - 0x0000, /* R1265 */ - 0x0000, /* R1266 */ - 0x0000, /* R1267 */ - 0x0000, /* R1268 */ - 0x0000, /* R1269 */ - 0x0000, /* R1270 */ - 0x0000, /* R1271 */ - 0x0000, /* R1272 */ - 0x0000, /* R1273 */ - 0x0000, /* R1274 */ - 0x0000, /* R1275 */ - 0x0000, /* R1276 */ - 0x0000, /* R1277 */ - 0x0000, /* R1278 */ - 0x0000, /* R1279 */ - 0x00C0, /* R1280 - AIF2 ADC Left Volume */ - 0x00C0, /* R1281 - AIF2 ADC Right Volume */ - 0x00C0, /* R1282 - AIF2 DAC Left Volume */ - 0x00C0, /* R1283 - AIF2 DAC Right Volume */ - 0x0000, /* R1284 */ - 0x0000, /* R1285 */ - 0x0000, /* R1286 */ - 0x0000, /* R1287 */ - 0x0000, /* R1288 */ - 0x0000, /* R1289 */ - 0x0000, /* R1290 */ - 0x0000, /* R1291 */ - 0x0000, /* R1292 */ - 0x0000, /* R1293 */ - 0x0000, /* R1294 */ - 0x0000, /* R1295 */ - 0x0000, /* R1296 - AIF2 ADC Filters */ - 0x0000, /* R1297 */ - 0x0000, /* R1298 */ - 0x0000, /* R1299 */ - 0x0000, /* R1300 */ - 0x0000, /* R1301 */ - 0x0000, /* R1302 */ - 0x0000, /* R1303 */ - 0x0000, /* R1304 */ - 0x0000, /* R1305 */ - 0x0000, /* R1306 */ - 0x0000, /* R1307 */ - 0x0000, /* R1308 */ - 0x0000, /* R1309 */ - 0x0000, /* R1310 */ - 0x0000, /* R1311 */ - 0x0200, /* R1312 - AIF2 DAC Filters (1) */ - 0x0010, /* R1313 - AIF2 DAC Filters (2) */ - 0x0000, /* R1314 */ - 0x0000, /* R1315 */ - 0x0000, /* R1316 */ - 0x0000, /* R1317 */ - 0x0000, /* R1318 */ - 0x0000, /* R1319 */ - 0x0000, /* R1320 */ - 0x0000, /* R1321 */ - 0x0000, /* R1322 */ - 0x0000, /* R1323 */ - 0x0000, /* R1324 */ - 0x0000, /* R1325 */ - 0x0000, /* R1326 */ - 0x0000, /* R1327 */ - 0x0068, /* R1328 - AIF2 DAC Noise Gate */ - 0x0000, /* R1329 */ - 0x0000, /* R1330 */ - 0x0000, /* R1331 */ - 0x0000, /* R1332 */ - 0x0000, /* R1333 */ - 0x0000, /* R1334 */ - 0x0000, /* R1335 */ - 0x0000, /* R1336 */ - 0x0000, /* R1337 */ - 0x0000, /* R1338 */ - 0x0000, /* R1339 */ - 0x0000, /* R1340 */ - 0x0000, /* R1341 */ - 0x0000, /* R1342 */ - 0x0000, /* R1343 */ - 0x0098, /* R1344 - AIF2 DRC (1) */ - 0x0845, /* R1345 - AIF2 DRC (2) */ - 0x0000, /* R1346 - AIF2 DRC (3) */ - 0x0000, /* R1347 - AIF2 DRC (4) */ - 0x0000, /* R1348 - AIF2 DRC (5) */ - 0x0000, /* R1349 */ - 0x0000, /* R1350 */ - 0x0000, /* R1351 */ - 0x0000, /* R1352 */ - 0x0000, /* R1353 */ - 0x0000, /* R1354 */ - 0x0000, /* R1355 */ - 0x0000, /* R1356 */ - 0x0000, /* R1357 */ - 0x0000, /* R1358 */ - 0x0000, /* R1359 */ - 0x0000, /* R1360 */ - 0x0000, /* R1361 */ - 0x0000, /* R1362 */ - 0x0000, /* R1363 */ - 0x0000, /* R1364 */ - 0x0000, /* R1365 */ - 0x0000, /* R1366 */ - 0x0000, /* R1367 */ - 0x0000, /* R1368 */ - 0x0000, /* R1369 */ - 0x0000, /* R1370 */ - 0x0000, /* R1371 */ - 0x0000, /* R1372 */ - 0x0000, /* R1373 */ - 0x0000, /* R1374 */ - 0x0000, /* R1375 */ - 0x0000, /* R1376 */ - 0x0000, /* R1377 */ - 0x0000, /* R1378 */ - 0x0000, /* R1379 */ - 0x0000, /* R1380 */ - 0x0000, /* R1381 */ - 0x0000, /* R1382 */ - 0x0000, /* R1383 */ - 0x0000, /* R1384 */ - 0x0000, /* R1385 */ - 0x0000, /* R1386 */ - 0x0000, /* R1387 */ - 0x0000, /* R1388 */ - 0x0000, /* R1389 */ - 0x0000, /* R1390 */ - 0x0000, /* R1391 */ - 0x0000, /* R1392 */ - 0x0000, /* R1393 */ - 0x0000, /* R1394 */ - 0x0000, /* R1395 */ - 0x0000, /* R1396 */ - 0x0000, /* R1397 */ - 0x0000, /* R1398 */ - 0x0000, /* R1399 */ - 0x0000, /* R1400 */ - 0x0000, /* R1401 */ - 0x0000, /* R1402 */ - 0x0000, /* R1403 */ - 0x0000, /* R1404 */ - 0x0000, /* R1405 */ - 0x0000, /* R1406 */ - 0x0000, /* R1407 */ - 0x6318, /* R1408 - AIF2 EQ Gains (1) */ - 0x6300, /* R1409 - AIF2 EQ Gains (2) */ - 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */ - 0x0400, /* R1411 - AIF2 EQ Band 1 B */ - 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */ - 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */ - 0xF145, /* R1414 - AIF2 EQ Band 2 B */ - 0x0B75, /* R1415 - AIF2 EQ Band 2 C */ - 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */ - 0x1C58, /* R1417 - AIF2 EQ Band 3 A */ - 0xF373, /* R1418 - AIF2 EQ Band 3 B */ - 0x0A54, /* R1419 - AIF2 EQ Band 3 C */ - 0x0558, /* R1420 - AIF2 EQ Band 3 PG */ - 0x168E, /* R1421 - AIF2 EQ Band 4 A */ - 0xF829, /* R1422 - AIF2 EQ Band 4 B */ - 0x07AD, /* R1423 - AIF2 EQ Band 4 C */ - 0x1103, /* R1424 - AIF2 EQ Band 4 PG */ - 0x0564, /* R1425 - AIF2 EQ Band 5 A */ - 0x0559, /* R1426 - AIF2 EQ Band 5 B */ - 0x4000, /* R1427 - AIF2 EQ Band 5 PG */ - 0x0000, /* R1428 */ - 0x0000, /* R1429 */ - 0x0000, /* R1430 */ - 0x0000, /* R1431 */ - 0x0000, /* R1432 */ - 0x0000, /* R1433 */ - 0x0000, /* R1434 */ - 0x0000, /* R1435 */ - 0x0000, /* R1436 */ - 0x0000, /* R1437 */ - 0x0000, /* R1438 */ - 0x0000, /* R1439 */ - 0x0000, /* R1440 */ - 0x0000, /* R1441 */ - 0x0000, /* R1442 */ - 0x0000, /* R1443 */ - 0x0000, /* R1444 */ - 0x0000, /* R1445 */ - 0x0000, /* R1446 */ - 0x0000, /* R1447 */ - 0x0000, /* R1448 */ - 0x0000, /* R1449 */ - 0x0000, /* R1450 */ - 0x0000, /* R1451 */ - 0x0000, /* R1452 */ - 0x0000, /* R1453 */ - 0x0000, /* R1454 */ - 0x0000, /* R1455 */ - 0x0000, /* R1456 */ - 0x0000, /* R1457 */ - 0x0000, /* R1458 */ - 0x0000, /* R1459 */ - 0x0000, /* R1460 */ - 0x0000, /* R1461 */ - 0x0000, /* R1462 */ - 0x0000, /* R1463 */ - 0x0000, /* R1464 */ - 0x0000, /* R1465 */ - 0x0000, /* R1466 */ - 0x0000, /* R1467 */ - 0x0000, /* R1468 */ - 0x0000, /* R1469 */ - 0x0000, /* R1470 */ - 0x0000, /* R1471 */ - 0x0000, /* R1472 */ - 0x0000, /* R1473 */ - 0x0000, /* R1474 */ - 0x0000, /* R1475 */ - 0x0000, /* R1476 */ - 0x0000, /* R1477 */ - 0x0000, /* R1478 */ - 0x0000, /* R1479 */ - 0x0000, /* R1480 */ - 0x0000, /* R1481 */ - 0x0000, /* R1482 */ - 0x0000, /* R1483 */ - 0x0000, /* R1484 */ - 0x0000, /* R1485 */ - 0x0000, /* R1486 */ - 0x0000, /* R1487 */ - 0x0000, /* R1488 */ - 0x0000, /* R1489 */ - 0x0000, /* R1490 */ - 0x0000, /* R1491 */ - 0x0000, /* R1492 */ - 0x0000, /* R1493 */ - 0x0000, /* R1494 */ - 0x0000, /* R1495 */ - 0x0000, /* R1496 */ - 0x0000, /* R1497 */ - 0x0000, /* R1498 */ - 0x0000, /* R1499 */ - 0x0000, /* R1500 */ - 0x0000, /* R1501 */ - 0x0000, /* R1502 */ - 0x0000, /* R1503 */ - 0x0000, /* R1504 */ - 0x0000, /* R1505 */ - 0x0000, /* R1506 */ - 0x0000, /* R1507 */ - 0x0000, /* R1508 */ - 0x0000, /* R1509 */ - 0x0000, /* R1510 */ - 0x0000, /* R1511 */ - 0x0000, /* R1512 */ - 0x0000, /* R1513 */ - 0x0000, /* R1514 */ - 0x0000, /* R1515 */ - 0x0000, /* R1516 */ - 0x0000, /* R1517 */ - 0x0000, /* R1518 */ - 0x0000, /* R1519 */ - 0x0000, /* R1520 */ - 0x0000, /* R1521 */ - 0x0000, /* R1522 */ - 0x0000, /* R1523 */ - 0x0000, /* R1524 */ - 0x0000, /* R1525 */ - 0x0000, /* R1526 */ - 0x0000, /* R1527 */ - 0x0000, /* R1528 */ - 0x0000, /* R1529 */ - 0x0000, /* R1530 */ - 0x0000, /* R1531 */ - 0x0000, /* R1532 */ - 0x0000, /* R1533 */ - 0x0000, /* R1534 */ - 0x0000, /* R1535 */ - 0x0000, /* R1536 - DAC1 Mixer Volumes */ - 0x0000, /* R1537 - DAC1 Left Mixer Routing */ - 0x0000, /* R1538 - DAC1 Right Mixer Routing */ - 0x0000, /* R1539 - DAC2 Mixer Volumes */ - 0x0000, /* R1540 - DAC2 Left Mixer Routing */ - 0x0000, /* R1541 - DAC2 Right Mixer Routing */ - 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */ - 0x0000, /* R1546 */ - 0x0000, /* R1547 */ - 0x0000, /* R1548 */ - 0x0000, /* R1549 */ - 0x0000, /* R1550 */ - 0x0000, /* R1551 */ - 0x02C0, /* R1552 - DAC1 Left Volume */ - 0x02C0, /* R1553 - DAC1 Right Volume */ - 0x02C0, /* R1554 - DAC2 Left Volume */ - 0x02C0, /* R1555 - DAC2 Right Volume */ - 0x0000, /* R1556 - DAC Softmute */ - 0x0000, /* R1557 */ - 0x0000, /* R1558 */ - 0x0000, /* R1559 */ - 0x0000, /* R1560 */ - 0x0000, /* R1561 */ - 0x0000, /* R1562 */ - 0x0000, /* R1563 */ - 0x0000, /* R1564 */ - 0x0000, /* R1565 */ - 0x0000, /* R1566 */ - 0x0000, /* R1567 */ - 0x0002, /* R1568 - Oversampling */ - 0x0000, /* R1569 - Sidetone */ -}; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6b73efd2699..93d27b66025 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -38,6 +38,11 @@ #include "wm8994.h" #include "wm_hubs.h" +#define WM1811_JACKDET_MODE_NONE 0x0000 +#define WM1811_JACKDET_MODE_JACK 0x0100 +#define WM1811_JACKDET_MODE_MIC 0x0080 +#define WM1811_JACKDET_MODE_AUDIO 0x0180 + #define WM8994_NUM_DRC 3 #define WM8994_NUM_EQ 3 @@ -53,103 +58,69 @@ static int wm8994_retune_mobile_base[] = { WM8994_AIF2_EQ_GAINS_1, }; -static int wm8994_readable(struct snd_soc_codec *codec, unsigned int reg) -{ - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = wm8994->control_data; - - switch (reg) { - case WM8994_GPIO_1: - case WM8994_GPIO_2: - case WM8994_GPIO_3: - case WM8994_GPIO_4: - case WM8994_GPIO_5: - case WM8994_GPIO_6: - case WM8994_GPIO_7: - case WM8994_GPIO_8: - case WM8994_GPIO_9: - case WM8994_GPIO_10: - case WM8994_GPIO_11: - case WM8994_INTERRUPT_STATUS_1: - case WM8994_INTERRUPT_STATUS_2: - case WM8994_INTERRUPT_RAW_STATUS_2: - return 1; +static void wm8958_default_micdet(u16 status, void *data); - case WM8958_DSP2_PROGRAM: - case WM8958_DSP2_CONFIG: - case WM8958_DSP2_EXECCONTROL: - if (control->type == WM8958) - return 1; - else - return 0; - - default: - break; - } +static const struct wm8958_micd_rate micdet_rates[] = { + { 32768, true, 1, 4 }, + { 32768, false, 1, 1 }, + { 44100 * 256, true, 7, 10 }, + { 44100 * 256, false, 7, 10 }, +}; - if (reg >= WM8994_CACHE_SIZE) - return 0; - return wm8994_access_masks[reg].readable != 0; -} +static const struct wm8958_micd_rate jackdet_rates[] = { + { 32768, true, 0, 1 }, + { 32768, false, 0, 1 }, + { 44100 * 256, true, 7, 10 }, + { 44100 * 256, false, 7, 10 }, +}; -static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg) +static void wm8958_micd_set_rate(struct snd_soc_codec *codec) { - if (reg >= WM8994_CACHE_SIZE) - return 1; - - switch (reg) { - case WM8994_SOFTWARE_RESET: - case WM8994_CHIP_REVISION: - case WM8994_DC_SERVO_1: - case WM8994_DC_SERVO_READBACK: - case WM8994_RATE_STATUS: - case WM8994_LDO_1: - case WM8994_LDO_2: - case WM8958_DSP2_EXECCONTROL: - case WM8958_MIC_DETECT_3: - case WM8994_DC_SERVO_4E: - return 1; - default: - return 0; - } -} + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int best, i, sysclk, val; + bool idle; + const struct wm8958_micd_rate *rates; + int num_rates; -static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - int ret; + if (wm8994->jack_cb != wm8958_default_micdet) + return; - BUG_ON(reg > WM8994_MAX_REGISTER); + idle = !wm8994->jack_mic; - if (!wm8994_volatile(codec, reg)) { - ret = snd_soc_cache_write(codec, reg, value); - if (ret != 0) - dev_err(codec->dev, "Cache write to %x failed: %d\n", - reg, ret); + sysclk = snd_soc_read(codec, WM8994_CLOCKING_1); + if (sysclk & WM8994_SYSCLK_SRC) + sysclk = wm8994->aifclk[1]; + else + sysclk = wm8994->aifclk[0]; + + if (wm8994->pdata && wm8994->pdata->micd_rates) { + rates = wm8994->pdata->micd_rates; + num_rates = wm8994->pdata->num_micd_rates; + } else if (wm8994->jackdet) { + rates = jackdet_rates; + num_rates = ARRAY_SIZE(jackdet_rates); + } else { + rates = micdet_rates; + num_rates = ARRAY_SIZE(micdet_rates); } - return wm8994_reg_write(codec->control_data, reg, value); -} - -static unsigned int wm8994_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - unsigned int val; - int ret; - - BUG_ON(reg > WM8994_MAX_REGISTER); - - if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) && - reg < codec->driver->reg_cache_size) { - ret = snd_soc_cache_read(codec, reg, &val); - if (ret >= 0) - return val; - else - dev_err(codec->dev, "Cache read from %x failed: %d\n", - reg, ret); + best = 0; + for (i = 0; i < num_rates; i++) { + if (rates[i].idle != idle) + continue; + if (abs(rates[i].sysclk - sysclk) < + abs(rates[best].sysclk - sysclk)) + best = i; + else if (rates[best].idle != idle) + best = i; } - return wm8994_reg_read(codec->control_data, reg); + val = rates[best].start << WM8958_MICD_BIAS_STARTTIME_SHIFT + | rates[best].rate << WM8958_MICD_RATE_SHIFT; + + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_BIAS_STARTTIME_MASK | + WM8958_MICD_RATE_MASK, val); } static int configure_aif_clock(struct snd_soc_codec *codec, int aif) @@ -221,8 +192,10 @@ static int configure_clock(struct snd_soc_codec *codec) */ /* If they're equal it doesn't matter which is used */ - if (wm8994->aifclk[0] == wm8994->aifclk[1]) + if (wm8994->aifclk[0] == wm8994->aifclk[1]) { + wm8958_micd_set_rate(codec); return 0; + } if (wm8994->aifclk[0] < wm8994->aifclk[1]) new = WM8994_SYSCLK_SRC; @@ -231,10 +204,10 @@ static int configure_clock(struct snd_soc_codec *codec) change = snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); - if (!change) - return 0; + if (change) + snd_soc_dapm_sync(&codec->dapm); - snd_soc_dapm_sync(&codec->dapm); + wm8958_micd_set_rate(codec); return 0; } @@ -708,6 +681,74 @@ SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0, mixin_boost_tlv), }; +/* We run all mode setting through a function to enforce audio mode */ +static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (wm8994->active_refcount) + mode = WM1811_JACKDET_MODE_AUDIO; + + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM1811_JACKDET_MODE_MASK, mode); + + if (mode == WM1811_JACKDET_MODE_MIC) + msleep(2); +} + +static void active_reference(struct snd_soc_codec *codec) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&wm8994->accdet_lock); + + wm8994->active_refcount++; + + dev_dbg(codec->dev, "Active refcount incremented, now %d\n", + wm8994->active_refcount); + + if (wm8994->active_refcount == 1) { + /* If we're using jack detection go into audio mode */ + if (wm8994->jackdet && wm8994->jack_cb) { + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM1811_JACKDET_MODE_MASK, + WM1811_JACKDET_MODE_AUDIO); + msleep(2); + } + } + + mutex_unlock(&wm8994->accdet_lock); +} + +static void active_dereference(struct snd_soc_codec *codec) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + u16 mode; + + mutex_lock(&wm8994->accdet_lock); + + wm8994->active_refcount--; + + dev_dbg(codec->dev, "Active refcount decremented, now %d\n", + wm8994->active_refcount); + + if (wm8994->active_refcount == 0) { + /* Go into appropriate detection only mode */ + if (wm8994->jackdet && wm8994->jack_cb) { + if (wm8994->jack_mic || wm8994->mic_detecting) + mode = WM1811_JACKDET_MODE_MIC; + else + mode = WM1811_JACKDET_MODE_JACK; + + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM1811_JACKDET_MODE_MASK, + mode); + } + } + + mutex_unlock(&wm8994->accdet_lock); +} + static int clk_sys_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1325,15 +1366,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), }; static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { -SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), -SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), }; static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { -SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), }; static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { @@ -1768,7 +1809,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, unsigned int freq_in, unsigned int freq_out) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int reg_offset, ret; struct fll_div fll; u16 reg, aif1, aif2; @@ -1865,6 +1906,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, if (freq_out) { /* Enable VMID if we need it */ if (!was_enabled) { + active_reference(codec); + switch (control->type) { case WM8994: vmid_reference(codec); @@ -1908,6 +1951,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, default: break; } + + active_dereference(codec); } } @@ -2017,20 +2062,33 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, static int wm8994_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: + /* MICBIAS into regulating mode */ + switch (control->type) { + case WM8958: + case WM1811: + snd_soc_update_bits(codec, WM8958_MICBIAS1, + WM8958_MICB1_MODE, 0); + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_MODE, 0); + break; + default: + break; + } + + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) + active_reference(codec); break; case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - pm_runtime_get_sync(codec->dev); - switch (control->type) { case WM8994: if (wm8994->revision < 4) { @@ -2077,25 +2135,40 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, WM8994_LINEOUT2_DISCH); } + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) + active_dereference(codec); + /* MICBIAS into bypass mode on newer devices */ + switch (control->type) { + case WM8958: + case WM1811: + snd_soc_update_bits(codec, WM8958_MICBIAS1, + WM8958_MICB1_MODE, + WM8958_MICB1_MODE); + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_MODE, + WM8958_MICB2_MODE); + break; + default: + break; + } break; case SND_SOC_BIAS_OFF: - if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) wm8994->cur_fw = NULL; - - pm_runtime_put(codec->dev); - } break; } codec->dapm.bias_level = level; + return 0; } static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_codec *codec = dai->codec; - struct wm8994 *control = codec->control_data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; int ms_reg; int aif1_reg; int ms = 0; @@ -2357,6 +2430,11 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; lrclk = bclk_rate / params_rate(params); + if (!lrclk) { + dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n", + bclk_rate); + return -EINVAL; + } dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", lrclk, bclk_rate / lrclk); @@ -2390,7 +2468,8 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; - struct wm8994 *control = codec->control_data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; int aif1_reg; int aif1 = 0; @@ -2531,7 +2610,7 @@ static int wm8994_aif2_probe(struct snd_soc_dai *dai) #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { +static const struct snd_soc_dai_ops wm8994_aif1_dai_ops = { .set_sysclk = wm8994_set_dai_sysclk, .set_fmt = wm8994_set_dai_fmt, .hw_params = wm8994_hw_params, @@ -2541,7 +2620,7 @@ static struct snd_soc_dai_ops wm8994_aif1_dai_ops = { .set_tristate = wm8994_set_tristate, }; -static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { +static const struct snd_soc_dai_ops wm8994_aif2_dai_ops = { .set_sysclk = wm8994_set_dai_sysclk, .set_fmt = wm8994_set_dai_fmt, .hw_params = wm8994_hw_params, @@ -2551,7 +2630,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { .set_tristate = wm8994_set_tristate, }; -static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { +static const struct snd_soc_dai_ops wm8994_aif3_dai_ops = { .hw_params = wm8994_aif3_hw_params, .set_tristate = wm8994_set_tristate, }; @@ -2618,10 +2697,10 @@ static struct snd_soc_dai_driver wm8994_dai[] = { }; #ifdef CONFIG_PM -static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8994_suspend(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int i, ret; switch (control->type) { @@ -2629,6 +2708,9 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); break; case WM1811: + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM1811_JACKDET_MODE_MASK, 0); + /* Fall through */ case WM8958: snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); @@ -2652,14 +2734,14 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm8994_resume(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int i, ret; unsigned int val, mask; if (wm8994->revision < 4) { /* force a HW read */ - val = wm8994_reg_read(codec->control_data, - WM8994_POWER_MANAGEMENT_5); + ret = regmap_read(control->regmap, + WM8994_POWER_MANAGEMENT_5, &val); /* modify the cache only */ codec->cache_only = 1; @@ -2698,6 +2780,13 @@ static int wm8994_resume(struct snd_soc_codec *codec) WM8994_MICD_ENA, WM8994_MICD_ENA); break; case WM1811: + if (wm8994->jackdet && wm8994->jack_cb) { + /* Restart from idle */ + snd_soc_update_bits(codec, WM8994_ANTIPOP_2, + WM1811_JACKDET_MODE_MASK, + WM1811_JACKDET_MODE_JACK); + break; + } case WM8958: if (wm8994->jack_cb) snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, @@ -2810,8 +2899,8 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) }; /* We need an array of texts for the enum API */ - wm8994->drc_texts = kmalloc(sizeof(char *) - * pdata->num_drc_cfgs, GFP_KERNEL); + wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev, + sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL); if (!wm8994->drc_texts) { dev_err(wm8994->codec->dev, "Failed to allocate %d DRC config texts\n", @@ -2874,7 +2963,7 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_micdet *micdet; - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int reg; if (control->type != WM8994) @@ -2957,21 +3046,136 @@ static void wm8958_default_micdet(u16 status, void *data) { struct snd_soc_codec *codec = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - int report = 0; + int report; + + dev_dbg(codec->dev, "MICDET %x\n", status); + + /* Either nothing present or just starting detection */ + if (!(status & WM8958_MICD_STS)) { + if (!wm8994->jackdet) { + /* If nothing present then clear our statuses */ + dev_dbg(codec->dev, "Detected open circuit\n"); + wm8994->jack_mic = false; + wm8994->mic_detecting = true; + + wm8958_micd_set_rate(codec); + + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + wm8994->btn_mask | + SND_JACK_HEADSET); + } + return; + } + + /* If the measurement is showing a high impedence we've got a + * microphone. + */ + if (wm8994->mic_detecting && (status & 0x600)) { + dev_dbg(codec->dev, "Detected microphone\n"); - /* If nothing present then clear our statuses */ - if (!(status & WM8958_MICD_STS)) - goto done; + wm8994->mic_detecting = false; + wm8994->jack_mic = true; + + wm8958_micd_set_rate(codec); + + snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, + SND_JACK_HEADSET); + } - report = SND_JACK_MICROPHONE; - /* Everything else is buttons; just assign slots */ - if (status & 0x1c) - report |= SND_JACK_BTN_0; + if (wm8994->mic_detecting && status & 0x4) { + dev_dbg(codec->dev, "Detected headphone\n"); + wm8994->mic_detecting = false; -done: - snd_soc_jack_report(wm8994->micdet[0].jack, report, - SND_JACK_BTN_0 | SND_JACK_MICROPHONE); + wm8958_micd_set_rate(codec); + + snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, + SND_JACK_HEADSET); + + /* If we have jackdet that will detect removal */ + if (wm8994->jackdet) { + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, 0); + + wm1811_jackdet_set_mode(codec, + WM1811_JACKDET_MODE_JACK); + } + } + + /* Report short circuit as a button */ + if (wm8994->jack_mic) { + report = 0; + if (status & 0x4) + report |= SND_JACK_BTN_0; + + if (status & 0x8) + report |= SND_JACK_BTN_1; + + if (status & 0x10) + report |= SND_JACK_BTN_2; + + if (status & 0x20) + report |= SND_JACK_BTN_3; + + if (status & 0x40) + report |= SND_JACK_BTN_4; + + if (status & 0x80) + report |= SND_JACK_BTN_5; + + snd_soc_jack_report(wm8994->micdet[0].jack, report, + wm8994->btn_mask); + } +} + +static irqreturn_t wm1811_jackdet_irq(int irq, void *data) +{ + struct wm8994_priv *wm8994 = data; + struct snd_soc_codec *codec = wm8994->codec; + int reg; + + mutex_lock(&wm8994->accdet_lock); + + reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); + if (reg < 0) { + dev_err(codec->dev, "Failed to read jack status: %d\n", reg); + mutex_unlock(&wm8994->accdet_lock); + return IRQ_NONE; + } + + dev_dbg(codec->dev, "JACKDET %x\n", reg); + + if (reg & WM1811_JACKDET_LVL) { + dev_dbg(codec->dev, "Jack detected\n"); + + snd_soc_jack_report(wm8994->micdet[0].jack, + SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); + + /* + * Start off measument of microphone impedence to find + * out what's actually there. + */ + wm8994->mic_detecting = true; + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, WM8958_MICD_ENA); + } else { + dev_dbg(codec->dev, "Jack not detected\n"); + + snd_soc_jack_report(wm8994->micdet[0].jack, 0, + SND_JACK_MECHANICAL | SND_JACK_HEADSET | + wm8994->btn_mask); + + wm8994->mic_detecting = false; + wm8994->jack_mic = false; + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, 0); + wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); + } + + mutex_unlock(&wm8994->accdet_lock); + + return IRQ_HANDLED; } /** @@ -2994,7 +3198,8 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8958_micdet_cb cb, void *cb_data) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; + u16 micd_lvl_sel; switch (control->type) { case WM1811: @@ -3011,15 +3216,50 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, cb_data = codec; } + snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); + wm8994->micdet[0].jack = jack; wm8994->jack_cb = cb; wm8994->jack_cb_data = cb_data; - snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, - WM8958_MICD_ENA, WM8958_MICD_ENA); + wm8994->mic_detecting = true; + wm8994->jack_mic = false; + + wm8958_micd_set_rate(codec); + + /* Detect microphones and short circuits by default */ + if (wm8994->pdata->micd_lvl_sel) + micd_lvl_sel = wm8994->pdata->micd_lvl_sel; + else + micd_lvl_sel = 0x41; + + wm8994->btn_mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | + SND_JACK_BTN_4 | SND_JACK_BTN_5; + + snd_soc_update_bits(codec, WM8958_MIC_DETECT_2, + WM8958_MICD_LVL_SEL_MASK, micd_lvl_sel); + + WARN_ON(codec->dapm.bias_level > SND_SOC_BIAS_STANDBY); + + /* + * If we can use jack detection start off with that, + * otherwise jump straight to microphone detection. + */ + if (wm8994->jackdet) { + snd_soc_update_bits(codec, WM8994_LDO_1, + WM8994_LDO1_DISCH, 0); + wm1811_jackdet_set_mode(codec, + WM1811_JACKDET_MODE_JACK); + } else { + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, WM8958_MICD_ENA); + } + } else { snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); + snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); } return 0; @@ -3030,20 +3270,48 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) { struct wm8994_priv *wm8994 = data; struct snd_soc_codec *codec = wm8994->codec; - int reg; + int reg, count; - reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); - if (reg < 0) { - dev_err(codec->dev, "Failed to read mic detect status: %d\n", - reg); - return IRQ_NONE; - } + mutex_lock(&wm8994->accdet_lock); - if (!(reg & WM8958_MICD_VALID)) { - dev_dbg(codec->dev, "Mic detect data not valid\n"); - goto out; + /* + * Jack detection may have detected a removal simulataneously + * with an update of the MICDET status; if so it will have + * stopped detection and we can ignore this interrupt. + */ + if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { + mutex_unlock(&wm8994->accdet_lock); + return IRQ_HANDLED; } + /* We may occasionally read a detection without an impedence + * range being provided - if that happens loop again. + */ + count = 10; + do { + reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); + if (reg < 0) { + mutex_unlock(&wm8994->accdet_lock); + dev_err(codec->dev, + "Failed to read mic detect status: %d\n", + reg); + return IRQ_NONE; + } + + if (!(reg & WM8958_MICD_VALID)) { + dev_dbg(codec->dev, "Mic detect data not valid\n"); + goto out; + } + + if (!(reg & WM8958_MICD_STS) || (reg & WM8958_MICD_LVL_MASK)) + break; + + msleep(1); + } while (count--); + + if (count == 0) + dev_warn(codec->dev, "No impedence range reported for jack\n"); + #ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); #endif @@ -3054,6 +3322,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) dev_warn(codec->dev, "Accessory detection with no callback\n"); out: + mutex_unlock(&wm8994->accdet_lock); + return IRQ_HANDLED; } @@ -3086,22 +3356,28 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data) static int wm8994_codec_probe(struct snd_soc_codec *codec) { - struct wm8994 *control; + struct wm8994 *control = dev_get_drvdata(codec->dev->parent); struct wm8994_priv *wm8994; struct snd_soc_dapm_context *dapm = &codec->dapm; + unsigned int reg; int ret, i; - codec->control_data = dev_get_drvdata(codec->dev->parent); - control = codec->control_data; + codec->control_data = control->regmap; - wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); + wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv), + GFP_KERNEL); if (wm8994 == NULL) return -ENOMEM; snd_soc_codec_set_drvdata(codec, wm8994); + snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); + + wm8994->wm8994 = dev_get_drvdata(codec->dev->parent); wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->codec = codec; + mutex_init(&wm8994->accdet_lock); + for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) init_completion(&wm8994->fll_locked[i]); @@ -3114,25 +3390,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) pm_runtime_enable(codec->dev); pm_runtime_resume(codec->dev); - /* Read our current status back from the chip - we don't want to - * reset as this may interfere with the GPIO or LDO operation. */ - for (i = 0; i < WM8994_CACHE_SIZE; i++) { - if (!wm8994_readable(codec, i) || wm8994_volatile(codec, i)) - continue; - - ret = wm8994_reg_read(codec->control_data, i); - if (ret <= 0) - continue; - - ret = snd_soc_cache_write(codec, i, ret); - if (ret != 0) { - dev_err(codec->dev, - "Failed to initialise cache for 0x%x: %d\n", - i, ret); - goto err; - } - } - /* Set revision-specific configuration */ wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); switch (control->type) { @@ -3163,6 +3420,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (wm8994->revision) { case 0: case 1: + case 2: + case 3: wm8994->hubs.dcs_codes_l = -9; wm8994->hubs.dcs_codes_r = -5; break; @@ -3178,14 +3437,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) break; } - wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, + wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, wm8994_fifo_error, "FIFO error", codec); - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, + wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, wm8994_temp_warn, "Thermal warning", codec); - wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, + wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, wm8994_temp_shut, "Thermal shutdown", codec); - ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, wm_hubs_dcs_done, "DC servo done", &wm8994->hubs); if (ret == 0) @@ -3205,7 +3464,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ret); } - ret = wm8994_request_irq(codec->control_data, + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994_mic_irq, "Mic 1 short", wm8994); @@ -3214,7 +3473,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) "Failed to request Mic1 short IRQ: %d\n", ret); - ret = wm8994_request_irq(codec->control_data, + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994_mic_irq, "Mic 2 detect", wm8994); @@ -3223,7 +3482,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) "Failed to request Mic2 detect IRQ: %d\n", ret); - ret = wm8994_request_irq(codec->control_data, + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC2_SHRT, wm8994_mic_irq, "Mic 2 short", wm8994); @@ -3248,9 +3507,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) } } + switch (control->type) { + case WM1811: + if (wm8994->revision > 1) { + ret = wm8994_request_irq(wm8994->wm8994, + WM8994_IRQ_GPIO(6), + wm1811_jackdet_irq, "JACKDET", + wm8994); + if (ret == 0) + wm8994->jackdet = true; + } + break; + default: + break; + } + wm8994->fll_locked_irq = true; for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) { - ret = wm8994_request_irq(codec->control_data, + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, wm8994_fll_locked_irq, "FLL lock", &wm8994->fll_locked[i]); @@ -3262,24 +3536,24 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) * configured on init - if a system wants to do this dynamically * at runtime we can deal with that then. */ - ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1); + ret = regmap_read(control->regmap, WM8994_GPIO_1, ®); if (ret < 0) { dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret); goto err_irq; } - if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { + if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { wm8994->lrclk_shared[0] = 1; wm8994_dai[0].symmetric_rates = 1; } else { wm8994->lrclk_shared[0] = 0; } - ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6); + ret = regmap_read(control->regmap, WM8994_GPIO_6, ®); if (ret < 0) { dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret); goto err_irq; } - if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { + if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) { wm8994->lrclk_shared[1] = 1; wm8994_dai[1].symmetric_rates = 1; } else { @@ -3346,6 +3620,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) break; } + /* Put MICBIAS into bypass mode by default on newer devices */ + switch (control->type) { + case WM8958: + case WM1811: + snd_soc_update_bits(codec, WM8958_MICBIAS1, + WM8958_MICB1_MODE, WM8958_MICB1_MODE); + snd_soc_update_bits(codec, WM8958_MICBIAS2, + WM8958_MICB2_MODE, WM8958_MICB2_MODE); + break; + default: + break; + } + wm8994_update_class_w(codec); wm8994_handle_pdata(wm8994); @@ -3457,28 +3744,29 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) return 0; err_irq: - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); + if (wm8994->jackdet) + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_SHRT, wm8994); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994); if (wm8994->micdet_irq) free_irq(wm8994->micdet_irq, wm8994); for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) - wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, &wm8994->fll_locked[i]); - wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, &wm8994->hubs); - wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); - wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); - wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); -err: - kfree(wm8994); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec); + return ret; } static int wm8994_codec_remove(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - struct wm8994 *control = codec->control_data; + struct wm8994 *control = wm8994->wm8994; int i; wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -3486,24 +3774,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) pm_runtime_disable(codec->dev); for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++) - wm8994_free_irq(codec->control_data, WM8994_IRQ_FLL1_LOCK + i, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FLL1_LOCK + i, &wm8994->fll_locked[i]); - wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_DCS_DONE, &wm8994->hubs); - wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); - wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); - wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_FIFOS_ERR, codec); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_SHUT, codec); + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_TEMP_WARN, codec); + + if (wm8994->jackdet) + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_GPIO(6), wm8994); switch (control->type) { case WM8994: if (wm8994->micdet_irq) free_irq(wm8994->micdet_irq, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC2_DET, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, + wm8994_free_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET, wm8994); break; @@ -3520,27 +3811,24 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) if (wm8994->enh_eq) release_firmware(wm8994->enh_eq); kfree(wm8994->retune_mobile_texts); - kfree(wm8994->drc_texts); - kfree(wm8994); return 0; } +static int wm8994_soc_volatile(struct snd_soc_codec *codec, + unsigned int reg) +{ + return true; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .probe = wm8994_codec_probe, .remove = wm8994_codec_remove, .suspend = wm8994_suspend, .resume = wm8994_resume, - .read = wm8994_read, - .write = wm8994_write, - .readable_register = wm8994_readable, - .volatile_register = wm8994_volatile, .set_bias_level = wm8994_set_bias_level, - - .reg_cache_size = WM8994_CACHE_SIZE, - .reg_cache_default = wm8994_reg_defaults, - .reg_word_size = 2, - .compress_type = SND_SOC_RBTREE_COMPRESSION, + .reg_cache_size = WM8994_MAX_REGISTER, + .volatile_register = wm8994_soc_volatile, }; static int __devinit wm8994_probe(struct platform_device *pdev) @@ -3564,18 +3852,7 @@ static struct platform_driver wm8994_codec_driver = { .remove = __devexit_p(wm8994_remove), }; -static __init int wm8994_init(void) -{ - return platform_driver_register(&wm8994_codec_driver); -} -module_init(wm8994_init); - -static __exit void wm8994_exit(void) -{ - platform_driver_unregister(&wm8994_codec_driver); -} -module_exit(wm8994_exit); - +module_platform_driver(wm8994_codec_driver); MODULE_DESCRIPTION("ASoC WM8994 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index f4f1355efc8..c3a42474ab1 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -39,16 +39,6 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, wm8958_micdet_cb cb, void *cb_data); -#define WM8994_CACHE_SIZE 1570 - -struct wm8994_access_mask { - unsigned short readable; /* Mask of readable bits */ - unsigned short writable; /* Mask of writable bits */ -}; - -extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; -extern const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; - int wm8958_aif_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); @@ -70,10 +60,11 @@ struct wm8994_fll_config { #define WM8994_NUM_DRC 3 #define WM8994_NUM_EQ 3 +struct wm8994; + struct wm8994_priv { struct wm_hubs_data hubs; - enum snd_soc_control_type control_type; - void *control_data; + struct wm8994 *wm8994; struct snd_soc_codec *codec; int sysclk[2]; int sysclk_rate[2]; @@ -84,6 +75,7 @@ struct wm8994_priv { bool fll_locked_irq; int vmid_refcount; + int active_refcount; int dac_rates[2]; int lrclk_shared[2]; @@ -125,7 +117,12 @@ struct wm8994_priv { const char **enh_eq_texts; struct soc_enum enh_eq_enum; + struct mutex accdet_lock; struct wm8994_micdet micdet[2]; + bool mic_detecting; + bool jack_mic; + int btn_mask; + bool jackdet; wm8958_micdet_cb jack_cb; void *jack_cb_data; diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 78eeb21e669..c8aada597d7 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> @@ -43,88 +44,331 @@ static const char *wm8995_supply_names[WM8995_NUM_SUPPLIES] = { "MICVDD" }; -static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = { - [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b, - [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0, - [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003, - [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25, - [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060, - [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083, - [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050, - [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040, - [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000, - [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0, - [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0, - [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200, - [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098, - [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318, - [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8, - [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5, - [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558, - [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103, - [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318, - [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8, - [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5, - [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558, - [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103, - [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0, - [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200, - [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318, - [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8, - [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5, - [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558, - [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103, - [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002, - [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101, - [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101, - [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101, - [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff, - [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002, - [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001, - [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f, - [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104, - [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050, - [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003, - [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b, - [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff, - [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff, - [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001, - [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001, - [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003, - [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401, - [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060, - [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff, - [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff, - [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff, - [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006, - [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006, - [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061, - [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003, - [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106, - [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502, - [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff, - [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff, - [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001, - [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f, - [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106, - [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050, - [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b, - [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff, - [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff, - [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff, - [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100, - [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff, - [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff, - [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff, - [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff, - [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102, - [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff, - [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff, - [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff, - [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff, - [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601, - [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304, - [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100 +static struct reg_default wm8995_reg_defaults[] = { + { 0, 0x8995 }, + { 5, 0x0100 }, + { 16, 0x000b }, + { 17, 0x000b }, + { 24, 0x02c0 }, + { 25, 0x02c0 }, + { 26, 0x02c0 }, + { 27, 0x02c0 }, + { 28, 0x000f }, + { 32, 0x0005 }, + { 33, 0x0005 }, + { 40, 0x0003 }, + { 41, 0x0013 }, + { 48, 0x0004 }, + { 56, 0x09f8 }, + { 64, 0x1f25 }, + { 69, 0x0004 }, + { 82, 0xaaaa }, + { 84, 0x2a2a }, + { 146, 0x0060 }, + { 256, 0x0002 }, + { 257, 0x8004 }, + { 520, 0x0010 }, + { 528, 0x0083 }, + { 529, 0x0083 }, + { 548, 0x0c80 }, + { 580, 0x0c80 }, + { 768, 0x4050 }, + { 769, 0x4000 }, + { 771, 0x0040 }, + { 772, 0x0040 }, + { 773, 0x0040 }, + { 774, 0x0004 }, + { 775, 0x0100 }, + { 784, 0x4050 }, + { 785, 0x4000 }, + { 787, 0x0040 }, + { 788, 0x0040 }, + { 789, 0x0040 }, + { 1024, 0x00c0 }, + { 1025, 0x00c0 }, + { 1026, 0x00c0 }, + { 1027, 0x00c0 }, + { 1028, 0x00c0 }, + { 1029, 0x00c0 }, + { 1030, 0x00c0 }, + { 1031, 0x00c0 }, + { 1056, 0x0200 }, + { 1057, 0x0010 }, + { 1058, 0x0200 }, + { 1059, 0x0010 }, + { 1088, 0x0098 }, + { 1089, 0x0845 }, + { 1104, 0x0098 }, + { 1105, 0x0845 }, + { 1152, 0x6318 }, + { 1153, 0x6300 }, + { 1154, 0x0fca }, + { 1155, 0x0400 }, + { 1156, 0x00d8 }, + { 1157, 0x1eb5 }, + { 1158, 0xf145 }, + { 1159, 0x0b75 }, + { 1160, 0x01c5 }, + { 1161, 0x1c58 }, + { 1162, 0xf373 }, + { 1163, 0x0a54 }, + { 1164, 0x0558 }, + { 1165, 0x168e }, + { 1166, 0xf829 }, + { 1167, 0x07ad }, + { 1168, 0x1103 }, + { 1169, 0x0564 }, + { 1170, 0x0559 }, + { 1171, 0x4000 }, + { 1184, 0x6318 }, + { 1185, 0x6300 }, + { 1186, 0x0fca }, + { 1187, 0x0400 }, + { 1188, 0x00d8 }, + { 1189, 0x1eb5 }, + { 1190, 0xf145 }, + { 1191, 0x0b75 }, + { 1192, 0x01c5 }, + { 1193, 0x1c58 }, + { 1194, 0xf373 }, + { 1195, 0x0a54 }, + { 1196, 0x0558 }, + { 1197, 0x168e }, + { 1198, 0xf829 }, + { 1199, 0x07ad }, + { 1200, 0x1103 }, + { 1201, 0x0564 }, + { 1202, 0x0559 }, + { 1203, 0x4000 }, + { 1280, 0x00c0 }, + { 1281, 0x00c0 }, + { 1282, 0x00c0 }, + { 1283, 0x00c0 }, + { 1312, 0x0200 }, + { 1313, 0x0010 }, + { 1344, 0x0098 }, + { 1345, 0x0845 }, + { 1408, 0x6318 }, + { 1409, 0x6300 }, + { 1410, 0x0fca }, + { 1411, 0x0400 }, + { 1412, 0x00d8 }, + { 1413, 0x1eb5 }, + { 1414, 0xf145 }, + { 1415, 0x0b75 }, + { 1416, 0x01c5 }, + { 1417, 0x1c58 }, + { 1418, 0xf373 }, + { 1419, 0x0a54 }, + { 1420, 0x0558 }, + { 1421, 0x168e }, + { 1422, 0xf829 }, + { 1423, 0x07ad }, + { 1424, 0x1103 }, + { 1425, 0x0564 }, + { 1426, 0x0559 }, + { 1427, 0x4000 }, + { 1568, 0x0002 }, + { 1792, 0xa100 }, + { 1793, 0xa101 }, + { 1794, 0xa101 }, + { 1795, 0xa101 }, + { 1796, 0xa101 }, + { 1797, 0xa101 }, + { 1798, 0xa101 }, + { 1799, 0xa101 }, + { 1800, 0xa101 }, + { 1801, 0xa101 }, + { 1802, 0xa101 }, + { 1803, 0xa101 }, + { 1804, 0xa101 }, + { 1805, 0xa101 }, + { 1825, 0x0055 }, + { 1848, 0x3fff }, + { 1849, 0x1fff }, + { 2049, 0x0001 }, + { 2050, 0x0069 }, + { 2056, 0x0002 }, + { 2057, 0x0003 }, + { 2058, 0x0069 }, + { 12288, 0x0001 }, + { 12289, 0x0001 }, + { 12291, 0x0006 }, + { 12292, 0x0040 }, + { 12293, 0x0001 }, + { 12294, 0x000f }, + { 12295, 0x0006 }, + { 12296, 0x0001 }, + { 12297, 0x0003 }, + { 12298, 0x0104 }, + { 12300, 0x0060 }, + { 12301, 0x0011 }, + { 12302, 0x0401 }, + { 12304, 0x0050 }, + { 12305, 0x0003 }, + { 12306, 0x0100 }, + { 12308, 0x0051 }, + { 12309, 0x0003 }, + { 12310, 0x0104 }, + { 12311, 0x000a }, + { 12312, 0x0060 }, + { 12313, 0x003b }, + { 12314, 0x0502 }, + { 12315, 0x0100 }, + { 12316, 0x2fff }, + { 12320, 0x2fff }, + { 12324, 0x2fff }, + { 12328, 0x2fff }, + { 12332, 0x2fff }, + { 12336, 0x2fff }, + { 12340, 0x2fff }, + { 12344, 0x2fff }, + { 12348, 0x2fff }, + { 12352, 0x0001 }, + { 12353, 0x0001 }, + { 12355, 0x0006 }, + { 12356, 0x0040 }, + { 12357, 0x0001 }, + { 12358, 0x000f }, + { 12359, 0x0006 }, + { 12360, 0x0001 }, + { 12361, 0x0003 }, + { 12362, 0x0104 }, + { 12364, 0x0060 }, + { 12365, 0x0011 }, + { 12366, 0x0401 }, + { 12368, 0x0050 }, + { 12369, 0x0003 }, + { 12370, 0x0100 }, + { 12372, 0x0060 }, + { 12373, 0x003b }, + { 12374, 0x0502 }, + { 12375, 0x0100 }, + { 12376, 0x2fff }, + { 12380, 0x2fff }, + { 12384, 0x2fff }, + { 12388, 0x2fff }, + { 12392, 0x2fff }, + { 12396, 0x2fff }, + { 12400, 0x2fff }, + { 12404, 0x2fff }, + { 12408, 0x2fff }, + { 12412, 0x2fff }, + { 12416, 0x0001 }, + { 12417, 0x0001 }, + { 12419, 0x0006 }, + { 12420, 0x0040 }, + { 12421, 0x0001 }, + { 12422, 0x000f }, + { 12423, 0x0006 }, + { 12424, 0x0001 }, + { 12425, 0x0003 }, + { 12426, 0x0106 }, + { 12428, 0x0061 }, + { 12429, 0x0011 }, + { 12430, 0x0401 }, + { 12432, 0x0050 }, + { 12433, 0x0003 }, + { 12434, 0x0102 }, + { 12436, 0x0051 }, + { 12437, 0x0003 }, + { 12438, 0x0106 }, + { 12439, 0x000a }, + { 12440, 0x0061 }, + { 12441, 0x003b }, + { 12442, 0x0502 }, + { 12443, 0x0100 }, + { 12444, 0x2fff }, + { 12448, 0x2fff }, + { 12452, 0x2fff }, + { 12456, 0x2fff }, + { 12460, 0x2fff }, + { 12464, 0x2fff }, + { 12468, 0x2fff }, + { 12472, 0x2fff }, + { 12476, 0x2fff }, + { 12480, 0x0001 }, + { 12481, 0x0001 }, + { 12483, 0x0006 }, + { 12484, 0x0040 }, + { 12485, 0x0001 }, + { 12486, 0x000f }, + { 12487, 0x0006 }, + { 12488, 0x0001 }, + { 12489, 0x0003 }, + { 12490, 0x0106 }, + { 12492, 0x0061 }, + { 12493, 0x0011 }, + { 12494, 0x0401 }, + { 12496, 0x0050 }, + { 12497, 0x0003 }, + { 12498, 0x0102 }, + { 12500, 0x0061 }, + { 12501, 0x003b }, + { 12502, 0x0502 }, + { 12503, 0x0100 }, + { 12504, 0x2fff }, + { 12508, 0x2fff }, + { 12512, 0x2fff }, + { 12516, 0x2fff }, + { 12520, 0x2fff }, + { 12524, 0x2fff }, + { 12528, 0x2fff }, + { 12532, 0x2fff }, + { 12536, 0x2fff }, + { 12540, 0x2fff }, + { 12544, 0x0060 }, + { 12546, 0x0601 }, + { 12548, 0x0050 }, + { 12550, 0x0100 }, + { 12552, 0x0001 }, + { 12554, 0x0104 }, + { 12555, 0x0100 }, + { 12556, 0x2fff }, + { 12560, 0x2fff }, + { 12564, 0x2fff }, + { 12568, 0x2fff }, + { 12572, 0x2fff }, + { 12576, 0x2fff }, + { 12580, 0x2fff }, + { 12584, 0x2fff }, + { 12588, 0x2fff }, + { 12592, 0x2fff }, + { 12596, 0x2fff }, + { 12600, 0x2fff }, + { 12604, 0x2fff }, + { 12608, 0x0061 }, + { 12610, 0x0601 }, + { 12612, 0x0050 }, + { 12614, 0x0102 }, + { 12616, 0x0001 }, + { 12618, 0x0106 }, + { 12619, 0x0100 }, + { 12620, 0x2fff }, + { 12624, 0x2fff }, + { 12628, 0x2fff }, + { 12632, 0x2fff }, + { 12636, 0x2fff }, + { 12640, 0x2fff }, + { 12644, 0x2fff }, + { 12648, 0x2fff }, + { 12652, 0x2fff }, + { 12656, 0x2fff }, + { 12660, 0x2fff }, + { 12664, 0x2fff }, + { 12668, 0x2fff }, + { 12672, 0x0060 }, + { 12674, 0x0601 }, + { 12676, 0x0061 }, + { 12678, 0x0601 }, + { 12680, 0x0050 }, + { 12682, 0x0300 }, + { 12684, 0x0001 }, + { 12686, 0x0304 }, + { 12688, 0x0040 }, + { 12690, 0x000f }, + { 12692, 0x0001 }, + { 12695, 0x0100 }, }; struct fll_config { @@ -134,7 +378,7 @@ struct fll_config { }; struct wm8995_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; int sysclk[2]; int mclk[2]; int aifclk[2]; @@ -156,7 +400,7 @@ static int wm8995_regulator_event_##n(struct notifier_block *nb, \ struct wm8995_priv *wm8995 = container_of(nb, struct wm8995_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - wm8995->codec->cache_sync = 1; \ + regcache_mark_dirty(wm8995->regmap); \ } \ return 0; \ } @@ -688,8 +932,10 @@ static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = { SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0, &in1r_pga, 1), - SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0), - SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0, + NULL, 0), SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0), @@ -947,31 +1193,244 @@ static const struct snd_soc_dapm_route wm8995_intercon[] = { { "SPK2R", NULL, "SPK2R Driver" } }; -static int wm8995_volatile(struct snd_soc_codec *codec, unsigned int reg) +static bool wm8995_readable(struct device *dev, unsigned int reg) { - /* out of bounds registers are generally considered - * volatile to support register banks that are partially - * owned by something else for e.g. a DSP - */ - if (reg > WM8995_MAX_CACHED_REGISTER) - return 1; - switch (reg) { case WM8995_SOFTWARE_RESET: + case WM8995_POWER_MANAGEMENT_1: + case WM8995_POWER_MANAGEMENT_2: + case WM8995_POWER_MANAGEMENT_3: + case WM8995_POWER_MANAGEMENT_4: + case WM8995_POWER_MANAGEMENT_5: + case WM8995_LEFT_LINE_INPUT_1_VOLUME: + case WM8995_RIGHT_LINE_INPUT_1_VOLUME: + case WM8995_LEFT_LINE_INPUT_CONTROL: + case WM8995_DAC1_LEFT_VOLUME: + case WM8995_DAC1_RIGHT_VOLUME: + case WM8995_DAC2_LEFT_VOLUME: + case WM8995_DAC2_RIGHT_VOLUME: + case WM8995_OUTPUT_VOLUME_ZC_1: + case WM8995_MICBIAS_1: + case WM8995_MICBIAS_2: + case WM8995_LDO_1: + case WM8995_LDO_2: + case WM8995_ACCESSORY_DETECT_MODE1: + case WM8995_ACCESSORY_DETECT_MODE2: + case WM8995_HEADPHONE_DETECT1: + case WM8995_HEADPHONE_DETECT2: + case WM8995_MIC_DETECT_1: + case WM8995_MIC_DETECT_2: + case WM8995_CHARGE_PUMP_1: + case WM8995_CLASS_W_1: + case WM8995_DC_SERVO_1: + case WM8995_DC_SERVO_2: + case WM8995_DC_SERVO_3: + case WM8995_DC_SERVO_5: + case WM8995_DC_SERVO_6: + case WM8995_DC_SERVO_7: case WM8995_DC_SERVO_READBACK_0: + case WM8995_ANALOGUE_HP_1: + case WM8995_ANALOGUE_HP_2: + case WM8995_CHIP_REVISION: + case WM8995_CONTROL_INTERFACE_1: + case WM8995_CONTROL_INTERFACE_2: + case WM8995_WRITE_SEQUENCER_CTRL_1: + case WM8995_WRITE_SEQUENCER_CTRL_2: + case WM8995_AIF1_CLOCKING_1: + case WM8995_AIF1_CLOCKING_2: + case WM8995_AIF2_CLOCKING_1: + case WM8995_AIF2_CLOCKING_2: + case WM8995_CLOCKING_1: + case WM8995_CLOCKING_2: + case WM8995_AIF1_RATE: + case WM8995_AIF2_RATE: + case WM8995_RATE_STATUS: + case WM8995_FLL1_CONTROL_1: + case WM8995_FLL1_CONTROL_2: + case WM8995_FLL1_CONTROL_3: + case WM8995_FLL1_CONTROL_4: + case WM8995_FLL1_CONTROL_5: + case WM8995_FLL2_CONTROL_1: + case WM8995_FLL2_CONTROL_2: + case WM8995_FLL2_CONTROL_3: + case WM8995_FLL2_CONTROL_4: + case WM8995_FLL2_CONTROL_5: + case WM8995_AIF1_CONTROL_1: + case WM8995_AIF1_CONTROL_2: + case WM8995_AIF1_MASTER_SLAVE: + case WM8995_AIF1_BCLK: + case WM8995_AIF1ADC_LRCLK: + case WM8995_AIF1DAC_LRCLK: + case WM8995_AIF1DAC_DATA: + case WM8995_AIF1ADC_DATA: + case WM8995_AIF2_CONTROL_1: + case WM8995_AIF2_CONTROL_2: + case WM8995_AIF2_MASTER_SLAVE: + case WM8995_AIF2_BCLK: + case WM8995_AIF2ADC_LRCLK: + case WM8995_AIF2DAC_LRCLK: + case WM8995_AIF2DAC_DATA: + case WM8995_AIF2ADC_DATA: + case WM8995_AIF1_ADC1_LEFT_VOLUME: + case WM8995_AIF1_ADC1_RIGHT_VOLUME: + case WM8995_AIF1_DAC1_LEFT_VOLUME: + case WM8995_AIF1_DAC1_RIGHT_VOLUME: + case WM8995_AIF1_ADC2_LEFT_VOLUME: + case WM8995_AIF1_ADC2_RIGHT_VOLUME: + case WM8995_AIF1_DAC2_LEFT_VOLUME: + case WM8995_AIF1_DAC2_RIGHT_VOLUME: + case WM8995_AIF1_ADC1_FILTERS: + case WM8995_AIF1_ADC2_FILTERS: + case WM8995_AIF1_DAC1_FILTERS_1: + case WM8995_AIF1_DAC1_FILTERS_2: + case WM8995_AIF1_DAC2_FILTERS_1: + case WM8995_AIF1_DAC2_FILTERS_2: + case WM8995_AIF1_DRC1_1: + case WM8995_AIF1_DRC1_2: + case WM8995_AIF1_DRC1_3: + case WM8995_AIF1_DRC1_4: + case WM8995_AIF1_DRC1_5: + case WM8995_AIF1_DRC2_1: + case WM8995_AIF1_DRC2_2: + case WM8995_AIF1_DRC2_3: + case WM8995_AIF1_DRC2_4: + case WM8995_AIF1_DRC2_5: + case WM8995_AIF1_DAC1_EQ_GAINS_1: + case WM8995_AIF1_DAC1_EQ_GAINS_2: + case WM8995_AIF1_DAC1_EQ_BAND_1_A: + case WM8995_AIF1_DAC1_EQ_BAND_1_B: + case WM8995_AIF1_DAC1_EQ_BAND_1_PG: + case WM8995_AIF1_DAC1_EQ_BAND_2_A: + case WM8995_AIF1_DAC1_EQ_BAND_2_B: + case WM8995_AIF1_DAC1_EQ_BAND_2_C: + case WM8995_AIF1_DAC1_EQ_BAND_2_PG: + case WM8995_AIF1_DAC1_EQ_BAND_3_A: + case WM8995_AIF1_DAC1_EQ_BAND_3_B: + case WM8995_AIF1_DAC1_EQ_BAND_3_C: + case WM8995_AIF1_DAC1_EQ_BAND_3_PG: + case WM8995_AIF1_DAC1_EQ_BAND_4_A: + case WM8995_AIF1_DAC1_EQ_BAND_4_B: + case WM8995_AIF1_DAC1_EQ_BAND_4_C: + case WM8995_AIF1_DAC1_EQ_BAND_4_PG: + case WM8995_AIF1_DAC1_EQ_BAND_5_A: + case WM8995_AIF1_DAC1_EQ_BAND_5_B: + case WM8995_AIF1_DAC1_EQ_BAND_5_PG: + case WM8995_AIF1_DAC2_EQ_GAINS_1: + case WM8995_AIF1_DAC2_EQ_GAINS_2: + case WM8995_AIF1_DAC2_EQ_BAND_1_A: + case WM8995_AIF1_DAC2_EQ_BAND_1_B: + case WM8995_AIF1_DAC2_EQ_BAND_1_PG: + case WM8995_AIF1_DAC2_EQ_BAND_2_A: + case WM8995_AIF1_DAC2_EQ_BAND_2_B: + case WM8995_AIF1_DAC2_EQ_BAND_2_C: + case WM8995_AIF1_DAC2_EQ_BAND_2_PG: + case WM8995_AIF1_DAC2_EQ_BAND_3_A: + case WM8995_AIF1_DAC2_EQ_BAND_3_B: + case WM8995_AIF1_DAC2_EQ_BAND_3_C: + case WM8995_AIF1_DAC2_EQ_BAND_3_PG: + case WM8995_AIF1_DAC2_EQ_BAND_4_A: + case WM8995_AIF1_DAC2_EQ_BAND_4_B: + case WM8995_AIF1_DAC2_EQ_BAND_4_C: + case WM8995_AIF1_DAC2_EQ_BAND_4_PG: + case WM8995_AIF1_DAC2_EQ_BAND_5_A: + case WM8995_AIF1_DAC2_EQ_BAND_5_B: + case WM8995_AIF1_DAC2_EQ_BAND_5_PG: + case WM8995_AIF2_ADC_LEFT_VOLUME: + case WM8995_AIF2_ADC_RIGHT_VOLUME: + case WM8995_AIF2_DAC_LEFT_VOLUME: + case WM8995_AIF2_DAC_RIGHT_VOLUME: + case WM8995_AIF2_ADC_FILTERS: + case WM8995_AIF2_DAC_FILTERS_1: + case WM8995_AIF2_DAC_FILTERS_2: + case WM8995_AIF2_DRC_1: + case WM8995_AIF2_DRC_2: + case WM8995_AIF2_DRC_3: + case WM8995_AIF2_DRC_4: + case WM8995_AIF2_DRC_5: + case WM8995_AIF2_EQ_GAINS_1: + case WM8995_AIF2_EQ_GAINS_2: + case WM8995_AIF2_EQ_BAND_1_A: + case WM8995_AIF2_EQ_BAND_1_B: + case WM8995_AIF2_EQ_BAND_1_PG: + case WM8995_AIF2_EQ_BAND_2_A: + case WM8995_AIF2_EQ_BAND_2_B: + case WM8995_AIF2_EQ_BAND_2_C: + case WM8995_AIF2_EQ_BAND_2_PG: + case WM8995_AIF2_EQ_BAND_3_A: + case WM8995_AIF2_EQ_BAND_3_B: + case WM8995_AIF2_EQ_BAND_3_C: + case WM8995_AIF2_EQ_BAND_3_PG: + case WM8995_AIF2_EQ_BAND_4_A: + case WM8995_AIF2_EQ_BAND_4_B: + case WM8995_AIF2_EQ_BAND_4_C: + case WM8995_AIF2_EQ_BAND_4_PG: + case WM8995_AIF2_EQ_BAND_5_A: + case WM8995_AIF2_EQ_BAND_5_B: + case WM8995_AIF2_EQ_BAND_5_PG: + case WM8995_DAC1_MIXER_VOLUMES: + case WM8995_DAC1_LEFT_MIXER_ROUTING: + case WM8995_DAC1_RIGHT_MIXER_ROUTING: + case WM8995_DAC2_MIXER_VOLUMES: + case WM8995_DAC2_LEFT_MIXER_ROUTING: + case WM8995_DAC2_RIGHT_MIXER_ROUTING: + case WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING: + case WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING: + case WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING: + case WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING: + case WM8995_DAC_SOFTMUTE: + case WM8995_OVERSAMPLING: + case WM8995_SIDETONE: + case WM8995_GPIO_1: + case WM8995_GPIO_2: + case WM8995_GPIO_3: + case WM8995_GPIO_4: + case WM8995_GPIO_5: + case WM8995_GPIO_6: + case WM8995_GPIO_7: + case WM8995_GPIO_8: + case WM8995_GPIO_9: + case WM8995_GPIO_10: + case WM8995_GPIO_11: + case WM8995_GPIO_12: + case WM8995_GPIO_13: + case WM8995_GPIO_14: + case WM8995_PULL_CONTROL_1: + case WM8995_PULL_CONTROL_2: case WM8995_INTERRUPT_STATUS_1: case WM8995_INTERRUPT_STATUS_2: + case WM8995_INTERRUPT_RAW_STATUS_2: case WM8995_INTERRUPT_STATUS_1_MASK: case WM8995_INTERRUPT_STATUS_2_MASK: case WM8995_INTERRUPT_CONTROL: + case WM8995_LEFT_PDM_SPEAKER_1: + case WM8995_RIGHT_PDM_SPEAKER_1: + case WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE: + case WM8995_LEFT_PDM_SPEAKER_2: + case WM8995_RIGHT_PDM_SPEAKER_2: + case WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE: + return true; + default: + return false; + } +} + +static bool wm8995_volatile(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM8995_SOFTWARE_RESET: + case WM8995_DC_SERVO_READBACK_0: + case WM8995_INTERRUPT_STATUS_1: + case WM8995_INTERRUPT_STATUS_2: + case WM8995_INTERRUPT_CONTROL: case WM8995_ACCESSORY_DETECT_MODE1: case WM8995_ACCESSORY_DETECT_MODE2: case WM8995_HEADPHONE_DETECT1: case WM8995_HEADPHONE_DETECT2: - return 1; + case WM8995_RATE_STATUS: + return true; + default: + return false; } - - return 0; } static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute) @@ -1526,7 +1985,7 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec, if (ret) return ret; - ret = snd_soc_cache_sync(codec); + ret = regcache_sync(wm8995->regmap); if (ret) { dev_err(codec->dev, "Failed to sync cache: %d\n", ret); @@ -1550,7 +2009,7 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec, } #ifdef CONFIG_PM -static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm8995_suspend(struct snd_soc_codec *codec) { wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -1592,7 +2051,8 @@ static int wm8995_probe(struct snd_soc_codec *codec) wm8995 = snd_soc_codec_get_drvdata(codec); wm8995->codec = codec; - ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type); + codec->control_data = wm8995->regmap; + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); if (ret < 0) { dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); return ret; @@ -1696,7 +2156,7 @@ err_reg_get: #define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8995_aif1_dai_ops = { +static const struct snd_soc_dai_ops wm8995_aif1_dai_ops = { .set_sysclk = wm8995_set_dai_sysclk, .set_fmt = wm8995_set_dai_fmt, .hw_params = wm8995_hw_params, @@ -1705,7 +2165,7 @@ static struct snd_soc_dai_ops wm8995_aif1_dai_ops = { .set_tristate = wm8995_set_tristate, }; -static struct snd_soc_dai_ops wm8995_aif2_dai_ops = { +static const struct snd_soc_dai_ops wm8995_aif2_dai_ops = { .set_sysclk = wm8995_set_dai_sysclk, .set_fmt = wm8995_set_dai_fmt, .hw_params = wm8995_hw_params, @@ -1714,7 +2174,7 @@ static struct snd_soc_dai_ops wm8995_aif2_dai_ops = { .set_tristate = wm8995_set_tristate, }; -static struct snd_soc_dai_ops wm8995_aif3_dai_ops = { +static const struct snd_soc_dai_ops wm8995_aif3_dai_ops = { .set_tristate = wm8995_set_tristate, }; @@ -1781,11 +2241,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { .suspend = wm8995_suspend, .resume = wm8995_resume, .set_bias_level = wm8995_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8995_reg_defs, - .volatile_register = wm8995_volatile, - .compress_type = SND_SOC_RBTREE_COMPRESSION +}; + +static struct regmap_config wm8995_regmap = { + .reg_bits = 16, + .val_bits = 16, + + .max_register = WM8995_MAX_REGISTER, + .reg_defaults = wm8995_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(wm8995_reg_defaults), + .volatile_reg = wm8995_volatile, + .readable_reg = wm8995_readable, + .cache_type = REGCACHE_RBTREE, }; #if defined(CONFIG_SPI_MASTER) @@ -1798,21 +2265,37 @@ static int __devinit wm8995_spi_probe(struct spi_device *spi) if (!wm8995) return -ENOMEM; - wm8995->control_type = SND_SOC_SPI; spi_set_drvdata(spi, wm8995); + wm8995->regmap = regmap_init_spi(spi, &wm8995_regmap); + if (IS_ERR(wm8995->regmap)) { + ret = PTR_ERR(wm8995->regmap); + dev_err(&spi->dev, "Failed to register regmap: %d\n", ret); + goto err_alloc; + } + ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8995, wm8995_dai, ARRAY_SIZE(wm8995_dai)); if (ret < 0) - kfree(wm8995); + goto err_regmap; + + return ret; + +err_regmap: + regmap_exit(wm8995->regmap); +err_alloc: + kfree(wm8995); + return ret; } static int __devexit wm8995_spi_remove(struct spi_device *spi) { + struct wm8995_priv *wm8995 = spi_get_drvdata(spi); snd_soc_unregister_codec(&spi->dev); - kfree(spi_get_drvdata(spi)); + regmap_exit(wm8995->regmap); + kfree(wm8995); return 0; } @@ -1837,21 +2320,40 @@ static __devinit int wm8995_i2c_probe(struct i2c_client *i2c, if (!wm8995) return -ENOMEM; - wm8995->control_type = SND_SOC_I2C; i2c_set_clientdata(i2c, wm8995); + wm8995->regmap = regmap_init_i2c(i2c, &wm8995_regmap); + if (IS_ERR(wm8995->regmap)) { + ret = PTR_ERR(wm8995->regmap); + dev_err(&i2c->dev, "Failed to register regmap: %d\n", ret); + goto err_alloc; + } + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8995, wm8995_dai, ARRAY_SIZE(wm8995_dai)); - if (ret < 0) - kfree(wm8995); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); + goto err_regmap; + } + + return ret; + +err_regmap: + regmap_exit(wm8995->regmap); +err_alloc: + kfree(wm8995); + return ret; } static __devexit int wm8995_i2c_remove(struct i2c_client *client) { + struct wm8995_priv *wm8995 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm8995->regmap); + kfree(wm8995); return 0; } diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 645c980d6b8..d8da10fe5b5 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -19,6 +19,7 @@ #include <linux/gcd.h> #include <linux/gpio.h> #include <linux/i2c.h> +#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/workqueue.h> @@ -49,6 +50,8 @@ static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { }; struct wm8996_priv { + struct device *dev; + struct regmap *regmap; struct snd_soc_codec *codec; int ldo1ena; @@ -105,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ disable_nb[n]); \ if (event & REGULATOR_EVENT_DISABLE) { \ - wm8996->codec->cache_sync = 1; \ + regcache_cache_only(wm8996->regmap, true); \ } \ return 0; \ } @@ -114,297 +117,365 @@ WM8996_REGULATOR_EVENT(0) WM8996_REGULATOR_EVENT(1) WM8996_REGULATOR_EVENT(2) -static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { - [WM8996_SOFTWARE_RESET] = 0x8996, - [WM8996_POWER_MANAGEMENT_7] = 0x10, - [WM8996_DAC1_HPOUT1_VOLUME] = 0x88, - [WM8996_DAC2_HPOUT2_VOLUME] = 0x88, - [WM8996_DAC1_LEFT_VOLUME] = 0x2c0, - [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0, - [WM8996_DAC2_LEFT_VOLUME] = 0x2c0, - [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0, - [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80, - [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80, - [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80, - [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80, - [WM8996_MICBIAS_1] = 0x39, - [WM8996_MICBIAS_2] = 0x39, - [WM8996_LDO_1] = 0x3, - [WM8996_LDO_2] = 0x13, - [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4, - [WM8996_HEADPHONE_DETECT_1] = 0x20, - [WM8996_MIC_DETECT_1] = 0x7600, - [WM8996_MIC_DETECT_2] = 0xbf, - [WM8996_CHARGE_PUMP_1] = 0x1f25, - [WM8996_CHARGE_PUMP_2] = 0xab19, - [WM8996_DC_SERVO_5] = 0x2a2a, - [WM8996_CONTROL_INTERFACE_1] = 0x8004, - [WM8996_CLOCKING_1] = 0x10, - [WM8996_AIF_RATE] = 0x83, - [WM8996_FLL_CONTROL_4] = 0x5dc0, - [WM8996_FLL_CONTROL_5] = 0xc84, - [WM8996_FLL_EFS_2] = 0x2, - [WM8996_AIF1_TX_LRCLK_1] = 0x80, - [WM8996_AIF1_TX_LRCLK_2] = 0x8, - [WM8996_AIF1_RX_LRCLK_1] = 0x80, - [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818, - [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818, - [WM8996_AIF1TX_TEST] = 0x7, - [WM8996_AIF2_TX_LRCLK_1] = 0x80, - [WM8996_AIF2_TX_LRCLK_2] = 0x8, - [WM8996_AIF2_RX_LRCLK_1] = 0x80, - [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818, - [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818, - [WM8996_AIF2TX_TEST] = 0x1, - [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP1_TX_FILTERS] = 0x2000, - [WM8996_DSP1_RX_FILTERS_1] = 0x200, - [WM8996_DSP1_RX_FILTERS_2] = 0x10, - [WM8996_DSP1_DRC_1] = 0x98, - [WM8996_DSP1_DRC_2] = 0x845, - [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318, - [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300, - [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca, - [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400, - [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8, - [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5, - [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145, - [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75, - [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5, - [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58, - [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373, - [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54, - [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558, - [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e, - [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829, - [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad, - [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103, - [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564, - [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559, - [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000, - [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP2_TX_FILTERS] = 0x2000, - [WM8996_DSP2_RX_FILTERS_1] = 0x200, - [WM8996_DSP2_RX_FILTERS_2] = 0x10, - [WM8996_DSP2_DRC_1] = 0x98, - [WM8996_DSP2_DRC_2] = 0x845, - [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318, - [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300, - [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca, - [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400, - [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8, - [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5, - [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145, - [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75, - [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5, - [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58, - [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373, - [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54, - [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558, - [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e, - [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829, - [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad, - [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103, - [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564, - [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559, - [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000, - [WM8996_OVERSAMPLING] = 0xd, - [WM8996_SIDETONE] = 0x1040, - [WM8996_GPIO_1] = 0xa101, - [WM8996_GPIO_2] = 0xa101, - [WM8996_GPIO_3] = 0xa101, - [WM8996_GPIO_4] = 0xa101, - [WM8996_GPIO_5] = 0xa101, - [WM8996_PULL_CONTROL_2] = 0x140, - [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f, - [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf, - [WM8996_RIGHT_PDM_SPEAKER] = 0x1, - [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69, - [WM8996_PDM_SPEAKER_VOLUME] = 0x66, - [WM8996_WRITE_SEQUENCER_0] = 0x1, - [WM8996_WRITE_SEQUENCER_1] = 0x1, - [WM8996_WRITE_SEQUENCER_3] = 0x6, - [WM8996_WRITE_SEQUENCER_4] = 0x40, - [WM8996_WRITE_SEQUENCER_5] = 0x1, - [WM8996_WRITE_SEQUENCER_6] = 0xf, - [WM8996_WRITE_SEQUENCER_7] = 0x6, - [WM8996_WRITE_SEQUENCER_8] = 0x1, - [WM8996_WRITE_SEQUENCER_9] = 0x3, - [WM8996_WRITE_SEQUENCER_10] = 0x104, - [WM8996_WRITE_SEQUENCER_12] = 0x60, - [WM8996_WRITE_SEQUENCER_13] = 0x11, - [WM8996_WRITE_SEQUENCER_14] = 0x401, - [WM8996_WRITE_SEQUENCER_16] = 0x50, - [WM8996_WRITE_SEQUENCER_17] = 0x3, - [WM8996_WRITE_SEQUENCER_18] = 0x100, - [WM8996_WRITE_SEQUENCER_20] = 0x51, - [WM8996_WRITE_SEQUENCER_21] = 0x3, - [WM8996_WRITE_SEQUENCER_22] = 0x104, - [WM8996_WRITE_SEQUENCER_23] = 0xa, - [WM8996_WRITE_SEQUENCER_24] = 0x60, - [WM8996_WRITE_SEQUENCER_25] = 0x3b, - [WM8996_WRITE_SEQUENCER_26] = 0x502, - [WM8996_WRITE_SEQUENCER_27] = 0x100, - [WM8996_WRITE_SEQUENCER_28] = 0x2fff, - [WM8996_WRITE_SEQUENCER_32] = 0x2fff, - [WM8996_WRITE_SEQUENCER_36] = 0x2fff, - [WM8996_WRITE_SEQUENCER_40] = 0x2fff, - [WM8996_WRITE_SEQUENCER_44] = 0x2fff, - [WM8996_WRITE_SEQUENCER_48] = 0x2fff, - [WM8996_WRITE_SEQUENCER_52] = 0x2fff, - [WM8996_WRITE_SEQUENCER_56] = 0x2fff, - [WM8996_WRITE_SEQUENCER_60] = 0x2fff, - [WM8996_WRITE_SEQUENCER_64] = 0x1, - [WM8996_WRITE_SEQUENCER_65] = 0x1, - [WM8996_WRITE_SEQUENCER_67] = 0x6, - [WM8996_WRITE_SEQUENCER_68] = 0x40, - [WM8996_WRITE_SEQUENCER_69] = 0x1, - [WM8996_WRITE_SEQUENCER_70] = 0xf, - [WM8996_WRITE_SEQUENCER_71] = 0x6, - [WM8996_WRITE_SEQUENCER_72] = 0x1, - [WM8996_WRITE_SEQUENCER_73] = 0x3, - [WM8996_WRITE_SEQUENCER_74] = 0x104, - [WM8996_WRITE_SEQUENCER_76] = 0x60, - [WM8996_WRITE_SEQUENCER_77] = 0x11, - [WM8996_WRITE_SEQUENCER_78] = 0x401, - [WM8996_WRITE_SEQUENCER_80] = 0x50, - [WM8996_WRITE_SEQUENCER_81] = 0x3, - [WM8996_WRITE_SEQUENCER_82] = 0x100, - [WM8996_WRITE_SEQUENCER_84] = 0x60, - [WM8996_WRITE_SEQUENCER_85] = 0x3b, - [WM8996_WRITE_SEQUENCER_86] = 0x502, - [WM8996_WRITE_SEQUENCER_87] = 0x100, - [WM8996_WRITE_SEQUENCER_88] = 0x2fff, - [WM8996_WRITE_SEQUENCER_92] = 0x2fff, - [WM8996_WRITE_SEQUENCER_96] = 0x2fff, - [WM8996_WRITE_SEQUENCER_100] = 0x2fff, - [WM8996_WRITE_SEQUENCER_104] = 0x2fff, - [WM8996_WRITE_SEQUENCER_108] = 0x2fff, - [WM8996_WRITE_SEQUENCER_112] = 0x2fff, - [WM8996_WRITE_SEQUENCER_116] = 0x2fff, - [WM8996_WRITE_SEQUENCER_120] = 0x2fff, - [WM8996_WRITE_SEQUENCER_124] = 0x2fff, - [WM8996_WRITE_SEQUENCER_128] = 0x1, - [WM8996_WRITE_SEQUENCER_129] = 0x1, - [WM8996_WRITE_SEQUENCER_131] = 0x6, - [WM8996_WRITE_SEQUENCER_132] = 0x40, - [WM8996_WRITE_SEQUENCER_133] = 0x1, - [WM8996_WRITE_SEQUENCER_134] = 0xf, - [WM8996_WRITE_SEQUENCER_135] = 0x6, - [WM8996_WRITE_SEQUENCER_136] = 0x1, - [WM8996_WRITE_SEQUENCER_137] = 0x3, - [WM8996_WRITE_SEQUENCER_138] = 0x106, - [WM8996_WRITE_SEQUENCER_140] = 0x61, - [WM8996_WRITE_SEQUENCER_141] = 0x11, - [WM8996_WRITE_SEQUENCER_142] = 0x401, - [WM8996_WRITE_SEQUENCER_144] = 0x50, - [WM8996_WRITE_SEQUENCER_145] = 0x3, - [WM8996_WRITE_SEQUENCER_146] = 0x102, - [WM8996_WRITE_SEQUENCER_148] = 0x51, - [WM8996_WRITE_SEQUENCER_149] = 0x3, - [WM8996_WRITE_SEQUENCER_150] = 0x106, - [WM8996_WRITE_SEQUENCER_151] = 0xa, - [WM8996_WRITE_SEQUENCER_152] = 0x61, - [WM8996_WRITE_SEQUENCER_153] = 0x3b, - [WM8996_WRITE_SEQUENCER_154] = 0x502, - [WM8996_WRITE_SEQUENCER_155] = 0x100, - [WM8996_WRITE_SEQUENCER_156] = 0x2fff, - [WM8996_WRITE_SEQUENCER_160] = 0x2fff, - [WM8996_WRITE_SEQUENCER_164] = 0x2fff, - [WM8996_WRITE_SEQUENCER_168] = 0x2fff, - [WM8996_WRITE_SEQUENCER_172] = 0x2fff, - [WM8996_WRITE_SEQUENCER_176] = 0x2fff, - [WM8996_WRITE_SEQUENCER_180] = 0x2fff, - [WM8996_WRITE_SEQUENCER_184] = 0x2fff, - [WM8996_WRITE_SEQUENCER_188] = 0x2fff, - [WM8996_WRITE_SEQUENCER_192] = 0x1, - [WM8996_WRITE_SEQUENCER_193] = 0x1, - [WM8996_WRITE_SEQUENCER_195] = 0x6, - [WM8996_WRITE_SEQUENCER_196] = 0x40, - [WM8996_WRITE_SEQUENCER_197] = 0x1, - [WM8996_WRITE_SEQUENCER_198] = 0xf, - [WM8996_WRITE_SEQUENCER_199] = 0x6, - [WM8996_WRITE_SEQUENCER_200] = 0x1, - [WM8996_WRITE_SEQUENCER_201] = 0x3, - [WM8996_WRITE_SEQUENCER_202] = 0x106, - [WM8996_WRITE_SEQUENCER_204] = 0x61, - [WM8996_WRITE_SEQUENCER_205] = 0x11, - [WM8996_WRITE_SEQUENCER_206] = 0x401, - [WM8996_WRITE_SEQUENCER_208] = 0x50, - [WM8996_WRITE_SEQUENCER_209] = 0x3, - [WM8996_WRITE_SEQUENCER_210] = 0x102, - [WM8996_WRITE_SEQUENCER_212] = 0x61, - [WM8996_WRITE_SEQUENCER_213] = 0x3b, - [WM8996_WRITE_SEQUENCER_214] = 0x502, - [WM8996_WRITE_SEQUENCER_215] = 0x100, - [WM8996_WRITE_SEQUENCER_216] = 0x2fff, - [WM8996_WRITE_SEQUENCER_220] = 0x2fff, - [WM8996_WRITE_SEQUENCER_224] = 0x2fff, - [WM8996_WRITE_SEQUENCER_228] = 0x2fff, - [WM8996_WRITE_SEQUENCER_232] = 0x2fff, - [WM8996_WRITE_SEQUENCER_236] = 0x2fff, - [WM8996_WRITE_SEQUENCER_240] = 0x2fff, - [WM8996_WRITE_SEQUENCER_244] = 0x2fff, - [WM8996_WRITE_SEQUENCER_248] = 0x2fff, - [WM8996_WRITE_SEQUENCER_252] = 0x2fff, - [WM8996_WRITE_SEQUENCER_256] = 0x60, - [WM8996_WRITE_SEQUENCER_258] = 0x601, - [WM8996_WRITE_SEQUENCER_260] = 0x50, - [WM8996_WRITE_SEQUENCER_262] = 0x100, - [WM8996_WRITE_SEQUENCER_264] = 0x1, - [WM8996_WRITE_SEQUENCER_266] = 0x104, - [WM8996_WRITE_SEQUENCER_267] = 0x100, - [WM8996_WRITE_SEQUENCER_268] = 0x2fff, - [WM8996_WRITE_SEQUENCER_272] = 0x2fff, - [WM8996_WRITE_SEQUENCER_276] = 0x2fff, - [WM8996_WRITE_SEQUENCER_280] = 0x2fff, - [WM8996_WRITE_SEQUENCER_284] = 0x2fff, - [WM8996_WRITE_SEQUENCER_288] = 0x2fff, - [WM8996_WRITE_SEQUENCER_292] = 0x2fff, - [WM8996_WRITE_SEQUENCER_296] = 0x2fff, - [WM8996_WRITE_SEQUENCER_300] = 0x2fff, - [WM8996_WRITE_SEQUENCER_304] = 0x2fff, - [WM8996_WRITE_SEQUENCER_308] = 0x2fff, - [WM8996_WRITE_SEQUENCER_312] = 0x2fff, - [WM8996_WRITE_SEQUENCER_316] = 0x2fff, - [WM8996_WRITE_SEQUENCER_320] = 0x61, - [WM8996_WRITE_SEQUENCER_322] = 0x601, - [WM8996_WRITE_SEQUENCER_324] = 0x50, - [WM8996_WRITE_SEQUENCER_326] = 0x102, - [WM8996_WRITE_SEQUENCER_328] = 0x1, - [WM8996_WRITE_SEQUENCER_330] = 0x106, - [WM8996_WRITE_SEQUENCER_331] = 0x100, - [WM8996_WRITE_SEQUENCER_332] = 0x2fff, - [WM8996_WRITE_SEQUENCER_336] = 0x2fff, - [WM8996_WRITE_SEQUENCER_340] = 0x2fff, - [WM8996_WRITE_SEQUENCER_344] = 0x2fff, - [WM8996_WRITE_SEQUENCER_348] = 0x2fff, - [WM8996_WRITE_SEQUENCER_352] = 0x2fff, - [WM8996_WRITE_SEQUENCER_356] = 0x2fff, - [WM8996_WRITE_SEQUENCER_360] = 0x2fff, - [WM8996_WRITE_SEQUENCER_364] = 0x2fff, - [WM8996_WRITE_SEQUENCER_368] = 0x2fff, - [WM8996_WRITE_SEQUENCER_372] = 0x2fff, - [WM8996_WRITE_SEQUENCER_376] = 0x2fff, - [WM8996_WRITE_SEQUENCER_380] = 0x2fff, - [WM8996_WRITE_SEQUENCER_384] = 0x60, - [WM8996_WRITE_SEQUENCER_386] = 0x601, - [WM8996_WRITE_SEQUENCER_388] = 0x61, - [WM8996_WRITE_SEQUENCER_390] = 0x601, - [WM8996_WRITE_SEQUENCER_392] = 0x50, - [WM8996_WRITE_SEQUENCER_394] = 0x300, - [WM8996_WRITE_SEQUENCER_396] = 0x1, - [WM8996_WRITE_SEQUENCER_398] = 0x304, - [WM8996_WRITE_SEQUENCER_400] = 0x40, - [WM8996_WRITE_SEQUENCER_402] = 0xf, - [WM8996_WRITE_SEQUENCER_404] = 0x1, - [WM8996_WRITE_SEQUENCER_407] = 0x100, +static struct reg_default wm8996_reg[] = { + { WM8996_SOFTWARE_RESET, 0x8996 }, + { WM8996_POWER_MANAGEMENT_1, 0x0 }, + { WM8996_POWER_MANAGEMENT_2, 0x0 }, + { WM8996_POWER_MANAGEMENT_3, 0x0 }, + { WM8996_POWER_MANAGEMENT_4, 0x0 }, + { WM8996_POWER_MANAGEMENT_5, 0x0 }, + { WM8996_POWER_MANAGEMENT_6, 0x0 }, + { WM8996_POWER_MANAGEMENT_7, 0x10 }, + { WM8996_POWER_MANAGEMENT_8, 0x0 }, + { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 }, + { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 }, + { WM8996_LINE_INPUT_CONTROL, 0x0 }, + { WM8996_DAC1_HPOUT1_VOLUME, 0x88 }, + { WM8996_DAC2_HPOUT2_VOLUME, 0x88 }, + { WM8996_DAC1_LEFT_VOLUME, 0x2c0 }, + { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 }, + { WM8996_DAC2_LEFT_VOLUME, 0x2c0 }, + { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 }, + { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 }, + { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 }, + { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 }, + { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 }, + { WM8996_MICBIAS_1, 0x39 }, + { WM8996_MICBIAS_2, 0x39 }, + { WM8996_LDO_1, 0x3 }, + { WM8996_LDO_2, 0x13 }, + { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 }, + { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 }, + { WM8996_HEADPHONE_DETECT_1, 0x20 }, + { WM8996_HEADPHONE_DETECT_2, 0x0 }, + { WM8996_MIC_DETECT_1, 0x7600 }, + { WM8996_MIC_DETECT_2, 0xbf }, + { WM8996_CHARGE_PUMP_1, 0x1f25 }, + { WM8996_CHARGE_PUMP_2, 0xab19 }, + { WM8996_DC_SERVO_1, 0x0 }, + { WM8996_DC_SERVO_2, 0x0 }, + { WM8996_DC_SERVO_3, 0x0 }, + { WM8996_DC_SERVO_5, 0x2a2a }, + { WM8996_DC_SERVO_6, 0x0 }, + { WM8996_DC_SERVO_7, 0x0 }, + { WM8996_ANALOGUE_HP_1, 0x0 }, + { WM8996_ANALOGUE_HP_2, 0x0 }, + { WM8996_CONTROL_INTERFACE_1, 0x8004 }, + { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 }, + { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 }, + { WM8996_AIF_CLOCKING_1, 0x0 }, + { WM8996_AIF_CLOCKING_2, 0x0 }, + { WM8996_CLOCKING_1, 0x10 }, + { WM8996_CLOCKING_2, 0x0 }, + { WM8996_AIF_RATE, 0x83 }, + { WM8996_FLL_CONTROL_1, 0x0 }, + { WM8996_FLL_CONTROL_2, 0x0 }, + { WM8996_FLL_CONTROL_3, 0x0 }, + { WM8996_FLL_CONTROL_4, 0x5dc0 }, + { WM8996_FLL_CONTROL_5, 0xc84 }, + { WM8996_FLL_EFS_1, 0x0 }, + { WM8996_FLL_EFS_2, 0x2 }, + { WM8996_AIF1_CONTROL, 0x0 }, + { WM8996_AIF1_BCLK, 0x0 }, + { WM8996_AIF1_TX_LRCLK_1, 0x80 }, + { WM8996_AIF1_TX_LRCLK_2, 0x8 }, + { WM8996_AIF1_RX_LRCLK_1, 0x80 }, + { WM8996_AIF1_RX_LRCLK_2, 0x0 }, + { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 }, + { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 }, + { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 }, + { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 }, + { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 }, + { WM8996_AIF1TX_TEST, 0x7 }, + { WM8996_AIF2_CONTROL, 0x0 }, + { WM8996_AIF2_BCLK, 0x0 }, + { WM8996_AIF2_TX_LRCLK_1, 0x80 }, + { WM8996_AIF2_TX_LRCLK_2, 0x8 }, + { WM8996_AIF2_RX_LRCLK_1, 0x80 }, + { WM8996_AIF2_RX_LRCLK_2, 0x0 }, + { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 }, + { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 }, + { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 }, + { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 }, + { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 }, + { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 }, + { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 }, + { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 }, + { WM8996_AIF2TX_TEST, 0x1 }, + { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 }, + { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 }, + { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 }, + { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 }, + { WM8996_DSP1_TX_FILTERS, 0x2000 }, + { WM8996_DSP1_RX_FILTERS_1, 0x200 }, + { WM8996_DSP1_RX_FILTERS_2, 0x10 }, + { WM8996_DSP1_DRC_1, 0x98 }, + { WM8996_DSP1_DRC_2, 0x845 }, + { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 }, + { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 }, + { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca }, + { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 }, + { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 }, + { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 }, + { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 }, + { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 }, + { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 }, + { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 }, + { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 }, + { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 }, + { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 }, + { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e }, + { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 }, + { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad }, + { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 }, + { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 }, + { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 }, + { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 }, + { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 }, + { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 }, + { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 }, + { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 }, + { WM8996_DSP2_TX_FILTERS, 0x2000 }, + { WM8996_DSP2_RX_FILTERS_1, 0x200 }, + { WM8996_DSP2_RX_FILTERS_2, 0x10 }, + { WM8996_DSP2_DRC_1, 0x98 }, + { WM8996_DSP2_DRC_2, 0x845 }, + { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 }, + { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 }, + { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca }, + { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 }, + { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 }, + { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 }, + { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 }, + { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 }, + { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 }, + { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 }, + { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 }, + { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 }, + { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 }, + { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e }, + { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 }, + { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad }, + { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 }, + { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 }, + { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 }, + { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 }, + { WM8996_DAC1_MIXER_VOLUMES, 0x0 }, + { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 }, + { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 }, + { WM8996_DAC2_MIXER_VOLUMES, 0x0 }, + { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 }, + { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 }, + { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 }, + { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 }, + { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 }, + { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 }, + { WM8996_DSP_TX_MIXER_SELECT, 0x0 }, + { WM8996_DAC_SOFTMUTE, 0x0 }, + { WM8996_OVERSAMPLING, 0xd }, + { WM8996_SIDETONE, 0x1040 }, + { WM8996_GPIO_1, 0xa101 }, + { WM8996_GPIO_2, 0xa101 }, + { WM8996_GPIO_3, 0xa101 }, + { WM8996_GPIO_4, 0xa101 }, + { WM8996_GPIO_5, 0xa101 }, + { WM8996_PULL_CONTROL_1, 0x0 }, + { WM8996_PULL_CONTROL_2, 0x140 }, + { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f }, + { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf }, + { WM8996_LEFT_PDM_SPEAKER, 0x0 }, + { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, + { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, + { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, + { WM8996_WRITE_SEQUENCER_0, 0x1 }, + { WM8996_WRITE_SEQUENCER_1, 0x1 }, + { WM8996_WRITE_SEQUENCER_3, 0x6 }, + { WM8996_WRITE_SEQUENCER_4, 0x40 }, + { WM8996_WRITE_SEQUENCER_5, 0x1 }, + { WM8996_WRITE_SEQUENCER_6, 0xf }, + { WM8996_WRITE_SEQUENCER_7, 0x6 }, + { WM8996_WRITE_SEQUENCER_8, 0x1 }, + { WM8996_WRITE_SEQUENCER_9, 0x3 }, + { WM8996_WRITE_SEQUENCER_10, 0x104 }, + { WM8996_WRITE_SEQUENCER_12, 0x60 }, + { WM8996_WRITE_SEQUENCER_13, 0x11 }, + { WM8996_WRITE_SEQUENCER_14, 0x401 }, + { WM8996_WRITE_SEQUENCER_16, 0x50 }, + { WM8996_WRITE_SEQUENCER_17, 0x3 }, + { WM8996_WRITE_SEQUENCER_18, 0x100 }, + { WM8996_WRITE_SEQUENCER_20, 0x51 }, + { WM8996_WRITE_SEQUENCER_21, 0x3 }, + { WM8996_WRITE_SEQUENCER_22, 0x104 }, + { WM8996_WRITE_SEQUENCER_23, 0xa }, + { WM8996_WRITE_SEQUENCER_24, 0x60 }, + { WM8996_WRITE_SEQUENCER_25, 0x3b }, + { WM8996_WRITE_SEQUENCER_26, 0x502 }, + { WM8996_WRITE_SEQUENCER_27, 0x100 }, + { WM8996_WRITE_SEQUENCER_28, 0x2fff }, + { WM8996_WRITE_SEQUENCER_32, 0x2fff }, + { WM8996_WRITE_SEQUENCER_36, 0x2fff }, + { WM8996_WRITE_SEQUENCER_40, 0x2fff }, + { WM8996_WRITE_SEQUENCER_44, 0x2fff }, + { WM8996_WRITE_SEQUENCER_48, 0x2fff }, + { WM8996_WRITE_SEQUENCER_52, 0x2fff }, + { WM8996_WRITE_SEQUENCER_56, 0x2fff }, + { WM8996_WRITE_SEQUENCER_60, 0x2fff }, + { WM8996_WRITE_SEQUENCER_64, 0x1 }, + { WM8996_WRITE_SEQUENCER_65, 0x1 }, + { WM8996_WRITE_SEQUENCER_67, 0x6 }, + { WM8996_WRITE_SEQUENCER_68, 0x40 }, + { WM8996_WRITE_SEQUENCER_69, 0x1 }, + { WM8996_WRITE_SEQUENCER_70, 0xf }, + { WM8996_WRITE_SEQUENCER_71, 0x6 }, + { WM8996_WRITE_SEQUENCER_72, 0x1 }, + { WM8996_WRITE_SEQUENCER_73, 0x3 }, + { WM8996_WRITE_SEQUENCER_74, 0x104 }, + { WM8996_WRITE_SEQUENCER_76, 0x60 }, + { WM8996_WRITE_SEQUENCER_77, 0x11 }, + { WM8996_WRITE_SEQUENCER_78, 0x401 }, + { WM8996_WRITE_SEQUENCER_80, 0x50 }, + { WM8996_WRITE_SEQUENCER_81, 0x3 }, + { WM8996_WRITE_SEQUENCER_82, 0x100 }, + { WM8996_WRITE_SEQUENCER_84, 0x60 }, + { WM8996_WRITE_SEQUENCER_85, 0x3b }, + { WM8996_WRITE_SEQUENCER_86, 0x502 }, + { WM8996_WRITE_SEQUENCER_87, 0x100 }, + { WM8996_WRITE_SEQUENCER_88, 0x2fff }, + { WM8996_WRITE_SEQUENCER_92, 0x2fff }, + { WM8996_WRITE_SEQUENCER_96, 0x2fff }, + { WM8996_WRITE_SEQUENCER_100, 0x2fff }, + { WM8996_WRITE_SEQUENCER_104, 0x2fff }, + { WM8996_WRITE_SEQUENCER_108, 0x2fff }, + { WM8996_WRITE_SEQUENCER_112, 0x2fff }, + { WM8996_WRITE_SEQUENCER_116, 0x2fff }, + { WM8996_WRITE_SEQUENCER_120, 0x2fff }, + { WM8996_WRITE_SEQUENCER_124, 0x2fff }, + { WM8996_WRITE_SEQUENCER_128, 0x1 }, + { WM8996_WRITE_SEQUENCER_129, 0x1 }, + { WM8996_WRITE_SEQUENCER_131, 0x6 }, + { WM8996_WRITE_SEQUENCER_132, 0x40 }, + { WM8996_WRITE_SEQUENCER_133, 0x1 }, + { WM8996_WRITE_SEQUENCER_134, 0xf }, + { WM8996_WRITE_SEQUENCER_135, 0x6 }, + { WM8996_WRITE_SEQUENCER_136, 0x1 }, + { WM8996_WRITE_SEQUENCER_137, 0x3 }, + { WM8996_WRITE_SEQUENCER_138, 0x106 }, + { WM8996_WRITE_SEQUENCER_140, 0x61 }, + { WM8996_WRITE_SEQUENCER_141, 0x11 }, + { WM8996_WRITE_SEQUENCER_142, 0x401 }, + { WM8996_WRITE_SEQUENCER_144, 0x50 }, + { WM8996_WRITE_SEQUENCER_145, 0x3 }, + { WM8996_WRITE_SEQUENCER_146, 0x102 }, + { WM8996_WRITE_SEQUENCER_148, 0x51 }, + { WM8996_WRITE_SEQUENCER_149, 0x3 }, + { WM8996_WRITE_SEQUENCER_150, 0x106 }, + { WM8996_WRITE_SEQUENCER_151, 0xa }, + { WM8996_WRITE_SEQUENCER_152, 0x61 }, + { WM8996_WRITE_SEQUENCER_153, 0x3b }, + { WM8996_WRITE_SEQUENCER_154, 0x502 }, + { WM8996_WRITE_SEQUENCER_155, 0x100 }, + { WM8996_WRITE_SEQUENCER_156, 0x2fff }, + { WM8996_WRITE_SEQUENCER_160, 0x2fff }, + { WM8996_WRITE_SEQUENCER_164, 0x2fff }, + { WM8996_WRITE_SEQUENCER_168, 0x2fff }, + { WM8996_WRITE_SEQUENCER_172, 0x2fff }, + { WM8996_WRITE_SEQUENCER_176, 0x2fff }, + { WM8996_WRITE_SEQUENCER_180, 0x2fff }, + { WM8996_WRITE_SEQUENCER_184, 0x2fff }, + { WM8996_WRITE_SEQUENCER_188, 0x2fff }, + { WM8996_WRITE_SEQUENCER_192, 0x1 }, + { WM8996_WRITE_SEQUENCER_193, 0x1 }, + { WM8996_WRITE_SEQUENCER_195, 0x6 }, + { WM8996_WRITE_SEQUENCER_196, 0x40 }, + { WM8996_WRITE_SEQUENCER_197, 0x1 }, + { WM8996_WRITE_SEQUENCER_198, 0xf }, + { WM8996_WRITE_SEQUENCER_199, 0x6 }, + { WM8996_WRITE_SEQUENCER_200, 0x1 }, + { WM8996_WRITE_SEQUENCER_201, 0x3 }, + { WM8996_WRITE_SEQUENCER_202, 0x106 }, + { WM8996_WRITE_SEQUENCER_204, 0x61 }, + { WM8996_WRITE_SEQUENCER_205, 0x11 }, + { WM8996_WRITE_SEQUENCER_206, 0x401 }, + { WM8996_WRITE_SEQUENCER_208, 0x50 }, + { WM8996_WRITE_SEQUENCER_209, 0x3 }, + { WM8996_WRITE_SEQUENCER_210, 0x102 }, + { WM8996_WRITE_SEQUENCER_212, 0x61 }, + { WM8996_WRITE_SEQUENCER_213, 0x3b }, + { WM8996_WRITE_SEQUENCER_214, 0x502 }, + { WM8996_WRITE_SEQUENCER_215, 0x100 }, + { WM8996_WRITE_SEQUENCER_216, 0x2fff }, + { WM8996_WRITE_SEQUENCER_220, 0x2fff }, + { WM8996_WRITE_SEQUENCER_224, 0x2fff }, + { WM8996_WRITE_SEQUENCER_228, 0x2fff }, + { WM8996_WRITE_SEQUENCER_232, 0x2fff }, + { WM8996_WRITE_SEQUENCER_236, 0x2fff }, + { WM8996_WRITE_SEQUENCER_240, 0x2fff }, + { WM8996_WRITE_SEQUENCER_244, 0x2fff }, + { WM8996_WRITE_SEQUENCER_248, 0x2fff }, + { WM8996_WRITE_SEQUENCER_252, 0x2fff }, + { WM8996_WRITE_SEQUENCER_256, 0x60 }, + { WM8996_WRITE_SEQUENCER_258, 0x601 }, + { WM8996_WRITE_SEQUENCER_260, 0x50 }, + { WM8996_WRITE_SEQUENCER_262, 0x100 }, + { WM8996_WRITE_SEQUENCER_264, 0x1 }, + { WM8996_WRITE_SEQUENCER_266, 0x104 }, + { WM8996_WRITE_SEQUENCER_267, 0x100 }, + { WM8996_WRITE_SEQUENCER_268, 0x2fff }, + { WM8996_WRITE_SEQUENCER_272, 0x2fff }, + { WM8996_WRITE_SEQUENCER_276, 0x2fff }, + { WM8996_WRITE_SEQUENCER_280, 0x2fff }, + { WM8996_WRITE_SEQUENCER_284, 0x2fff }, + { WM8996_WRITE_SEQUENCER_288, 0x2fff }, + { WM8996_WRITE_SEQUENCER_292, 0x2fff }, + { WM8996_WRITE_SEQUENCER_296, 0x2fff }, + { WM8996_WRITE_SEQUENCER_300, 0x2fff }, + { WM8996_WRITE_SEQUENCER_304, 0x2fff }, + { WM8996_WRITE_SEQUENCER_308, 0x2fff }, + { WM8996_WRITE_SEQUENCER_312, 0x2fff }, + { WM8996_WRITE_SEQUENCER_316, 0x2fff }, + { WM8996_WRITE_SEQUENCER_320, 0x61 }, + { WM8996_WRITE_SEQUENCER_322, 0x601 }, + { WM8996_WRITE_SEQUENCER_324, 0x50 }, + { WM8996_WRITE_SEQUENCER_326, 0x102 }, + { WM8996_WRITE_SEQUENCER_328, 0x1 }, + { WM8996_WRITE_SEQUENCER_330, 0x106 }, + { WM8996_WRITE_SEQUENCER_331, 0x100 }, + { WM8996_WRITE_SEQUENCER_332, 0x2fff }, + { WM8996_WRITE_SEQUENCER_336, 0x2fff }, + { WM8996_WRITE_SEQUENCER_340, 0x2fff }, + { WM8996_WRITE_SEQUENCER_344, 0x2fff }, + { WM8996_WRITE_SEQUENCER_348, 0x2fff }, + { WM8996_WRITE_SEQUENCER_352, 0x2fff }, + { WM8996_WRITE_SEQUENCER_356, 0x2fff }, + { WM8996_WRITE_SEQUENCER_360, 0x2fff }, + { WM8996_WRITE_SEQUENCER_364, 0x2fff }, + { WM8996_WRITE_SEQUENCER_368, 0x2fff }, + { WM8996_WRITE_SEQUENCER_372, 0x2fff }, + { WM8996_WRITE_SEQUENCER_376, 0x2fff }, + { WM8996_WRITE_SEQUENCER_380, 0x2fff }, + { WM8996_WRITE_SEQUENCER_384, 0x60 }, + { WM8996_WRITE_SEQUENCER_386, 0x601 }, + { WM8996_WRITE_SEQUENCER_388, 0x61 }, + { WM8996_WRITE_SEQUENCER_390, 0x601 }, + { WM8996_WRITE_SEQUENCER_392, 0x50 }, + { WM8996_WRITE_SEQUENCER_394, 0x300 }, + { WM8996_WRITE_SEQUENCER_396, 0x1 }, + { WM8996_WRITE_SEQUENCER_398, 0x304 }, + { WM8996_WRITE_SEQUENCER_400, 0x40 }, + { WM8996_WRITE_SEQUENCER_402, 0xf }, + { WM8996_WRITE_SEQUENCER_404, 0x1 }, + { WM8996_WRITE_SEQUENCER_407, 0x100 }, }; static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); @@ -1413,8 +1484,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { { "SPKDAT", NULL, "SPKR PGA" }, }; -static int wm8996_readable_register(struct snd_soc_codec *codec, - unsigned int reg) +static bool wm8996_readable_register(struct device *dev, unsigned int reg) { /* Due to the sparseness of the register map the compiler * output from an explicit switch statement ends up being much @@ -1621,8 +1691,7 @@ static int wm8996_readable_register(struct snd_soc_codec *codec, } } -static int wm8996_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) +static bool wm8996_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM8996_SOFTWARE_RESET: @@ -1646,9 +1715,15 @@ static int wm8996_volatile_register(struct snd_soc_codec *codec, } } -static int wm8996_reset(struct snd_soc_codec *codec) +static int wm8996_reset(struct wm8996_priv *wm8996) { - return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915); + if (wm8996->pdata.ldo_ena > 0) { + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); + return 0; + } else { + return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, + 0x8915); + } } static const int bclk_divs[] = { @@ -1723,13 +1798,13 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, msleep(5); } - codec->cache_only = false; - snd_soc_cache_sync(codec); + regcache_cache_only(codec->control_data, false); + regcache_sync(codec->control_data); } break; case SND_SOC_BIAS_OFF: - codec->cache_only = true; + regcache_cache_only(codec->control_data, true); if (wm8996->pdata.ldo_ena >= 0) gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), @@ -1968,6 +2043,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, break; case 24576000: ratediv = WM8996_SYSCLK_DIV; + wm8996->sysclk /= 2; case 12288000: snd_soc_update_bits(codec, WM8996_AIF_RATE, WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE); @@ -2251,48 +2327,45 @@ static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip) static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT); + regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, + WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT); } static int wm8996_gpio_direction_out(struct gpio_chip *chip, unsigned offset, int value) { struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; int val; val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT); - return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_FN_MASK | WM8996_GP1_DIR | - WM8996_GP1_LVL, val); + return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, + WM8996_GP1_FN_MASK | WM8996_GP1_DIR | + WM8996_GP1_LVL, val); } static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset) { struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; + unsigned int reg; int ret; - ret = snd_soc_read(codec, WM8996_GPIO_1 + offset); + ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, ®); if (ret < 0) return ret; - return (ret & WM8996_GP1_LVL) != 0; + return (reg & WM8996_GP1_LVL) != 0; } static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_FN_MASK | WM8996_GP1_DIR, - (1 << WM8996_GP1_FN_SHIFT) | - (1 << WM8996_GP1_DIR_SHIFT)); + return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset, + WM8996_GP1_FN_MASK | WM8996_GP1_DIR, + (1 << WM8996_GP1_FN_SHIFT) | + (1 << WM8996_GP1_DIR_SHIFT)); } static struct gpio_chip wm8996_template_chip = { @@ -2305,14 +2378,13 @@ static struct gpio_chip wm8996_template_chip = { .can_sleep = 1, }; -static void wm8996_init_gpio(struct snd_soc_codec *codec) +static void wm8996_init_gpio(struct wm8996_priv *wm8996) { - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int ret; wm8996->gpio_chip = wm8996_template_chip; wm8996->gpio_chip.ngpio = 5; - wm8996->gpio_chip.dev = codec->dev; + wm8996->gpio_chip.dev = wm8996->dev; if (wm8996->pdata.gpio_base) wm8996->gpio_chip.base = wm8996->pdata.gpio_base; @@ -2321,24 +2393,23 @@ static void wm8996_init_gpio(struct snd_soc_codec *codec) ret = gpiochip_add(&wm8996->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); + dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret); } -static void wm8996_free_gpio(struct snd_soc_codec *codec) +static void wm8996_free_gpio(struct wm8996_priv *wm8996) { - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int ret; ret = gpiochip_remove(&wm8996->gpio_chip); if (ret != 0) - dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); + dev_err(wm8996->dev, "Failed to remove GPIOs: %d\n", ret); } #else -static void wm8996_init_gpio(struct snd_soc_codec *codec) +static void wm8996_init_gpio(struct wm8996_priv *wm8996) { } -static void wm8996_free_gpio(struct snd_soc_codec *codec) +static void wm8996_free_gpio(struct wm8996_priv *wm8996) { } #endif @@ -2501,8 +2572,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) SND_JACK_BTN_0); snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - WM8996_MICD_RATE_MASK); + WM8996_MICD_RATE_MASK | + WM8996_MICD_BIAS_STARTTIME_MASK, + WM8996_MICD_RATE_MASK | + 9 << WM8996_MICD_BIAS_STARTTIME_SHIFT); return; } @@ -2519,8 +2592,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) /* Increase poll rate to give better responsiveness * for buttons */ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - 5 << WM8996_MICD_RATE_SHIFT); + WM8996_MICD_RATE_MASK | + WM8996_MICD_BIAS_STARTTIME_MASK, + 5 << WM8996_MICD_RATE_SHIFT | + 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); } else { dev_dbg(codec->dev, "Mic button up\n"); snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0); @@ -2568,8 +2643,10 @@ static void wm8996_micd(struct snd_soc_codec *codec) * responsiveness. */ snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - 7 << WM8996_MICD_RATE_SHIFT); + WM8996_MICD_RATE_MASK | + WM8996_MICD_BIAS_STARTTIME_MASK, + 7 << WM8996_MICD_RATE_SHIFT | + 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); } } } @@ -2692,6 +2769,18 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) "Failed to add ReTune Mobile controls: %d\n", ret); } +static const struct regmap_config wm8996_regmap = { + .reg_bits = 16, + .val_bits = 16, + + .max_register = WM8996_MAX_REGISTER, + .reg_defaults = wm8996_reg, + .num_reg_defaults = ARRAY_SIZE(wm8996_reg), + .volatile_reg = wm8996_volatile_register, + .readable_reg = wm8996_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + static int wm8996_probe(struct snd_soc_codec *codec) { int ret; @@ -2707,19 +2796,11 @@ static int wm8996_probe(struct snd_soc_codec *codec) dapm->idle_bias_off = true; - ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - goto err; - } - - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) - wm8996->supplies[i].supply = wm8996_supply_names[i]; + codec->control_data = wm8996->regmap; - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); if (ret != 0) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); goto err; } @@ -2727,13 +2808,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; - wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); - if (IS_ERR(wm8996->cpvdd)) { - ret = PTR_ERR(wm8996->cpvdd); - dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); - goto err_get; - } - /* This should really be moved into the regulator core */ for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { ret = regulator_register_notifier(wm8996->supplies[i].consumer, @@ -2745,50 +2819,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) } } - ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_cpvdd; - } - - if (wm8996->pdata.ldo_ena >= 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); - msleep(5); - } - - ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET); - if (ret < 0) { - dev_err(codec->dev, "Failed to read ID register: %d\n", ret); - goto err_enable; - } - if (ret != 0x8915) { - dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret); - ret = -EINVAL; - goto err_enable; - } - - ret = snd_soc_read(codec, WM8996_CHIP_REVISION); - if (ret < 0) { - dev_err(codec->dev, "Failed to read device revision: %d\n", - ret); - goto err_enable; - } - - dev_info(codec->dev, "revision %c\n", - (ret & WM8996_CHIP_REV_MASK) + 'A'); - - if (wm8996->pdata.ldo_ena >= 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - } else { - ret = wm8996_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_enable; - } - } - - codec->cache_only = true; + regcache_cache_only(codec->control_data, true); /* Apply platform data settings */ snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, @@ -2946,10 +2977,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) WM8996_AIF2TX_LRCLK_MODE, WM8996_AIF2TX_LRCLK_MODE); - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); - - wm8996_init_gpio(codec); - if (i2c->irq) { if (wm8996->pdata.irq_flags) irq_flags = wm8996->pdata.irq_flags; @@ -2987,15 +3014,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) return 0; -err_enable: - if (wm8996->pdata.ldo_ena >= 0) - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); -err_cpvdd: - regulator_put(wm8996->cpvdd); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); err: return ret; } @@ -3012,8 +3030,6 @@ static int wm8996_remove(struct snd_soc_codec *codec) if (i2c->irq) free_irq(i2c->irq, codec); - wm8996_free_gpio(codec); - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) regulator_unregister_notifier(wm8996->supplies[i].consumer, &wm8996->disable_nb[i]); @@ -3023,17 +3039,17 @@ static int wm8996_remove(struct snd_soc_codec *codec) return 0; } +static int wm8996_soc_volatile_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + return true; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { .probe = wm8996_probe, .remove = wm8996_remove, .set_bias_level = wm8996_set_bias_level, .seq_notifier = wm8996_seq_notifier, - .reg_cache_size = WM8996_MAX_REGISTER + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8996_reg, - .volatile_register = wm8996_volatile_register, - .readable_register = wm8996_readable_register, - .compress_type = SND_SOC_RBTREE_COMPRESSION, .controls = wm8996_snd_controls, .num_controls = ARRAY_SIZE(wm8996_snd_controls), .dapm_widgets = wm8996_dapm_widgets, @@ -3041,6 +3057,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { .dapm_routes = wm8996_dapm_routes, .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), .set_pll = wm8996_set_fll, + .reg_cache_size = WM8996_MAX_REGISTER, + .volatile_register = wm8996_soc_volatile_register, }; #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ @@ -3049,7 +3067,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm8996_dai_ops = { +static const struct snd_soc_dai_ops wm8996_dai_ops = { .set_fmt = wm8996_set_fmt, .hw_params = wm8996_hw_params, .set_sysclk = wm8996_set_sysclk, @@ -3098,13 +3116,16 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm8996_priv *wm8996; - int ret; + int ret, i; + unsigned int reg; - wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL); + wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv), + GFP_KERNEL); if (wm8996 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, wm8996); + wm8996->dev = &i2c->dev; if (dev_get_platdata(&i2c->dev)) memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev), @@ -3120,19 +3141,97 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, } } + for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) + wm8996->supplies[i].supply = wm8996_supply_names[i]; + + ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), + wm8996->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); + goto err_gpio; + } + + wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); + if (IS_ERR(wm8996->cpvdd)) { + ret = PTR_ERR(wm8996->cpvdd); + dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); + goto err_get; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), + wm8996->supplies); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); + goto err_cpvdd; + } + + if (wm8996->pdata.ldo_ena > 0) { + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); + msleep(5); + } + + wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); + if (IS_ERR(wm8996->regmap)) { + ret = PTR_ERR(wm8996->regmap); + dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); + goto err_enable; + } + + ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); + goto err_regmap; + } + if (reg != 0x8915) { + dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); + ret = -EINVAL; + goto err_regmap; + } + + ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, ®); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to read device revision: %d\n", + ret); + goto err_regmap; + } + + dev_info(&i2c->dev, "revision %c\n", + (reg & WM8996_CHIP_REV_MASK) + 'A'); + + regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); + + ret = wm8996_reset(wm8996); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset\n"); + goto err_regmap; + } + + wm8996_init_gpio(wm8996); + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8996, wm8996_dai, ARRAY_SIZE(wm8996_dai)); if (ret < 0) - goto err_gpio; + goto err_gpiolib; return ret; +err_gpiolib: + wm8996_free_gpio(wm8996); +err_regmap: + regmap_exit(wm8996->regmap); +err_enable: + if (wm8996->pdata.ldo_ena > 0) + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); + regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); +err_cpvdd: + regulator_put(wm8996->cpvdd); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); err_gpio: if (wm8996->pdata.ldo_ena > 0) gpio_free(wm8996->pdata.ldo_ena); err: - kfree(wm8996); return ret; } @@ -3142,9 +3241,14 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) struct wm8996_priv *wm8996 = i2c_get_clientdata(client); snd_soc_unregister_codec(&client->dev); - if (wm8996->pdata.ldo_ena > 0) + wm8996_free_gpio(wm8996); + regulator_put(wm8996->cpvdd); + regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); + regmap_exit(wm8996->regmap); + if (wm8996->pdata.ldo_ena > 0) { + gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); gpio_free(wm8996->pdata.ldo_ena); - kfree(i2c_get_clientdata(client)); + } return 0; } diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 3cd35a02c28..a6bab392700 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -18,7 +18,7 @@ #include <linux/device.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> +#include <linux/regmap.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -30,69 +30,60 @@ #include <sound/wm9081.h> #include "wm9081.h" -static u16 wm9081_reg_defaults[] = { - 0x0000, /* R0 - Software Reset */ - 0x0000, /* R1 */ - 0x00B9, /* R2 - Analogue Lineout */ - 0x00B9, /* R3 - Analogue Speaker PGA */ - 0x0001, /* R4 - VMID Control */ - 0x0068, /* R5 - Bias Control 1 */ - 0x0000, /* R6 */ - 0x0000, /* R7 - Analogue Mixer */ - 0x0000, /* R8 - Anti Pop Control */ - 0x01DB, /* R9 - Analogue Speaker 1 */ - 0x0018, /* R10 - Analogue Speaker 2 */ - 0x0180, /* R11 - Power Management */ - 0x0000, /* R12 - Clock Control 1 */ - 0x0038, /* R13 - Clock Control 2 */ - 0x4000, /* R14 - Clock Control 3 */ - 0x0000, /* R15 */ - 0x0000, /* R16 - FLL Control 1 */ - 0x0200, /* R17 - FLL Control 2 */ - 0x0000, /* R18 - FLL Control 3 */ - 0x0204, /* R19 - FLL Control 4 */ - 0x0000, /* R20 - FLL Control 5 */ - 0x0000, /* R21 */ - 0x0000, /* R22 - Audio Interface 1 */ - 0x0002, /* R23 - Audio Interface 2 */ - 0x0008, /* R24 - Audio Interface 3 */ - 0x0022, /* R25 - Audio Interface 4 */ - 0x0000, /* R26 - Interrupt Status */ - 0x0006, /* R27 - Interrupt Status Mask */ - 0x0000, /* R28 - Interrupt Polarity */ - 0x0000, /* R29 - Interrupt Control */ - 0x00C0, /* R30 - DAC Digital 1 */ - 0x0008, /* R31 - DAC Digital 2 */ - 0x09AF, /* R32 - DRC 1 */ - 0x4201, /* R33 - DRC 2 */ - 0x0000, /* R34 - DRC 3 */ - 0x0000, /* R35 - DRC 4 */ - 0x0000, /* R36 */ - 0x0000, /* R37 */ - 0x0000, /* R38 - Write Sequencer 1 */ - 0x0000, /* R39 - Write Sequencer 2 */ - 0x0002, /* R40 - MW Slave 1 */ - 0x0000, /* R41 */ - 0x0000, /* R42 - EQ 1 */ - 0x0000, /* R43 - EQ 2 */ - 0x0FCA, /* R44 - EQ 3 */ - 0x0400, /* R45 - EQ 4 */ - 0x00B8, /* R46 - EQ 5 */ - 0x1EB5, /* R47 - EQ 6 */ - 0xF145, /* R48 - EQ 7 */ - 0x0B75, /* R49 - EQ 8 */ - 0x01C5, /* R50 - EQ 9 */ - 0x169E, /* R51 - EQ 10 */ - 0xF829, /* R52 - EQ 11 */ - 0x07AD, /* R53 - EQ 12 */ - 0x1103, /* R54 - EQ 13 */ - 0x1C58, /* R55 - EQ 14 */ - 0xF373, /* R56 - EQ 15 */ - 0x0A54, /* R57 - EQ 16 */ - 0x0558, /* R58 - EQ 17 */ - 0x0564, /* R59 - EQ 18 */ - 0x0559, /* R60 - EQ 19 */ - 0x4000, /* R61 - EQ 20 */ +static struct reg_default wm9081_reg[] = { + { 2, 0x00B9 }, /* R2 - Analogue Lineout */ + { 3, 0x00B9 }, /* R3 - Analogue Speaker PGA */ + { 4, 0x0001 }, /* R4 - VMID Control */ + { 5, 0x0068 }, /* R5 - Bias Control 1 */ + { 7, 0x0000 }, /* R7 - Analogue Mixer */ + { 8, 0x0000 }, /* R8 - Anti Pop Control */ + { 9, 0x01DB }, /* R9 - Analogue Speaker 1 */ + { 10, 0x0018 }, /* R10 - Analogue Speaker 2 */ + { 11, 0x0180 }, /* R11 - Power Management */ + { 12, 0x0000 }, /* R12 - Clock Control 1 */ + { 13, 0x0038 }, /* R13 - Clock Control 2 */ + { 14, 0x4000 }, /* R14 - Clock Control 3 */ + { 16, 0x0000 }, /* R16 - FLL Control 1 */ + { 17, 0x0200 }, /* R17 - FLL Control 2 */ + { 18, 0x0000 }, /* R18 - FLL Control 3 */ + { 19, 0x0204 }, /* R19 - FLL Control 4 */ + { 20, 0x0000 }, /* R20 - FLL Control 5 */ + { 22, 0x0000 }, /* R22 - Audio Interface 1 */ + { 23, 0x0002 }, /* R23 - Audio Interface 2 */ + { 24, 0x0008 }, /* R24 - Audio Interface 3 */ + { 25, 0x0022 }, /* R25 - Audio Interface 4 */ + { 27, 0x0006 }, /* R27 - Interrupt Status Mask */ + { 28, 0x0000 }, /* R28 - Interrupt Polarity */ + { 29, 0x0000 }, /* R29 - Interrupt Control */ + { 30, 0x00C0 }, /* R30 - DAC Digital 1 */ + { 31, 0x0008 }, /* R31 - DAC Digital 2 */ + { 32, 0x09AF }, /* R32 - DRC 1 */ + { 33, 0x4201 }, /* R33 - DRC 2 */ + { 34, 0x0000 }, /* R34 - DRC 3 */ + { 35, 0x0000 }, /* R35 - DRC 4 */ + { 38, 0x0000 }, /* R38 - Write Sequencer 1 */ + { 39, 0x0000 }, /* R39 - Write Sequencer 2 */ + { 40, 0x0002 }, /* R40 - MW Slave 1 */ + { 42, 0x0000 }, /* R42 - EQ 1 */ + { 43, 0x0000 }, /* R43 - EQ 2 */ + { 44, 0x0FCA }, /* R44 - EQ 3 */ + { 45, 0x0400 }, /* R45 - EQ 4 */ + { 46, 0x00B8 }, /* R46 - EQ 5 */ + { 47, 0x1EB5 }, /* R47 - EQ 6 */ + { 48, 0xF145 }, /* R48 - EQ 7 */ + { 49, 0x0B75 }, /* R49 - EQ 8 */ + { 50, 0x01C5 }, /* R50 - EQ 9 */ + { 51, 0x169E }, /* R51 - EQ 10 */ + { 52, 0xF829 }, /* R52 - EQ 11 */ + { 53, 0x07AD }, /* R53 - EQ 12 */ + { 54, 0x1103 }, /* R54 - EQ 13 */ + { 55, 0x1C58 }, /* R55 - EQ 14 */ + { 56, 0xF373 }, /* R56 - EQ 15 */ + { 57, 0x0A54 }, /* R57 - EQ 16 */ + { 58, 0x0558 }, /* R58 - EQ 17 */ + { 59, 0x0564 }, /* R59 - EQ 18 */ + { 60, 0x0559 }, /* R60 - EQ 19 */ + { 61, 0x4000 }, /* R61 - EQ 20 */ }; static struct { @@ -156,7 +147,7 @@ static struct { }; struct wm9081_priv { - enum snd_soc_control_type control_type; + struct regmap *regmap; int sysclk_source; int mclk_rate; int sysclk_rate; @@ -169,20 +160,84 @@ struct wm9081_priv { struct wm9081_pdata pdata; }; -static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg) +static bool wm9081_volatile_register(struct device *dev, unsigned int reg) { switch (reg) { case WM9081_SOFTWARE_RESET: case WM9081_INTERRUPT_STATUS: - return 1; + return true; default: - return 0; + return false; + } +} + +static bool wm9081_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case WM9081_SOFTWARE_RESET: + case WM9081_ANALOGUE_LINEOUT: + case WM9081_ANALOGUE_SPEAKER_PGA: + case WM9081_VMID_CONTROL: + case WM9081_BIAS_CONTROL_1: + case WM9081_ANALOGUE_MIXER: + case WM9081_ANTI_POP_CONTROL: + case WM9081_ANALOGUE_SPEAKER_1: + case WM9081_ANALOGUE_SPEAKER_2: + case WM9081_POWER_MANAGEMENT: + case WM9081_CLOCK_CONTROL_1: + case WM9081_CLOCK_CONTROL_2: + case WM9081_CLOCK_CONTROL_3: + case WM9081_FLL_CONTROL_1: + case WM9081_FLL_CONTROL_2: + case WM9081_FLL_CONTROL_3: + case WM9081_FLL_CONTROL_4: + case WM9081_FLL_CONTROL_5: + case WM9081_AUDIO_INTERFACE_1: + case WM9081_AUDIO_INTERFACE_2: + case WM9081_AUDIO_INTERFACE_3: + case WM9081_AUDIO_INTERFACE_4: + case WM9081_INTERRUPT_STATUS: + case WM9081_INTERRUPT_STATUS_MASK: + case WM9081_INTERRUPT_POLARITY: + case WM9081_INTERRUPT_CONTROL: + case WM9081_DAC_DIGITAL_1: + case WM9081_DAC_DIGITAL_2: + case WM9081_DRC_1: + case WM9081_DRC_2: + case WM9081_DRC_3: + case WM9081_DRC_4: + case WM9081_WRITE_SEQUENCER_1: + case WM9081_WRITE_SEQUENCER_2: + case WM9081_MW_SLAVE_1: + case WM9081_EQ_1: + case WM9081_EQ_2: + case WM9081_EQ_3: + case WM9081_EQ_4: + case WM9081_EQ_5: + case WM9081_EQ_6: + case WM9081_EQ_7: + case WM9081_EQ_8: + case WM9081_EQ_9: + case WM9081_EQ_10: + case WM9081_EQ_11: + case WM9081_EQ_12: + case WM9081_EQ_13: + case WM9081_EQ_14: + case WM9081_EQ_15: + case WM9081_EQ_16: + case WM9081_EQ_17: + case WM9081_EQ_18: + case WM9081_EQ_19: + case WM9081_EQ_20: + return true; + default: + return false; } } -static int wm9081_reset(struct snd_soc_codec *codec) +static int wm9081_reset(struct regmap *map) { - return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0); + return regmap_write(map, WM9081_SOFTWARE_RESET, 0x9081); } static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); @@ -737,6 +792,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0), SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("TSENSE", WM9081_POWER_MANAGEMENT, 7, 0, NULL, 0), }; @@ -759,6 +815,7 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { { "Speaker PGA", NULL, "CLK_SYS" }, { "Speaker", NULL, "Speaker PGA" }, + { "Speaker", NULL, "TSENSE" }, { "SPKN", NULL, "Speaker" }, { "SPKP", NULL, "Speaker" }, @@ -767,84 +824,74 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { static int wm9081_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg; - switch (level) { case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: /* VMID=2*40k */ - reg = snd_soc_read(codec, WM9081_VMID_CONTROL); - reg &= ~WM9081_VMID_SEL_MASK; - reg |= 0x2; - snd_soc_write(codec, WM9081_VMID_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_VMID_CONTROL, + WM9081_VMID_SEL_MASK, 0x2); /* Normal bias current */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_STBY_BIAS_ENA; - snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); + snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, + WM9081_STBY_BIAS_ENA, 0); break; case SND_SOC_BIAS_STANDBY: /* Initial cold start */ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Disable LINEOUT discharge */ - reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); - reg &= ~WM9081_LINEOUT_DISCH; - snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, + WM9081_LINEOUT_DISCH, 0); /* Select startup bias source */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA; - snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); + snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, + WM9081_BIAS_SRC | WM9081_BIAS_ENA, + WM9081_BIAS_SRC | WM9081_BIAS_ENA); /* VMID 2*4k; Soft VMID ramp enable */ - reg = snd_soc_read(codec, WM9081_VMID_CONTROL); - reg |= WM9081_VMID_RAMP | 0x6; - snd_soc_write(codec, WM9081_VMID_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_VMID_CONTROL, + WM9081_VMID_RAMP | + WM9081_VMID_SEL_MASK, + WM9081_VMID_RAMP | 0x6); mdelay(100); /* Normal bias enable & soft start off */ - reg |= WM9081_BIAS_ENA; - reg &= ~WM9081_VMID_RAMP; - snd_soc_write(codec, WM9081_VMID_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_VMID_CONTROL, + WM9081_VMID_RAMP, 0); /* Standard bias source */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_BIAS_SRC; - snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); + snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, + WM9081_BIAS_SRC, 0); } /* VMID 2*240k */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_VMID_SEL_MASK; - reg |= 0x04; - snd_soc_write(codec, WM9081_VMID_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_VMID_CONTROL, + WM9081_VMID_SEL_MASK, 0x04); /* Standby bias current on */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_STBY_BIAS_ENA; - snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); + snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, + WM9081_STBY_BIAS_ENA, + WM9081_STBY_BIAS_ENA); break; case SND_SOC_BIAS_OFF: - /* Startup bias source */ - reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_BIAS_SRC; - snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); + /* Startup bias source and disable bias */ + snd_soc_update_bits(codec, WM9081_BIAS_CONTROL_1, + WM9081_BIAS_SRC | WM9081_BIAS_ENA, + WM9081_BIAS_SRC); - /* Disable VMID and biases with soft ramping */ - reg = snd_soc_read(codec, WM9081_VMID_CONTROL); - reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); - reg |= WM9081_VMID_RAMP; - snd_soc_write(codec, WM9081_VMID_CONTROL, reg); + /* Disable VMID with soft ramping */ + snd_soc_update_bits(codec, WM9081_VMID_CONTROL, + WM9081_VMID_RAMP | WM9081_VMID_SEL_MASK, + WM9081_VMID_RAMP); /* Actively discharge LINEOUT */ - reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); - reg |= WM9081_LINEOUT_DISCH; - snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg); + snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, + WM9081_LINEOUT_DISCH, + WM9081_LINEOUT_DISCH); break; } @@ -1185,7 +1232,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops wm9081_dai_ops = { +static const struct snd_soc_dai_ops wm9081_dai_ops = { .hw_params = wm9081_hw_params, .set_fmt = wm9081_set_dai_fmt, .digital_mute = wm9081_digital_mute, @@ -1213,25 +1260,14 @@ static int wm9081_probe(struct snd_soc_codec *codec) int ret; u16 reg; - ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); + codec->control_data = wm9081->regmap; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); return ret; } - reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET); - if (reg != 0x9081) { - dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); - ret = -EINVAL; - return ret; - } - - ret = wm9081_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - reg = 0; if (wm9081->pdata.irq_high) reg |= WM9081_IRQ_POL; @@ -1243,11 +1279,10 @@ static int wm9081_probe(struct snd_soc_codec *codec) wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Enable zero cross by default */ - reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT); - snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); - reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); - snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, - reg | WM9081_SPKPGAZC); + snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, + WM9081_LINEOUTZC, WM9081_LINEOUTZC); + snd_soc_update_bits(codec, WM9081_ANALOGUE_SPEAKER_PGA, + WM9081_SPKPGAZC, WM9081_SPKPGAZC); if (!wm9081->pdata.num_retune_configs) { dev_dbg(codec->dev, @@ -1266,7 +1301,7 @@ static int wm9081_remove(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm9081_suspend(struct snd_soc_codec *codec) { wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -1275,15 +1310,9 @@ static int wm9081_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm9081_resume(struct snd_soc_codec *codec) { - u16 *reg_cache = codec->reg_cache; - int i; - - for (i = 0; i < codec->driver->reg_cache_size; i++) { - if (i == WM9081_SOFTWARE_RESET) - continue; + struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); - snd_soc_write(codec, i, reg_cache[i]); - } + regcache_sync(wm9081->regmap); wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1303,11 +1332,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { .set_sysclk = wm9081_set_sysclk, .set_bias_level = wm9081_set_bias_level, - .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), - .reg_word_size = sizeof(u16), - .reg_cache_default = wm9081_reg_defaults, - .volatile_register = wm9081_volatile_register, - .controls = wm9081_snd_controls, .num_controls = ARRAY_SIZE(wm9081_snd_controls), .dapm_widgets = wm9081_dapm_widgets, @@ -1316,19 +1340,56 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths), }; +static const struct regmap_config wm9081_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = WM9081_MAX_REGISTER, + .reg_defaults = wm9081_reg, + .num_reg_defaults = ARRAY_SIZE(wm9081_reg), + .volatile_reg = wm9081_volatile_register, + .readable_reg = wm9081_readable_register, + .cache_type = REGCACHE_RBTREE, +}; + #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct wm9081_priv *wm9081; + unsigned int reg; int ret; - wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); + wm9081 = devm_kzalloc(&i2c->dev, sizeof(struct wm9081_priv), + GFP_KERNEL); if (wm9081 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, wm9081); - wm9081->control_type = SND_SOC_I2C; + + wm9081->regmap = regmap_init_i2c(i2c, &wm9081_regmap); + if (IS_ERR(wm9081->regmap)) { + ret = PTR_ERR(wm9081->regmap); + dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); + goto err; + } + + ret = regmap_read(wm9081->regmap, WM9081_SOFTWARE_RESET, ®); + if (ret != 0) { + dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); + goto err_regmap; + } + if (reg != 0x9081) { + dev_err(&i2c->dev, "Device is not a WM9081: ID=0x%x\n", reg); + ret = -EINVAL; + goto err_regmap; + } + + ret = wm9081_reset(wm9081->regmap); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to issue reset\n"); + goto err_regmap; + } if (dev_get_platdata(&i2c->dev)) memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), @@ -1337,14 +1398,23 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9081, &wm9081_dai, 1); if (ret < 0) - kfree(wm9081); + goto err_regmap; + + return 0; + +err_regmap: + regmap_exit(wm9081->regmap); +err: + return ret; } static __devexit int wm9081_i2c_remove(struct i2c_client *client) { + struct wm9081_priv *wm9081 = i2c_get_clientdata(client); + snd_soc_unregister_codec(&client->dev); - kfree(i2c_get_clientdata(client)); + regmap_exit(wm9081->regmap); return 0; } diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 2b5252c9e37..41ebe0dce77 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -177,19 +177,19 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) } static const unsigned int in_tlv[] = { - TLV_DB_RANGE_HEAD(6), + TLV_DB_RANGE_HEAD(3), 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0), 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0), 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0), }; static const unsigned int mix_tlv[] = { - TLV_DB_RANGE_HEAD(4), + TLV_DB_RANGE_HEAD(2), 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0), 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0), }; static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); static const unsigned int spkboost_tlv[] = { - TLV_DB_RANGE_HEAD(7), + TLV_DB_RANGE_HEAD(2), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; @@ -513,18 +513,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Restore the register cache */ - for (i = 1; i < codec->driver->reg_cache_size; i++) { - if (reg_cache[i] == wm9090_reg_defaults[i]) - continue; - if (wm9090_volatile(codec, i)) - continue; - - ret = snd_soc_write(codec, i, reg_cache[i]); - if (ret != 0) - dev_warn(codec->dev, - "Failed to restore register %d: %d\n", - i, ret); - } + snd_soc_cache_sync(codec); } /* We keep VMID off during standby since the combination of @@ -604,7 +593,7 @@ static int wm9090_probe(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int wm9090_suspend(struct snd_soc_codec *codec, pm_message_t state) +static int wm9090_suspend(struct snd_soc_codec *codec) { wm9090_set_bias_level(codec, SND_SOC_BIAS_OFF); @@ -647,7 +636,7 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, struct wm9090_priv *wm9090; int ret; - wm9090 = kzalloc(sizeof(*wm9090), GFP_KERNEL); + wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL); if (wm9090 == NULL) { dev_err(&i2c->dev, "Can not allocate memory\n"); return -ENOMEM; @@ -661,8 +650,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm9090, NULL, 0); - if (ret < 0) - kfree(wm9090); return ret; } @@ -671,7 +658,6 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); snd_soc_unregister_codec(&i2c->dev); - kfree(wm9090); return 0; } @@ -685,7 +671,7 @@ MODULE_DEVICE_TABLE(i2c, wm9090_id); static struct i2c_driver wm9090_i2c_driver = { .driver = { - .name = "wm9090-codec", + .name = "wm9090", .owner = THIS_MODULE, }, .probe = wm9090_i2c_probe, diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 646b58dda84..40c92ead85a 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -258,7 +258,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops wm9705_dai_ops = { +static const struct snd_soc_dai_ops wm9705_dai_ops = { .prepare = ac97_prepare, }; @@ -306,7 +306,7 @@ static int wm9705_reset(struct snd_soc_codec *codec) } #ifdef CONFIG_PM -static int wm9705_soc_suspend(struct snd_soc_codec *codec, pm_message_t msg) +static int wm9705_soc_suspend(struct snd_soc_codec *codec) { soc_ac97_ops.write(codec->ac97, AC97_POWERDOWN, 0xffff); @@ -406,17 +406,7 @@ static struct platform_driver wm9705_codec_driver = { .remove = __devexit_p(wm9705_remove), }; -static int __init wm9705_init(void) -{ - return platform_driver_register(&wm9705_codec_driver); -} -module_init(wm9705_init); - -static void __exit wm9705_exit(void) -{ - platform_driver_unregister(&wm9705_codec_driver); -} -module_exit(wm9705_exit); +module_platform_driver(wm9705_codec_driver); MODULE_DESCRIPTION("ASoC WM9705 driver"); MODULE_AUTHOR("Ian Molton"); diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 90117f8156e..b7b31f84c10 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -505,11 +505,11 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops wm9712_dai_ops_hifi = { +static const struct snd_soc_dai_ops wm9712_dai_ops_hifi = { .prepare = ac97_prepare, }; -static struct snd_soc_dai_ops wm9712_dai_ops_aux = { +static const struct snd_soc_dai_ops wm9712_dai_ops_aux = { .prepare = ac97_aux_prepare, }; @@ -583,8 +583,7 @@ err: return -EIO; } -static int wm9712_soc_suspend(struct snd_soc_codec *codec, - pm_message_t state) +static int wm9712_soc_suspend(struct snd_soc_codec *codec) { wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; @@ -694,17 +693,7 @@ static struct platform_driver wm9712_codec_driver = { .remove = __devexit_p(wm9712_remove), }; -static int __init wm9712_init(void) -{ - return platform_driver_register(&wm9712_codec_driver); -} -module_init(wm9712_init); - -static void __exit wm9712_exit(void) -{ - platform_driver_unregister(&wm9712_codec_driver); -} -module_exit(wm9712_exit); +module_platform_driver(wm9712_codec_driver); MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver"); MODULE_AUTHOR("Liam Girdwood"); diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 7167cb6787d..2b8479bfcd9 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -1026,19 +1026,19 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, (SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S20_3LE | \ SNDRV_PCM_FORMAT_S24_LE) -static struct snd_soc_dai_ops wm9713_dai_ops_hifi = { +static const struct snd_soc_dai_ops wm9713_dai_ops_hifi = { .prepare = ac97_hifi_prepare, .set_clkdiv = wm9713_set_dai_clkdiv, .set_pll = wm9713_set_dai_pll, }; -static struct snd_soc_dai_ops wm9713_dai_ops_aux = { +static const struct snd_soc_dai_ops wm9713_dai_ops_aux = { .prepare = ac97_aux_prepare, .set_clkdiv = wm9713_set_dai_clkdiv, .set_pll = wm9713_set_dai_pll, }; -static struct snd_soc_dai_ops wm9713_dai_ops_voice = { +static const struct snd_soc_dai_ops wm9713_dai_ops_voice = { .hw_params = wm9713_pcm_hw_params, .set_clkdiv = wm9713_set_dai_clkdiv, .set_pll = wm9713_set_dai_pll, @@ -1140,8 +1140,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec, return 0; } -static int wm9713_soc_suspend(struct snd_soc_codec *codec, - pm_message_t state) +static int wm9713_soc_suspend(struct snd_soc_codec *codec) { u16 reg; @@ -1277,17 +1276,7 @@ static struct platform_driver wm9713_codec_driver = { .remove = __devexit_p(wm9713_remove), }; -static int __init wm9713_init(void) -{ - return platform_driver_register(&wm9713_codec_driver); -} -module_init(wm9713_init); - -static void __exit wm9713_exit(void) -{ - platform_driver_unregister(&wm9713_codec_driver); -} -module_exit(wm9713_exit); +module_platform_driver(wm9713_codec_driver); MODULE_DESCRIPTION("ASoC WM9713/WM9714 driver"); MODULE_AUTHOR("Liam Girdwood"); diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 84f33d4ea2c..2a61094075f 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -17,7 +17,6 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/i2c.h> -#include <linux/platform_device.h> #include <linux/mfd/wm8994/registers.h> #include <sound/core.h> #include <sound/pcm.h> @@ -40,7 +39,7 @@ static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0); static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1); static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0); static const unsigned int spkboost_tlv[] = { - TLV_DB_RANGE_HEAD(7), + TLV_DB_RANGE_HEAD(2), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; @@ -611,8 +610,8 @@ SND_SOC_DAPM_INPUT("IN1RP"), SND_SOC_DAPM_INPUT("IN2RN"), SND_SOC_DAPM_INPUT("IN2RP:VXRP"), -SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0), -SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0), SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0, in1l_pga, ARRAY_SIZE(in1l_pga)), @@ -654,6 +653,7 @@ SND_SOC_DAPM_MIXER("SPKL Boost", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0, right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), +SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, NULL, 0), SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, @@ -789,10 +789,12 @@ static const struct snd_soc_dapm_route analogue_routes[] = { { "SPKL Driver", NULL, "VMID" }, { "SPKL Driver", NULL, "SPKL Boost" }, { "SPKL Driver", NULL, "CLK_SYS" }, + { "SPKL Driver", NULL, "TSHUT" }, { "SPKR Driver", NULL, "VMID" }, { "SPKR Driver", NULL, "SPKR Boost" }, { "SPKR Driver", NULL, "CLK_SYS" }, + { "SPKR Driver", NULL, "TSHUT" }, { "SPKOUTLP", NULL, "SPKL Driver" }, { "SPKOUTLN", NULL, "SPKL Driver" }, diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index f78c3f0f280..10a2d8c788b 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -242,6 +242,7 @@ static struct snd_soc_dai_link da850_evm_dai = { /* davinci dm6446 evm audio machine driver */ static struct snd_soc_card dm6446_snd_soc_card_evm = { .name = "DaVinci DM6446 EVM", + .owner = THIS_MODULE, .dai_link = &dm6446_evm_dai, .num_links = 1, }; @@ -249,6 +250,7 @@ static struct snd_soc_card dm6446_snd_soc_card_evm = { /* davinci dm355 evm audio machine driver */ static struct snd_soc_card dm355_snd_soc_card_evm = { .name = "DaVinci DM355 EVM", + .owner = THIS_MODULE, .dai_link = &dm355_evm_dai, .num_links = 1, }; @@ -256,6 +258,7 @@ static struct snd_soc_card dm355_snd_soc_card_evm = { /* davinci dm365 evm audio machine driver */ static struct snd_soc_card dm365_snd_soc_card_evm = { .name = "DaVinci DM365 EVM", + .owner = THIS_MODULE, .dai_link = &dm365_evm_dai, .num_links = 1, }; @@ -263,18 +266,21 @@ static struct snd_soc_card dm365_snd_soc_card_evm = { /* davinci dm6467 evm audio machine driver */ static struct snd_soc_card dm6467_snd_soc_card_evm = { .name = "DaVinci DM6467 EVM", + .owner = THIS_MODULE, .dai_link = dm6467_evm_dai, .num_links = ARRAY_SIZE(dm6467_evm_dai), }; static struct snd_soc_card da830_snd_soc_card = { .name = "DA830/OMAP-L137 EVM", + .owner = THIS_MODULE, .dai_link = &da830_evm_dai, .num_links = 1, }; static struct snd_soc_card da850_snd_soc_card = { .name = "DA850/OMAP-L138 EVM", + .owner = THIS_MODULE, .dai_link = &da850_evm_dai, .num_links = 1, }; diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 300e12118c0..0a74b9587a2 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c @@ -620,7 +620,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 -static struct snd_soc_dai_ops davinci_i2s_dai_ops = { +static const struct snd_soc_dai_ops davinci_i2s_dai_ops = { .startup = davinci_i2s_startup, .shutdown = davinci_i2s_shutdown, .prepare = davinci_i2s_prepare, @@ -661,18 +661,18 @@ static int davinci_i2s_probe(struct platform_device *pdev) return -ENODEV; } - ioarea = request_mem_region(mem->start, resource_size(mem), - pdev->name); + ioarea = devm_request_mem_region(&pdev->dev, mem->start, + resource_size(mem), + pdev->name); if (!ioarea) { dev_err(&pdev->dev, "McBSP region already claimed\n"); return -EBUSY; } - dev = kzalloc(sizeof(struct davinci_mcbsp_dev), GFP_KERNEL); - if (!dev) { - ret = -ENOMEM; - goto err_release_region; - } + dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev), + GFP_KERNEL); + if (!dev) + return -ENOMEM; if (pdata) { dev->enable_channel_combine = pdata->enable_channel_combine; dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size = @@ -691,13 +691,11 @@ static int davinci_i2s_probe(struct platform_device *pdev) dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].ram_chan_q = ram_chan_q; dev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) { - ret = -ENODEV; - goto err_free_mem; - } + if (IS_ERR(dev->clk)) + return -ENODEV; clk_enable(dev->clk); - dev->base = ioremap(mem->start, resource_size(mem)); + dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!dev->base) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; @@ -715,7 +713,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; - goto err_iounmap; + goto err_release_clk; } dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].channel = res->start; @@ -723,7 +721,7 @@ static int davinci_i2s_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; - goto err_iounmap; + goto err_release_clk; } dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; dev->dev = &pdev->dev; @@ -732,35 +730,24 @@ static int davinci_i2s_probe(struct platform_device *pdev) ret = snd_soc_register_dai(&pdev->dev, &davinci_i2s_dai); if (ret != 0) - goto err_iounmap; + goto err_release_clk; return 0; -err_iounmap: - iounmap(dev->base); err_release_clk: clk_disable(dev->clk); clk_put(dev->clk); -err_free_mem: - kfree(dev); -err_release_region: - release_mem_region(mem->start, resource_size(mem)); - return ret; } static int davinci_i2s_remove(struct platform_device *pdev) { struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); - struct resource *mem; snd_soc_unregister_dai(&pdev->dev); clk_disable(dev->clk); clk_put(dev->clk); dev->clk = NULL; - kfree(dev); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); return 0; } @@ -774,17 +761,7 @@ static struct platform_driver davinci_mcbsp_driver = { }, }; -static int __init davinci_i2s_init(void) -{ - return platform_driver_register(&davinci_mcbsp_driver); -} -module_init(davinci_i2s_init); - -static void __exit davinci_i2s_exit(void) -{ - platform_driver_unregister(&davinci_mcbsp_driver); -} -module_exit(davinci_i2s_exit); +module_platform_driver(davinci_mcbsp_driver); MODULE_AUTHOR("Vladimir Barinov"); MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface"); diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 7173df254a9..95441bfc819 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -813,7 +813,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { +static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .startup = davinci_mcasp_startup, .trigger = davinci_mcasp_trigger, .hw_params = davinci_mcasp_hw_params, @@ -865,38 +865,35 @@ static int davinci_mcasp_probe(struct platform_device *pdev) struct resource *mem, *ioarea, *res; struct snd_platform_data *pdata; struct davinci_audio_dev *dev; - int ret = 0; + int ret; - dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL); + dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev), + GFP_KERNEL); if (!dev) return -ENOMEM; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(&pdev->dev, "no mem resource?\n"); - ret = -ENODEV; - goto err_release_data; + return -ENODEV; } - ioarea = request_mem_region(mem->start, + ioarea = devm_request_mem_region(&pdev->dev, mem->start, resource_size(mem), pdev->name); if (!ioarea) { dev_err(&pdev->dev, "Audio region already claimed\n"); - ret = -EBUSY; - goto err_release_data; + return -EBUSY; } pdata = pdev->dev.platform_data; dev->clk = clk_get(&pdev->dev, NULL); - if (IS_ERR(dev->clk)) { - ret = -ENODEV; - goto err_release_region; - } + if (IS_ERR(dev->clk)) + return -ENODEV; clk_enable(dev->clk); dev->clk_active = 1; - dev->base = ioremap(mem->start, resource_size(mem)); + dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!dev->base) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; @@ -924,7 +921,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENODEV; - goto err_iounmap; + goto err_release_clk; } dma_data->channel = res->start; @@ -940,7 +937,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENODEV; - goto err_iounmap; + goto err_release_clk; } dma_data->channel = res->start; @@ -948,37 +945,24 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ret = snd_soc_register_dai(&pdev->dev, &davinci_mcasp_dai[pdata->op_mode]); if (ret != 0) - goto err_iounmap; + goto err_release_clk; return 0; -err_iounmap: - iounmap(dev->base); err_release_clk: clk_disable(dev->clk); clk_put(dev->clk); -err_release_region: - release_mem_region(mem->start, resource_size(mem)); -err_release_data: - kfree(dev); - return ret; } static int davinci_mcasp_remove(struct platform_device *pdev) { struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev); - struct resource *mem; snd_soc_unregister_dai(&pdev->dev); clk_disable(dev->clk); clk_put(dev->clk); dev->clk = NULL; - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem->start, resource_size(mem)); - - kfree(dev); - return 0; } @@ -991,17 +975,7 @@ static struct platform_driver davinci_mcasp_driver = { }, }; -static int __init davinci_mcasp_init(void) -{ - return platform_driver_register(&davinci_mcasp_driver); -} -module_init(davinci_mcasp_init); - -static void __exit davinci_mcasp_exit(void) -{ - platform_driver_unregister(&davinci_mcasp_driver); -} -module_exit(davinci_mcasp_exit); +module_platform_driver(davinci_mcasp_driver); MODULE_AUTHOR("Steve Chen"); MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface"); diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index d5fe08cc5db..b26401f87b8 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -831,7 +831,6 @@ static u64 davinci_pcm_dmamask = 0xffffffff; static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret; @@ -840,7 +839,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = davinci_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK, pcm_hardware_playback.buffer_bytes_max); @@ -848,7 +847,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) return ret; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = davinci_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE, pcm_hardware_capture.buffer_bytes_max); @@ -886,17 +885,7 @@ static struct platform_driver davinci_pcm_driver = { .remove = __devexit_p(davinci_soc_platform_remove), }; -static int __init snd_davinci_pcm_init(void) -{ - return platform_driver_register(&davinci_pcm_driver); -} -module_init(snd_davinci_pcm_init); - -static void __exit snd_davinci_pcm_exit(void) -{ - platform_driver_unregister(&davinci_pcm_driver); -} -module_exit(snd_davinci_pcm_exit); +module_platform_driver(davinci_pcm_driver); MODULE_AUTHOR("Vladimir Barinov"); MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c index 0fe558c6514..f71175b29e3 100644 --- a/sound/soc/davinci/davinci-sffsdr.c +++ b/sound/soc/davinci/davinci-sffsdr.c @@ -93,6 +93,7 @@ static struct snd_soc_dai_link sffsdr_dai = { /* davinci-sffsdr audio machine driver */ static struct snd_soc_card snd_soc_sffsdr = { .name = "DaVinci SFFSDR", + .owner = THIS_MODULE, .dai_link = &sffsdr_dai, .num_links = 1, }; diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 1f11525d97e..da030ff883d 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c @@ -183,7 +183,7 @@ static int davinci_vcif_startup(struct snd_pcm_substream *substream, #define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 -static struct snd_soc_dai_ops davinci_vcif_dai_ops = { +static const struct snd_soc_dai_ops davinci_vcif_dai_ops = { .startup = davinci_vcif_startup, .trigger = davinci_vcif_trigger, .hw_params = davinci_vcif_hw_params, @@ -210,7 +210,9 @@ static int davinci_vcif_probe(struct platform_device *pdev) struct davinci_vcif_dev *davinci_vcif_dev; int ret; - davinci_vcif_dev = kzalloc(sizeof(struct davinci_vcif_dev), GFP_KERNEL); + davinci_vcif_dev = devm_kzalloc(&pdev->dev, + sizeof(struct davinci_vcif_dev), + GFP_KERNEL); if (!davinci_vcif_dev) { dev_dbg(&pdev->dev, "could not allocate memory for private data\n"); @@ -235,23 +237,15 @@ static int davinci_vcif_probe(struct platform_device *pdev) ret = snd_soc_register_dai(&pdev->dev, &davinci_vcif_dai); if (ret != 0) { dev_err(&pdev->dev, "could not register dai\n"); - goto fail; + return ret; } return 0; - -fail: - kfree(davinci_vcif_dev); - - return ret; } static int davinci_vcif_remove(struct platform_device *pdev) { - struct davinci_vcif_dev *davinci_vcif_dev = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_dai(&pdev->dev); - kfree(davinci_vcif_dev); return 0; } @@ -265,17 +259,7 @@ static struct platform_driver davinci_vcif_driver = { }, }; -static int __init davinci_vcif_init(void) -{ - return platform_driver_probe(&davinci_vcif_driver, davinci_vcif_probe); -} -module_init(davinci_vcif_init); - -static void __exit davinci_vcif_exit(void) -{ - platform_driver_unregister(&davinci_vcif_driver); -} -module_exit(davinci_vcif_exit); +module_platform_driver(davinci_vcif_driver); MODULE_AUTHOR("Miguel Aguilar"); MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface"); diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c index 51930b6a83a..bae5cbbbd2b 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/ep93xx/edb93xx.c @@ -48,18 +48,6 @@ static int edb93xx_hw_params(struct snd_pcm_substream *substream, else mclk_rate = rate * 64 * 2; - err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBS_CFS); - if (err) - return err; - - err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBS_CFS); - if (err) - return err; - err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk_rate, SND_SOC_CLOCK_IN); if (err) @@ -80,11 +68,14 @@ static struct snd_soc_dai_link edb93xx_dai = { .cpu_dai_name = "ep93xx-i2s", .codec_name = "spi0.0", .codec_dai_name = "cs4271-hifi", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &edb93xx_ops, }; static struct snd_soc_card snd_soc_edb93xx = { .name = "EDB93XX", + .owner = THIS_MODULE, .dai_link = &edb93xx_dai, .num_links = 1, }; @@ -131,17 +122,7 @@ static struct platform_driver edb93xx_driver = { .remove = __devexit_p(edb93xx_remove), }; -static int __init edb93xx_init(void) -{ - return platform_driver_register(&edb93xx_driver); -} -module_init(edb93xx_init); - -static void __exit edb93xx_exit(void) -{ - platform_driver_unregister(&edb93xx_driver); -} -module_exit(edb93xx_exit); +module_platform_driver(edb93xx_driver); MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); MODULE_DESCRIPTION("ALSA SoC EDB93xx"); diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c index 3cd6158d83e..0678637abd6 100644 --- a/sound/soc/ep93xx/ep93xx-ac97.c +++ b/sound/soc/ep93xx/ep93xx-ac97.c @@ -330,7 +330,7 @@ static int ep93xx_ac97_startup(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { +static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { .startup = ep93xx_ac97_startup, .trigger = ep93xx_ac97_trigger, }; @@ -449,17 +449,7 @@ static struct platform_driver ep93xx_ac97_driver = { }, }; -static int __init ep93xx_ac97_init(void) -{ - return platform_driver_register(&ep93xx_ac97_driver); -} -module_init(ep93xx_ac97_init); - -static void __exit ep93xx_ac97_exit(void) -{ - platform_driver_unregister(&ep93xx_ac97_driver); -} -module_exit(ep93xx_ac97_exit); +module_platform_driver(ep93xx_ac97_driver); MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver"); MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c index 099614e1665..f7a62348e3f 100644 --- a/sound/soc/ep93xx/ep93xx-i2s.c +++ b/sound/soc/ep93xx/ep93xx-i2s.c @@ -338,7 +338,7 @@ static int ep93xx_i2s_resume(struct snd_soc_dai *dai) #define ep93xx_i2s_resume NULL #endif -static struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { +static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = { .startup = ep93xx_i2s_startup, .shutdown = ep93xx_i2s_shutdown, .hw_params = ep93xx_i2s_hw_params, @@ -464,18 +464,7 @@ static struct platform_driver ep93xx_i2s_driver = { }, }; -static int __init ep93xx_i2s_init(void) -{ - return platform_driver_register(&ep93xx_i2s_driver); -} - -static void __exit ep93xx_i2s_exit(void) -{ - platform_driver_unregister(&ep93xx_i2s_driver); -} - -module_init(ep93xx_i2s_init); -module_exit(ep93xx_i2s_exit); +module_platform_driver(ep93xx_i2s_driver); MODULE_ALIAS("platform:ep93xx-i2s"); MODULE_AUTHOR("Ryan Mallon"); diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index d00230a591b..3fc96130d1a 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c @@ -286,7 +286,6 @@ static u64 ep93xx_pcm_dmamask = 0xffffffff; static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -295,14 +294,14 @@ static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = ep93xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) return ret; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = ep93xx_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -339,18 +338,7 @@ static struct platform_driver ep93xx_pcm_driver = { .remove = __devexit_p(ep93xx_soc_platform_remove), }; -static int __init ep93xx_soc_platform_init(void) -{ - return platform_driver_register(&ep93xx_pcm_driver); -} - -static void __exit ep93xx_soc_platform_exit(void) -{ - platform_driver_unregister(&ep93xx_pcm_driver); -} - -module_init(ep93xx_soc_platform_init); -module_exit(ep93xx_soc_platform_exit); +module_platform_driver(ep93xx_pcm_driver); MODULE_AUTHOR("Ryan Mallon"); MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c index 968cb316d51..dd997094eb3 100644 --- a/sound/soc/ep93xx/simone.c +++ b/sound/soc/ep93xx/simone.c @@ -34,6 +34,7 @@ static struct snd_soc_dai_link simone_dai = { static struct snd_soc_card snd_soc_simone = { .name = "Sim.One", + .owner = THIS_MODULE, .dai_link = &simone_dai, .num_links = 1, }; @@ -81,17 +82,7 @@ static struct platform_driver simone_driver = { .remove = __devexit_p(simone_remove), }; -static int __init simone_init(void) -{ - return platform_driver_register(&simone_driver); -} -module_init(simone_init); - -static void __exit simone_exit(void) -{ - platform_driver_unregister(&simone_driver); -} -module_exit(simone_exit); +module_platform_driver(simone_driver); MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index 2cde43321ee..ccae34a3f28 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -33,16 +33,6 @@ static int snappercl15_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int err; - err = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBS_CFS); - - err = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBS_CFS); - if (err) - return err; - err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); if (err) @@ -96,11 +86,14 @@ static struct snd_soc_dai_link snappercl15_dai = { .codec_name = "tlv320aic23-codec.0-001a", .platform_name = "ep93xx-pcm-audio", .init = snappercl15_tlv320aic23_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &snappercl15_ops, }; static struct snd_soc_card snd_soc_snappercl15 = { .name = "Snapper CL15", + .owner = THIS_MODULE, .dai_link = &snappercl15_dai, .num_links = 1, }; @@ -147,18 +140,7 @@ static struct platform_driver snappercl15_driver = { .remove = __devexit_p(snappercl15_remove), }; -static int __init snappercl15_init(void) -{ - return platform_driver_register(&snappercl15_driver); -} - -static void __exit snappercl15_exit(void) -{ - platform_driver_unregister(&snappercl15_driver); -} - -module_init(snappercl15_init); -module_exit(snappercl15_exit); +module_platform_driver(snappercl15_driver); MODULE_AUTHOR("Ryan Mallon"); MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c index 108b5d8bd0e..b2acd3293ea 100644 --- a/sound/soc/fsl/efika-audio-fabric.c +++ b/sound/soc/fsl/efika-audio-fabric.c @@ -31,8 +31,6 @@ #define DRV_NAME "efika-audio-fabric" -static struct snd_soc_card card; - static struct snd_soc_dai_link efika_fabric_dai[] = { { .name = "AC97", @@ -52,6 +50,13 @@ static struct snd_soc_dai_link efika_fabric_dai[] = { }, }; +static struct snd_soc_card card = { + .name = "Efika", + .owner = THIS_MODULE, + .dai_link = efika_fabric_dai, + .num_links = ARRAY_SIZE(efika_fabric_dai), +}; + static __init int efika_fabric_init(void) { struct platform_device *pdev; @@ -60,11 +65,6 @@ static __init int efika_fabric_init(void) if (!of_machine_is_compatible("bplan,efika")) return -ENODEV; - card.name = "Efika"; - card.dai_link = efika_fabric_dai; - card.num_links = ARRAY_SIZE(efika_fabric_dai); - - pdev = platform_device_alloc("soc-audio", 1); if (!pdev) { pr_err("efika_fabric_init: platform_device_alloc() failed\n"); diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index ef15402a3bc..4f59bbaba48 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -992,20 +992,7 @@ static struct platform_driver fsl_soc_dma_driver = { .remove = __devexit_p(fsl_soc_dma_remove), }; -static int __init fsl_soc_dma_init(void) -{ - pr_info("Freescale Elo DMA ASoC PCM Driver\n"); - - return platform_driver_register(&fsl_soc_dma_driver); -} - -static void __exit fsl_soc_dma_exit(void) -{ - platform_driver_unregister(&fsl_soc_dma_driver); -} - -module_init(fsl_soc_dma_init); -module_exit(fsl_soc_dma_exit); +module_platform_driver(fsl_soc_dma_driver); MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM Driver"); diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 0268cf98973..3e066966d87 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -514,7 +514,7 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, } } -static struct snd_soc_dai_ops fsl_ssi_dai_ops = { +static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { .startup = fsl_ssi_startup, .hw_params = fsl_ssi_hw_params, .shutdown = fsl_ssi_shutdown, @@ -694,6 +694,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) /* Initialize the the device_attribute structure */ dev_attr = &ssi_private->dev_attr; + sysfs_attr_init(&dev_attr->attr); dev_attr->attr.name = "statistics"; dev_attr->attr.mode = S_IRUGO; dev_attr->show = fsl_sysfs_ssi_show; @@ -792,20 +793,7 @@ static struct platform_driver fsl_ssi_driver = { .remove = fsl_ssi_remove, }; -static int __init fsl_ssi_init(void) -{ - printk(KERN_INFO "Freescale Synchronous Serial Interface (SSI) ASoC Driver\n"); - - return platform_driver_register(&fsl_ssi_driver); -} - -static void __exit fsl_ssi_exit(void) -{ - platform_driver_unregister(&fsl_ssi_driver); -} - -module_init(fsl_ssi_init); -module_exit(fsl_ssi_exit); +module_platform_driver(fsl_ssi_driver); MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 5c6c2457386..e7803d34c42 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -526,17 +526,7 @@ static struct platform_driver mpc5200_hpcd_of_driver = { } }; -static int __init mpc5200_hpcd_init(void) -{ - return platform_driver_register(&mpc5200_hpcd_of_driver); -} -module_init(mpc5200_hpcd_init); - -static void __exit mpc5200_hpcd_exit(void) -{ - platform_driver_unregister(&mpc5200_hpcd_of_driver); -} -module_exit(mpc5200_hpcd_exit); +module_platform_driver(mpc5200_hpcd_of_driver); MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c index ad36b095bb7..ffa00a2eb77 100644 --- a/sound/soc/fsl/mpc5200_psc_ac97.c +++ b/sound/soc/fsl/mpc5200_psc_ac97.c @@ -226,12 +226,12 @@ static int psc_ac97_probe(struct snd_soc_dai *cpu_dai) /** * psc_ac97_dai_template: template CPU Digital Audio Interface */ -static struct snd_soc_dai_ops psc_ac97_analog_ops = { +static const struct snd_soc_dai_ops psc_ac97_analog_ops = { .hw_params = psc_ac97_hw_analog_params, .trigger = psc_ac97_trigger, }; -static struct snd_soc_dai_ops psc_ac97_digital_ops = { +static const struct snd_soc_dai_ops psc_ac97_digital_ops = { .hw_params = psc_ac97_hw_digital_params, }; @@ -325,21 +325,7 @@ static struct platform_driver psc_ac97_driver = { }, }; -/* --------------------------------------------------------------------- - * Module setup and teardown; simply register the of_platform driver - * for the PSC in AC97 mode. - */ -static int __init psc_ac97_init(void) -{ - return platform_driver_register(&psc_ac97_driver); -} -module_init(psc_ac97_init); - -static void __exit psc_ac97_exit(void) -{ - platform_driver_unregister(&psc_ac97_driver); -} -module_exit(psc_ac97_exit); +module_platform_driver(psc_ac97_driver); MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>"); MODULE_DESCRIPTION("mpc5200 AC97 module"); diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 87cf2a5c2b2..7b530327553 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -123,7 +123,7 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) /** * psc_i2s_dai_template: template CPU Digital Audio Interface */ -static struct snd_soc_dai_ops psc_i2s_dai_ops = { +static const struct snd_soc_dai_ops psc_i2s_dai_ops = { .hw_params = psc_i2s_hw_params, .set_sysclk = psc_i2s_set_sysclk, .set_fmt = psc_i2s_set_fmt, @@ -222,21 +222,7 @@ static struct platform_driver psc_i2s_driver = { }, }; -/* --------------------------------------------------------------------- - * Module setup and teardown; simply register the of_platform driver - * for the PSC in I2S mode. - */ -static int __init psc_i2s_init(void) -{ - return platform_driver_register(&psc_i2s_driver); -} -module_init(psc_i2s_init); - -static void __exit psc_i2s_exit(void) -{ - platform_driver_unregister(&psc_i2s_driver); -} -module_exit(psc_i2s_exit); +module_platform_driver(psc_i2s_driver); MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver"); diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 31af405bda8..0ea4a5a96e0 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c @@ -14,6 +14,7 @@ #include <linux/interrupt.h> #include <linux/of_device.h> #include <linux/slab.h> +#include <linux/of_i2c.h> #include <sound/soc.h> #include <asm/fsl_guts.h> @@ -249,8 +250,9 @@ static int get_parent_cell_index(struct device_node *np) static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) { const u32 *iprop; - int bus, addr; + int addr; char temp[DAI_NAME_SIZE]; + struct i2c_client *i2c; of_modalias_node(np, temp, DAI_NAME_SIZE); @@ -260,11 +262,12 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) addr = be32_to_cpup(iprop); - bus = get_parent_cell_index(np); - if (bus < 0) - return bus; + /* We need the adapter number */ + i2c = of_find_i2c_device_by_node(np); + if (!i2c) + return -ENODEV; - snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr); + snprintf(buf, len, "%s-codec.%u-%04x", temp, i2c->adapter->nr, addr); return 0; } @@ -392,7 +395,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) } if (strcasecmp(sprop, "i2s-slave") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_I2S; + machine_data->dai_format = + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; @@ -409,31 +413,38 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) } machine_data->clk_frequency = be32_to_cpup(iprop); } else if (strcasecmp(sprop, "i2s-master") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_I2S; + machine_data->dai_format = + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "lj-slave") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; + machine_data->dai_format = + SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "lj-master") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; + machine_data->dai_format = + SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "rj-slave") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; + machine_data->dai_format = + SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "rj-master") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; + machine_data->dai_format = + SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "ac97-slave") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_AC97; + machine_data->dai_format = + SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "ac97-master") == 0) { - machine_data->dai_format = SND_SOC_DAIFMT_AC97; + machine_data->dai_format = + SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else { diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index 2c064a9824a..a5d4e80a9cf 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -14,6 +14,7 @@ #include <linux/interrupt.h> #include <linux/of_device.h> #include <linux/slab.h> +#include <linux/of_i2c.h> #include <sound/soc.h> #include <asm/fsl_guts.h> @@ -252,8 +253,9 @@ static int get_parent_cell_index(struct device_node *np) static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) { const u32 *iprop; - int bus, addr; + int addr; char temp[DAI_NAME_SIZE]; + struct i2c_client *i2c; of_modalias_node(np, temp, DAI_NAME_SIZE); @@ -263,11 +265,12 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) addr = be32_to_cpup(iprop); - bus = get_parent_cell_index(np); - if (bus < 0) - return bus; + /* We need the adapter number */ + i2c = of_find_i2c_device_by_node(np); + if (!i2c) + return -ENODEV; - snprintf(buf, len, "%s.%u-%04x", temp, bus, addr); + snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr); return 0; } @@ -540,12 +543,6 @@ static struct platform_driver p1022_ds_driver = { .probe = p1022_ds_probe, .remove = __devexit_p(p1022_ds_remove), .driver = { - /* The name must match the 'model' property in the device tree, - * in lowercase letters, but only the part after that last - * comma. This is because some model properties have a "fsl," - * prefix. - */ - .name = "snd-soc-p1022", .owner = THIS_MODULE, }, }; @@ -559,13 +556,39 @@ static int __init p1022_ds_init(void) { struct device_node *guts_np; struct resource res; + const char *sprop; + + /* + * Check if we're actually running on a P1022DS. Older device trees + * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we + * need to support both. The SSI driver uses that property to link to + * the machine driver, so have to match it. + */ + sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); + if (!sprop) { + pr_err("snd-soc-p1022ds: missing /model node"); + return -ENODEV; + } + + pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop); - pr_info("Freescale P1022 DS ALSA SoC machine driver\n"); + /* + * The name of this board, taken from the device tree. Normally, this is a* + * fixed string, but some P1022DS device trees have a /model property of + * "fsl,P1022", and others have "fsl,P1022DS". + */ + if (strcasecmp(sprop, "fsl,p1022ds") == 0) + p1022_ds_driver.driver.name = "snd-soc-p1022ds"; + else if (strcasecmp(sprop, "fsl,p1022") == 0) + p1022_ds_driver.driver.name = "snd-soc-p1022"; + else + return -ENODEV; /* Get the physical address of the global utilities registers */ guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); if (of_address_to_resource(guts_np, 0, &res)) { - pr_err("p1022-ds: missing/invalid global utilities node\n"); + pr_err("snd-soc-p1022ds: missing/invalid global utils node\n"); + of_node_put(guts_np); return -EINVAL; } guts_phys = res.start; diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index ba4d85e317e..b3af55dcde9 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -31,8 +31,6 @@ #define DRV_NAME "pcm030-audio-fabric" -static struct snd_soc_card card; - static struct snd_soc_dai_link pcm030_fabric_dai[] = { { .name = "AC97", @@ -52,6 +50,13 @@ static struct snd_soc_dai_link pcm030_fabric_dai[] = { }, }; +static struct snd_soc_card card = { + .name = "pcm030", + .owner = THIS_MODULE, + .dai_link = pcm030_fabric_dai, + .num_links = ARRAY_SIZE(pcm030_fabric_dai), +}; + static __init int pcm030_fabric_init(void) { struct platform_device *pdev; @@ -60,11 +65,6 @@ static __init int pcm030_fabric_init(void) if (!of_machine_is_compatible("phytec,pcm030")) return -ENODEV; - - card.name = "pcm030"; - card.dai_link = pcm030_fabric_dai; - card.num_links = ARRAY_SIZE(pcm030_fabric_dai); - pdev = platform_device_alloc("soc-audio", 1); if (!pdev) { pr_err("pcm030_fabric_init: platform_device_alloc() failed\n"); diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index b133bfcc584..738391757f2 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig @@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1 config SND_SOC_MX27VIS_AIC32X4 tristate "SoC audio support for Visstrim M10 boards" - depends on MACH_IMX27_VISSTRIM_M10 + depends on MACH_IMX27_VISSTRIM_M10 && I2C select SND_SOC_TLV320AIC32X4 select SND_MXC_SOC_MX2 help diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index 75fb4b83548..1c1fdd10f73 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c @@ -87,6 +87,7 @@ static struct snd_soc_dai_link eukrea_tlv320_dai = { static struct snd_soc_card eukrea_tlv320 = { .name = "cpuimx-audio", + .owner = THIS_MODULE, .dai_link = &eukrea_tlv320_dai, .num_links = 1, }; diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 43fdc24f7e8..1cf2fe889f6 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c @@ -326,16 +326,6 @@ static struct platform_driver imx_pcm_driver = { .remove = __devexit_p(imx_soc_platform_remove), }; -static int __init snd_imx_pcm_init(void) -{ - return platform_driver_register(&imx_pcm_driver); -} -module_init(snd_imx_pcm_init); - -static void __exit snd_imx_pcm_exit(void) -{ - platform_driver_unregister(&imx_pcm_driver); -} -module_exit(snd_imx_pcm_exit); +module_platform_driver(imx_pcm_driver); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:imx-pcm-audio"); diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index 8df0fae2194..456b7d723d6 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c @@ -331,14 +331,6 @@ static struct platform_driver imx_pcm_driver = { .remove = __devexit_p(imx_soc_platform_remove), }; -static int __init snd_imx_pcm_init(void) -{ - return platform_driver_register(&imx_pcm_driver); -} -module_init(snd_imx_pcm_init); +module_platform_driver(imx_pcm_driver); -static void __exit snd_imx_pcm_exit(void) -{ - platform_driver_unregister(&imx_pcm_driver); -} -module_exit(snd_imx_pcm_exit); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 4c05e2b8f4d..01d1f749cf0 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -342,7 +342,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, return 0; } -static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { +static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { .hw_params = imx_ssi_hw_params, .set_fmt = imx_ssi_set_dai_fmt, .set_clkdiv = imx_ssi_set_dai_clkdiv, @@ -757,18 +757,7 @@ static struct platform_driver imx_ssi_driver = { }, }; -static int __init imx_ssi_init(void) -{ - return platform_driver_register(&imx_ssi_driver); -} - -static void __exit imx_ssi_exit(void) -{ - platform_driver_unregister(&imx_ssi_driver); -} - -module_init(imx_ssi_init); -module_exit(imx_ssi_exit); +module_platform_driver(imx_ssi_driver); /* Module information */ MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>"); diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c index 054110b91d4..3c2eed9094d 100644 --- a/sound/soc/imx/mx27vis-aic32x4.c +++ b/sound/soc/imx/mx27vis-aic32x4.c @@ -86,6 +86,7 @@ static struct snd_soc_dai_link mx27vis_aic32x4_dai = { static struct snd_soc_card mx27vis_aic32x4 = { .name = "visstrim_m10-audio", + .owner = THIS_MODULE, .dai_link = &mx27vis_aic32x4_dai, .num_links = 1, }; diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index a7deb5cb243..6ac12111de6 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c @@ -38,6 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { static struct snd_soc_card imx_phycore = { .name = "PhyCORE-ac97-audio", + .owner = THIS_MODULE, .dai_link = imx_phycore_dai_ac97, .num_links = ARRAY_SIZE(imx_phycore_dai_ac97), }; diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 490a1260c22..37480c90e99 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c @@ -255,6 +255,7 @@ static struct snd_soc_dai_link wm1133_ev1_dai = { static struct snd_soc_card wm1133_ev1 = { .name = "WM1133-EV1", + .owner = THIS_MODULE, .dai_link = &wm1133_ev1_dai, .num_links = 1, }; diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index cd22a54b2f1..a5af7c42e62 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -392,7 +392,7 @@ static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops jz4740_i2s_dai_ops = { +static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = { .startup = jz4740_i2s_startup, .shutdown = jz4740_i2s_shutdown, .trigger = jz4740_i2s_trigger, @@ -519,17 +519,7 @@ static struct platform_driver jz4740_i2s_driver = { }, }; -static int __init jz4740_i2s_init(void) -{ - return platform_driver_register(&jz4740_i2s_driver); -} -module_init(jz4740_i2s_init); - -static void __exit jz4740_i2s_exit(void) -{ - platform_driver_unregister(&jz4740_i2s_driver); -} -module_exit(jz4740_i2s_exit); +module_platform_driver(jz4740_i2s_driver); MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>"); MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver"); diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c index d1989cde9f1..9b8cf256847 100644 --- a/sound/soc/jz4740/jz4740-pcm.c +++ b/sound/soc/jz4740/jz4740-pcm.c @@ -302,7 +302,6 @@ static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -312,14 +311,14 @@ static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = jz4740_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto err; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = jz4740_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -356,17 +355,7 @@ static struct platform_driver jz4740_pcm_driver = { }, }; -static int __init jz4740_soc_platform_init(void) -{ - return platform_driver_register(&jz4740_pcm_driver); -} -module_init(jz4740_soc_platform_init); - -static void __exit jz4740_soc_platform_exit(void) -{ - return platform_driver_unregister(&jz4740_pcm_driver); -} -module_exit(jz4740_soc_platform_exit); +module_platform_driver(jz4740_pcm_driver); MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); MODULE_DESCRIPTION("Ingenic SoC JZ4740 PCM driver"); diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index c5fc339f68f..0097c3b13a1 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -81,6 +81,7 @@ static struct snd_soc_dai_link qi_lb60_dai = { static struct snd_soc_card qi_lb60 = { .name = "QI LB60", + .owner = THIS_MODULE, .dai_link = &qi_lb60_dai, .num_links = 1, diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 8f49e165f4d..c62d715235e 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig @@ -12,6 +12,7 @@ config SND_KIRKWOOD_SOC_I2S config SND_KIRKWOOD_SOC_OPENRD tristate "SoC Audio support for Kirkwood Openrd Client" depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) + depends on I2C select SND_KIRKWOOD_SOC_I2S select SND_SOC_CS42L51 help @@ -20,7 +21,7 @@ config SND_KIRKWOOD_SOC_OPENRD config SND_KIRKWOOD_SOC_T5325 tristate "SoC Audio support for HP t5325" - depends on SND_KIRKWOOD_SOC && MACH_T5325 + depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C select SND_KIRKWOOD_SOC_I2S select SND_SOC_ALC5623 help diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index cd33de1c5b7..d0385402712 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c @@ -94,9 +94,10 @@ static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static void kirkwood_dma_conf_mbus_windows(void __iomem *base, int win, - unsigned long dma, - struct mbus_dram_target_info *dram) +static void +kirkwood_dma_conf_mbus_windows(void __iomem *base, int win, + unsigned long dma, + const struct mbus_dram_target_info *dram) { int i; @@ -106,7 +107,7 @@ static void kirkwood_dma_conf_mbus_windows(void __iomem *base, int win, /* try to find matching cs for current dma address */ for (i = 0; i < dram->num_cs; i++) { - struct mbus_dram_window *cs = dram->cs + i; + const struct mbus_dram_window *cs = dram->cs + i; if ((cs->base & 0xffff0000) < (dma & 0xffff0000)) { writel(cs->base & 0xffff0000, base + KIRKWOOD_AUDIO_WIN_BASE_REG(win)); @@ -127,6 +128,7 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) struct snd_soc_dai *cpu_dai = soc_runtime->cpu_dai; struct kirkwood_dma_data *priv; struct kirkwood_dma_priv *prdata = snd_soc_platform_get_drvdata(platform); + const struct mbus_dram_target_info *dram; unsigned long addr; priv = snd_soc_dai_get_dma_data(cpu_dai, substream); @@ -175,15 +177,16 @@ static int kirkwood_dma_open(struct snd_pcm_substream *substream) writel((unsigned long)-1, priv->io + KIRKWOOD_ERR_MASK); } + dram = mv_mbus_dram_info(); addr = virt_to_phys(substream->dma_buffer.area); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { prdata->play_stream = substream; kirkwood_dma_conf_mbus_windows(priv->io, - KIRKWOOD_PLAYBACK_WIN, addr, priv->dram); + KIRKWOOD_PLAYBACK_WIN, addr, dram); } else { prdata->rec_stream = substream; kirkwood_dma_conf_mbus_windows(priv->io, - KIRKWOOD_RECORD_WIN, addr, priv->dram); + KIRKWOOD_RECORD_WIN, addr, dram); } return 0; @@ -315,7 +318,6 @@ static int kirkwood_dma_preallocate_dma_buffer(struct snd_pcm *pcm, static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret; @@ -324,14 +326,14 @@ static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = kirkwood_dma_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) return ret; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = kirkwood_dma_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -388,17 +390,7 @@ static struct platform_driver kirkwood_pcm_driver = { .remove = __devexit_p(kirkwood_soc_platform_remove), }; -static int __init kirkwood_pcm_init(void) -{ - return platform_driver_register(&kirkwood_pcm_driver); -} -module_init(kirkwood_pcm_init); - -static void __exit kirkwood_pcm_exit(void) -{ - platform_driver_unregister(&kirkwood_pcm_driver); -} -module_exit(kirkwood_pcm_exit); +module_platform_driver(kirkwood_pcm_driver); MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); MODULE_DESCRIPTION("Marvell Kirkwood Audio DMA module"); diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index 715e841c050..3cb9aa4299d 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -373,7 +373,7 @@ static int kirkwood_i2s_remove(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { +static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = { .startup = kirkwood_i2s_startup, .trigger = kirkwood_i2s_trigger, .hw_params = kirkwood_i2s_hw_params, @@ -441,13 +441,12 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) goto err_ioremap; } - if (!data || !data->dram) { + if (!data) { dev_err(&pdev->dev, "no platform data ?!\n"); err = -EINVAL; goto err_ioremap; } - priv->dram = data->dram; priv->burst = data->burst; return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); @@ -483,17 +482,7 @@ static struct platform_driver kirkwood_i2s_driver = { }, }; -static int __init kirkwood_i2s_init(void) -{ - return platform_driver_register(&kirkwood_i2s_driver); -} -module_init(kirkwood_i2s_init); - -static void __exit kirkwood_i2s_exit(void) -{ - platform_driver_unregister(&kirkwood_i2s_driver); -} -module_exit(kirkwood_i2s_exit); +module_platform_driver(kirkwood_i2s_driver); /* Module information */ MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>"); diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c index d863afb3ee5..55d2ed3df30 100644 --- a/sound/soc/kirkwood/kirkwood-openrd.c +++ b/sound/soc/kirkwood/kirkwood-openrd.c @@ -26,18 +26,7 @@ static int openrd_client_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret; - unsigned int freq, fmt; - - fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(codec_dai, fmt); - if (ret < 0) - return ret; + unsigned int freq; switch (params_rate(params)) { default: @@ -69,6 +58,7 @@ static struct snd_soc_dai_link openrd_client_dai[] = { .platform_name = "kirkwood-pcm-audio", .codec_dai_name = "cs42l51-hifi", .codec_name = "cs42l51-codec.0-004a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, .ops = &openrd_client_ops, }, }; @@ -76,6 +66,7 @@ static struct snd_soc_dai_link openrd_client_dai[] = { static struct snd_soc_card openrd_client = { .name = "OpenRD Client", + .owner = THIS_MODULE, .dai_link = openrd_client_dai, .num_links = ARRAY_SIZE(openrd_client_dai), }; diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index c772b3cf403..b47cc4e9b74 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -25,18 +25,7 @@ static int t5325_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret; - unsigned int freq, fmt; - - fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; - ret = snd_soc_dai_set_fmt(cpu_dai, fmt); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(codec_dai, fmt); - if (ret < 0) - return ret; + unsigned int freq; freq = params_rate(params) * 256; @@ -70,11 +59,6 @@ static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets, - ARRAY_SIZE(t5325_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route)); - snd_soc_dapm_enable_pin(dapm, "Mic Jack"); snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); snd_soc_dapm_enable_pin(dapm, "Speaker"); @@ -90,6 +74,7 @@ static struct snd_soc_dai_link t5325_dai[] = { .platform_name = "kirkwood-pcm-audio", .codec_dai_name = "alc5621-hifi", .codec_name = "alc562x-codec.0-001a", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, .ops = &t5325_ops, .init = t5325_dai_init, }, @@ -98,8 +83,14 @@ static struct snd_soc_dai_link t5325_dai[] = { static struct snd_soc_card t5325 = { .name = "t5325", + .owner = THIS_MODULE, .dai_link = t5325_dai, .num_links = ARRAY_SIZE(t5325_dai), + + .dapm_widgets = t5325_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(t5325_dapm_widgets), + .dapm_routes = t5325_route, + .num_dapm_routes = ARRAY_SIZE(t5325_route), }; static struct platform_device *t5325_snd_device; diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h index bb6e6a5648c..9047436b393 100644 --- a/sound/soc/kirkwood/kirkwood.h +++ b/sound/soc/kirkwood/kirkwood.h @@ -123,7 +123,6 @@ struct kirkwood_dma_data { void __iomem *io; int irq; int burst; - struct mbus_dram_target_info *dram; }; #endif diff --git a/sound/soc/mid-x86/Kconfig b/sound/soc/mid-x86/Kconfig index 29350428f1c..61c10bf503d 100644 --- a/sound/soc/mid-x86/Kconfig +++ b/sound/soc/mid-x86/Kconfig @@ -1,7 +1,6 @@ config SND_MFLD_MACHINE tristate "SOC Machine Audio driver for Intel Medfield MID platform" depends on INTEL_SCU_IPC - depends on SND_INTEL_SST select SND_SOC_SN95031 select SND_SST_PLATFORM help diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index cca693ae1bd..6f77eef0f13 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c @@ -281,7 +281,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) return ret_val; } -struct snd_soc_dai_link mfld_msic_dailink[] = { +static struct snd_soc_dai_link mfld_msic_dailink[] = { { .name = "Medfield Headset", .stream_name = "Headset", @@ -323,6 +323,7 @@ struct snd_soc_dai_link mfld_msic_dailink[] = { /* SoC card */ static struct snd_soc_card snd_soc_card_mfld = { .name = "medfield_audio", + .owner = THIS_MODULE, .dai_link = mfld_msic_dailink, .num_links = ARRAY_SIZE(mfld_msic_dailink), }; @@ -428,19 +429,7 @@ static struct platform_driver snd_mfld_mc_driver = { .remove = __devexit_p(snd_mfld_mc_remove), }; -static int __init snd_mfld_driver_init(void) -{ - pr_debug("snd_mfld_driver_init called\n"); - return platform_driver_register(&snd_mfld_mc_driver); -} -module_init(snd_mfld_driver_init); - -static void __exit snd_mfld_driver_exit(void) -{ - pr_debug("snd_mfld_driver_exit called\n"); - platform_driver_unregister(&snd_mfld_mc_driver); -} -module_exit(snd_mfld_driver_exit); +module_platform_driver(snd_mfld_mc_driver); MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver"); MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 23057020aa0..d34563b12c3 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c @@ -32,10 +32,51 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include "../../../drivers/staging/intel_sst/intel_sst_ioctl.h" -#include "../../../drivers/staging/intel_sst/intel_sst.h" #include "sst_platform.h" +static struct sst_device *sst; +static DEFINE_MUTEX(sst_lock); + +int sst_register_dsp(struct sst_device *dev) +{ + BUG_ON(!dev); + if (!try_module_get(dev->dev->driver->owner)) + return -ENODEV; + mutex_lock(&sst_lock); + if (sst) { + pr_err("we already have a device %s\n", sst->name); + module_put(dev->dev->driver->owner); + mutex_unlock(&sst_lock); + return -EEXIST; + } + pr_debug("registering device %s\n", dev->name); + sst = dev; + mutex_unlock(&sst_lock); + return 0; +} +EXPORT_SYMBOL_GPL(sst_register_dsp); + +int sst_unregister_dsp(struct sst_device *dev) +{ + BUG_ON(!dev); + if (dev != sst) + return -EINVAL; + + mutex_lock(&sst_lock); + + if (!sst) { + mutex_unlock(&sst_lock); + return -EIO; + } + + module_put(sst->dev->driver->owner); + pr_debug("unreg %s\n", sst->name); + sst = NULL; + mutex_unlock(&sst_lock); + return 0; +} +EXPORT_SYMBOL_GPL(sst_unregister_dsp); + static struct snd_pcm_hardware sst_platform_pcm_hw = { .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_DOUBLE | @@ -135,37 +176,34 @@ static inline int sst_get_stream_status(struct sst_runtime_stream *stream) } static void sst_fill_pcm_params(struct snd_pcm_substream *substream, - struct snd_sst_stream_params *param) + struct sst_pcm_params *param) { - param->uc.pcm_params.codec = SST_CODEC_TYPE_PCM; - param->uc.pcm_params.num_chan = (u8) substream->runtime->channels; - param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits; - param->uc.pcm_params.reserved = 0; - param->uc.pcm_params.sfreq = substream->runtime->rate; - param->uc.pcm_params.ring_buffer_size = - snd_pcm_lib_buffer_bytes(substream); - param->uc.pcm_params.period_count = substream->runtime->period_size; - param->uc.pcm_params.ring_buffer_addr = - virt_to_phys(substream->dma_buffer.area); - pr_debug("period_cnt = %d\n", param->uc.pcm_params.period_count); - pr_debug("sfreq= %d, wd_sz = %d\n", - param->uc.pcm_params.sfreq, param->uc.pcm_params.pcm_wd_sz); + param->codec = SST_CODEC_TYPE_PCM; + param->num_chan = (u8) substream->runtime->channels; + param->pcm_wd_sz = substream->runtime->sample_bits; + param->reserved = 0; + param->sfreq = substream->runtime->rate; + param->ring_buffer_size = snd_pcm_lib_buffer_bytes(substream); + param->period_count = substream->runtime->period_size; + param->ring_buffer_addr = virt_to_phys(substream->dma_buffer.area); + pr_debug("period_cnt = %d\n", param->period_count); + pr_debug("sfreq= %d, wd_sz = %d\n", param->sfreq, param->pcm_wd_sz); } static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) { struct sst_runtime_stream *stream = substream->runtime->private_data; - struct snd_sst_stream_params param = {{{0,},},}; - struct snd_sst_params str_params = {0}; + struct sst_pcm_params param = {0}; + struct sst_stream_params str_params = {0}; int ret_val; /* set codec params and inform SST driver the same */ sst_fill_pcm_params(substream, ¶m); substream->runtime->dma_area = substream->dma_buffer.area; str_params.sparams = param; - str_params.codec = param.uc.pcm_params.codec; + str_params.codec = param.codec; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { str_params.ops = STREAM_OPS_PLAYBACK; str_params.device_type = substream->pcm->device + 1; @@ -177,7 +215,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream) pr_debug("Capture stream,Device %d\n", substream->pcm->device); } - ret_val = stream->sstdrv_ops->pcm_control->open(&str_params); + ret_val = stream->ops->open(&str_params); pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); if (ret_val < 0) return ret_val; @@ -216,7 +254,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) stream->stream_info.mad_substream = substream; stream->stream_info.buffer_ptr = 0; stream->stream_info.sfreq = substream->runtime->rate; - ret_val = stream->sstdrv_ops->pcm_control->device_control( + ret_val = stream->ops->device_control( SST_SND_STREAM_INIT, &stream->stream_info); if (ret_val) pr_err("control_set ret error %d\n", ret_val); @@ -229,7 +267,7 @@ static int sst_platform_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct sst_runtime_stream *stream; - int ret_val = 0; + int ret_val; pr_debug("sst_platform_open called\n"); @@ -243,27 +281,27 @@ static int sst_platform_open(struct snd_pcm_substream *substream) if (!stream) return -ENOMEM; spin_lock_init(&stream->status_lock); - stream->stream_info.str_id = 0; - sst_set_stream_status(stream, SST_PLATFORM_INIT); - stream->stream_info.mad_substream = substream; - /* allocate memory for SST API set */ - stream->sstdrv_ops = kzalloc(sizeof(*stream->sstdrv_ops), - GFP_KERNEL); - if (!stream->sstdrv_ops) { - pr_err("sst: mem allocation for ops fail\n"); + + /* get the sst ops */ + mutex_lock(&sst_lock); + if (!sst) { + pr_err("no device available to run\n"); + mutex_unlock(&sst_lock); kfree(stream); - return -ENOMEM; + return -ENODEV; } - stream->sstdrv_ops->vendor_id = MSIC_VENDOR_ID; - stream->sstdrv_ops->module_name = SST_CARD_NAMES; - /* registering with SST driver to get access to SST APIs to use */ - ret_val = register_sst_card(stream->sstdrv_ops); - if (ret_val) { - pr_err("sst: sst card registration failed\n"); - kfree(stream->sstdrv_ops); + if (!try_module_get(sst->dev->driver->owner)) { + mutex_unlock(&sst_lock); kfree(stream); - return ret_val; + return -ENODEV; } + stream->ops = sst->ops; + mutex_unlock(&sst_lock); + + stream->stream_info.str_id = 0; + sst_set_stream_status(stream, SST_PLATFORM_INIT); + stream->stream_info.mad_substream = substream; + /* allocate memory for SST API set */ runtime->private_data = stream; return 0; @@ -278,9 +316,8 @@ static int sst_platform_close(struct snd_pcm_substream *substream) stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (str_id) - ret_val = stream->sstdrv_ops->pcm_control->close(str_id); - unregister_sst_card(stream->sstdrv_ops); - kfree(stream->sstdrv_ops); + ret_val = stream->ops->close(str_id); + module_put(sst->dev->driver->owner); kfree(stream); return ret_val; } @@ -294,8 +331,8 @@ static int sst_platform_pcm_prepare(struct snd_pcm_substream *substream) stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (stream->stream_info.str_id) { - ret_val = stream->sstdrv_ops->pcm_control->device_control( - SST_SND_DROP, &str_id); + ret_val = stream->ops->device_control( + SST_SND_DROP, &str_id); return ret_val; } @@ -347,8 +384,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, default: return -EINVAL; } - ret_val = stream->sstdrv_ops->pcm_control->device_control(str_cmd, - &str_id); + ret_val = stream->ops->device_control(str_cmd, &str_id); if (!ret_val) sst_set_stream_status(stream, status); @@ -368,7 +404,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer if (status == SST_PLATFORM_INIT) return 0; str_info = &stream->stream_info; - ret_val = stream->sstdrv_ops->pcm_control->device_control( + ret_val = stream->ops->device_control( SST_SND_BUFFER_POINTER, str_info); if (ret_val) { pr_err("sst: error code = %d\n", ret_val); @@ -408,15 +444,14 @@ static void sst_pcm_free(struct snd_pcm *pcm) snd_pcm_lib_preallocate_free_for_all(pcm); } -int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) +static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int retval = 0; pr_debug("sst_pcm_new called\n"); - if (dai->driver->playback.channels_min || - dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || + pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, snd_dma_continuous_data(GFP_KERNEL), @@ -428,7 +463,7 @@ int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) } return retval; } -struct snd_soc_platform_driver sst_soc_platform_drv = { +static struct snd_soc_platform_driver sst_soc_platform_drv = { .ops = &sst_platform_ops, .pcm_new = sst_pcm_new, .pcm_free = sst_pcm_free, @@ -439,6 +474,7 @@ static int sst_platform_probe(struct platform_device *pdev) int ret; pr_debug("sst_platform_probe called\n"); + sst = NULL; ret = snd_soc_register_platform(&pdev->dev, &sst_soc_platform_drv); if (ret) { pr_err("registering soc platform failed\n"); @@ -472,19 +508,7 @@ static struct platform_driver sst_platform_driver = { .remove = sst_platform_remove, }; -static int __init sst_soc_platform_init(void) -{ - pr_debug("sst_soc_platform_init called\n"); - return platform_driver_register(&sst_platform_driver); -} -module_init(sst_soc_platform_init); - -static void __exit sst_soc_platform_exit(void) -{ - platform_driver_unregister(&sst_platform_driver); - pr_debug("sst_soc_platform_exit success\n"); -} -module_exit(sst_soc_platform_exit); +module_platform_driver(sst_platform_driver); MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver"); MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h index df370286694..f04f4f72daa 100644 --- a/sound/soc/mid-x86/sst_platform.h +++ b/sound/soc/mid-x86/sst_platform.h @@ -42,14 +42,14 @@ #define SST_MIN_PERIODS 2 #define SST_MAX_PERIODS (1024*2) #define SST_FIFO_SIZE 0 -#define SST_CARD_NAMES "intel_mid_card" -#define MSIC_VENDOR_ID 3 +#define SST_CODEC_TYPE_PCM 1 -struct sst_runtime_stream { - int stream_status; - struct pcm_stream_info stream_info; - struct intel_sst_card_ops *sstdrv_ops; - spinlock_t status_lock; +struct pcm_stream_info { + int str_id; + void *mad_substream; + void (*period_elapsed) (void *mad_substream); + unsigned long long buffer_ptr; + int sfreq; }; enum sst_drv_status { @@ -60,4 +60,72 @@ enum sst_drv_status { SST_PLATFORM_DROPPED, }; +enum sst_controls { + SST_SND_ALLOC = 0x00, + SST_SND_PAUSE = 0x01, + SST_SND_RESUME = 0x02, + SST_SND_DROP = 0x03, + SST_SND_FREE = 0x04, + SST_SND_BUFFER_POINTER = 0x05, + SST_SND_STREAM_INIT = 0x06, + SST_SND_START = 0x07, + SST_MAX_CONTROLS = 0x07, +}; + +enum sst_stream_ops { + STREAM_OPS_PLAYBACK = 0, + STREAM_OPS_CAPTURE, +}; + +enum sst_audio_device_type { + SND_SST_DEVICE_HEADSET = 1, + SND_SST_DEVICE_IHF, + SND_SST_DEVICE_VIBRA, + SND_SST_DEVICE_HAPTIC, + SND_SST_DEVICE_CAPTURE, +}; + +/* PCM Parameters */ +struct sst_pcm_params { + u16 codec; /* codec type */ + u8 num_chan; /* 1=Mono, 2=Stereo */ + u8 pcm_wd_sz; /* 16/24 - bit*/ + u32 reserved; /* Bitrate in bits per second */ + u32 sfreq; /* Sampling rate in Hz */ + u32 ring_buffer_size; + u32 period_count; /* period elapsed in samples*/ + u32 ring_buffer_addr; +}; + +struct sst_stream_params { + u32 result; + u32 stream_id; + u8 codec; + u8 ops; + u8 stream_type; + u8 device_type; + struct sst_pcm_params sparams; +}; + +struct sst_ops { + int (*open) (struct sst_stream_params *str_param); + int (*device_control) (int cmd, void *arg); + int (*close) (unsigned int str_id); +}; + +struct sst_runtime_stream { + int stream_status; + struct pcm_stream_info stream_info; + struct sst_ops *ops; + spinlock_t status_lock; +}; + +struct sst_device { + char *name; + struct device *dev; + struct sst_ops *ops; +}; + +int sst_register_dsp(struct sst_device *sst); +int sst_unregister_dsp(struct sst_device *sst); #endif diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index dea5aa4aa64..0e12f4e0a76 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c @@ -346,14 +346,7 @@ static struct platform_driver mxs_pcm_driver = { .remove = __devexit_p(mxs_soc_platform_remove), }; -static int __init snd_mxs_pcm_init(void) -{ - return platform_driver_register(&mxs_pcm_driver); -} -module_init(snd_mxs_pcm_init); +module_platform_driver(mxs_pcm_driver); -static void __exit snd_mxs_pcm_exit(void) -{ - platform_driver_unregister(&mxs_pcm_driver); -} -module_exit(snd_mxs_pcm_exit); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mxs-pcm-audio"); diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index 76dc74d24fc..dccfb37a962 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c @@ -210,7 +210,7 @@ int mxs_saif_put_mclk(unsigned int saif_id) return -EBUSY; } - clk_disable(saif->clk); + clk_disable_unprepare(saif->clk); /* disable MCLK output */ __raw_writel(BM_SAIF_CTRL_CLKGATE, @@ -264,7 +264,7 @@ int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk, if (ret) return ret; - ret = clk_enable(saif->clk); + ret = clk_prepare_enable(saif->clk); if (ret) return ret; @@ -550,7 +550,7 @@ static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE) -static struct snd_soc_dai_ops mxs_saif_dai_ops = { +static const struct snd_soc_dai_ops mxs_saif_dai_ops = { .startup = mxs_saif_startup, .trigger = mxs_saif_trigger, .prepare = mxs_saif_prepare, @@ -625,13 +625,6 @@ static int mxs_saif_probe(struct platform_device *pdev) if (pdev->id >= ARRAY_SIZE(mxs_saif)) return -EINVAL; - pdata = pdev->dev.platform_data; - if (pdata && pdata->init) { - ret = pdata->init(); - if (ret) - return ret; - } - saif = kzalloc(sizeof(*saif), GFP_KERNEL); if (!saif) return -ENOMEM; @@ -639,12 +632,17 @@ static int mxs_saif_probe(struct platform_device *pdev) mxs_saif[pdev->id] = saif; saif->id = pdev->id; - saif->master_id = saif->id; - if (pdata && pdata->get_master_id) { - saif->master_id = pdata->get_master_id(saif->id); + pdata = pdev->dev.platform_data; + if (pdata && !pdata->master_mode) { + saif->master_id = pdata->master_id; if (saif->master_id < 0 || - saif->master_id >= ARRAY_SIZE(mxs_saif)) + saif->master_id >= ARRAY_SIZE(mxs_saif) || + saif->master_id == saif->id) { + dev_err(&pdev->dev, "get wrong master id\n"); return -EINVAL; + } + } else { + saif->master_id = saif->id; } saif->clk = clk_get(&pdev->dev, NULL); @@ -781,18 +779,8 @@ static struct platform_driver mxs_saif_driver = { }, }; -static int __init mxs_saif_init(void) -{ - return platform_driver_register(&mxs_saif_driver); -} - -static void __exit mxs_saif_exit(void) -{ - platform_driver_unregister(&mxs_saif_driver); -} +module_platform_driver(mxs_saif_driver); -module_init(mxs_saif_init); -module_exit(mxs_saif_exit); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("MXS ASoC SAIF driver"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 7fbeaec06eb..60f052b7cf2 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c @@ -105,6 +105,7 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { static struct snd_soc_card mxs_sgtl5000 = { .name = "mxs_sgtl5000", + .owner = THIS_MODULE, .dai_link = mxs_sgtl5000_dai, .num_links = ARRAY_SIZE(mxs_sgtl5000_dai), }; @@ -156,18 +157,9 @@ static struct platform_driver mxs_sgtl5000_audio_driver = { .remove = __devexit_p(mxs_sgtl5000_remove), }; -static int __init mxs_sgtl5000_init(void) -{ - return platform_driver_register(&mxs_sgtl5000_audio_driver); -} -module_init(mxs_sgtl5000_init); - -static void __exit mxs_sgtl5000_exit(void) -{ - platform_driver_unregister(&mxs_sgtl5000_audio_driver); -} -module_exit(mxs_sgtl5000_exit); +module_platform_driver(mxs_sgtl5000_audio_driver); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_DESCRIPTION("MXS ALSA SoC Machine driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:mxs-sgtl5000"); diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index 9c0edad90d8..45d11ddaeea 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c @@ -291,7 +291,7 @@ static int nuc900_ac97_remove(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops nuc900_ac97_dai_ops = { +static const struct snd_soc_dai_ops nuc900_ac97_dai_ops = { .trigger = nuc900_ac97_trigger, }; @@ -365,7 +365,8 @@ static int __devinit nuc900_ac97_drvprobe(struct platform_device *pdev) if (ret) goto out3; - mfp_set_groupg(nuc900_audio->dev); /* enbale ac97 multifunction pin*/ + /* enbale ac97 multifunction pin */ + mfp_set_groupg(nuc900_audio->dev, "nuc900-audio"); return 0; @@ -405,18 +406,7 @@ static struct platform_driver nuc900_ac97_driver = { .remove = __devexit_p(nuc900_ac97_drvremove), }; -static int __init nuc900_ac97_init(void) -{ - return platform_driver_register(&nuc900_ac97_driver); -} - -static void __exit nuc900_ac97_exit(void) -{ - platform_driver_unregister(&nuc900_ac97_driver); -} - -module_init(nuc900_ac97_init); -module_exit(nuc900_ac97_exit); +module_platform_driver(nuc900_ac97_driver); MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); MODULE_DESCRIPTION("NUC900 AC97 SoC driver!"); diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c index 38a2d0d883b..2f6e6fd6e05 100644 --- a/sound/soc/nuc900/nuc900-audio.c +++ b/sound/soc/nuc900/nuc900-audio.c @@ -32,6 +32,7 @@ static struct snd_soc_dai_link nuc900evb_ac97_dai = { static struct snd_soc_card nuc900evb_audio_machine = { .name = "NUC900EVB_AC97", + .owner = THIS_MODULE, .dai_link = &nuc900evb_ac97_dai, .num_links = 1, }; diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index ae8d6806966..37585b47f4e 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c @@ -358,17 +358,7 @@ static struct platform_driver nuc900_pcm_driver = { .remove = __devexit_p(nuc900_soc_platform_remove), }; -static int __init nuc900_pcm_init(void) -{ - return platform_driver_register(&nuc900_pcm_driver); -} -module_init(nuc900_pcm_init); - -static void __exit nuc900_pcm_exit(void) -{ - platform_driver_unregister(&nuc900_pcm_driver); -} -module_exit(nuc900_pcm_exit); +module_platform_driver(nuc900_pcm_driver); MODULE_AUTHOR("Wan ZongShun, <mcuos.com@gmail.com>"); MODULE_DESCRIPTION("nuc900 Audio DMA module"); diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index fe83d0d176b..fb1bf2581ef 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -2,6 +2,9 @@ config SND_OMAP_SOC tristate "SoC Audio for the Texas Instruments OMAP chips" depends on ARCH_OMAP +config SND_OMAP_SOC_DMIC + tristate + config SND_OMAP_SOC_MCBSP tristate select OMAP_MCBSP @@ -97,8 +100,10 @@ config SND_OMAP_SOC_SDP3430 config SND_OMAP_SOC_SDP4430 tristate "SoC Audio support for Texas Instruments SDP4430" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP + select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 + select SND_SOC_DMIC help Say Y if you want to add support for SoC audio on Texas Instruments SDP4430. diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 052fd758722..1fd723fb559 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile @@ -1,10 +1,12 @@ # OMAP Platform Support snd-soc-omap-objs := omap-pcm.o +snd-soc-omap-dmic-objs := omap-dmic.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o snd-soc-omap-mcpdm-objs := omap-mcpdm.o snd-soc-omap-hdmi-objs := omap-hdmi.o obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o +obj-$(CONFIG_SND_OMAP_SOC_DMIC) += snd-soc-omap-dmic.o obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o obj-$(CONFIG_SND_OMAP_SOC_HDMI) += snd-soc-omap-hdmi.o diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index c1cd4a0cbe9..add4866d7e6 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -107,6 +107,7 @@ static struct snd_soc_dai_link am3517evm_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_am3517evm = { .name = "am3517evm", + .owner = THIS_MODULE, .dai_link = &am3517evm_dai, .num_links = 1, diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index ccb8a6aa181..a67f4370bc9 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -431,22 +431,20 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { - struct snd_soc_codec *codec = card->rtd->codec; - switch (level) { case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) + if (card->dapm.bias_level == SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, AMS_DELTA_LATCH2_MODEM_NRESET); break; case SND_SOC_BIAS_OFF: - if (codec->dapm.bias_level != SND_SOC_BIAS_OFF) + if (card->dapm.bias_level != SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 0); } - codec->dapm.bias_level = level; + card->dapm.bias_level = level; return 0; } @@ -474,7 +472,7 @@ static int ams_delta_digital_mute(struct snd_soc_dai *dai, int mute) } /* Our codec DAI probably doesn't have its own .ops structure */ -static struct snd_soc_dai_ops ams_delta_dai_ops = { +static const struct snd_soc_dai_ops ams_delta_dai_ops = { .digital_mute = ams_delta_digital_mute, }; @@ -597,6 +595,7 @@ static struct snd_soc_dai_link ams_delta_dai_link = { /* Audio card driver */ static struct snd_soc_card ams_delta_audio_card = { .name = "AMS_DELTA", + .owner = THIS_MODULE, .dai_link = &ams_delta_dai_link, .num_links = 1, .set_bias_level = ams_delta_set_bias_level, diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c index 591fbf8f7cd..ccae58a1339 100644 --- a/sound/soc/omap/igep0020.c +++ b/sound/soc/omap/igep0020.c @@ -72,6 +72,7 @@ static struct snd_soc_dai_link igep2_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_card_igep2 = { .name = "igep2", + .owner = THIS_MODULE, .dai_link = &igep2_dai, .num_links = 1, }; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index fc6209b3f20..597be412f1e 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -289,6 +289,7 @@ static struct snd_soc_dai_link n810_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_n810 = { .name = "N810", + .owner = THIS_MODULE, .dai_link = &n810_dai, .num_links = 1, diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c new file mode 100644 index 00000000000..0855c1cfa7f --- /dev/null +++ b/sound/soc/omap/omap-dmic.c @@ -0,0 +1,546 @@ +/* + * omap-dmic.c -- OMAP ASoC DMIC DAI driver + * + * Copyright (C) 2010 - 2011 Texas Instruments + * + * Author: David Lambert <dlambert@ti.com> + * Misael Lopez Cruz <misael.lopez@ti.com> + * Liam Girdwood <lrg@ti.com> + * Peter Ujfalusi <peter.ujfalusi@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h> +#include <plat/dma.h> + +#include <sound/core.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/initval.h> +#include <sound/soc.h> + +#include "omap-pcm.h" +#include "omap-dmic.h" + +struct omap_dmic { + struct device *dev; + void __iomem *io_base; + struct clk *fclk; + int fclk_freq; + int out_freq; + int clk_div; + int sysclk; + int threshold; + u32 ch_enabled; + bool active; + struct mutex mutex; +}; + +/* + * Stream DMA parameters + */ +static struct omap_pcm_dma_data omap_dmic_dai_dma_params = { + .name = "DMIC capture", + .data_type = OMAP_DMA_DATA_TYPE_S32, + .sync_mode = OMAP_DMA_SYNC_PACKET, +}; + +static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val) +{ + __raw_writel(val, dmic->io_base + reg); +} + +static inline int omap_dmic_read(struct omap_dmic *dmic, u16 reg) +{ + return __raw_readl(dmic->io_base + reg); +} + +static inline void omap_dmic_start(struct omap_dmic *dmic) +{ + u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG); + + /* Configure DMA controller */ + omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_SET_REG, + OMAP_DMIC_DMA_ENABLE); + + omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl | dmic->ch_enabled); +} + +static inline void omap_dmic_stop(struct omap_dmic *dmic) +{ + u32 ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG); + omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, + ctrl & ~OMAP_DMIC_UP_ENABLE_MASK); + + /* Disable DMA request generation */ + omap_dmic_write(dmic, OMAP_DMIC_DMAENABLE_CLR_REG, + OMAP_DMIC_DMA_ENABLE); + +} + +static inline int dmic_is_enabled(struct omap_dmic *dmic) +{ + return omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG) & + OMAP_DMIC_UP_ENABLE_MASK; +} + +static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + mutex_lock(&dmic->mutex); + + if (!dai->active) { + snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); + dmic->active = 1; + } else { + ret = -EBUSY; + } + + mutex_unlock(&dmic->mutex); + + return ret; +} + +static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + + mutex_lock(&dmic->mutex); + + if (!dai->active) + dmic->active = 0; + + mutex_unlock(&dmic->mutex); +} + +static int omap_dmic_select_divider(struct omap_dmic *dmic, int sample_rate) +{ + int divider = -EINVAL; + + /* + * 192KHz rate is only supported with 19.2MHz/3.84MHz clock + * configuration. + */ + if (sample_rate == 192000) { + if (dmic->fclk_freq == 19200000 && dmic->out_freq == 3840000) + divider = 0x6; /* Divider: 5 (192KHz sampling rate) */ + else + dev_err(dmic->dev, + "invalid clock configuration for 192KHz\n"); + + return divider; + } + + switch (dmic->out_freq) { + case 1536000: + if (dmic->fclk_freq != 24576000) + goto div_err; + divider = 0x4; /* Divider: 16 */ + break; + case 2400000: + switch (dmic->fclk_freq) { + case 12000000: + divider = 0x5; /* Divider: 5 */ + break; + case 19200000: + divider = 0x0; /* Divider: 8 */ + break; + case 24000000: + divider = 0x2; /* Divider: 10 */ + break; + default: + goto div_err; + } + break; + case 3072000: + if (dmic->fclk_freq != 24576000) + goto div_err; + divider = 0x3; /* Divider: 8 */ + break; + case 3840000: + if (dmic->fclk_freq != 19200000) + goto div_err; + divider = 0x1; /* Divider: 5 (96KHz sampling rate) */ + break; + default: + dev_err(dmic->dev, "invalid out frequency: %dHz\n", + dmic->out_freq); + break; + } + + return divider; + +div_err: + dev_err(dmic->dev, "invalid out frequency %dHz for %dHz input\n", + dmic->out_freq, dmic->fclk_freq); + return -EINVAL; +} + +static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + int channels; + + dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params)); + if (dmic->clk_div < 0) { + dev_err(dmic->dev, "no valid divider for %dHz from %dHz\n", + dmic->out_freq, dmic->fclk_freq); + return -EINVAL; + } + + dmic->ch_enabled = 0; + channels = params_channels(params); + switch (channels) { + case 6: + dmic->ch_enabled |= OMAP_DMIC_UP3_ENABLE; + case 4: + dmic->ch_enabled |= OMAP_DMIC_UP2_ENABLE; + case 2: + dmic->ch_enabled |= OMAP_DMIC_UP1_ENABLE; + break; + default: + dev_err(dmic->dev, "invalid number of legacy channels\n"); + return -EINVAL; + } + + /* packet size is threshold * channels */ + omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels; + snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params); + + return 0; +} + +static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + u32 ctrl; + + /* Configure uplink threshold */ + omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold); + + ctrl = omap_dmic_read(dmic, OMAP_DMIC_CTRL_REG); + + /* Set dmic out format */ + ctrl &= ~(OMAP_DMIC_FORMAT | OMAP_DMIC_POLAR_MASK); + ctrl |= (OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 | + OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3); + + /* Configure dmic clock divider */ + ctrl &= ~OMAP_DMIC_CLK_DIV_MASK; + ctrl |= OMAP_DMIC_CLK_DIV(dmic->clk_div); + + omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, ctrl); + + omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, + ctrl | OMAP_DMICOUTFORMAT_LJUST | OMAP_DMIC_POLAR1 | + OMAP_DMIC_POLAR2 | OMAP_DMIC_POLAR3); + + return 0; +} + +static int omap_dmic_dai_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + omap_dmic_start(dmic); + break; + case SNDRV_PCM_TRIGGER_STOP: + omap_dmic_stop(dmic); + break; + default: + break; + } + + return 0; +} + +static int omap_dmic_select_fclk(struct omap_dmic *dmic, int clk_id, + unsigned int freq) +{ + struct clk *parent_clk; + char *parent_clk_name; + int ret = 0; + + switch (freq) { + case 12000000: + case 19200000: + case 24000000: + case 24576000: + break; + default: + dev_err(dmic->dev, "invalid input frequency: %dHz\n", freq); + dmic->fclk_freq = 0; + return -EINVAL; + } + + if (dmic->sysclk == clk_id) { + dmic->fclk_freq = freq; + return 0; + } + + /* re-parent not allowed if a stream is ongoing */ + if (dmic->active && dmic_is_enabled(dmic)) { + dev_err(dmic->dev, "can't re-parent when DMIC active\n"); + return -EBUSY; + } + + switch (clk_id) { + case OMAP_DMIC_SYSCLK_PAD_CLKS: + parent_clk_name = "pad_clks_ck"; + break; + case OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS: + parent_clk_name = "slimbus_clk"; + break; + case OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS: + parent_clk_name = "dmic_sync_mux_ck"; + break; + default: + dev_err(dmic->dev, "fclk clk_id (%d) not supported\n", clk_id); + return -EINVAL; + } + + parent_clk = clk_get(dmic->dev, parent_clk_name); + if (IS_ERR(parent_clk)) { + dev_err(dmic->dev, "can't get %s\n", parent_clk_name); + return -ENODEV; + } + + mutex_lock(&dmic->mutex); + if (dmic->active) { + /* disable clock while reparenting */ + pm_runtime_put_sync(dmic->dev); + ret = clk_set_parent(dmic->fclk, parent_clk); + pm_runtime_get_sync(dmic->dev); + } else { + ret = clk_set_parent(dmic->fclk, parent_clk); + } + mutex_unlock(&dmic->mutex); + + if (ret < 0) { + dev_err(dmic->dev, "re-parent failed\n"); + goto err_busy; + } + + dmic->sysclk = clk_id; + dmic->fclk_freq = freq; + +err_busy: + clk_put(parent_clk); + + return ret; +} + +static int omap_dmic_select_outclk(struct omap_dmic *dmic, int clk_id, + unsigned int freq) +{ + int ret = 0; + + if (clk_id != OMAP_DMIC_ABE_DMIC_CLK) { + dev_err(dmic->dev, "output clk_id (%d) not supported\n", + clk_id); + return -EINVAL; + } + + switch (freq) { + case 1536000: + case 2400000: + case 3072000: + case 3840000: + dmic->out_freq = freq; + break; + default: + dev_err(dmic->dev, "invalid out frequency: %dHz\n", freq); + dmic->out_freq = 0; + ret = -EINVAL; + } + + return ret; +} + +static int omap_dmic_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + + if (dir == SND_SOC_CLOCK_IN) + return omap_dmic_select_fclk(dmic, clk_id, freq); + else if (dir == SND_SOC_CLOCK_OUT) + return omap_dmic_select_outclk(dmic, clk_id, freq); + + dev_err(dmic->dev, "invalid clock direction (%d)\n", dir); + return -EINVAL; +} + +static const struct snd_soc_dai_ops omap_dmic_dai_ops = { + .startup = omap_dmic_dai_startup, + .shutdown = omap_dmic_dai_shutdown, + .hw_params = omap_dmic_dai_hw_params, + .prepare = omap_dmic_dai_prepare, + .trigger = omap_dmic_dai_trigger, + .set_sysclk = omap_dmic_set_dai_sysclk, +}; + +static int omap_dmic_probe(struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + + pm_runtime_enable(dmic->dev); + + /* Disable lines while request is ongoing */ + pm_runtime_get_sync(dmic->dev); + omap_dmic_write(dmic, OMAP_DMIC_CTRL_REG, 0x00); + pm_runtime_put_sync(dmic->dev); + + /* Configure DMIC threshold value */ + dmic->threshold = OMAP_DMIC_THRES_MAX - 3; + return 0; +} + +static int omap_dmic_remove(struct snd_soc_dai *dai) +{ + struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai); + + pm_runtime_disable(dmic->dev); + + return 0; +} + +static struct snd_soc_dai_driver omap_dmic_dai = { + .name = "omap-dmic", + .probe = omap_dmic_probe, + .remove = omap_dmic_remove, + .capture = { + .channels_min = 2, + .channels_max = 6, + .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S32_LE, + }, + .ops = &omap_dmic_dai_ops, +}; + +static __devinit int asoc_dmic_probe(struct platform_device *pdev) +{ + struct omap_dmic *dmic; + struct resource *res; + int ret; + + dmic = devm_kzalloc(&pdev->dev, sizeof(struct omap_dmic), GFP_KERNEL); + if (!dmic) + return -ENOMEM; + + platform_set_drvdata(pdev, dmic); + dmic->dev = &pdev->dev; + dmic->sysclk = OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS; + + mutex_init(&dmic->mutex); + + dmic->fclk = clk_get(dmic->dev, "dmic_fck"); + if (IS_ERR(dmic->fclk)) { + dev_err(dmic->dev, "cant get dmic_fck\n"); + return -ENODEV; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); + if (!res) { + dev_err(dmic->dev, "invalid dma memory resource\n"); + ret = -ENODEV; + goto err_put_clk; + } + omap_dmic_dai_dma_params.port_addr = res->start + OMAP_DMIC_DATA_REG; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(dmic->dev, "invalid dma resource\n"); + ret = -ENODEV; + goto err_put_clk; + } + omap_dmic_dai_dma_params.dma_req = res->start; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); + if (!res) { + dev_err(dmic->dev, "invalid memory resource\n"); + ret = -ENODEV; + goto err_put_clk; + } + + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), pdev->name)) { + dev_err(dmic->dev, "memory region already claimed\n"); + ret = -ENODEV; + goto err_put_clk; + } + + dmic->io_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!dmic->io_base) { + ret = -ENOMEM; + goto err_put_clk; + } + + ret = snd_soc_register_dai(&pdev->dev, &omap_dmic_dai); + if (ret) + goto err_put_clk; + + return 0; + +err_put_clk: + clk_put(dmic->fclk); + return ret; +} + +static int __devexit asoc_dmic_remove(struct platform_device *pdev) +{ + struct omap_dmic *dmic = platform_get_drvdata(pdev); + + snd_soc_unregister_dai(&pdev->dev); + clk_put(dmic->fclk); + + return 0; +} + +static struct platform_driver asoc_dmic_driver = { + .driver = { + .name = "omap-dmic", + .owner = THIS_MODULE, + }, + .probe = asoc_dmic_probe, + .remove = __devexit_p(asoc_dmic_remove), +}; + +module_platform_driver(asoc_dmic_driver); + +MODULE_ALIAS("platform:omap-dmic"); +MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); +MODULE_DESCRIPTION("OMAP DMIC ASoC Interface"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/omap/omap-dmic.h b/sound/soc/omap/omap-dmic.h new file mode 100644 index 00000000000..231e728bff0 --- /dev/null +++ b/sound/soc/omap/omap-dmic.h @@ -0,0 +1,69 @@ +/* + * omap-dmic.h -- OMAP Digital Microphone Controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _OMAP_DMIC_H +#define _OMAP_DMIC_H + +#define OMAP_DMIC_REVISION_REG 0x00 +#define OMAP_DMIC_SYSCONFIG_REG 0x10 +#define OMAP_DMIC_IRQSTATUS_RAW_REG 0x24 +#define OMAP_DMIC_IRQSTATUS_REG 0x28 +#define OMAP_DMIC_IRQENABLE_SET_REG 0x2C +#define OMAP_DMIC_IRQENABLE_CLR_REG 0x30 +#define OMAP_DMIC_IRQWAKE_EN_REG 0x34 +#define OMAP_DMIC_DMAENABLE_SET_REG 0x38 +#define OMAP_DMIC_DMAENABLE_CLR_REG 0x3C +#define OMAP_DMIC_DMAWAKEEN_REG 0x40 +#define OMAP_DMIC_CTRL_REG 0x44 +#define OMAP_DMIC_DATA_REG 0x48 +#define OMAP_DMIC_FIFO_CTRL_REG 0x4C +#define OMAP_DMIC_FIFO_DMIC1R_DATA_REG 0x50 +#define OMAP_DMIC_FIFO_DMIC1L_DATA_REG 0x54 +#define OMAP_DMIC_FIFO_DMIC2R_DATA_REG 0x58 +#define OMAP_DMIC_FIFO_DMIC2L_DATA_REG 0x5C +#define OMAP_DMIC_FIFO_DMIC3R_DATA_REG 0x60 +#define OMAP_DMIC_FIFO_DMIC3L_DATA_REG 0x64 + +/* IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR bit fields */ +#define OMAP_DMIC_IRQ (1 << 0) +#define OMAP_DMIC_IRQ_FULL (1 << 1) +#define OMAP_DMIC_IRQ_ALMST_EMPTY (1 << 2) +#define OMAP_DMIC_IRQ_EMPTY (1 << 3) +#define OMAP_DMIC_IRQ_MASK 0x07 + +/* DMIC_DMAENABLE bit fields */ +#define OMAP_DMIC_DMA_ENABLE 0x1 + +/* DMIC_CTRL bit fields */ +#define OMAP_DMIC_UP1_ENABLE (1 << 0) +#define OMAP_DMIC_UP2_ENABLE (1 << 1) +#define OMAP_DMIC_UP3_ENABLE (1 << 2) +#define OMAP_DMIC_UP_ENABLE_MASK 0x7 +#define OMAP_DMIC_FORMAT (1 << 3) +#define OMAP_DMIC_POLAR1 (1 << 4) +#define OMAP_DMIC_POLAR2 (1 << 5) +#define OMAP_DMIC_POLAR3 (1 << 6) +#define OMAP_DMIC_POLAR_MASK (0x7 << 4) +#define OMAP_DMIC_CLK_DIV(x) (((x) & 0x7) << 7) +#define OMAP_DMIC_CLK_DIV_MASK (0x7 << 7) +#define OMAP_DMIC_RESET (1 << 10) + +#define OMAP_DMICOUTFORMAT_LJUST (0 << 3) +#define OMAP_DMICOUTFORMAT_RJUST (1 << 3) + +/* DMIC_FIFO_CTRL bit fields */ +#define OMAP_DMIC_THRES_MAX 0xF + +enum omap_dmic_clk { + OMAP_DMIC_SYSCLK_PAD_CLKS, /* PAD_CLKS */ + OMAP_DMIC_SYSCLK_SLIMBLUS_CLKS, /* SLIMBUS_CLK */ + OMAP_DMIC_SYSCLK_SYNC_MUX_CLKS, /* DMIC_SYNC_MUX_CLK */ + OMAP_DMIC_ABE_DMIC_CLK, /* abe_dmic_clk */ +}; + +#endif diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index 36c6eaeffb0..38e0defa707 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -83,7 +83,7 @@ static int omap_hdmi_dai_hw_params(struct snd_pcm_substream *substream, return err; } -static struct snd_soc_dai_ops omap_hdmi_dai_ops = { +static const struct snd_soc_dai_ops omap_hdmi_dai_ops = { .startup = omap_hdmi_dai_startup, .hw_params = omap_hdmi_dai_hw_params, }; @@ -139,17 +139,7 @@ static struct platform_driver hdmi_dai_driver = { .remove = __devexit_p(omap_hdmi_remove), }; -static int __init hdmi_dai_init(void) -{ - return platform_driver_register(&hdmi_dai_driver); -} -module_init(hdmi_dai_init); - -static void __exit hdmi_dai_exit(void) -{ - platform_driver_unregister(&hdmi_dai_driver); -} -module_exit(hdmi_dai_exit); +module_platform_driver(hdmi_dai_driver); MODULE_AUTHOR("Jorge Candelaria <jorge.candelaria@ti.com>"); MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>"); diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 4314647e735..017371913ec 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -258,7 +258,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, default: return -EINVAL; } - if (cpu_is_omap34xx()) { + if (cpu_is_omap34xx() || cpu_is_omap44xx()) { dma_data->set_threshold = omap_mcbsp_set_threshold; /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ if (omap_mcbsp_get_dma_op_mode(bus_id) == @@ -599,7 +599,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, return err; } -static struct snd_soc_dai_ops mcbsp_dai_ops = { +static const struct snd_soc_dai_ops mcbsp_dai_ops = { .startup = omap_mcbsp_dai_startup, .shutdown = omap_mcbsp_dai_shutdown, .trigger = omap_mcbsp_dai_trigger, @@ -785,17 +785,7 @@ static struct platform_driver asoc_mcbsp_driver = { .remove = __devexit_p(asoc_mcbsp_remove), }; -static int __init snd_omap_mcbsp_init(void) -{ - return platform_driver_register(&asoc_mcbsp_driver); -} -module_init(snd_omap_mcbsp_init); - -static void __exit snd_omap_mcbsp_exit(void) -{ - platform_driver_unregister(&asoc_mcbsp_driver); -} -module_exit(snd_omap_mcbsp_exit); +module_platform_driver(asoc_mcbsp_driver); MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); MODULE_DESCRIPTION("OMAP I2S SoC Interface"); diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 41d17067cc7..0e25df4fa9e 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -266,8 +266,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, mutex_lock(&mcpdm->mutex); if (!dai->active) { - pm_runtime_get_sync(mcpdm->dev); - /* Enable watch dog for ES above ES 1.0 to avoid saturation */ if (omap_rev() != OMAP4430_REV_ES1_0) { u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); @@ -295,9 +293,6 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, omap_mcpdm_stop(mcpdm); omap_mcpdm_close_streams(mcpdm); } - - if (!omap_mcpdm_active(mcpdm)) - pm_runtime_put_sync(mcpdm->dev); } mutex_unlock(&mcpdm->mutex); @@ -367,7 +362,7 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { +static const struct snd_soc_dai_ops omap_mcpdm_dai_ops = { .startup = omap_mcpdm_dai_startup, .shutdown = omap_mcpdm_dai_shutdown, .hw_params = omap_mcpdm_dai_hw_params, @@ -520,17 +515,7 @@ static struct platform_driver asoc_mcpdm_driver = { .remove = __devexit_p(asoc_mcpdm_remove), }; -static int __init snd_omap_mcpdm_init(void) -{ - return platform_driver_register(&asoc_mcpdm_driver); -} -module_init(snd_omap_mcpdm_init); - -static void __exit snd_omap_mcpdm_exit(void) -{ - platform_driver_unregister(&asoc_mcpdm_driver); -} -module_exit(snd_omap_mcpdm_exit); +module_platform_driver(asoc_mcpdm_driver); MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); MODULE_DESCRIPTION("OMAP PDM SoC Interface"); diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 6ede7dc6c10..a59bd352d34 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -378,7 +378,6 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm) static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -387,14 +386,14 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(64); - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = omap_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = omap_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -433,17 +432,7 @@ static struct platform_driver omap_pcm_driver = { .remove = __devexit_p(omap_pcm_remove), }; -static int __init snd_omap_pcm_init(void) -{ - return platform_driver_register(&omap_pcm_driver); -} -module_init(snd_omap_pcm_init); - -static void __exit snd_omap_pcm_exit(void) -{ - platform_driver_unregister(&omap_pcm_driver); -} -module_exit(snd_omap_pcm_exit); +module_platform_driver(omap_pcm_driver); MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); MODULE_DESCRIPTION("OMAP PCM DMA module"); diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 68578959e4a..071fcb09b8b 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c @@ -70,6 +70,7 @@ static struct snd_soc_dai_link omap3evm_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_omap3evm = { .name = "omap3evm", + .owner = THIS_MODULE, .dai_link = &omap3evm_dai, .num_links = 1, }; diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 7605c37c91e..07794bd1095 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -233,6 +233,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { /* SoC card */ static struct snd_soc_card snd_soc_card_omap3pandora = { .name = "omap3pandora", + .owner = THIS_MODULE, .dai_link = omap3pandora_dai, .num_links = ARRAY_SIZE(omap3pandora_dai), }; diff --git a/sound/soc/omap/omap4-hdmi-card.c b/sound/soc/omap/omap4-hdmi-card.c index 8671261ba16..28d689b2714 100644 --- a/sound/soc/omap/omap4-hdmi-card.c +++ b/sound/soc/omap/omap4-hdmi-card.c @@ -74,6 +74,7 @@ static struct snd_soc_dai_link omap4_hdmi_dai = { static struct snd_soc_card snd_soc_omap4_hdmi = { .name = "OMAP4HDMI", + .owner = THIS_MODULE, .dai_link = &omap4_hdmi_dai, .num_links = 1, }; @@ -112,17 +113,7 @@ static struct platform_driver omap4_hdmi_driver = { .remove = __devexit_p(omap4_hdmi_remove), }; -static int __init omap4_hdmi_init(void) -{ - return platform_driver_register(&omap4_hdmi_driver); -} -module_init(omap4_hdmi_init); - -static void __exit omap4_hdmi_exit(void) -{ - platform_driver_unregister(&omap4_hdmi_driver); -} -module_exit(omap4_hdmi_exit); +module_platform_driver(omap4_hdmi_driver); MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>"); MODULE_DESCRIPTION("OMAP4 HDMI machine ASoC driver"); diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index 351ec9db384..d859b597e7e 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c @@ -108,6 +108,7 @@ static struct snd_soc_dai_link osk_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_card_osk = { .name = "OSK5912", + .owner = THIS_MODULE, .dai_link = &osk_dai, .num_links = 1, diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index c3550aeee53..2ee889c5025 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c @@ -72,6 +72,7 @@ static struct snd_soc_dai_link overo_dai = { /* Audio machine driver */ static struct snd_soc_card snd_soc_card_overo = { .name = "overo", + .owner = THIS_MODULE, .dai_link = &overo_dai, .num_links = 1, }; diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 4cabb74d97e..fada6ef43ee 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -365,7 +365,7 @@ static struct snd_soc_dai_link rx51_dai[] = { }, }; -struct snd_soc_aux_dev rx51_aux_dev[] = { +static struct snd_soc_aux_dev rx51_aux_dev[] = { { .name = "TLV320AIC34b", .codec_name = "tlv320aic3x-codec.2-0019", @@ -383,6 +383,7 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = { /* Audio card */ static struct snd_soc_card rx51_sound_card = { .name = "RX-51", + .owner = THIS_MODULE, .dai_link = rx51_dai, .num_links = ARRAY_SIZE(rx51_dai), .aux_dev = rx51_aux_dev, diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index e8fbf8efdbb..2c850662ea7 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -213,6 +213,7 @@ static struct snd_soc_dai_link sdp3430_dai[] = { /* Audio machine driver */ static struct snd_soc_card snd_soc_sdp3430 = { .name = "SDP3430", + .owner = THIS_MODULE, .dai_link = sdp3430_dai, .num_links = ARRAY_SIZE(sdp3430_dai), diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 03d9fa4192f..175ba9a04ed 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -33,6 +33,7 @@ #include <plat/hardware.h> #include <plat/mux.h> +#include "omap-dmic.h" #include "omap-mcpdm.h" #include "omap-pcm.h" #include "../codecs/twl6040.h" @@ -67,6 +68,32 @@ static struct snd_soc_ops sdp4430_ops = { .hw_params = sdp4430_hw_params, }; +static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret = 0; + + ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, + 19200000, SND_SOC_CLOCK_IN); + if (ret < 0) { + printk(KERN_ERR "can't set DMIC cpu system clock\n"); + return ret; + } + ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, + SND_SOC_CLOCK_OUT); + if (ret < 0) { + printk(KERN_ERR "can't set DMIC output clock\n"); + return ret; + } + return 0; +} + +static struct snd_soc_ops sdp4430_dmic_ops = { + .hw_params = sdp4430_dmic_hw_params, +}; + /* Headset jack */ static struct snd_soc_jack hs_jack; @@ -148,23 +175,60 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) return ret; } +static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Digital Mic", NULL), +}; + +static const struct snd_soc_dapm_route dmic_audio_map[] = { + {"DMic", NULL, "Digital Mic1 Bias"}, + {"Digital Mic1 Bias", NULL, "Digital Mic"}, +}; + +static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret; + + ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets, + ARRAY_SIZE(sdp4430_dmic_dapm_widgets)); + if (ret) + return ret; + + return snd_soc_dapm_add_routes(dapm, dmic_audio_map, + ARRAY_SIZE(dmic_audio_map)); +} + /* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link sdp4430_dai = { - .name = "TWL6040", - .stream_name = "TWL6040", - .cpu_dai_name = "omap-mcpdm", - .codec_dai_name = "twl6040-legacy", - .platform_name = "omap-pcm-audio", - .codec_name = "twl6040-codec", - .init = sdp4430_twl6040_init, - .ops = &sdp4430_ops, +static struct snd_soc_dai_link sdp4430_dai[] = { + { + .name = "TWL6040", + .stream_name = "TWL6040", + .cpu_dai_name = "omap-mcpdm", + .codec_dai_name = "twl6040-legacy", + .platform_name = "omap-pcm-audio", + .codec_name = "twl6040-codec", + .init = sdp4430_twl6040_init, + .ops = &sdp4430_ops, + }, + { + .name = "DMIC", + .stream_name = "DMIC Capture", + .cpu_dai_name = "omap-dmic", + .codec_dai_name = "dmic-hifi", + .platform_name = "omap-pcm-audio", + .codec_name = "dmic-codec", + .init = sdp4430_dmic_init, + .ops = &sdp4430_dmic_ops, + }, }; /* Audio machine driver */ static struct snd_soc_card snd_soc_sdp4430 = { .name = "SDP4430", - .dai_link = &sdp4430_dai, - .num_links = 1, + .owner = THIS_MODULE, + .dai_link = sdp4430_dai, + .num_links = ARRAY_SIZE(sdp4430_dai), .dapm_widgets = sdp4430_twl6040_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 7641a7fa8f9..981616d61f6 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c @@ -157,6 +157,7 @@ static struct snd_soc_dai_link zoom2_dai[] = { /* Audio machine driver */ static struct snd_soc_card snd_soc_zoom2 = { .name = "Zoom2", + .owner = THIS_MODULE, .dai_link = zoom2_dai, .num_links = ARRAY_SIZE(zoom2_dai), diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index ffd2242e305..a0f7d3cfa47 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -151,6 +151,7 @@ config SND_SOC_ZYLONITE config SND_SOC_RAUMFELD tristate "SoC Audio support Raumfeld audio adapter" depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) + depends on I2C && SPI_MASTER select SND_PXA_SOC_SSP select SND_SOC_CS4270 select SND_SOC_AK4104 @@ -159,7 +160,7 @@ config SND_SOC_RAUMFELD config SND_PXA2XX_SOC_HX4700 tristate "SoC Audio support for HP iPAQ hx4700" - depends on SND_PXA2XX_SOC && MACH_H4700 + depends on SND_PXA2XX_SOC && MACH_H4700 && I2C select SND_PXA2XX_SOC_I2S select SND_SOC_AK4641 help diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index b0e2fb72091..bc21944851c 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -142,18 +142,6 @@ static int corgi_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk, SND_SOC_CLOCK_IN); @@ -239,7 +227,7 @@ SND_SOC_DAPM_HP("Headset Jack", NULL), }; /* Corgi machine audio map (connections to the codec pins) */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route corgi_audio_map[] = { /* headset Jack - in = micin, out = LHPOUT*/ {"Headset Jack", NULL, "LHPOUT"}, @@ -281,24 +269,10 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; snd_soc_dapm_nc_pin(dapm, "LLINEIN"); snd_soc_dapm_nc_pin(dapm, "RLINEIN"); - /* Add corgi specific controls */ - err = snd_soc_add_controls(codec, wm8731_corgi_controls, - ARRAY_SIZE(wm8731_corgi_controls)); - if (err < 0) - return err; - - /* Add corgi specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, - ARRAY_SIZE(wm8731_dapm_widgets)); - - /* Set up corgi specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - return 0; } @@ -311,48 +285,61 @@ static struct snd_soc_dai_link corgi_dai = { .platform_name = "pxa-pcm-audio", .codec_name = "wm8731.0-001b", .init = corgi_wm8731_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &corgi_ops, }; /* corgi audio machine driver */ -static struct snd_soc_card snd_soc_corgi = { +static struct snd_soc_card corgi = { .name = "Corgi", + .owner = THIS_MODULE, .dai_link = &corgi_dai, .num_links = 1, -}; -static struct platform_device *corgi_snd_device; + .controls = wm8731_corgi_controls, + .num_controls = ARRAY_SIZE(wm8731_corgi_controls), + .dapm_widgets = wm8731_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), + .dapm_routes = corgi_audio_map, + .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), +}; -static int __init corgi_init(void) +static int __devinit corgi_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &corgi; int ret; - if (!(machine_is_corgi() || machine_is_shepherd() || - machine_is_husky())) - return -ENODEV; - - corgi_snd_device = platform_device_alloc("soc-audio", -1); - if (!corgi_snd_device) - return -ENOMEM; - - platform_set_drvdata(corgi_snd_device, &snd_soc_corgi); - ret = platform_device_add(corgi_snd_device); + card->dev = &pdev->dev; + ret = snd_soc_register_card(card); if (ret) - platform_device_put(corgi_snd_device); - + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); return ret; } -static void __exit corgi_exit(void) +static int __devexit corgi_remove(struct platform_device *pdev) { - platform_device_unregister(corgi_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + return 0; } -module_init(corgi_init); -module_exit(corgi_exit); +static struct platform_driver corgi_driver = { + .driver = { + .name = "corgi-audio", + .owner = THIS_MODULE, + }, + .probe = corgi_probe, + .remove = __devexit_p(corgi_remove), +}; + +module_platform_driver(corgi_driver); /* Module information */ MODULE_AUTHOR("Richard Purdie"); MODULE_DESCRIPTION("ALSA SoC Corgi"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:corgi-audio"); diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 35ed7eb8cff..7b1bc239003 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -133,78 +133,60 @@ static struct snd_soc_dai_link e740_dai[] = { static struct snd_soc_card e740 = { .name = "Toshiba e740", + .owner = THIS_MODULE, .dai_link = e740_dai, .num_links = ARRAY_SIZE(e740_dai), }; -static struct platform_device *e740_snd_device; +static struct gpio e740_audio_gpios[] = { + { GPIO_E740_MIC_ON, GPIOF_OUT_INIT_LOW, "Mic amp" }, + { GPIO_E740_AMP_ON, GPIOF_OUT_INIT_LOW, "Output amp" }, + { GPIO_E740_WM9705_nAVDD2, GPIOF_OUT_INIT_HIGH, "Audio power" }, +}; -static int __init e740_init(void) +static int __devinit e740_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &e740; int ret; - if (!machine_is_e740()) - return -ENODEV; - - ret = gpio_request(GPIO_E740_MIC_ON, "Mic amp"); + ret = gpio_request_array(e740_audio_gpios, + ARRAY_SIZE(e740_audio_gpios)); if (ret) return ret; - ret = gpio_request(GPIO_E740_AMP_ON, "Output amp"); - if (ret) - goto free_mic_amp_gpio; - - ret = gpio_request(GPIO_E740_WM9705_nAVDD2, "Audio power"); - if (ret) - goto free_op_amp_gpio; - - /* Disable audio */ - ret = gpio_direction_output(GPIO_E740_MIC_ON, 0); - if (ret) - goto free_apwr_gpio; - ret = gpio_direction_output(GPIO_E740_AMP_ON, 0); - if (ret) - goto free_apwr_gpio; - ret = gpio_direction_output(GPIO_E740_WM9705_nAVDD2, 1); - if (ret) - goto free_apwr_gpio; + card->dev = &pdev->dev; - e740_snd_device = platform_device_alloc("soc-audio", -1); - if (!e740_snd_device) { - ret = -ENOMEM; - goto free_apwr_gpio; + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios)); } - - platform_set_drvdata(e740_snd_device, &e740); - ret = platform_device_add(e740_snd_device); - - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e740_snd_device); -free_apwr_gpio: - gpio_free(GPIO_E740_WM9705_nAVDD2); -free_op_amp_gpio: - gpio_free(GPIO_E740_AMP_ON); -free_mic_amp_gpio: - gpio_free(GPIO_E740_MIC_ON); - return ret; } -static void __exit e740_exit(void) +static int __devexit e740_remove(struct platform_device *pdev) { - platform_device_unregister(e740_snd_device); - gpio_free(GPIO_E740_WM9705_nAVDD2); - gpio_free(GPIO_E740_AMP_ON); - gpio_free(GPIO_E740_MIC_ON); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + gpio_free_array(e740_audio_gpios, ARRAY_SIZE(e740_audio_gpios)); + snd_soc_unregister_card(card); + return 0; } -module_init(e740_init); -module_exit(e740_exit); +static struct platform_driver e740_driver = { + .driver = { + .name = "e740-audio", + .owner = THIS_MODULE, + }, + .probe = e740_probe, + .remove = __devexit_p(e740_remove), +}; + +module_platform_driver(e740_driver); /* Module information */ MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); MODULE_DESCRIPTION("ALSA SoC driver for e740"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:e740-audio"); diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index ce5f056009a..47b89d71e28 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -116,68 +116,59 @@ static struct snd_soc_dai_link e750_dai[] = { static struct snd_soc_card e750 = { .name = "Toshiba e750", + .owner = THIS_MODULE, .dai_link = e750_dai, .num_links = ARRAY_SIZE(e750_dai), }; -static struct platform_device *e750_snd_device; +static struct gpio e750_audio_gpios[] = { + { GPIO_E750_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Headphone amp" }, + { GPIO_E750_SPK_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" }, +}; -static int __init e750_init(void) +static int __devinit e750_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &e750; int ret; - if (!machine_is_e750()) - return -ENODEV; - - ret = gpio_request(GPIO_E750_HP_AMP_OFF, "Headphone amp"); + ret = gpio_request_array(e750_audio_gpios, + ARRAY_SIZE(e750_audio_gpios)); if (ret) return ret; - ret = gpio_request(GPIO_E750_SPK_AMP_OFF, "Speaker amp"); - if (ret) - goto free_hp_amp_gpio; - - ret = gpio_direction_output(GPIO_E750_HP_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; - - ret = gpio_direction_output(GPIO_E750_SPK_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; + card->dev = &pdev->dev; - e750_snd_device = platform_device_alloc("soc-audio", -1); - if (!e750_snd_device) { - ret = -ENOMEM; - goto free_spk_amp_gpio; + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios)); } - - platform_set_drvdata(e750_snd_device, &e750); - ret = platform_device_add(e750_snd_device); - - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e750_snd_device); -free_spk_amp_gpio: - gpio_free(GPIO_E750_SPK_AMP_OFF); -free_hp_amp_gpio: - gpio_free(GPIO_E750_HP_AMP_OFF); - return ret; } -static void __exit e750_exit(void) +static int __devexit e750_remove(struct platform_device *pdev) { - platform_device_unregister(e750_snd_device); - gpio_free(GPIO_E750_SPK_AMP_OFF); - gpio_free(GPIO_E750_HP_AMP_OFF); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + gpio_free_array(e750_audio_gpios, ARRAY_SIZE(e750_audio_gpios)); + snd_soc_unregister_card(card); + return 0; } -module_init(e750_init); -module_exit(e750_exit); +static struct platform_driver e750_driver = { + .driver = { + .name = "e750-audio", + .owner = THIS_MODULE, + }, + .probe = e750_probe, + .remove = __devexit_p(e750_remove), +}; + +module_platform_driver(e750_driver); /* Module information */ MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); MODULE_DESCRIPTION("ALSA SoC driver for e750"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:e750-audio"); diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 6a8f38b6c37..ea9707ec6f2 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -106,66 +106,59 @@ static struct snd_soc_dai_link e800_dai[] = { static struct snd_soc_card e800 = { .name = "Toshiba e800", + .owner = THIS_MODULE, .dai_link = e800_dai, .num_links = ARRAY_SIZE(e800_dai), }; -static struct platform_device *e800_snd_device; +static struct gpio e800_audio_gpios[] = { + { GPIO_E800_SPK_AMP_ON, GPIOF_OUT_INIT_HIGH, "Headphone amp" }, + { GPIO_E800_HP_AMP_OFF, GPIOF_OUT_INIT_HIGH, "Speaker amp" }, +}; -static int __init e800_init(void) +static int __devinit e800_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &e800; int ret; - if (!machine_is_e800()) - return -ENODEV; - - ret = gpio_request(GPIO_E800_HP_AMP_OFF, "Headphone amp"); + ret = gpio_request_array(e800_audio_gpios, + ARRAY_SIZE(e800_audio_gpios)); if (ret) return ret; - ret = gpio_request(GPIO_E800_SPK_AMP_ON, "Speaker amp"); - if (ret) - goto free_hp_amp_gpio; - - ret = gpio_direction_output(GPIO_E800_HP_AMP_OFF, 1); - if (ret) - goto free_spk_amp_gpio; - - ret = gpio_direction_output(GPIO_E800_SPK_AMP_ON, 1); - if (ret) - goto free_spk_amp_gpio; - - e800_snd_device = platform_device_alloc("soc-audio", -1); - if (!e800_snd_device) - return -ENOMEM; - - platform_set_drvdata(e800_snd_device, &e800); - ret = platform_device_add(e800_snd_device); - - if (!ret) - return 0; - -/* Fail gracefully */ - platform_device_put(e800_snd_device); -free_spk_amp_gpio: - gpio_free(GPIO_E800_SPK_AMP_ON); -free_hp_amp_gpio: - gpio_free(GPIO_E800_HP_AMP_OFF); + card->dev = &pdev->dev; + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios)); + } return ret; } -static void __exit e800_exit(void) +static int __devexit e800_remove(struct platform_device *pdev) { - platform_device_unregister(e800_snd_device); - gpio_free(GPIO_E800_SPK_AMP_ON); - gpio_free(GPIO_E800_HP_AMP_OFF); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + gpio_free_array(e800_audio_gpios, ARRAY_SIZE(e800_audio_gpios)); + snd_soc_unregister_card(card); + return 0; } -module_init(e800_init); -module_exit(e800_exit); +static struct platform_driver e800_driver = { + .driver = { + .name = "e800-audio", + .owner = THIS_MODULE, + }, + .probe = e800_probe, + .remove = __devexit_p(e800_remove), +}; + +module_platform_driver(e800_driver); /* Module information */ MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); MODULE_DESCRIPTION("ALSA SoC driver for e800"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:e800-audio"); diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index b13a4252812..64743a05aea 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -54,6 +54,7 @@ static struct snd_soc_dai_link em_x270_dai[] = { static struct snd_soc_card em_x270 = { .name = "EM-X270", + .owner = THIS_MODULE, .dai_link = em_x270_dai, .num_links = ARRAY_SIZE(em_x270_dai), }; diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c index 65c124831a0..2a342c92d82 100644 --- a/sound/soc/pxa/hx4700.c +++ b/sound/soc/pxa/hx4700.c @@ -65,20 +65,6 @@ static int hx4700_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai = rtd->cpu_dai; int ret = 0; - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the I2S system clock as output */ ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, SND_SOC_CLOCK_OUT); @@ -175,12 +161,15 @@ static struct snd_soc_dai_link hx4700_dai = { .platform_name = "pxa-pcm-audio", .codec_name = "ak4641.0-0012", .init = hx4700_ak4641_init, + .dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &hx4700_ops, }; /* hx4700 audio machine driver */ static struct snd_soc_card snd_soc_card_hx4700 = { .name = "iPAQ hx4700", + .owner = THIS_MODULE, .dai_link = &hx4700_dai, .num_links = 1, .dapm_widgets = hx4700_dapm_widgets, @@ -209,9 +198,10 @@ static int __devinit hx4700_audio_probe(struct platform_device *pdev) snd_soc_card_hx4700.dev = &pdev->dev; ret = snd_soc_register_card(&snd_soc_card_hx4700); if (ret) - return ret; + gpio_free_array(hx4700_audio_gpios, + ARRAY_SIZE(hx4700_audio_gpios)); - return 0; + return ret; } static int __devexit hx4700_audio_remove(struct platform_device *pdev) @@ -236,18 +226,7 @@ static struct platform_driver hx4700_audio_driver = { .remove = __devexit_p(hx4700_audio_remove), }; -static int __init hx4700_modinit(void) -{ - return platform_driver_register(&hx4700_audio_driver); -} -module_init(hx4700_modinit); - -static void __exit hx4700_modexit(void) -{ - platform_driver_unregister(&hx4700_audio_driver); -} - -module_exit(hx4700_modexit); +module_platform_driver(hx4700_audio_driver); MODULE_AUTHOR("Philipp Zabel"); MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700"); diff --git a/sound/soc/pxa/imote2.c b/sound/soc/pxa/imote2.c index 154fc6f2343..b93dafd32b8 100644 --- a/sound/soc/pxa/imote2.c +++ b/sound/soc/pxa/imote2.c @@ -30,20 +30,6 @@ static int imote2_asoc_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* CPU should be clock master */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, SND_SOC_CLOCK_IN); if (ret < 0) @@ -67,42 +53,52 @@ static struct snd_soc_dai_link imote2_dai = { .codec_dai_name = "wm8940-hifi", .platform_name = "pxa-pcm-audio", .codec_name = "wm8940-codec.0-0034", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &imote2_asoc_ops, }; -static struct snd_soc_card snd_soc_imote2 = { +static struct snd_soc_card imote2 = { .name = "Imote2", + .owner = THIS_MODULE, .dai_link = &imote2_dai, .num_links = 1, }; -static struct platform_device *imote2_snd_device; - -static int __init imote2_asoc_init(void) +static int __devinit imote2_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &imote2; int ret; - if (!machine_is_intelmote2()) - return -ENODEV; - imote2_snd_device = platform_device_alloc("soc-audio", -1); - if (!imote2_snd_device) - return -ENOMEM; + card->dev = &pdev->dev; - platform_set_drvdata(imote2_snd_device, &snd_soc_imote2); - ret = platform_device_add(imote2_snd_device); + ret = snd_soc_register_card(card); if (ret) - platform_device_put(imote2_snd_device); - + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); return ret; } -module_init(imote2_asoc_init); -static void __exit imote2_asoc_exit(void) +static int __devexit imote2_remove(struct platform_device *pdev) { - platform_device_unregister(imote2_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + return 0; } -module_exit(imote2_asoc_exit); + +static struct platform_driver imote2_driver = { + .driver = { + .name = "imote2-audio", + .owner = THIS_MODULE, + }, + .probe = imote2_probe, + .remove = __devexit_p(imote2_remove), +}; + +module_platform_driver(imote2_driver); MODULE_AUTHOR("Jonathan Cameron"); MODULE_DESCRIPTION("ALSA SoC Imote 2"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:imote2-audio"); diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index e79f516c400..3f7a8ecb972 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c @@ -452,6 +452,7 @@ static struct snd_soc_dai_link magician_dai[] = { /* magician audio machine driver */ static struct snd_soc_card snd_soc_card_magician = { .name = "Magician", + .owner = THIS_MODULE, .dai_link = magician_dai, .num_links = ARRAY_SIZE(magician_dai), diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 0b8d1ee738a..9c585af59b5 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -181,6 +181,7 @@ static struct snd_soc_dai_link mioa701_dai[] = { static struct snd_soc_card mioa701 = { .name = "MioA701", + .owner = THIS_MODULE, .dai_link = mioa701_dai, .num_links = ARRAY_SIZE(mioa701_dai), }; @@ -227,18 +228,7 @@ static struct platform_driver mioa701_wm9713_driver = { }, }; -static int __init mioa701_asoc_init(void) -{ - return platform_driver_register(&mioa701_wm9713_driver); -} - -static void __exit mioa701_asoc_exit(void) -{ - platform_driver_unregister(&mioa701_wm9713_driver); -} - -module_init(mioa701_asoc_init); -module_exit(mioa701_asoc_exit); +module_platform_driver(mioa701_wm9713_driver); /* Module information */ MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)"); diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 7edc1fb71fa..db24bc685bd 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -146,6 +146,7 @@ static struct snd_soc_dai_link palm27x_dai[] = { static struct snd_soc_card palm27x_asoc = { .name = "Palm/PXA27x", + .owner = THIS_MODULE, .dai_link = palm27x_dai, .num_links = ARRAY_SIZE(palm27x_dai), }; @@ -201,18 +202,7 @@ static struct platform_driver palm27x_wm9712_driver = { }, }; -static int __init palm27x_asoc_init(void) -{ - return platform_driver_register(&palm27x_wm9712_driver); -} - -static void __exit palm27x_asoc_exit(void) -{ - platform_driver_unregister(&palm27x_wm9712_driver); -} - -module_init(palm27x_asoc_init); -module_exit(palm27x_asoc_exit); +module_platform_driver(palm27x_wm9712_driver); /* Module information */ MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index 4c29bc1f9cf..fd0ed10c6fe 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -121,18 +121,6 @@ static int poodle_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk, SND_SOC_CLOCK_IN); @@ -214,7 +202,7 @@ SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event), }; /* Corgi machine connections to the codec pins */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route poodle_audio_map[] = { /* headphone connected to LHPOUT1, RHPOUT1 */ {"Headphone Jack", NULL, "LHPOUT"}, @@ -246,25 +234,11 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; snd_soc_dapm_nc_pin(dapm, "LLINEIN"); snd_soc_dapm_nc_pin(dapm, "RLINEIN"); snd_soc_dapm_enable_pin(dapm, "MICIN"); - /* Add poodle specific controls */ - err = snd_soc_add_controls(codec, wm8731_poodle_controls, - ARRAY_SIZE(wm8731_poodle_controls)); - if (err < 0) - return err; - - /* Add poodle specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, - ARRAY_SIZE(wm8731_dapm_widgets)); - - /* Set up poodle specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - return 0; } @@ -277,26 +251,31 @@ static struct snd_soc_dai_link poodle_dai = { .platform_name = "pxa-pcm-audio", .codec_name = "wm8731.0-001b", .init = poodle_wm8731_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &poodle_ops, }; /* poodle audio machine driver */ -static struct snd_soc_card snd_soc_poodle = { +static struct snd_soc_card poodle = { .name = "Poodle", .dai_link = &poodle_dai, .num_links = 1, .owner = THIS_MODULE, -}; -static struct platform_device *poodle_snd_device; + .controls = wm8731_poodle_controls, + .num_controls = ARRAY_SIZE(wm8731_poodle_controls), + .dapm_widgets = wm8731_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), + .dapm_routes = poodle_audio_map, + .num_dapm_routes = ARRAY_SIZE(poodle_audio_map), +}; -static int __init poodle_init(void) +static int __devinit poodle_probe(struct platform_device *pdev) { + struct snd_soc_card *card = &poodle; int ret; - if (!machine_is_poodle()) - return -ENODEV; - locomo_gpio_set_dir(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_AMP_ON, 0); /* should we mute HP at startup - burning power ?*/ @@ -305,28 +284,36 @@ static int __init poodle_init(void) locomo_gpio_set_dir(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 0); - poodle_snd_device = platform_device_alloc("soc-audio", -1); - if (!poodle_snd_device) - return -ENOMEM; - - platform_set_drvdata(poodle_snd_device, &snd_soc_poodle); - ret = platform_device_add(poodle_snd_device); + card->dev = &pdev->dev; + ret = snd_soc_register_card(card); if (ret) - platform_device_put(poodle_snd_device); - + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); return ret; } -static void __exit poodle_exit(void) +static int __devexit poodle_remove(struct platform_device *pdev) { - platform_device_unregister(poodle_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + return 0; } -module_init(poodle_init); -module_exit(poodle_exit); +static struct platform_driver poodle_driver = { + .driver = { + .name = "poodle-audio", + .owner = THIS_MODULE, + }, + .probe = poodle_probe, + .remove = __devexit_p(poodle_remove), +}; + +module_platform_driver(poodle_driver); /* Module information */ MODULE_AUTHOR("Richard Purdie"); MODULE_DESCRIPTION("ALSA SoC Poodle"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:poodle-audio"); diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index 8ad93ee2e92..a57cfbc038e 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -771,7 +771,7 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) SNDRV_PCM_FMTBIT_S24_LE | \ SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops pxa_ssp_dai_ops = { +static const struct snd_soc_dai_ops pxa_ssp_dai_ops = { .startup = pxa_ssp_startup, .shutdown = pxa_ssp_shutdown, .trigger = pxa_ssp_trigger, @@ -825,17 +825,7 @@ static struct platform_driver asoc_ssp_driver = { .remove = __devexit_p(asoc_ssp_remove), }; -static int __init pxa_ssp_init(void) -{ - return platform_driver_register(&asoc_ssp_driver); -} -module_init(pxa_ssp_init); - -static void __exit pxa_ssp_exit(void) -{ - platform_driver_unregister(&asoc_ssp_driver); -} -module_exit(pxa_ssp_exit); +module_platform_driver(asoc_ssp_driver); /* Module information */ MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index ac51c6d25c4..837ff341fd6 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -163,15 +163,15 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000) -static struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { +static const struct snd_soc_dai_ops pxa_ac97_hifi_dai_ops = { .hw_params = pxa2xx_ac97_hw_params, }; -static struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { +static const struct snd_soc_dai_ops pxa_ac97_aux_dai_ops = { .hw_params = pxa2xx_ac97_hw_aux_params, }; -static struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { +static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { .hw_params = pxa2xx_ac97_hw_mic_params, }; @@ -263,17 +263,7 @@ static struct platform_driver pxa2xx_ac97_driver = { }, }; -static int __init pxa_ac97_init(void) -{ - return platform_driver_register(&pxa2xx_ac97_driver); -} -module_init(pxa_ac97_init); - -static void __exit pxa_ac97_exit(void) -{ - platform_driver_unregister(&pxa2xx_ac97_driver); -} -module_exit(pxa_ac97_exit); +module_platform_driver(pxa2xx_ac97_driver); MODULE_AUTHOR("Nicolas Pitre"); MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 11be5952a50..609abd51e55 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -331,7 +331,7 @@ static int pxa2xx_i2s_remove(struct snd_soc_dai *dai) SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops pxa_i2s_dai_ops = { +static const struct snd_soc_dai_ops pxa_i2s_dai_ops = { .startup = pxa2xx_i2s_startup, .shutdown = pxa2xx_i2s_shutdown, .trigger = pxa2xx_i2s_trigger, diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index 600676f709a..fdd6bedef9b 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c @@ -141,17 +141,7 @@ static struct platform_driver pxa_pcm_driver = { .remove = __devexit_p(pxa2xx_soc_platform_remove), }; -static int __init snd_pxa_pcm_init(void) -{ - return platform_driver_register(&pxa_pcm_driver); -} -module_init(snd_pxa_pcm_init); - -static void __exit snd_pxa_pcm_exit(void) -{ - platform_driver_unregister(&pxa_pcm_driver); -} -module_exit(snd_pxa_pcm_exit); +module_platform_driver(pxa_pcm_driver); MODULE_AUTHOR("Nicolas Pitre"); MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index b899a3bc8f4..ba1545188ec 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c @@ -260,6 +260,7 @@ static struct snd_soc_dai_link snd_soc_raumfeld_speaker_dai[] = static struct snd_soc_card snd_soc_raumfeld_connector = { .name = "Raumfeld Connector", + .owner = THIS_MODULE, .dai_link = snd_soc_raumfeld_connector_dai, .num_links = ARRAY_SIZE(snd_soc_raumfeld_connector_dai), .suspend_post = raumfeld_analog_suspend, @@ -268,6 +269,7 @@ static struct snd_soc_card snd_soc_raumfeld_connector = { static struct snd_soc_card snd_soc_raumfeld_speaker = { .name = "Raumfeld Speaker", + .owner = THIS_MODULE, .dai_link = snd_soc_raumfeld_speaker_dai, .num_links = ARRAY_SIZE(snd_soc_raumfeld_speaker_dai), .suspend_post = raumfeld_analog_suspend, diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c index d9467a2c6de..c34146b776b 100644 --- a/sound/soc/pxa/saarb.c +++ b/sound/soc/pxa/saarb.c @@ -51,7 +51,7 @@ static const struct snd_soc_dapm_widget saarb_dapm_widgets[] = { }; /* saarb machine audio map */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route saarb_audio_map[] = { {"Headset Stereophone", NULL, "HS1"}, {"Headset Stereophone", NULL, "HS2"}, @@ -92,15 +92,6 @@ static int saarb_i2s_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width); return ret; @@ -119,25 +110,28 @@ static struct snd_soc_dai_link saarb_dai[] = { .platform_name = "pxa-pcm-audio", .codec_name = "88pm860x-codec", .init = saarb_pm860x_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .ops = &saarb_i2s_ops, }, }; static struct snd_soc_card snd_soc_card_saarb = { .name = "Saarb", + .owner = THIS_MODULE, .dai_link = saarb_dai, .num_links = ARRAY_SIZE(saarb_dai), + + .dapm_widgets = saarb_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(saarb_dapm_widgets), + .dapm_routes = saarb_audio_map, + .num_dapm_routes = ARRAY_SIZE(saarb_audio_map), }; static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets, - ARRAY_SIZE(saarb_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index c2d6ff9b158..90c5245c474 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -143,18 +143,6 @@ static int spitz_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, SND_SOC_CLOCK_IN); @@ -234,7 +222,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { }; /* Spitz machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route spitz_audio_map[] = { /* headphone connected to LOUT1, ROUT1 */ {"Headphone Jack", NULL, "LOUT1"}, @@ -277,7 +265,6 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; /* NC codec pins */ snd_soc_dapm_nc_pin(dapm, "RINPUT1"); @@ -288,19 +275,6 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "OUT3"); snd_soc_dapm_nc_pin(dapm, "MONO1"); - /* Add spitz specific controls */ - err = snd_soc_add_controls(codec, wm8750_spitz_controls, - ARRAY_SIZE(wm8750_spitz_controls)); - if (err < 0) - return err; - - /* Add spitz specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); - - /* Set up spitz specific audio paths */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - return 0; } @@ -313,14 +287,24 @@ static struct snd_soc_dai_link spitz_dai = { .platform_name = "pxa-pcm-audio", .codec_name = "wm8750.0-001b", .init = spitz_wm8750_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &spitz_ops, }; /* spitz audio machine driver */ static struct snd_soc_card snd_soc_spitz = { .name = "Spitz", + .owner = THIS_MODULE, .dai_link = &spitz_dai, .num_links = 1, + + .controls = wm8750_spitz_controls, + .num_controls = ARRAY_SIZE(wm8750_spitz_controls), + .dapm_widgets = wm8750_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), + .dapm_routes = spitz_audio_map, + .num_dapm_routes = ARRAY_SIZE(spitz_audio_map), }; static struct platform_device *spitz_snd_device; diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c index eeec892e0e0..8b5ab8f7272 100644 --- a/sound/soc/pxa/tavorevb3.c +++ b/sound/soc/pxa/tavorevb3.c @@ -51,7 +51,7 @@ static const struct snd_soc_dapm_widget evb3_dapm_widgets[] = { }; /* tavorevb3 machine audio map */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route evb3_audio_map[] = { {"Headset Stereophone", NULL, "HS1"}, {"Headset Stereophone", NULL, "HS2"}, @@ -92,16 +92,6 @@ static int evb3_i2s_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 3, 3, 2, width); return ret; } @@ -119,25 +109,28 @@ static struct snd_soc_dai_link evb3_dai[] = { .platform_name = "pxa-pcm-audio", .codec_name = "88pm860x-codec", .init = evb3_pm860x_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM, .ops = &evb3_i2s_ops, }, }; static struct snd_soc_card snd_soc_card_evb3 = { .name = "Tavor EVB3", + .owner = THIS_MODULE, .dai_link = evb3_dai, .num_links = ARRAY_SIZE(evb3_dai), + + .dapm_widgets = evb3_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(evb3_dapm_widgets), + .dapm_routes = evb3_audio_map, + .num_dapm_routes = ARRAY_SIZE(evb3_audio_map), }; static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets, - ARRAY_SIZE(evb3_dapm_widgets)); - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 620fc69ae63..564ef08a89f 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -34,8 +34,6 @@ #include "../codecs/wm9712.h" #include "pxa2xx-ac97.h" -static struct snd_soc_card tosa; - #define TOSA_HP 0 #define TOSA_MIC_INT 1 #define TOSA_HEADSET 2 @@ -236,70 +234,56 @@ static struct snd_soc_dai_link tosa_dai[] = { }, }; -static int tosa_probe(struct snd_soc_card *card) -{ - int ret; - - ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack"); - if (ret) - return ret; - ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0); - if (ret) - gpio_free(TOSA_GPIO_L_MUTE); - - return ret; -} - -static int tosa_remove(struct snd_soc_card *card) -{ - gpio_free(TOSA_GPIO_L_MUTE); - return 0; -} - static struct snd_soc_card tosa = { .name = "Tosa", + .owner = THIS_MODULE, .dai_link = tosa_dai, .num_links = ARRAY_SIZE(tosa_dai), - .probe = tosa_probe, - .remove = tosa_remove, }; -static struct platform_device *tosa_snd_device; - -static int __init tosa_init(void) +static int __devinit tosa_probe(struct platform_device *pdev) { + struct snd_soc_card *card = ⤩ int ret; - if (!machine_is_tosa()) - return -ENODEV; - - tosa_snd_device = platform_device_alloc("soc-audio", -1); - if (!tosa_snd_device) { - ret = -ENOMEM; - goto err_alloc; - } - - platform_set_drvdata(tosa_snd_device, &tosa); - ret = platform_device_add(tosa_snd_device); - - if (!ret) - return 0; + ret = gpio_request_one(TOSA_GPIO_L_MUTE, GPIOF_OUT_INIT_LOW, + "Headphone Jack"); + if (ret) + return ret; - platform_device_put(tosa_snd_device); + card->dev = &pdev->dev; -err_alloc: + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + gpio_free(TOSA_GPIO_L_MUTE); + } return ret; } -static void __exit tosa_exit(void) +static int __devexit tosa_remove(struct platform_device *pdev) { - platform_device_unregister(tosa_snd_device); + struct snd_soc_card *card = platform_get_drvdata(pdev); + + gpio_free(TOSA_GPIO_L_MUTE); + snd_soc_unregister_card(card); + return 0; } -module_init(tosa_init); -module_exit(tosa_exit); +static struct platform_driver tosa_driver = { + .driver = { + .name = "tosa-audio", + .owner = THIS_MODULE, + }, + .probe = tosa_probe, + .remove = __devexit_p(tosa_remove), +}; + +module_platform_driver(tosa_driver); /* Module information */ MODULE_AUTHOR("Richard Purdie"); MODULE_DESCRIPTION("ALSA SoC Tosa"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:tosa-audio"); diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index b311ffe04b7..76ccb172d0a 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c @@ -56,18 +56,6 @@ static int z2_hw_params(struct snd_pcm_substream *substream, break; } - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - /* set the codec system clock for DAC and ADC */ ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, SND_SOC_CLOCK_IN); @@ -124,7 +112,7 @@ static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { }; /* Z2 machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { +static const struct snd_soc_dapm_route z2_audio_map[] = { /* headphone connected to LOUT1, ROUT1 */ {"Headphone Jack", NULL, "LOUT1"}, @@ -154,13 +142,6 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_disable_pin(dapm, "OUT3"); snd_soc_dapm_disable_pin(dapm, "MONO1"); - /* Add z2 specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); - - /* Set up z2 specific audio paths */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - /* Jack detection API stuff */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); @@ -196,14 +177,22 @@ static struct snd_soc_dai_link z2_dai = { .platform_name = "pxa-pcm-audio", .codec_name = "wm8750.0-001b", .init = z2_wm8750_init, + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, .ops = &z2_ops, }; /* z2 audio machine driver */ static struct snd_soc_card snd_soc_z2 = { .name = "Z2", + .owner = THIS_MODULE, .dai_link = &z2_dai, .num_links = 1, + + .dapm_widgets = wm8750_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), + .dapm_routes = z2_audio_map, + .num_dapm_routes = ARRAY_SIZE(z2_audio_map), }; static struct platform_device *z2_snd_device; diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index 580aae38e50..ceb656695b0 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c @@ -249,6 +249,7 @@ static int zylonite_resume_pre(struct snd_soc_card *card) static struct snd_soc_card zylonite = { .name = "Zylonite", + .owner = THIS_MODULE, .probe = &zylonite_probe, .remove = &zylonite_remove, .suspend_post = &zylonite_suspend_post, diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 3052f64b240..aaabdbaec19 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c @@ -409,7 +409,7 @@ static int s6000_i2s_dai_probe(struct snd_soc_dai *dai) SNDRV_PCM_RATE_8000_192000) #define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) -static struct snd_soc_dai_ops s6000_i2s_dai_ops = { +static const struct snd_soc_dai_ops s6000_i2s_dai_ops = { .set_fmt = s6000_i2s_set_dai_fmt, .set_clkdiv = s6000_i2s_set_clkdiv, .hw_params = s6000_i2s_hw_params, @@ -604,17 +604,7 @@ static struct platform_driver s6000_i2s_driver = { }, }; -static int __init s6000_i2s_init(void) -{ - return platform_driver_register(&s6000_i2s_driver); -} -module_init(s6000_i2s_init); - -static void __exit s6000_i2s_exit(void) -{ - platform_driver_unregister(&s6000_i2s_driver); -} -module_exit(s6000_i2s_exit); +module_platform_driver(s6000_i2s_driver); MODULE_AUTHOR("Daniel Gloeckner"); MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface"); diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 55efc2bdf0b..43c014f362f 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c @@ -520,17 +520,7 @@ static struct platform_driver s6000_pcm_driver = { .remove = __devexit_p(s6000_soc_platform_remove), }; -static int __init snd_s6000_pcm_init(void) -{ - return platform_driver_register(&s6000_pcm_driver); -} -module_init(snd_s6000_pcm_init); - -static void __exit snd_s6000_pcm_exit(void) -{ - platform_driver_unregister(&s6000_pcm_driver); -} -module_exit(snd_s6000_pcm_exit); +module_platform_driver(s6000_pcm_driver); MODULE_AUTHOR("Daniel Gloeckner"); MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module"); diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c index 5890e431852..58cfb1eb7dd 100644 --- a/sound/soc/s6000/s6105-ipcam.c +++ b/sound/soc/s6000/s6105-ipcam.c @@ -187,6 +187,7 @@ static struct snd_soc_dai_link s6105_dai = { /* s6105 audio machine driver */ static struct snd_soc_card snd_soc_card_s6105 = { .name = "Stretch IP Camera", + .owner = THIS_MODULE, .dai_link = &s6105_dai, .num_links = 1, }; diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 53aaa69eda0..f3417f2311b 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -193,8 +193,22 @@ config SND_SOC_SPEYSIDE select SND_SOC_WM9081 select SND_SOC_WM1250_EV1 -config SND_SOC_SPEYSIDE_WM8962 - tristate "Audio support for Wolfson Speyside with WM8962" +config SND_SOC_TOBERMORY + tristate "Audio support for Wolfson Tobermory" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 select SND_SAMSUNG_I2S select SND_SOC_WM8962 + +config SND_SOC_LOWLAND + tristate "Audio support for Wolfson Lowland" + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 + select SND_SAMSUNG_I2S + select SND_SOC_WM5100 + select SND_SOC_WM9081 + +config SND_SOC_LITTLEMILL + tristate "Audio support for Wolfson Littlemill" + depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 + select SND_SAMSUNG_I2S + select MFD_WM8994 + select SND_SOC_WM8994 diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 8509d3c4366..9d03beb40c8 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -39,7 +39,9 @@ snd-soc-smdk-spdif-objs := smdk_spdif.o snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o snd-soc-speyside-objs := speyside.o -snd-soc-speyside-wm8962-objs := speyside_wm8962.o +snd-soc-tobermory-objs := tobermory.o +snd-soc-lowland-objs := lowland.o +snd-soc-littlemill-objs := littlemill.o obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o @@ -60,4 +62,6 @@ obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o -obj-$(CONFIG_SND_SOC_SPEYSIDE_WM8962) += snd-soc-speyside-wm8962.o +obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o +obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o +obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 16521e3ffc0..7b9bf93e370 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c @@ -329,12 +329,12 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_dai_ops s3c_ac97_dai_ops = { +static const struct snd_soc_dai_ops s3c_ac97_dai_ops = { .hw_params = s3c_ac97_hw_params, .trigger = s3c_ac97_trigger, }; -static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { +static const struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { .hw_params = s3c_ac97_hw_mic_params, .trigger = s3c_ac97_mic_trigger, }; @@ -509,17 +509,7 @@ static struct platform_driver s3c_ac97_driver = { }, }; -static int __init s3c_ac97_init(void) -{ - return platform_driver_register(&s3c_ac97_driver); -} -module_init(s3c_ac97_init); - -static void __exit s3c_ac97_exit(void) -{ - platform_driver_unregister(&s3c_ac97_driver); -} -module_exit(s3c_ac97_exit); +module_platform_driver(s3c_ac97_driver); MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index a68b2644178..427ae0d9817 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c @@ -403,7 +403,6 @@ static u64 dma_mask = DMA_BIT_MASK(32); static int dma_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -414,14 +413,14 @@ static int dma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -458,17 +457,7 @@ static struct platform_driver asoc_dma_driver = { .remove = __devexit_p(samsung_asoc_platform_remove), }; -static int __init samsung_asoc_init(void) -{ - return platform_driver_register(&asoc_dma_driver); -} -module_init(samsung_asoc_init); - -static void __exit samsung_asoc_exit(void) -{ - platform_driver_unregister(&asoc_dma_driver); -} -module_exit(samsung_asoc_exit); +module_platform_driver(asoc_dma_driver); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index 84f9c3cf7f3..c23c2ae91f5 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -244,6 +244,7 @@ static struct snd_soc_dai_link goni_dai[] = { static struct snd_soc_card goni = { .name = "goni", + .owner = THIS_MODULE, .dai_link = goni_dai, .num_links = ARRAY_SIZE(goni_dai), diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 03cfa5fcdcc..6e3257717c5 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c @@ -215,6 +215,7 @@ static struct snd_soc_dai_link h1940_uda1380_dai[] = { static struct snd_soc_card h1940_asoc = { .name = "h1940", + .owner = THIS_MODULE, .dai_link = h1940_uda1380_dai, .num_links = ARRAY_SIZE(h1940_uda1380_dai), diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index bff42bf370b..87a874dc7a3 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -15,6 +15,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <sound/soc.h> #include <sound/pcm_params.h> @@ -881,7 +882,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) writel(CON_RSTCLR, i2s->addr + I2SCON); if (i2s->quirks & QUIRK_SEC_DAI) - idma_reg_addr_init((void *)i2s->addr, + idma_reg_addr_init(i2s->addr, i2s->sec_dai->idma_playback.dma_addr); probe_exit: @@ -923,7 +924,7 @@ static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops samsung_i2s_dai_ops = { +static const struct snd_soc_dai_ops samsung_i2s_dai_ops = { .trigger = i2s_trigger, .hw_params = i2s_hw_params, .set_fmt = i2s_set_fmt, @@ -945,7 +946,7 @@ struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) { struct i2s_dai *i2s; - i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL); + i2s = devm_kzalloc(&pdev->dev, sizeof(struct i2s_dai), GFP_KERNEL); if (i2s == NULL) return NULL; @@ -972,10 +973,8 @@ struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) i2s->pdev = platform_device_register_resndata(NULL, pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, NULL, 0, NULL, 0); - if (IS_ERR(i2s->pdev)) { - kfree(i2s); + if (IS_ERR(i2s->pdev)) return NULL; - } } /* Pre-assign snd_soc_dai_set_drvdata */ @@ -1048,7 +1047,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) if (!pri_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); ret = -ENOMEM; - goto err1; + goto err; } pri_dai->dma_playback.dma_addr = regs_base + I2STXD; @@ -1073,7 +1072,7 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) if (!sec_dai) { dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); ret = -ENOMEM; - goto err2; + goto err; } sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; sec_dai->dma_playback.client = @@ -1092,17 +1091,15 @@ static __devinit int samsung_i2s_probe(struct platform_device *pdev) if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { dev_err(&pdev->dev, "Unable to configure gpio\n"); ret = -EINVAL; - goto err3; + goto err; } snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); + pm_runtime_enable(&pdev->dev); + return 0; -err3: - kfree(sec_dai); -err2: - kfree(pri_dai); -err1: +err: release_mem_region(regs_base, resource_size(res)); return ret; @@ -1111,6 +1108,7 @@ err1: static __devexit int samsung_i2s_remove(struct platform_device *pdev) { struct i2s_dai *i2s, *other; + struct resource *res; i2s = dev_get_drvdata(&pdev->dev); other = i2s->pri_dai ? : i2s->sec_dai; @@ -1119,7 +1117,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) other->pri_dai = NULL; other->sec_dai = NULL; } else { - struct resource *res; + pm_runtime_disable(&pdev->dev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); @@ -1128,8 +1126,6 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) i2s->pri_dai = NULL; i2s->sec_dai = NULL; - kfree(i2s); - snd_soc_unregister_dai(&pdev->dev); return 0; @@ -1144,17 +1140,7 @@ static struct platform_driver samsung_i2s_driver = { }, }; -static int __init samsung_i2s_init(void) -{ - return platform_driver_register(&samsung_i2s_driver); -} -module_init(samsung_i2s_init); - -static void __exit samsung_i2s_exit(void) -{ - platform_driver_unregister(&samsung_i2s_driver); -} -module_exit(samsung_i2s_exit); +module_platform_driver(samsung_i2s_driver); /* Module information */ MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index c41178efc90..c227c3163ca 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -387,7 +387,6 @@ static u64 idma_mask = DMA_BIT_MASK(32); static int idma_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -396,21 +395,22 @@ static int idma_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = preallocate_idma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); + } return ret; } -void idma_reg_addr_init(void *regs, dma_addr_t addr) +void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr) { spin_lock_init(&idma.lock); idma.regs = regs; idma.lp_tx_addr = addr; } -struct snd_soc_platform_driver asoc_idma_platform = { +static struct snd_soc_platform_driver asoc_idma_platform = { .ops = &idma_ops, .pcm_new = idma_new, .pcm_free = idma_free, @@ -437,17 +437,7 @@ static struct platform_driver asoc_idma_driver = { .remove = __devexit_p(asoc_idma_platform_remove), }; -static int __init asoc_idma_init(void) -{ - return platform_driver_register(&asoc_idma_driver); -} -module_init(asoc_idma_init); - -static void __exit asoc_idma_exit(void) -{ - platform_driver_unregister(&asoc_idma_driver); -} -module_exit(asoc_idma_exit); +module_platform_driver(asoc_idma_driver); MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>"); MODULE_DESCRIPTION("Samsung ASoC IDMA Driver"); diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h index 48273216166..8644946973e 100644 --- a/sound/soc/samsung/idma.h +++ b/sound/soc/samsung/idma.h @@ -14,7 +14,7 @@ #ifndef __SND_SOC_SAMSUNG_IDMA_H_ #define __SND_SOC_SAMSUNG_IDMA_H_ -extern void idma_reg_addr_init(void *regs, dma_addr_t addr); +extern void idma_reg_addr_init(void __iomem *regs, dma_addr_t addr); /* dma_state */ #define LPAM_DMA_STOP 0 diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 1826acf20f7..1578663a1fa 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c @@ -101,7 +101,6 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; /* These endpoints are not being used. */ snd_soc_dapm_nc_pin(dapm, "LINPUT2"); @@ -128,10 +127,11 @@ static struct snd_soc_dai_link jive_dai = { /* jive audio machine driver */ static struct snd_soc_card snd_soc_machine_jive = { .name = "Jive", + .owner = THIS_MODULE, .dai_link = &jive_dai, .num_links = 1, - .dapm_widgtets = wm8750_dapm_widgets, + .dapm_widgets = wm8750_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), .dapm_routes = audio_map, .num_dapm_routes = ARRAY_SIZE(audio_map), diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c new file mode 100644 index 00000000000..9dd818bde06 --- /dev/null +++ b/sound/soc/samsung/littlemill.c @@ -0,0 +1,253 @@ +/* + * Littlemill audio support + * + * Copyright 2011 Wolfson Microelectronics + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include <linux/gpio.h> +#include <linux/module.h> + +#include "../codecs/wm8994.h" + +static int sample_rate = 44100; + +static int littlemill_set_bias_level(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) +{ + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + int ret; + + if (dapm->dev != codec_dai->dev) + return 0; + + switch (level) { + case SND_SOC_BIAS_PREPARE: + /* + * If we've not already clocked things via hw_params() + * then do so now, otherwise these are noops. + */ + if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, + WM8994_FLL_SRC_MCLK2, 32768, + sample_rate * 512); + if (ret < 0) { + pr_err("Failed to start FLL: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, + WM8994_SYSCLK_FLL1, + sample_rate * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + pr_err("Failed to set SYSCLK: %d\n", ret); + return ret; + } + } + break; + + default: + break; + } + + return 0; +} + +static int littlemill_set_bias_level_post(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) +{ + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + int ret; + + if (dapm->dev != codec_dai->dev) + return 0; + + switch (level) { + case SND_SOC_BIAS_STANDBY: + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2, + 32768, SND_SOC_CLOCK_IN); + if (ret < 0) { + pr_err("Failed to switch away from FLL: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, + 0, 0, 0); + if (ret < 0) { + pr_err("Failed to stop FLL: %d\n", ret); + return ret; + } + break; + + default: + break; + } + + dapm->bias_level = level; + + return 0; +} + +static int littlemill_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + sample_rate = params_rate(params); + + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, + WM8994_FLL_SRC_MCLK2, 32768, + sample_rate * 512); + if (ret < 0) { + pr_err("Failed to start FLL: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, + WM8994_SYSCLK_FLL1, + sample_rate * 512, + SND_SOC_CLOCK_IN); + if (ret < 0) { + pr_err("Failed to set SYSCLK: %d\n", ret); + return ret; + } + + return 0; +} + +static struct snd_soc_ops littlemill_ops = { + .hw_params = littlemill_hw_params, +}; + +static struct snd_soc_dai_link littlemill_dai[] = { + { + .name = "CPU", + .stream_name = "CPU", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm8994-aif1", + .platform_name = "samsung-audio", + .codec_name = "wm8994-codec", + .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM, + .ops = &littlemill_ops, + }, +}; + +static struct snd_soc_dapm_widget widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + + SND_SOC_DAPM_MIC("AMIC", NULL), + SND_SOC_DAPM_MIC("DMIC", NULL), +}; + +static struct snd_soc_dapm_route audio_paths[] = { + { "Headphone", NULL, "HPOUT1L" }, + { "Headphone", NULL, "HPOUT1R" }, + + { "AMIC", NULL, "MICBIAS1" }, /* Default for AMICBIAS jumper */ + { "IN1LN", NULL, "AMIC" }, + + { "DMIC", NULL, "MICBIAS2" }, /* Default for DMICBIAS jumper */ + { "DMIC1DAT", NULL, "DMIC" }, + { "DMIC2DAT", NULL, "DMIC" }, +}; + +static struct snd_soc_jack littlemill_headset; + +static int littlemill_late_probe(struct snd_soc_card *card) +{ + struct snd_soc_codec *codec = card->rtd[0].codec; + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + int ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK2, + 32768, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_jack_new(codec, "Headset", + SND_JACK_HEADSET | SND_JACK_MECHANICAL | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | + SND_JACK_BTN_4 | SND_JACK_BTN_5, + &littlemill_headset); + if (ret) + return ret; + + /* This will check device compatibility itself */ + wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); + + return 0; +} + +static struct snd_soc_card littlemill = { + .name = "Littlemill", + .owner = THIS_MODULE, + .dai_link = littlemill_dai, + .num_links = ARRAY_SIZE(littlemill_dai), + + .set_bias_level = littlemill_set_bias_level, + .set_bias_level_post = littlemill_set_bias_level_post, + + .dapm_widgets = widgets, + .num_dapm_widgets = ARRAY_SIZE(widgets), + .dapm_routes = audio_paths, + .num_dapm_routes = ARRAY_SIZE(audio_paths), + + .late_probe = littlemill_late_probe, +}; + +static __devinit int littlemill_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &littlemill; + int ret; + + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + return ret; + } + + return 0; +} + +static int __devexit littlemill_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver littlemill_driver = { + .driver = { + .name = "littlemill", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = littlemill_probe, + .remove = __devexit_p(littlemill_remove), +}; + +module_platform_driver(littlemill_driver); + +MODULE_DESCRIPTION("Littlemill audio support"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:littlemill"); diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c index cde38b8e9dc..69c4a5934a4 100644 --- a/sound/soc/samsung/ln2440sbc_alc650.c +++ b/sound/soc/samsung/ln2440sbc_alc650.c @@ -34,6 +34,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { static struct snd_soc_card ln2440sbc = { .name = "LN2440SBC", + .owner = THIS_MODULE, .dai_link = ln2440sbc_dai, .num_links = ARRAY_SIZE(ln2440sbc_dai), }; diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c new file mode 100644 index 00000000000..4adff934f77 --- /dev/null +++ b/sound/soc/samsung/lowland.c @@ -0,0 +1,237 @@ +/* + * Lowland audio support + * + * Copyright 2011 Wolfson Microelectronics + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <sound/soc.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include <linux/gpio.h> +#include <linux/module.h> + +#include "../codecs/wm5100.h" +#include "../codecs/wm9081.h" + +#define MCLK1_RATE (44100 * 512) +#define CLKOUT_RATE (44100 * 256) + +static int lowland_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int ret; + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops lowland_ops = { + .hw_params = lowland_hw_params, +}; + +static struct snd_soc_jack lowland_headset; + +/* Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin lowland_headset_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + int ret; + + ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_SYSCLK, + WM5100_CLKSRC_MCLK1, MCLK1_RATE, + SND_SOC_CLOCK_IN); + if (ret < 0) { + pr_err("Failed to set SYSCLK clock source: %d\n", ret); + return ret; + } + + /* Clock OPCLK, used by the other audio components. */ + ret = snd_soc_codec_set_sysclk(codec, WM5100_CLK_OPCLK, 0, + CLKOUT_RATE, 0); + if (ret < 0) { + pr_err("Failed to set OPCLK rate: %d\n", ret); + return ret; + } + + ret = snd_soc_jack_new(codec, "Headset", + SND_JACK_LINEOUT | SND_JACK_HEADSET | + SND_JACK_BTN_0, + &lowland_headset); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&lowland_headset, + ARRAY_SIZE(lowland_headset_pins), + lowland_headset_pins); + if (ret) + return ret; + + wm5100_detect(codec, &lowland_headset); + + return 0; +} + +static struct snd_soc_dai_link lowland_dai[] = { + { + .name = "CPU", + .stream_name = "CPU", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm5100-aif1", + .platform_name = "samsung-audio", + .codec_name = "wm5100.1-001a", + .ops = &lowland_ops, + .init = lowland_wm5100_init, + }, + { + .name = "Baseband", + .stream_name = "Baseband", + .cpu_dai_name = "wm5100-aif2", + .codec_dai_name = "wm1250-ev1", + .codec_name = "wm1250-ev1.1-0027", + .ops = &lowland_ops, + .ignore_suspend = 1, + }, +}; + +static int lowland_wm9081_init(struct snd_soc_dapm_context *dapm) +{ + snd_soc_dapm_nc_pin(dapm, "LINEOUT"); + + /* At any time the WM9081 is active it will have this clock */ + return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, + CLKOUT_RATE, 0); +} + +static struct snd_soc_aux_dev lowland_aux_dev[] = { + { + .name = "wm9081", + .codec_name = "wm9081.1-006c", + .init = lowland_wm9081_init, + }, +}; + +static struct snd_soc_codec_conf lowland_codec_conf[] = { + { + .dev_name = "wm9081.1-006c", + .name_prefix = "Sub", + }, +}; + +static const struct snd_kcontrol_new controls[] = { + SOC_DAPM_PIN_SWITCH("Main Speaker"), + SOC_DAPM_PIN_SWITCH("Main DMIC"), + SOC_DAPM_PIN_SWITCH("Main AMIC"), + SOC_DAPM_PIN_SWITCH("WM1250 Input"), + SOC_DAPM_PIN_SWITCH("WM1250 Output"), + SOC_DAPM_PIN_SWITCH("Headphone"), +}; + +static struct snd_soc_dapm_widget widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + + SND_SOC_DAPM_SPK("Main Speaker", NULL), + + SND_SOC_DAPM_MIC("Main AMIC", NULL), + SND_SOC_DAPM_MIC("Main DMIC", NULL), +}; + +static struct snd_soc_dapm_route audio_paths[] = { + { "Sub IN1", NULL, "HPOUT2L" }, + { "Sub IN2", NULL, "HPOUT2R" }, + + { "Main Speaker", NULL, "Sub SPKN" }, + { "Main Speaker", NULL, "Sub SPKP" }, + { "Main Speaker", NULL, "SPKDAT1" }, +}; + +static struct snd_soc_card lowland = { + .name = "Lowland", + .owner = THIS_MODULE, + .dai_link = lowland_dai, + .num_links = ARRAY_SIZE(lowland_dai), + .aux_dev = lowland_aux_dev, + .num_aux_devs = ARRAY_SIZE(lowland_aux_dev), + .codec_conf = lowland_codec_conf, + .num_configs = ARRAY_SIZE(lowland_codec_conf), + + .controls = controls, + .num_controls = ARRAY_SIZE(controls), + .dapm_widgets = widgets, + .num_dapm_widgets = ARRAY_SIZE(widgets), + .dapm_routes = audio_paths, + .num_dapm_routes = ARRAY_SIZE(audio_paths), +}; + +static __devinit int lowland_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &lowland; + int ret; + + card->dev = &pdev->dev; + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", + ret); + return ret; + } + + return 0; +} + +static int __devexit lowland_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + + snd_soc_unregister_card(card); + + return 0; +} + +static struct platform_driver lowland_driver = { + .driver = { + .name = "lowland", + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = lowland_probe, + .remove = __devexit_p(lowland_remove), +}; + +module_platform_driver(lowland_driver); + +MODULE_DESCRIPTION("Lowland audio support"); +MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:lowland"); diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 7207189cd21..7ac0ba2025c 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -465,6 +465,7 @@ static const struct gpio neo1973_gta02_gpios[] = {}; static struct snd_soc_card neo1973 = { .name = "neo1973", + .owner = THIS_MODULE, .dai_link = neo1973_dai, .num_links = ARRAY_SIZE(neo1973_dai), .aux_dev = neo1973_aux_devs, diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 05a47cf7f06..56780206c00 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c @@ -14,6 +14,7 @@ #include <linux/clk.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <sound/soc.h> #include <sound/pcm_params.h> @@ -452,7 +453,7 @@ static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, return 0; } -static struct snd_soc_dai_ops s3c_pcm_dai_ops = { +static const struct snd_soc_dai_ops s3c_pcm_dai_ops = { .set_sysclk = s3c_pcm_set_sysclk, .set_clkdiv = s3c_pcm_set_clkdiv, .trigger = s3c_pcm_trigger, @@ -478,7 +479,7 @@ static struct snd_soc_dai_ops s3c_pcm_dai_ops = { .formats = SNDRV_PCM_FMTBIT_S16_LE, \ } -struct snd_soc_dai_driver s3c_pcm_dai[] = { +static struct snd_soc_dai_driver s3c_pcm_dai[] = { [0] = { .name = "samsung-pcm.0", S3C_PCM_DAI_DECLARE, @@ -488,7 +489,6 @@ struct snd_soc_dai_driver s3c_pcm_dai[] = { S3C_PCM_DAI_DECLARE, }, }; -EXPORT_SYMBOL_GPL(s3c_pcm_dai); static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) { @@ -570,12 +570,6 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) } clk_enable(pcm->pclk); - ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); - if (ret != 0) { - dev_err(&pdev->dev, "failed to get pcm_clock\n"); - goto err5; - } - s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start + S3C_PCM_RXFIFO; s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start @@ -587,6 +581,14 @@ static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; + pm_runtime_enable(&pdev->dev); + + ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); + if (ret != 0) { + dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); + goto err5; + } + return 0; err5: @@ -610,6 +612,8 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) snd_soc_unregister_dai(&pdev->dev); + pm_runtime_disable(&pdev->dev); + iounmap(pcm->regs); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -632,17 +636,7 @@ static struct platform_driver s3c_pcm_driver = { }, }; -static int __init s3c_pcm_init(void) -{ - return platform_driver_register(&s3c_pcm_driver); -} -module_init(s3c_pcm_init); - -static void __exit s3c_pcm_exit(void) -{ - platform_driver_unregister(&s3c_pcm_driver); -} -module_exit(s3c_pcm_exit); +module_platform_driver(s3c_pcm_driver); /* Module information */ MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 71b4c029fc3..21e12361a9c 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -114,6 +114,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static struct snd_soc_card rx1950_asoc = { .name = "rx1950", + .owner = THIS_MODULE, .dai_link = rx1950_uda1380_dai, .num_links = ARRAY_SIZE(rx1950_uda1380_dai), diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 7bbec25e6e1..72185078ddf 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -142,7 +142,7 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { +static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { .hw_params = s3c2412_i2s_hw_params, }; @@ -184,17 +184,7 @@ static struct platform_driver s3c2412_iis_driver = { }, }; -static int __init s3c2412_i2s_init(void) -{ - return platform_driver_register(&s3c2412_iis_driver); -} -module_init(s3c2412_i2s_init); - -static void __exit s3c2412_i2s_exit(void) -{ - platform_driver_unregister(&s3c2412_iis_driver); -} -module_exit(s3c2412_i2s_exit); +module_platform_driver(s3c2412_iis_driver); /* Module information */ MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 558c64bbed2..c4aa4d412fb 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -444,7 +444,7 @@ static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) -static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { +static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { .trigger = s3c24xx_i2s_trigger, .hw_params = s3c24xx_i2s_hw_params, .set_fmt = s3c24xx_i2s_set_fmt, @@ -489,17 +489,7 @@ static struct platform_driver s3c24xx_iis_driver = { }, }; -static int __init s3c24xx_i2s_init(void) -{ - return platform_driver_register(&s3c24xx_iis_driver); -} -module_init(s3c24xx_i2s_init); - -static void __exit s3c24xx_i2s_exit(void) -{ - platform_driver_unregister(&s3c24xx_iis_driver); -} -module_exit(s3c24xx_i2s_exit); +module_platform_driver(s3c24xx_iis_driver); /* Module information */ MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index d125e79baf7..7ace6a87f41 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c @@ -89,6 +89,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = { /* simtec audio machine driver */ static struct snd_soc_card snd_soc_machine_simtec_aic33 = { .name = "Simtec-Hermes", + .owner = THIS_MODULE, .dai_link = &simtec_dai_aic33, .num_links = 1, @@ -114,21 +115,9 @@ static struct platform_driver simtec_audio_hermes_platdrv = { .remove = __devexit_p(simtec_audio_remove), }; -MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); - -static int __init simtec_hermes_modinit(void) -{ - return platform_driver_register(&simtec_audio_hermes_platdrv); -} - -static void __exit simtec_hermes_modexit(void) -{ - platform_driver_unregister(&simtec_audio_hermes_platdrv); -} - -module_init(simtec_hermes_modinit); -module_exit(simtec_hermes_modexit); +module_platform_driver(simtec_audio_hermes_platdrv); +MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index 5e4fd46b720..c42d5f00b0e 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c @@ -78,6 +78,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = { /* simtec audio machine driver */ static struct snd_soc_card snd_soc_machine_simtec_aic23 = { .name = "Simtec", + .owner = THIS_MODULE, .dai_link = &simtec_dai_aic23, .num_links = 1, @@ -92,7 +93,7 @@ static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); } -static struct platform_driver simtec_audio_tlv320aic23_platdrv = { +static struct platform_driver simtec_audio_tlv320aic23_driver = { .driver = { .owner = THIS_MODULE, .name = "s3c24xx-simtec-tlv320aic23", @@ -102,21 +103,9 @@ static struct platform_driver simtec_audio_tlv320aic23_platdrv = { .remove = __devexit_p(simtec_audio_remove), }; -MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); - -static int __init simtec_tlv320aic23_modinit(void) -{ - return platform_driver_register(&simtec_audio_tlv320aic23_platdrv); -} - -static void __exit simtec_tlv320aic23_modexit(void) -{ - platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv); -} - -module_init(simtec_tlv320aic23_modinit); -module_exit(simtec_tlv320aic23_modexit); +module_platform_driver(simtec_audio_tlv320aic23_driver); +MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index 548c6ac6e7b..d731042e51b 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -229,6 +229,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { static struct snd_soc_card snd_soc_s3c24xx_uda134x = { .name = "S3C24XX_UDA134X", + .owner = THIS_MODULE, .dai_link = &s3c24xx_uda134x_dai_link, .num_links = 1, }; @@ -343,19 +344,7 @@ static struct platform_driver s3c24xx_uda134x_driver = { }, }; -static int __init s3c24xx_uda134x_init(void) -{ - return platform_driver_register(&s3c24xx_uda134x_driver); -} - -static void __exit s3c24xx_uda134x_exit(void) -{ - platform_driver_unregister(&s3c24xx_uda134x_driver); -} - - -module_init(s3c24xx_uda134x_init); -module_exit(s3c24xx_uda134x_exit); +module_platform_driver(s3c24xx_uda134x_driver); MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver"); diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index a22fc440280..f2dcb424ea2 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -198,6 +198,7 @@ static struct snd_soc_dai_link smartq_dai[] = { static struct snd_soc_card snd_soc_smartq = { .name = "SmartQ", + .owner = THIS_MODULE, .dai_link = smartq_dai, .num_links = ARRAY_SIZE(smartq_dai), diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c index 3a0dbfc793f..720ba29bb7e 100644 --- a/sound/soc/samsung/smdk2443_wm9710.c +++ b/sound/soc/samsung/smdk2443_wm9710.c @@ -12,6 +12,7 @@ * */ +#include <linux/module.h> #include <sound/soc.h> static struct snd_soc_card smdk2443; @@ -29,6 +30,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { static struct snd_soc_card smdk2443 = { .name = "SMDK2443", + .owner = THIS_MODULE, .dai_link = smdk2443_dai, .num_links = ARRAY_SIZE(smdk2443_dai), }; diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index e0fd8ad2355..beaa9c15d69 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -160,6 +160,7 @@ static struct snd_soc_dai_link smdk_dai = { static struct snd_soc_card smdk = { .name = "SMDK-S/PDIF", + .owner = THIS_MODULE, .dai_link = &smdk_dai, .num_links = 1, }; diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 81b44782399..bff8758e7f2 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -203,6 +203,7 @@ static struct snd_soc_dai_link smdk_dai[] = { static struct snd_soc_card smdk = { .name = "SMDK-I2S", + .owner = THIS_MODULE, .dai_link = smdk_dai, .num_links = 2, diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 0677473e6b6..fab5322e9f0 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c @@ -143,6 +143,7 @@ static struct snd_soc_dai_link smdk_dai[] = { static struct snd_soc_card smdk_pcm = { .name = "SMDK-PCM", + .owner = THIS_MODULE, .dai_link = smdk_dai, .num_links = 2, }; @@ -188,19 +189,7 @@ static struct platform_driver snd_smdk_driver = { .remove = __devexit_p(snd_smdk_remove), }; -static int __init smdk_audio_init(void) -{ - return platform_driver_register(&snd_smdk_driver); -} - -module_init(smdk_audio_init); - -static void __exit smdk_audio_exit(void) -{ - platform_driver_unregister(&snd_smdk_driver); -} - -module_exit(smdk_audio_exit); +module_platform_driver(snd_smdk_driver); MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>"); MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM"); diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index f75e43997d5..8eb309f23d1 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c @@ -9,6 +9,7 @@ #include "../codecs/wm8994.h" #include <sound/pcm_params.h> +#include <linux/module.h> /* * Default CFG switch settings to use this driver: @@ -143,6 +144,7 @@ static struct snd_soc_dai_link smdk_dai[] = { static struct snd_soc_card smdk = { .name = "SMDK-I2S", + .owner = THIS_MODULE, .dai_link = smdk_dai, .num_links = ARRAY_SIZE(smdk_dai), }; diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index da9c2a264d9..77ecba93511 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c @@ -124,6 +124,7 @@ static struct snd_soc_dai_link smdk_dai[] = { static struct snd_soc_card smdk_pcm = { .name = "SMDK-PCM", + .owner = THIS_MODULE, .dai_link = smdk_dai, .num_links = 1, }; @@ -158,19 +159,7 @@ static struct platform_driver snd_smdk_driver = { .remove = __devexit_p(snd_smdk_remove), }; -static int __init smdk_audio_init(void) -{ - return platform_driver_register(&snd_smdk_driver); -} - -module_init(smdk_audio_init); - -static void __exit smdk_audio_exit(void) -{ - platform_driver_unregister(&snd_smdk_driver); -} - -module_exit(smdk_audio_exit); +module_platform_driver(snd_smdk_driver); MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>"); MODULE_DESCRIPTION("ALSA SoC SMDK WM8994 for PCM"); diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 31c6daf6d4d..8e26a730fcd 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -50,6 +50,7 @@ static struct snd_soc_dai_link smdk_dai = { static struct snd_soc_card smdk = { .name = "SMDK WM9713", + .owner = THIS_MODULE, .dai_link = &smdk_dai, .num_links = 1, }; diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 468cff1bb1a..a5a56a12034 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c @@ -334,7 +334,7 @@ static int spdif_resume(struct snd_soc_dai *cpu_dai) #define spdif_resume NULL #endif -static struct snd_soc_dai_ops spdif_dai_ops = { +static const struct snd_soc_dai_ops spdif_dai_ops = { .set_sysclk = spdif_set_sysclk, .trigger = spdif_trigger, .hw_params = spdif_hw_params, @@ -483,17 +483,7 @@ static struct platform_driver samsung_spdif_driver = { }, }; -static int __init spdif_init(void) -{ - return platform_driver_register(&samsung_spdif_driver); -} -module_init(spdif_init); - -static void __exit spdif_exit(void) -{ - platform_driver_unregister(&samsung_spdif_driver); -} -module_exit(spdif_exit); +module_platform_driver(samsung_spdif_driver); MODULE_AUTHOR("Seungwhan Youn, <sw.youn@samsung.com>"); MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver"); diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 85bf541a771..f9ab7707a3e 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -19,6 +19,7 @@ #include "../codecs/wm9081.h" #define WM8996_HPSEL_GPIO 214 +#define MCLK_AUDIO_RATE (512 * 48000) static int speyside_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, @@ -67,7 +68,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(codec_dai, 0, WM8996_FLL_MCLK2, - 32768, 48000 * 256); + 32768, MCLK_AUDIO_RATE); if (ret < 0) { pr_err("Failed to start FLL\n"); return ret; @@ -75,7 +76,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, ret = snd_soc_dai_set_sysclk(codec_dai, WM8996_SYSCLK_FLL, - 48000 * 256, + MCLK_AUDIO_RATE, SND_SOC_CLOCK_IN); if (ret < 0) return ret; @@ -191,7 +192,7 @@ static int speyside_late_probe(struct snd_soc_card *card) snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); @@ -222,11 +223,9 @@ static struct snd_soc_dai_link speyside_dai[] = { static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) { - snd_soc_dapm_nc_pin(dapm, "LINEOUT"); - /* At any time the WM9081 is active it will have this clock */ return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, - 48000 * 256, 0); + MCLK_AUDIO_RATE, 0); } static struct snd_soc_aux_dev speyside_aux_dev[] = { @@ -292,6 +291,7 @@ static struct snd_soc_dapm_route audio_paths[] = { static struct snd_soc_card speyside = { .name = "Speyside", + .owner = THIS_MODULE, .dai_link = speyside_dai, .num_links = ARRAY_SIZE(speyside_dai), .aux_dev = speyside_aux_dev, @@ -308,6 +308,7 @@ static struct snd_soc_card speyside = { .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_paths, .num_dapm_routes = ARRAY_SIZE(audio_paths), + .fully_routed = true, .late_probe = speyside_late_probe, }; @@ -348,17 +349,7 @@ static struct platform_driver speyside_driver = { .remove = __devexit_p(speyside_remove), }; -static int __init speyside_audio_init(void) -{ - return platform_driver_register(&speyside_driver); -} -module_init(speyside_audio_init); - -static void __exit speyside_audio_exit(void) -{ - platform_driver_unregister(&speyside_driver); -} -module_exit(speyside_audio_exit); +module_platform_driver(speyside_driver); MODULE_DESCRIPTION("Speyside audio support"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/tobermory.c index e3e27166cc5..9199649bf78 100644 --- a/sound/soc/samsung/speyside_wm8962.c +++ b/sound/soc/samsung/tobermory.c @@ -1,5 +1,5 @@ /* - * Speyside with WM8962 audio support + * Tobermory audio support * * Copyright 2011 Wolfson Microelectronics * @@ -19,7 +19,7 @@ static int sample_rate = 44100; -static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, +static int tobermory_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { @@ -56,7 +56,7 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, return 0; } -static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card, +static int tobermory_set_bias_level_post(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level) { @@ -92,7 +92,7 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card, return 0; } -static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, +static int tobermory_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { sample_rate = params_rate(params); @@ -100,11 +100,11 @@ static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, return 0; } -static struct snd_soc_ops speyside_wm8962_ops = { - .hw_params = speyside_wm8962_hw_params, +static struct snd_soc_ops tobermory_ops = { + .hw_params = tobermory_hw_params, }; -static struct snd_soc_dai_link speyside_wm8962_dai[] = { +static struct snd_soc_dai_link tobermory_dai[] = { { .name = "CPU", .stream_name = "CPU", @@ -114,7 +114,7 @@ static struct snd_soc_dai_link speyside_wm8962_dai[] = { .codec_name = "wm8962.1-001a", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, - .ops = &speyside_wm8962_ops, + .ops = &tobermory_ops, }, }; @@ -152,10 +152,10 @@ static struct snd_soc_dapm_route audio_paths[] = { { "DMICDAT", NULL, "DMIC" }, }; -static struct snd_soc_jack speyside_wm8962_headset; +static struct snd_soc_jack tobermory_headset; /* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin speyside_wm8962_headset_pins[] = { +static struct snd_soc_jack_pin tobermory_headset_pins[] = { { .pin = "Headset Mic", .mask = SND_JACK_MICROPHONE, @@ -166,7 +166,7 @@ static struct snd_soc_jack_pin speyside_wm8962_headset_pins[] = { }, }; -static int speyside_wm8962_late_probe(struct snd_soc_card *card) +static int tobermory_late_probe(struct snd_soc_card *card) { struct snd_soc_codec *codec = card->rtd[0].codec; struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; @@ -179,28 +179,29 @@ static int speyside_wm8962_late_probe(struct snd_soc_card *card) ret = snd_soc_jack_new(codec, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, - &speyside_wm8962_headset); + &tobermory_headset); if (ret) return ret; - ret = snd_soc_jack_add_pins(&speyside_wm8962_headset, - ARRAY_SIZE(speyside_wm8962_headset_pins), - speyside_wm8962_headset_pins); + ret = snd_soc_jack_add_pins(&tobermory_headset, + ARRAY_SIZE(tobermory_headset_pins), + tobermory_headset_pins); if (ret) return ret; - wm8962_mic_detect(codec, &speyside_wm8962_headset); + wm8962_mic_detect(codec, &tobermory_headset); return 0; } -static struct snd_soc_card speyside_wm8962 = { - .name = "Speyside WM8962", - .dai_link = speyside_wm8962_dai, - .num_links = ARRAY_SIZE(speyside_wm8962_dai), +static struct snd_soc_card tobermory = { + .name = "Tobermory", + .owner = THIS_MODULE, + .dai_link = tobermory_dai, + .num_links = ARRAY_SIZE(tobermory_dai), - .set_bias_level = speyside_wm8962_set_bias_level, - .set_bias_level_post = speyside_wm8962_set_bias_level_post, + .set_bias_level = tobermory_set_bias_level, + .set_bias_level_post = tobermory_set_bias_level_post, .controls = controls, .num_controls = ARRAY_SIZE(controls), @@ -208,13 +209,14 @@ static struct snd_soc_card speyside_wm8962 = { .num_dapm_widgets = ARRAY_SIZE(widgets), .dapm_routes = audio_paths, .num_dapm_routes = ARRAY_SIZE(audio_paths), + .fully_routed = true, - .late_probe = speyside_wm8962_late_probe, + .late_probe = tobermory_late_probe, }; -static __devinit int speyside_wm8962_probe(struct platform_device *pdev) +static __devinit int tobermory_probe(struct platform_device *pdev) { - struct snd_soc_card *card = &speyside_wm8962; + struct snd_soc_card *card = &tobermory; int ret; card->dev = &pdev->dev; @@ -229,7 +231,7 @@ static __devinit int speyside_wm8962_probe(struct platform_device *pdev) return 0; } -static int __devexit speyside_wm8962_remove(struct platform_device *pdev) +static int __devexit tobermory_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); @@ -238,29 +240,19 @@ static int __devexit speyside_wm8962_remove(struct platform_device *pdev) return 0; } -static struct platform_driver speyside_wm8962_driver = { +static struct platform_driver tobermory_driver = { .driver = { - .name = "speyside-wm8962", + .name = "tobermory", .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, }, - .probe = speyside_wm8962_probe, - .remove = __devexit_p(speyside_wm8962_remove), + .probe = tobermory_probe, + .remove = __devexit_p(tobermory_remove), }; -static int __init speyside_wm8962_audio_init(void) -{ - return platform_driver_register(&speyside_wm8962_driver); -} -module_init(speyside_wm8962_audio_init); - -static void __exit speyside_wm8962_audio_exit(void) -{ - platform_driver_unregister(&speyside_wm8962_driver); -} -module_exit(speyside_wm8962_audio_exit); +module_platform_driver(tobermory_driver); -MODULE_DESCRIPTION("Speyside WM8962 audio support"); +MODULE_DESCRIPTION("Tobermory audio support"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:speyside-wm8962"); +MODULE_ALIAS("platform:tobermory"); diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index db74005f37c..7da20186b19 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -369,17 +369,7 @@ static struct platform_driver sh7760_pcm_driver = { .remove = __devexit_p(sh7760_soc_platform_remove), }; -static int __init snd_sh7760_pcm_init(void) -{ - return platform_driver_register(&sh7760_pcm_driver); -} -module_init(snd_sh7760_pcm_init); - -static void __exit snd_sh7760_pcm_exit(void) -{ - platform_driver_unregister(&sh7760_pcm_driver); -} -module_exit(snd_sh7760_pcm_exit); +module_platform_driver(sh7760_pcm_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index dff64b95f5d..97f540aabbd 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -49,6 +49,7 @@ static struct snd_soc_dai_link fsi_dai_link = { }; static struct snd_soc_card fsi_soc_card = { + .owner = THIS_MODULE, .dai_link = &fsi_dai_link, .num_links = 1, }; @@ -58,27 +59,23 @@ static struct platform_device *fsi_snd_device; static int fsi_ak4642_probe(struct platform_device *pdev) { int ret = -ENOMEM; - const struct platform_device_id *id_entry; - struct fsi_ak4642_data *pdata; + struct fsi_ak4642_info *pinfo = pdev->dev.platform_data; - id_entry = pdev->id_entry; - if (!id_entry) { - dev_err(&pdev->dev, "unknown fsi ak4642\n"); - return -ENODEV; + if (!pinfo) { + dev_err(&pdev->dev, "no info for fsi ak4642\n"); + goto out; } - pdata = (struct fsi_ak4642_data *)id_entry->driver_data; - - fsi_snd_device = platform_device_alloc("soc-audio", pdata->id); + fsi_snd_device = platform_device_alloc("soc-audio", pinfo->id); if (!fsi_snd_device) goto out; - fsi_dai_link.name = pdata->name; - fsi_dai_link.stream_name = pdata->name; - fsi_dai_link.cpu_dai_name = pdata->cpu_dai; - fsi_dai_link.platform_name = pdata->platform; - fsi_dai_link.codec_name = pdata->codec; - fsi_soc_card.name = pdata->card; + fsi_dai_link.name = pinfo->name; + fsi_dai_link.stream_name = pinfo->name; + fsi_dai_link.cpu_dai_name = pinfo->cpu_dai; + fsi_dai_link.platform_name = pinfo->platform; + fsi_dai_link.codec_name = pinfo->codec; + fsi_soc_card.name = pinfo->card; platform_set_drvdata(fsi_snd_device, &fsi_soc_card); ret = platform_device_add(fsi_snd_device); @@ -96,114 +93,15 @@ static int fsi_ak4642_remove(struct platform_device *pdev) return 0; } -static struct fsi_ak4642_data fsi_a_ak4642 = { - .name = "AK4642", - .card = "FSIA-AK4642", - .cpu_dai = "fsia-dai", - .codec = "ak4642-codec.0-0012", - .platform = "sh_fsi.0", - .id = FSI_PORT_A, -}; - -static struct fsi_ak4642_data fsi_b_ak4642 = { - .name = "AK4642", - .card = "FSIB-AK4642", - .cpu_dai = "fsib-dai", - .codec = "ak4642-codec.0-0012", - .platform = "sh_fsi.0", - .id = FSI_PORT_B, -}; - -static struct fsi_ak4642_data fsi_a_ak4643 = { - .name = "AK4643", - .card = "FSIA-AK4643", - .cpu_dai = "fsia-dai", - .codec = "ak4642-codec.0-0013", - .platform = "sh_fsi.0", - .id = FSI_PORT_A, -}; - -static struct fsi_ak4642_data fsi_b_ak4643 = { - .name = "AK4643", - .card = "FSIB-AK4643", - .cpu_dai = "fsib-dai", - .codec = "ak4642-codec.0-0013", - .platform = "sh_fsi.0", - .id = FSI_PORT_B, -}; - -static struct fsi_ak4642_data fsi2_a_ak4642 = { - .name = "AK4642", - .card = "FSI2A-AK4642", - .cpu_dai = "fsia-dai", - .codec = "ak4642-codec.0-0012", - .platform = "sh_fsi2", - .id = FSI_PORT_A, -}; - -static struct fsi_ak4642_data fsi2_b_ak4642 = { - .name = "AK4642", - .card = "FSI2B-AK4642", - .cpu_dai = "fsib-dai", - .codec = "ak4642-codec.0-0012", - .platform = "sh_fsi2", - .id = FSI_PORT_B, -}; - -static struct fsi_ak4642_data fsi2_a_ak4643 = { - .name = "AK4643", - .card = "FSI2A-AK4643", - .cpu_dai = "fsia-dai", - .codec = "ak4642-codec.0-0013", - .platform = "sh_fsi2", - .id = FSI_PORT_A, -}; - -static struct fsi_ak4642_data fsi2_b_ak4643 = { - .name = "AK4643", - .card = "FSI2B-AK4643", - .cpu_dai = "fsib-dai", - .codec = "ak4642-codec.0-0013", - .platform = "sh_fsi2", - .id = FSI_PORT_B, -}; - -static struct platform_device_id fsi_id_table[] = { - /* FSI */ - { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 }, - { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 }, - { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 }, - { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 }, - - /* FSI 2 */ - { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 }, - { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 }, - { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 }, - { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 }, - {}, -}; - static struct platform_driver fsi_ak4642 = { .driver = { .name = "fsi-ak4642-audio", }, .probe = fsi_ak4642_probe, .remove = fsi_ak4642_remove, - .id_table = fsi_id_table, }; -static int __init fsi_ak4642_init(void) -{ - return platform_driver_register(&fsi_ak4642); -} - -static void __exit fsi_ak4642_exit(void) -{ - platform_driver_unregister(&fsi_ak4642); -} - -module_init(fsi_ak4642_init); -module_exit(fsi_ak4642_exit); +module_platform_driver(fsi_ak4642); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card"); diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c index f5586b5b0c3..1dd3354c741 100644 --- a/sound/soc/sh/fsi-da7210.c +++ b/sound/soc/sh/fsi-da7210.c @@ -44,6 +44,7 @@ static struct snd_soc_dai_link fsi_da7210_dai = { static struct snd_soc_card fsi_soc_card = { .name = "FSI-DA7210", + .owner = THIS_MODULE, .dai_link = &fsi_da7210_dai, .num_links = 1, }; diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c index 3ebebe706ad..6e41908323e 100644 --- a/sound/soc/sh/fsi-hdmi.c +++ b/sound/soc/sh/fsi-hdmi.c @@ -39,6 +39,7 @@ static struct snd_soc_dai_link fsi_dai_link = { }; static struct snd_soc_card fsi_soc_card = { + .owner = THIS_MODULE, .dai_link = &fsi_dai_link, .num_links = 1, }; @@ -110,18 +111,7 @@ static struct platform_driver fsi_hdmi = { .id_table = fsi_id_table, }; -static int __init fsi_hdmi_init(void) -{ - return platform_driver_register(&fsi_hdmi); -} - -static void __exit fsi_hdmi_exit(void) -{ - platform_driver_unregister(&fsi_hdmi); -} - -module_init(fsi_hdmi_init); -module_exit(fsi_hdmi_exit); +module_platform_driver(fsi_hdmi); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card"); diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3d7016e128f..db6c89a28bd 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -32,7 +32,9 @@ #define REG_DIDT 0x0020 #define REG_DODT 0x0024 #define REG_MUTE_ST 0x0028 +#define REG_OUT_DMAC 0x002C #define REG_OUT_SEL 0x0030 +#define REG_IN_DMAC 0x0038 /* master register */ #define MST_CLK_RST 0x0210 @@ -235,13 +237,13 @@ static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data) } #define fsi_reg_write(p, r, d)\ - __fsi_reg_write((u32)(p->base + REG_##r), d) + __fsi_reg_write((p->base + REG_##r), d) #define fsi_reg_read(p, r)\ - __fsi_reg_read((u32)(p->base + REG_##r)) + __fsi_reg_read((p->base + REG_##r)) #define fsi_reg_mask_set(p, r, m, d)\ - __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d) + __fsi_reg_mask_set((p->base + REG_##r), m, d) #define fsi_master_read(p, r) _fsi_master_read(p, MST_##r) #define fsi_core_read(p, r) _fsi_master_read(p, p->core->r) @@ -886,11 +888,11 @@ static int fsi_hw_startup(struct fsi_priv *fsi, int is_play, struct device *dev) { + struct fsi_master *master = fsi_get_master(fsi); + int fsi_ver = master->core->ver; u32 flags = fsi_get_info_flags(fsi); u32 data = 0; - pm_runtime_get_sync(dev); - /* clock setting */ if (fsi_is_clk_master(fsi)) data = DIMD | DOMD; @@ -920,6 +922,17 @@ static int fsi_hw_startup(struct fsi_priv *fsi, fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); } + /* + * FIXME + * + * FSI driver assumed that data package is in-back. + * FSI2 chip can select it. + */ + if (fsi_ver >= 2) { + fsi_reg_write(fsi, OUT_DMAC, (1 << 4)); + fsi_reg_write(fsi, IN_DMAC, (1 << 4)); + } + /* irq clear */ fsi_irq_disable(fsi, is_play); fsi_irq_clear_status(fsi); @@ -936,8 +949,6 @@ static void fsi_hw_shutdown(struct fsi_priv *fsi, { if (fsi_is_clk_master(fsi)) fsi_set_master_clk(dev, fsi, fsi->rate, 0); - - pm_runtime_put_sync(dev); } static int fsi_dai_startup(struct snd_pcm_substream *substream, @@ -1081,7 +1092,7 @@ static int fsi_dai_hw_params(struct snd_pcm_substream *substream, return ret; } -static struct snd_soc_dai_ops fsi_dai_ops = { +static const struct snd_soc_dai_ops fsi_dai_ops = { .startup = fsi_dai_startup, .shutdown = fsi_dai_shutdown, .trigger = fsi_dai_trigger, @@ -1453,18 +1464,7 @@ static struct platform_driver fsi_driver = { .id_table = fsi_id_table, }; -static int __init fsi_mobile_init(void) -{ - return platform_driver_register(&fsi_driver); -} - -static void __exit fsi_mobile_exit(void) -{ - platform_driver_unregister(&fsi_driver); -} - -module_init(fsi_mobile_init); -module_exit(fsi_mobile_exit); +module_platform_driver(fsi_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SuperH onchip FSI audio driver"); diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c index c87e3ff28a0..3474d7befe5 100644 --- a/sound/soc/sh/hac.c +++ b/sound/soc/sh/hac.c @@ -266,7 +266,7 @@ static int hac_hw_params(struct snd_pcm_substream *substream, #define AC97_FMTS \ SNDRV_PCM_FMTBIT_S16_LE -static struct snd_soc_dai_ops hac_dai_ops = { +static const struct snd_soc_dai_ops hac_dai_ops = { .hw_params = hac_hw_params, }; @@ -332,17 +332,7 @@ static struct platform_driver hac_pcm_driver = { .remove = __devexit_p(hac_soc_platform_remove), }; -static int __init sh4_hac_pcm_init(void) -{ - return platform_driver_register(&hac_pcm_driver); -} -module_init(sh4_hac_pcm_init); - -static void __exit sh4_hac_pcm_exit(void) -{ - platform_driver_unregister(&hac_pcm_driver); -} -module_exit(sh4_hac_pcm_exit); +module_platform_driver(hac_pcm_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index 6088a6a3238..9d9ad8d61c0 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -164,6 +164,7 @@ static struct snd_soc_dai_link migor_dai = { /* migor audio machine driver */ static struct snd_soc_card snd_soc_migor = { .name = "Migo-R", + .owner = THIS_MODULE, .dai_link = &migor_dai, .num_links = 1, }; diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index c62ae689c4a..4a3568a9bf5 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -16,10 +16,6 @@ #define IPSEL 0xFE400034 -/* platform specific structs can be declared here */ -extern struct snd_soc_dai_driver sh4_hac_dai[2]; -extern struct snd_soc_platform_driver sh7760_soc_platform; - static struct snd_soc_dai_link sh7760_ac97_dai = { .name = "AC97", .stream_name = "AC97 HiFi", @@ -32,6 +28,7 @@ static struct snd_soc_dai_link sh7760_ac97_dai = { static struct snd_soc_card sh7760_ac97_soc_machine = { .name = "SH7760 AC97", + .owner = THIS_MODULE, .dai_link = &sh7760_ac97_dai, .num_links = 1, }; diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index edacfeb13b9..52d4c17b123 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -112,9 +112,6 @@ static void siu_dai_start(struct siu_port *port_info) dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); - /* Turn on SIU clock */ - pm_runtime_get_sync(info->dev); - /* Issue software reset to siu */ siu_write32(base + SIU_SRCTL, 0); @@ -158,9 +155,6 @@ static void siu_dai_stop(struct siu_port *port_info) /* SIU software reset */ siu_write32(base + SIU_SRCTL, 0); - - /* Turn off SIU clock */ - pm_runtime_put_sync(info->dev); } static void siu_dai_spbAselect(struct siu_port *port_info) @@ -707,7 +701,7 @@ epclkget: return ret; } -static struct snd_soc_dai_ops siu_dai_ops = { +static const struct snd_soc_dai_ops siu_dai_ops = { .startup = siu_dai_startup, .shutdown = siu_dai_shutdown, .prepare = siu_dai_prepare, @@ -852,18 +846,7 @@ static struct platform_driver siu_driver = { .remove = __devexit_p(siu_remove), }; -static int __init siu_init(void) -{ - return platform_driver_register(&siu_driver); -} - -static void __exit siu_exit(void) -{ - platform_driver_unregister(&siu_driver); -} - -module_init(siu_init) -module_exit(siu_exit) +module_platform_driver(siu_driver); MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>"); MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver"); diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index e0c621c0553..ff82b56a886 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c @@ -332,7 +332,7 @@ static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) -static struct snd_soc_dai_ops ssi_dai_ops = { +static const struct snd_soc_dai_ops ssi_dai_ops = { .startup = ssi_startup, .shutdown = ssi_shutdown, .trigger = ssi_trigger, @@ -401,17 +401,7 @@ static struct platform_driver sh4_ssi_driver = { .remove = __devexit_p(sh4_soc_dai_remove), }; -static int __init snd_sh4_ssi_init(void) -{ - return platform_driver_register(&sh4_ssi_driver); -} -module_init(snd_sh4_ssi_init); - -static void __exit snd_sh4_ssi_exit(void) -{ - platform_driver_unregister(&sh4_ssi_driver); -} -module_exit(snd_sh4_ssi_exit); +module_platform_driver(sh4_ssi_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9077aa4b3b4..9d56f0218f4 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -14,7 +14,6 @@ #include <linux/i2c.h> #include <linux/spi/spi.h> #include <sound/soc.h> -#include <linux/lzo.h> #include <linux/bitmap.h> #include <linux/rbtree.h> #include <linux/export.h> @@ -67,750 +66,6 @@ static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx, return -1; } -struct snd_soc_rbtree_node { - struct rb_node node; /* the actual rbtree node holding this block */ - unsigned int base_reg; /* base register handled by this block */ - unsigned int word_size; /* number of bytes needed to represent the register index */ - void *block; /* block of adjacent registers */ - unsigned int blklen; /* number of registers available in the block */ -} __attribute__ ((packed)); - -struct snd_soc_rbtree_ctx { - struct rb_root root; - struct snd_soc_rbtree_node *cached_rbnode; -}; - -static inline void snd_soc_rbtree_get_base_top_reg( - struct snd_soc_rbtree_node *rbnode, - unsigned int *base, unsigned int *top) -{ - *base = rbnode->base_reg; - *top = rbnode->base_reg + rbnode->blklen - 1; -} - -static unsigned int snd_soc_rbtree_get_register( - struct snd_soc_rbtree_node *rbnode, unsigned int idx) -{ - unsigned int val; - - switch (rbnode->word_size) { - case 1: { - u8 *p = rbnode->block; - val = p[idx]; - return val; - } - case 2: { - u16 *p = rbnode->block; - val = p[idx]; - return val; - } - default: - BUG(); - break; - } - return -1; -} - -static void snd_soc_rbtree_set_register(struct snd_soc_rbtree_node *rbnode, - unsigned int idx, unsigned int val) -{ - switch (rbnode->word_size) { - case 1: { - u8 *p = rbnode->block; - p[idx] = val; - break; - } - case 2: { - u16 *p = rbnode->block; - p[idx] = val; - break; - } - default: - BUG(); - break; - } -} - -static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup( - struct rb_root *root, unsigned int reg) -{ - struct rb_node *node; - struct snd_soc_rbtree_node *rbnode; - unsigned int base_reg, top_reg; - - node = root->rb_node; - while (node) { - rbnode = container_of(node, struct snd_soc_rbtree_node, node); - snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); - if (reg >= base_reg && reg <= top_reg) - return rbnode; - else if (reg > top_reg) - node = node->rb_right; - else if (reg < base_reg) - node = node->rb_left; - } - - return NULL; -} - -static int snd_soc_rbtree_insert(struct rb_root *root, - struct snd_soc_rbtree_node *rbnode) -{ - struct rb_node **new, *parent; - struct snd_soc_rbtree_node *rbnode_tmp; - unsigned int base_reg_tmp, top_reg_tmp; - unsigned int base_reg; - - parent = NULL; - new = &root->rb_node; - while (*new) { - rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node, - node); - /* base and top registers of the current rbnode */ - snd_soc_rbtree_get_base_top_reg(rbnode_tmp, &base_reg_tmp, - &top_reg_tmp); - /* base register of the rbnode to be added */ - base_reg = rbnode->base_reg; - parent = *new; - /* if this register has already been inserted, just return */ - if (base_reg >= base_reg_tmp && - base_reg <= top_reg_tmp) - return 0; - else if (base_reg > top_reg_tmp) - new = &((*new)->rb_right); - else if (base_reg < base_reg_tmp) - new = &((*new)->rb_left); - } - - /* insert the node into the rbtree */ - rb_link_node(&rbnode->node, parent, new); - rb_insert_color(&rbnode->node, root); - - return 1; -} - -static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) -{ - struct snd_soc_rbtree_ctx *rbtree_ctx; - struct rb_node *node; - struct snd_soc_rbtree_node *rbnode; - unsigned int regtmp; - unsigned int val, def; - int ret; - int i; - - rbtree_ctx = codec->reg_cache; - for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { - rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); - for (i = 0; i < rbnode->blklen; ++i) { - regtmp = rbnode->base_reg + i; - val = snd_soc_rbtree_get_register(rbnode, i); - def = snd_soc_get_cache_val(codec->reg_def_copy, i, - rbnode->word_size); - if (val == def) - continue; - - WARN_ON(!snd_soc_codec_writable_register(codec, regtmp)); - - codec->cache_bypass = 1; - ret = snd_soc_write(codec, regtmp, val); - codec->cache_bypass = 0; - if (ret) - return ret; - dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", - regtmp, val); - } - } - - return 0; -} - -static int snd_soc_rbtree_insert_to_block(struct snd_soc_rbtree_node *rbnode, - unsigned int pos, unsigned int reg, - unsigned int value) -{ - u8 *blk; - - blk = krealloc(rbnode->block, - (rbnode->blklen + 1) * rbnode->word_size, GFP_KERNEL); - if (!blk) - return -ENOMEM; - - /* insert the register value in the correct place in the rbnode block */ - memmove(blk + (pos + 1) * rbnode->word_size, - blk + pos * rbnode->word_size, - (rbnode->blklen - pos) * rbnode->word_size); - - /* update the rbnode block, its size and the base register */ - rbnode->block = blk; - rbnode->blklen++; - if (!pos) - rbnode->base_reg = reg; - - snd_soc_rbtree_set_register(rbnode, pos, value); - return 0; -} - -static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - struct snd_soc_rbtree_ctx *rbtree_ctx; - struct snd_soc_rbtree_node *rbnode, *rbnode_tmp; - struct rb_node *node; - unsigned int val; - unsigned int reg_tmp; - unsigned int base_reg, top_reg; - unsigned int pos; - int i; - int ret; - - rbtree_ctx = codec->reg_cache; - /* look up the required register in the cached rbnode */ - rbnode = rbtree_ctx->cached_rbnode; - if (rbnode) { - snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); - if (reg >= base_reg && reg <= top_reg) { - reg_tmp = reg - base_reg; - val = snd_soc_rbtree_get_register(rbnode, reg_tmp); - if (val == value) - return 0; - snd_soc_rbtree_set_register(rbnode, reg_tmp, value); - return 0; - } - } - /* if we can't locate it in the cached rbnode we'll have - * to traverse the rbtree looking for it. - */ - rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); - if (rbnode) { - reg_tmp = reg - rbnode->base_reg; - val = snd_soc_rbtree_get_register(rbnode, reg_tmp); - if (val == value) - return 0; - snd_soc_rbtree_set_register(rbnode, reg_tmp, value); - rbtree_ctx->cached_rbnode = rbnode; - } else { - /* bail out early, no need to create the rbnode yet */ - if (!value) - return 0; - /* look for an adjacent register to the one we are about to add */ - for (node = rb_first(&rbtree_ctx->root); node; - node = rb_next(node)) { - rbnode_tmp = rb_entry(node, struct snd_soc_rbtree_node, node); - for (i = 0; i < rbnode_tmp->blklen; ++i) { - reg_tmp = rbnode_tmp->base_reg + i; - if (abs(reg_tmp - reg) != 1) - continue; - /* decide where in the block to place our register */ - if (reg_tmp + 1 == reg) - pos = i + 1; - else - pos = i; - ret = snd_soc_rbtree_insert_to_block(rbnode_tmp, pos, - reg, value); - if (ret) - return ret; - rbtree_ctx->cached_rbnode = rbnode_tmp; - return 0; - } - } - /* we did not manage to find a place to insert it in an existing - * block so create a new rbnode with a single register in its block. - * This block will get populated further if any other adjacent - * registers get modified in the future. - */ - rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); - if (!rbnode) - return -ENOMEM; - rbnode->blklen = 1; - rbnode->base_reg = reg; - rbnode->word_size = codec->driver->reg_word_size; - rbnode->block = kmalloc(rbnode->blklen * rbnode->word_size, - GFP_KERNEL); - if (!rbnode->block) { - kfree(rbnode); - return -ENOMEM; - } - snd_soc_rbtree_set_register(rbnode, 0, value); - snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode); - rbtree_ctx->cached_rbnode = rbnode; - } - - return 0; -} - -static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec, - unsigned int reg, unsigned int *value) -{ - struct snd_soc_rbtree_ctx *rbtree_ctx; - struct snd_soc_rbtree_node *rbnode; - unsigned int base_reg, top_reg; - unsigned int reg_tmp; - - rbtree_ctx = codec->reg_cache; - /* look up the required register in the cached rbnode */ - rbnode = rbtree_ctx->cached_rbnode; - if (rbnode) { - snd_soc_rbtree_get_base_top_reg(rbnode, &base_reg, &top_reg); - if (reg >= base_reg && reg <= top_reg) { - reg_tmp = reg - base_reg; - *value = snd_soc_rbtree_get_register(rbnode, reg_tmp); - return 0; - } - } - /* if we can't locate it in the cached rbnode we'll have - * to traverse the rbtree looking for it. - */ - rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); - if (rbnode) { - reg_tmp = reg - rbnode->base_reg; - *value = snd_soc_rbtree_get_register(rbnode, reg_tmp); - rbtree_ctx->cached_rbnode = rbnode; - } else { - /* uninitialized registers default to 0 */ - *value = 0; - } - - return 0; -} - -static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec) -{ - struct rb_node *next; - struct snd_soc_rbtree_ctx *rbtree_ctx; - struct snd_soc_rbtree_node *rbtree_node; - - /* if we've already been called then just return */ - rbtree_ctx = codec->reg_cache; - if (!rbtree_ctx) - return 0; - - /* free up the rbtree */ - next = rb_first(&rbtree_ctx->root); - while (next) { - rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node); - next = rb_next(&rbtree_node->node); - rb_erase(&rbtree_node->node, &rbtree_ctx->root); - kfree(rbtree_node->block); - kfree(rbtree_node); - } - - /* release the resources */ - kfree(codec->reg_cache); - codec->reg_cache = NULL; - - return 0; -} - -static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) -{ - struct snd_soc_rbtree_ctx *rbtree_ctx; - unsigned int word_size; - unsigned int val; - int i; - int ret; - - codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); - if (!codec->reg_cache) - return -ENOMEM; - - rbtree_ctx = codec->reg_cache; - rbtree_ctx->root = RB_ROOT; - rbtree_ctx->cached_rbnode = NULL; - - if (!codec->reg_def_copy) - return 0; - - word_size = codec->driver->reg_word_size; - for (i = 0; i < codec->driver->reg_cache_size; ++i) { - val = snd_soc_get_cache_val(codec->reg_def_copy, i, - word_size); - if (!val) - continue; - ret = snd_soc_rbtree_cache_write(codec, i, val); - if (ret) - goto err; - } - - return 0; - -err: - snd_soc_cache_exit(codec); - return ret; -} - -#ifdef CONFIG_SND_SOC_CACHE_LZO -struct snd_soc_lzo_ctx { - void *wmem; - void *dst; - const void *src; - size_t src_len; - size_t dst_len; - size_t decompressed_size; - unsigned long *sync_bmp; - int sync_bmp_nbits; -}; - -#define LZO_BLOCK_NUM 8 -static int snd_soc_lzo_block_count(void) -{ - return LZO_BLOCK_NUM; -} - -static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx) -{ - lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); - if (!lzo_ctx->wmem) - return -ENOMEM; - return 0; -} - -static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx) -{ - size_t compress_size; - int ret; - - ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len, - lzo_ctx->dst, &compress_size, lzo_ctx->wmem); - if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len) - return -EINVAL; - lzo_ctx->dst_len = compress_size; - return 0; -} - -static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx) -{ - size_t dst_len; - int ret; - - dst_len = lzo_ctx->dst_len; - ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len, - lzo_ctx->dst, &dst_len); - if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len) - return -EINVAL; - return 0; -} - -static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec, - struct snd_soc_lzo_ctx *lzo_ctx) -{ - int ret; - - lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE); - lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); - if (!lzo_ctx->dst) { - lzo_ctx->dst_len = 0; - return -ENOMEM; - } - - ret = snd_soc_lzo_compress(lzo_ctx); - if (ret < 0) - return ret; - return 0; -} - -static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec, - struct snd_soc_lzo_ctx *lzo_ctx) -{ - int ret; - - lzo_ctx->dst_len = lzo_ctx->decompressed_size; - lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); - if (!lzo_ctx->dst) { - lzo_ctx->dst_len = 0; - return -ENOMEM; - } - - ret = snd_soc_lzo_decompress(lzo_ctx); - if (ret < 0) - return ret; - return 0; -} - -static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, - unsigned int reg) -{ - const struct snd_soc_codec_driver *codec_drv; - - codec_drv = codec->driver; - return (reg * codec_drv->reg_word_size) / - DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); -} - -static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, - unsigned int reg) -{ - const struct snd_soc_codec_driver *codec_drv; - - codec_drv = codec->driver; - return reg % (DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()) / - codec_drv->reg_word_size); -} - -static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) -{ - return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); -} - -static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) -{ - struct snd_soc_lzo_ctx **lzo_blocks; - unsigned int val; - int i; - int ret; - - lzo_blocks = codec->reg_cache; - for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { - WARN_ON(!snd_soc_codec_writable_register(codec, i)); - ret = snd_soc_cache_read(codec, i, &val); - if (ret) - return ret; - codec->cache_bypass = 1; - ret = snd_soc_write(codec, i, val); - codec->cache_bypass = 0; - if (ret) - return ret; - dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", - i, val); - } - - return 0; -} - -static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; - int ret, blkindex, blkpos; - size_t blksize, tmp_dst_len; - void *tmp_dst; - - /* index of the compressed lzo block */ - blkindex = snd_soc_lzo_get_blkindex(codec, reg); - /* register index within the decompressed block */ - blkpos = snd_soc_lzo_get_blkpos(codec, reg); - /* size of the compressed block */ - blksize = snd_soc_lzo_get_blksize(codec); - lzo_blocks = codec->reg_cache; - lzo_block = lzo_blocks[blkindex]; - - /* save the pointer and length of the compressed block */ - tmp_dst = lzo_block->dst; - tmp_dst_len = lzo_block->dst_len; - - /* prepare the source to be the compressed block */ - lzo_block->src = lzo_block->dst; - lzo_block->src_len = lzo_block->dst_len; - - /* decompress the block */ - ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); - if (ret < 0) { - kfree(lzo_block->dst); - goto out; - } - - /* write the new value to the cache */ - if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value, - codec->driver->reg_word_size)) { - kfree(lzo_block->dst); - goto out; - } - - /* prepare the source to be the decompressed block */ - lzo_block->src = lzo_block->dst; - lzo_block->src_len = lzo_block->dst_len; - - /* compress the block */ - ret = snd_soc_lzo_compress_cache_block(codec, lzo_block); - if (ret < 0) { - kfree(lzo_block->dst); - kfree(lzo_block->src); - goto out; - } - - /* set the bit so we know we have to sync this register */ - set_bit(reg, lzo_block->sync_bmp); - kfree(tmp_dst); - kfree(lzo_block->src); - return 0; -out: - lzo_block->dst = tmp_dst; - lzo_block->dst_len = tmp_dst_len; - return ret; -} - -static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec, - unsigned int reg, unsigned int *value) -{ - struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; - int ret, blkindex, blkpos; - size_t blksize, tmp_dst_len; - void *tmp_dst; - - *value = 0; - /* index of the compressed lzo block */ - blkindex = snd_soc_lzo_get_blkindex(codec, reg); - /* register index within the decompressed block */ - blkpos = snd_soc_lzo_get_blkpos(codec, reg); - /* size of the compressed block */ - blksize = snd_soc_lzo_get_blksize(codec); - lzo_blocks = codec->reg_cache; - lzo_block = lzo_blocks[blkindex]; - - /* save the pointer and length of the compressed block */ - tmp_dst = lzo_block->dst; - tmp_dst_len = lzo_block->dst_len; - - /* prepare the source to be the compressed block */ - lzo_block->src = lzo_block->dst; - lzo_block->src_len = lzo_block->dst_len; - - /* decompress the block */ - ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); - if (ret >= 0) - /* fetch the value from the cache */ - *value = snd_soc_get_cache_val(lzo_block->dst, blkpos, - codec->driver->reg_word_size); - - kfree(lzo_block->dst); - /* restore the pointer and length of the compressed block */ - lzo_block->dst = tmp_dst; - lzo_block->dst_len = tmp_dst_len; - return 0; -} - -static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec) -{ - struct snd_soc_lzo_ctx **lzo_blocks; - int i, blkcount; - - lzo_blocks = codec->reg_cache; - if (!lzo_blocks) - return 0; - - blkcount = snd_soc_lzo_block_count(); - /* - * the pointer to the bitmap used for syncing the cache - * is shared amongst all lzo_blocks. Ensure it is freed - * only once. - */ - if (lzo_blocks[0]) - kfree(lzo_blocks[0]->sync_bmp); - for (i = 0; i < blkcount; ++i) { - if (lzo_blocks[i]) { - kfree(lzo_blocks[i]->wmem); - kfree(lzo_blocks[i]->dst); - } - /* each lzo_block is a pointer returned by kmalloc or NULL */ - kfree(lzo_blocks[i]); - } - kfree(lzo_blocks); - codec->reg_cache = NULL; - return 0; -} - -static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) -{ - struct snd_soc_lzo_ctx **lzo_blocks; - size_t bmp_size; - const struct snd_soc_codec_driver *codec_drv; - int ret, tofree, i, blksize, blkcount; - const char *p, *end; - unsigned long *sync_bmp; - - ret = 0; - codec_drv = codec->driver; - - /* - * If we have not been given a default register cache - * then allocate a dummy zero-ed out region, compress it - * and remember to free it afterwards. - */ - tofree = 0; - if (!codec->reg_def_copy) - tofree = 1; - - if (!codec->reg_def_copy) { - codec->reg_def_copy = kzalloc(codec->reg_size, GFP_KERNEL); - if (!codec->reg_def_copy) - return -ENOMEM; - } - - blkcount = snd_soc_lzo_block_count(); - codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks, - GFP_KERNEL); - if (!codec->reg_cache) { - ret = -ENOMEM; - goto err_tofree; - } - lzo_blocks = codec->reg_cache; - - /* - * allocate a bitmap to be used when syncing the cache with - * the hardware. Each time a register is modified, the corresponding - * bit is set in the bitmap, so we know that we have to sync - * that register. - */ - bmp_size = codec_drv->reg_cache_size; - sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long), - GFP_KERNEL); - if (!sync_bmp) { - ret = -ENOMEM; - goto err; - } - bitmap_zero(sync_bmp, bmp_size); - - /* allocate the lzo blocks and initialize them */ - for (i = 0; i < blkcount; ++i) { - lzo_blocks[i] = kzalloc(sizeof **lzo_blocks, - GFP_KERNEL); - if (!lzo_blocks[i]) { - kfree(sync_bmp); - ret = -ENOMEM; - goto err; - } - lzo_blocks[i]->sync_bmp = sync_bmp; - lzo_blocks[i]->sync_bmp_nbits = bmp_size; - /* alloc the working space for the compressed block */ - ret = snd_soc_lzo_prepare(lzo_blocks[i]); - if (ret < 0) - goto err; - } - - blksize = snd_soc_lzo_get_blksize(codec); - p = codec->reg_def_copy; - end = codec->reg_def_copy + codec->reg_size; - /* compress the register map and fill the lzo blocks */ - for (i = 0; i < blkcount; ++i, p += blksize) { - lzo_blocks[i]->src = p; - if (p + blksize > end) - lzo_blocks[i]->src_len = end - p; - else - lzo_blocks[i]->src_len = blksize; - ret = snd_soc_lzo_compress_cache_block(codec, - lzo_blocks[i]); - if (ret < 0) - goto err; - lzo_blocks[i]->decompressed_size = - lzo_blocks[i]->src_len; - } - - if (tofree) { - kfree(codec->reg_def_copy); - codec->reg_def_copy = NULL; - } - return 0; -err: - snd_soc_cache_exit(codec); -err_tofree: - if (tofree) { - kfree(codec->reg_def_copy); - codec->reg_def_copy = NULL; - } - return ret; -} -#endif - static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) { int i; @@ -889,26 +144,6 @@ static const struct snd_soc_cache_ops cache_types[] = { .write = snd_soc_flat_cache_write, .sync = snd_soc_flat_cache_sync }, -#ifdef CONFIG_SND_SOC_CACHE_LZO - { - .id = SND_SOC_LZO_COMPRESSION, - .name = "LZO", - .init = snd_soc_lzo_cache_init, - .exit = snd_soc_lzo_cache_exit, - .read = snd_soc_lzo_cache_read, - .write = snd_soc_lzo_cache_write, - .sync = snd_soc_lzo_cache_sync - }, -#endif - { - .id = SND_SOC_RBTREE_COMPRESSION, - .name = "rbtree", - .init = snd_soc_rbtree_cache_init, - .exit = snd_soc_rbtree_cache_exit, - .read = snd_soc_rbtree_cache_read, - .write = snd_soc_rbtree_cache_write, - .sync = snd_soc_rbtree_cache_sync - } }; int snd_soc_cache_init(struct snd_soc_codec *codec) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a5d3685a5d3..3986520b467 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -32,6 +32,7 @@ #include <linux/platform_device.h> #include <linux/ctype.h> #include <linux/slab.h> +#include <linux/of.h> #include <sound/ac97_codec.h> #include <sound/core.h> #include <sound/jack.h> @@ -58,8 +59,6 @@ static LIST_HEAD(dai_list); static LIST_HEAD(platform_list); static LIST_HEAD(codec_list); -int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); - /* * This is a timeout to do a DAPM powerdown after a stream is closed(). * It can be used to eliminate pops between different playback streams, e.g. @@ -170,8 +169,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf, static ssize_t codec_reg_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct snd_soc_pcm_runtime *rtd = - container_of(dev, struct snd_soc_pcm_runtime, dev); + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); return soc_codec_reg_show(rtd->codec, buf, PAGE_SIZE, 0); } @@ -181,8 +179,7 @@ static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); static ssize_t pmdown_time_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct snd_soc_pcm_runtime *rtd = - container_of(dev, struct snd_soc_pcm_runtime, dev); + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); return sprintf(buf, "%ld\n", rtd->pmdown_time); } @@ -191,8 +188,7 @@ static ssize_t pmdown_time_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct snd_soc_pcm_runtime *rtd = - container_of(dev, struct snd_soc_pcm_runtime, dev); + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); int ret; ret = strict_strtol(buf, 10, &rtd->pmdown_time); @@ -412,7 +408,7 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) snd_soc_debugfs_root); if (!card->debugfs_card_root) { dev_warn(card->dev, - "ASoC: Failed to create codec debugfs directory\n"); + "ASoC: Failed to create card debugfs directory\n"); return; } @@ -572,7 +568,7 @@ int snd_soc_suspend(struct device *dev) switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: - codec->driver->suspend(codec, PMSG_SUSPEND); + codec->driver->suspend(codec); codec->suspended = 1; codec->cache_sync = 1; break; @@ -709,6 +705,12 @@ int snd_soc_resume(struct device *dev) struct snd_soc_card *card = dev_get_drvdata(dev); int i, ac97_control = 0; + /* If the initialization of this soc device failed, there is no codec + * associated with it. Just bail out in this case. + */ + if (list_empty(&card->codec_dev_list)) + return 0; + /* AC97 devices might have other drivers hanging off them so * need to resume immediately. Other drivers don't have that * problem and may take a substantial amount of time to resume @@ -735,7 +737,7 @@ EXPORT_SYMBOL_GPL(snd_soc_resume); #define snd_soc_resume NULL #endif -static struct snd_soc_dai_ops null_dai_ops = { +static const struct snd_soc_dai_ops null_dai_ops = { }; static int soc_bind_dai_link(struct snd_soc_card *card, int num) @@ -757,10 +759,16 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) } /* no, then find CPU DAI from registered DAIs*/ list_for_each_entry(cpu_dai, &dai_list, list) { - if (!strcmp(cpu_dai->name, dai_link->cpu_dai_name)) { - rtd->cpu_dai = cpu_dai; - goto find_codec; + if (dai_link->cpu_dai_of_node) { + if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) + continue; + } else { + if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) + continue; } + + rtd->cpu_dai = cpu_dai; + goto find_codec; } dev_dbg(card->dev, "CPU DAI %s not registered\n", dai_link->cpu_dai_name); @@ -773,22 +781,33 @@ find_codec: /* no, then find CODEC from registered CODECs*/ list_for_each_entry(codec, &codec_list, list) { - if (!strcmp(codec->name, dai_link->codec_name)) { - rtd->codec = codec; - - /* CODEC found, so find CODEC DAI from registered DAIs from this CODEC*/ - list_for_each_entry(codec_dai, &dai_list, list) { - if (codec->dev == codec_dai->dev && - !strcmp(codec_dai->name, dai_link->codec_dai_name)) { - rtd->codec_dai = codec_dai; - goto find_platform; - } - } - dev_dbg(card->dev, "CODEC DAI %s not registered\n", - dai_link->codec_dai_name); + if (dai_link->codec_of_node) { + if (codec->dev->of_node != dai_link->codec_of_node) + continue; + } else { + if (strcmp(codec->name, dai_link->codec_name)) + continue; + } + + rtd->codec = codec; + + /* + * CODEC found, so find CODEC DAI from registered DAIs from + * this CODEC + */ + list_for_each_entry(codec_dai, &dai_list, list) { + if (codec->dev == codec_dai->dev && + !strcmp(codec_dai->name, + dai_link->codec_dai_name)) { - goto find_platform; + rtd->codec_dai = codec_dai; + goto find_platform; + } } + dev_dbg(card->dev, "CODEC DAI %s not registered\n", + dai_link->codec_dai_name); + + goto find_platform; } dev_dbg(card->dev, "CODEC %s not registered\n", dai_link->codec_name); @@ -800,15 +819,22 @@ find_platform: /* if there's no platform we match on the empty platform */ platform_name = dai_link->platform_name; - if (!platform_name) + if (!platform_name && !dai_link->platform_of_node) platform_name = "snd-soc-dummy"; /* no, then find one from the set of registered platforms */ list_for_each_entry(platform, &platform_list, list) { - if (!strcmp(platform->name, platform_name)) { - rtd->platform = platform; - goto out; + if (dai_link->platform_of_node) { + if (platform->dev->of_node != + dai_link->platform_of_node) + continue; + } else { + if (strcmp(platform->name, platform_name)) + continue; } + + rtd->platform = platform; + goto out; } dev_dbg(card->dev, "platform %s not registered\n", @@ -855,9 +881,9 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) /* unregister the rtd device */ if (rtd->dev_registered) { - device_remove_file(&rtd->dev, &dev_attr_pmdown_time); - device_remove_file(&rtd->dev, &dev_attr_codec_reg); - device_unregister(&rtd->dev); + device_remove_file(rtd->dev, &dev_attr_pmdown_time); + device_remove_file(rtd->dev, &dev_attr_codec_reg); + device_unregister(rtd->dev); rtd->dev_registered = 0; } @@ -1032,7 +1058,10 @@ err_probe: return ret; } -static void rtd_release(struct device *dev) {} +static void rtd_release(struct device *dev) +{ + kfree(dev); +} static int soc_post_component_init(struct snd_soc_card *card, struct snd_soc_codec *codec, @@ -1075,11 +1104,17 @@ static int soc_post_component_init(struct snd_soc_card *card, /* register the rtd device */ rtd->codec = codec; - rtd->dev.parent = card->dev; - rtd->dev.release = rtd_release; - rtd->dev.init_name = name; + + rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); + if (!rtd->dev) + return -ENOMEM; + device_initialize(rtd->dev); + rtd->dev->parent = card->dev; + rtd->dev->release = rtd_release; + rtd->dev->init_name = name; + dev_set_drvdata(rtd->dev, rtd); mutex_init(&rtd->pcm_mutex); - ret = device_register(&rtd->dev); + ret = device_add(rtd->dev); if (ret < 0) { dev_err(card->dev, "asoc: failed to register runtime device: %d\n", ret); @@ -1088,14 +1123,14 @@ static int soc_post_component_init(struct snd_soc_card *card, rtd->dev_registered = 1; /* add DAPM sysfs entries for this codec */ - ret = snd_soc_dapm_sys_add(&rtd->dev); + ret = snd_soc_dapm_sys_add(rtd->dev); if (ret < 0) dev_err(codec->dev, "asoc: failed to add codec dapm sysfs entries: %d\n", ret); /* add codec sysfs entries */ - ret = device_create_file(&rtd->dev, &dev_attr_codec_reg); + ret = device_create_file(rtd->dev, &dev_attr_codec_reg); if (ret < 0) dev_err(codec->dev, "asoc: failed to add codec sysfs files: %d\n", ret); @@ -1184,7 +1219,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) if (ret) return ret; - ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time); + ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); if (ret < 0) printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); @@ -1282,8 +1317,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) /* unregister the rtd device */ if (rtd->dev_registered) { - device_remove_file(&rtd->dev, &dev_attr_codec_reg); - device_unregister(&rtd->dev); + device_remove_file(rtd->dev, &dev_attr_codec_reg); + device_del(rtd->dev); rtd->dev_registered = 0; } @@ -1482,6 +1517,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) snd_soc_dapm_new_widgets(&card->dapm); + if (card->fully_routed) + list_for_each_entry(codec, &card->codec_dev_list, card_list) + snd_soc_dapm_auto_nc_codec_pins(codec); + ret = snd_card_register(card->snd_card); if (ret < 0) { printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); @@ -2812,6 +2851,40 @@ int snd_soc_register_card(struct snd_soc_card *card) if (!card->name || !card->dev) return -EINVAL; + for (i = 0; i < card->num_links; i++) { + struct snd_soc_dai_link *link = &card->dai_link[i]; + + /* + * Codec must be specified by 1 of name or OF node, + * not both or neither. + */ + if (!!link->codec_name == !!link->codec_of_node) { + dev_err(card->dev, + "Neither/both codec name/of_node are set\n"); + return -EINVAL; + } + + /* + * Platform may be specified by either name or OF node, but + * can be left unspecified, and a dummy platform will be used. + */ + if (link->platform_name && link->platform_of_node) { + dev_err(card->dev, + "Both platform name/of_node are set\n"); + return -EINVAL; + } + + /* + * CPU DAI must be specified by 1 of name or OF node, + * not both or neither. + */ + if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { + dev_err(card->dev, + "Neither/both cpu_dai name/of_node are set\n"); + return -EINVAL; + } + } + dev_set_drvdata(card->dev, card); snd_soc_initialize_card_lists(card); @@ -3299,6 +3372,87 @@ found: } EXPORT_SYMBOL_GPL(snd_soc_unregister_codec); +/* Retrieve a card's name from device tree */ +int snd_soc_of_parse_card_name(struct snd_soc_card *card, + const char *propname) +{ + struct device_node *np = card->dev->of_node; + int ret; + + ret = of_property_read_string_index(np, propname, 0, &card->name); + /* + * EINVAL means the property does not exist. This is fine providing + * card->name was previously set, which is checked later in + * snd_soc_register_card. + */ + if (ret < 0 && ret != -EINVAL) { + dev_err(card->dev, + "Property '%s' could not be read: %d\n", + propname, ret); + return ret; + } + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_of_parse_card_name); + +int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, + const char *propname) +{ + struct device_node *np = card->dev->of_node; + int num_routes; + struct snd_soc_dapm_route *routes; + int i, ret; + + num_routes = of_property_count_strings(np, propname); + if (num_routes & 1) { + dev_err(card->dev, + "Property '%s's length is not even\n", + propname); + return -EINVAL; + } + num_routes /= 2; + if (!num_routes) { + dev_err(card->dev, + "Property '%s's length is zero\n", + propname); + return -EINVAL; + } + + routes = devm_kzalloc(card->dev, num_routes * sizeof(*routes), + GFP_KERNEL); + if (!routes) { + dev_err(card->dev, + "Could not allocate DAPM route table\n"); + return -EINVAL; + } + + for (i = 0; i < num_routes; i++) { + ret = of_property_read_string_index(np, propname, + 2 * i, &routes[i].sink); + if (ret) { + dev_err(card->dev, + "Property '%s' index %d could not be read: %d\n", + propname, 2 * i, ret); + return -EINVAL; + } + ret = of_property_read_string_index(np, propname, + (2 * i) + 1, &routes[i].source); + if (ret) { + dev_err(card->dev, + "Property '%s' index %d could not be read: %d\n", + propname, (2 * i) + 1, ret); + return -EINVAL; + } + } + + card->num_dapm_routes = num_routes; + card->dapm_routes = routes; + + return 0; +} +EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); + static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f42e8b9fb17..3ad1f59b802 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -39,6 +39,7 @@ #include <linux/platform_device.h> #include <linux/jiffies.h> #include <linux/debugfs.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <sound/core.h> #include <sound/pcm.h> @@ -339,6 +340,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, case snd_soc_dapm_output: case snd_soc_dapm_adc: case snd_soc_dapm_input: + case snd_soc_dapm_siggen: case snd_soc_dapm_dac: case snd_soc_dapm_micbias: case snd_soc_dapm_vmid: @@ -772,6 +774,11 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) return widget->inputs; } + /* signal generator */ + if (widget->id == snd_soc_dapm_siggen) { + widget->inputs = snd_soc_dapm_suspend_check(widget); + return widget->inputs; + } } list_for_each_entry(path, &widget->sources, list_sink) { @@ -1200,6 +1207,9 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie) /* If we're off and we're not supposed to be go into STANDBY */ if (d->bias_level == SND_SOC_BIAS_OFF && d->target_bias_level != SND_SOC_BIAS_OFF) { + if (d->dev) + pm_runtime_get_sync(d->dev); + ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); if (ret != 0) dev_err(d->dev, @@ -1239,6 +1249,9 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); if (ret != 0) dev_err(d->dev, "Failed to turn off bias: %d\n", ret); + + if (d->dev) + pm_runtime_put_sync(d->dev); } /* If we just powered up then move to active bias */ @@ -1725,8 +1738,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, static ssize_t dapm_widget_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct snd_soc_pcm_runtime *rtd = - container_of(dev, struct snd_soc_pcm_runtime, dev); + struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); struct snd_soc_codec *codec =rtd->codec; struct snd_soc_dapm_widget *w; int count = 0; @@ -1982,6 +1994,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_out_drv: case snd_soc_dapm_input: case snd_soc_dapm_output: + case snd_soc_dapm_siggen: case snd_soc_dapm_micbias: case snd_soc_dapm_vmid: case snd_soc_dapm_pre: @@ -2947,6 +2960,79 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, } EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); +static bool snd_soc_dapm_widget_in_card_paths(struct snd_soc_card *card, + struct snd_soc_dapm_widget *w) +{ + struct snd_soc_dapm_path *p; + + list_for_each_entry(p, &card->paths, list) { + if ((p->source == w) || (p->sink == w)) { + dev_dbg(card->dev, + "... Path %s(id:%d dapm:%p) - %s(id:%d dapm:%p)\n", + p->source->name, p->source->id, p->source->dapm, + p->sink->name, p->sink->id, p->sink->dapm); + + /* Connected to something other than the codec */ + if (p->source->dapm != p->sink->dapm) + return true; + /* + * Loopback connection from codec external pin to + * codec external pin + */ + if (p->sink->id == snd_soc_dapm_input) { + switch (p->source->id) { + case snd_soc_dapm_output: + case snd_soc_dapm_micbias: + return true; + default: + break; + } + } + } + } + + return false; +} + +/** + * snd_soc_dapm_auto_nc_codec_pins - call snd_soc_dapm_nc_pin for unused pins + * @codec: The codec whose pins should be processed + * + * Automatically call snd_soc_dapm_nc_pin() for any external pins in the codec + * which are unused. Pins are used if they are connected externally to the + * codec, whether that be to some other device, or a loop-back connection to + * the codec itself. + */ +void snd_soc_dapm_auto_nc_codec_pins(struct snd_soc_codec *codec) +{ + struct snd_soc_card *card = codec->card; + struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_dapm_widget *w; + + dev_dbg(codec->dev, "Auto NC: DAPMs: card:%p codec:%p\n", + &card->dapm, &codec->dapm); + + list_for_each_entry(w, &card->widgets, list) { + if (w->dapm != dapm) + continue; + switch (w->id) { + case snd_soc_dapm_input: + case snd_soc_dapm_output: + case snd_soc_dapm_micbias: + dev_dbg(codec->dev, "Auto NC: Checking widget %s\n", + w->name); + if (!snd_soc_dapm_widget_in_card_paths(card, w)) { + dev_dbg(codec->dev, + "... Not in map; disabling\n"); + snd_soc_dapm_nc_pin(dapm, w->name); + } + break; + default: + break; + } + } +} + /** * snd_soc_dapm_free - free dapm resources * @dapm: DAPM context diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 6c5ebd38c1b..ee4353f843e 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -341,10 +341,8 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, gpios[i].gpio, ret); } -#ifdef CONFIG_GPIO_SYSFS /* Expose GPIO value over sysfs for diagnostic purposes */ gpio_export(gpios[i].gpio, false); -#endif /* Update initial jack status */ snd_soc_jack_gpio_detect(&gpios[i]); @@ -376,9 +374,7 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, int i; for (i = 0; i < count; i++) { -#ifdef CONFIG_GPIO_SYSFS gpio_unexport(gpios[i].gpio); -#endif free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]); cancel_delayed_work_sync(&gpios[i].work); gpio_free(gpios[i].gpio); diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index ee15337353f..cdc860a5ff3 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -19,6 +19,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/workqueue.h> #include <sound/core.h> @@ -77,6 +78,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver; int ret = 0; + pm_runtime_get_sync(cpu_dai->dev); + pm_runtime_get_sync(codec_dai->dev); + pm_runtime_get_sync(platform->dev); + mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); /* startup the audio subsystem */ @@ -233,6 +238,11 @@ platform_err: cpu_dai->driver->ops->shutdown(substream, cpu_dai); out: mutex_unlock(&rtd->pcm_mutex); + + pm_runtime_put(platform->dev); + pm_runtime_put(codec_dai->dev); + pm_runtime_put(cpu_dai->dev); + return ret; } @@ -319,7 +329,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) cpu_dai->runtime = NULL; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (unlikely(codec->ignore_pmdown_time)) { + if (codec->ignore_pmdown_time || + rtd->dai_link->ignore_pmdown_time) { /* powered down playback stream now */ snd_soc_dapm_stream_event(rtd, codec_dai->driver->playback.stream_name, @@ -338,6 +349,11 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) } mutex_unlock(&rtd->pcm_mutex); + + pm_runtime_put(platform->dev); + pm_runtime_put(codec_dai->dev); + pm_runtime_put(cpu_dai->dev); + return 0; } @@ -582,17 +598,6 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream) return offset; } -/* ASoC PCM operations */ -static struct snd_pcm_ops soc_pcm_ops = { - .open = soc_pcm_open, - .close = soc_pcm_close, - .hw_params = soc_pcm_hw_params, - .hw_free = soc_pcm_hw_free, - .prepare = soc_pcm_prepare, - .trigger = soc_pcm_trigger, - .pointer = soc_pcm_pointer, -}; - /* create a new pcm */ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { @@ -600,10 +605,19 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_pcm_ops *soc_pcm_ops = &rtd->ops; struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; + soc_pcm_ops->open = soc_pcm_open; + soc_pcm_ops->close = soc_pcm_close; + soc_pcm_ops->hw_params = soc_pcm_hw_params; + soc_pcm_ops->hw_free = soc_pcm_hw_free; + soc_pcm_ops->prepare = soc_pcm_prepare; + soc_pcm_ops->trigger = soc_pcm_trigger; + soc_pcm_ops->pointer = soc_pcm_pointer; + /* check client and interface hw capabilities */ snprintf(new_name, sizeof(new_name), "%s %s-%d", rtd->dai_link->stream_name, codec_dai->name, num); @@ -627,20 +641,20 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) rtd->pcm = pcm; pcm->private_data = rtd; if (platform->driver->ops) { - soc_pcm_ops.mmap = platform->driver->ops->mmap; - soc_pcm_ops.pointer = platform->driver->ops->pointer; - soc_pcm_ops.ioctl = platform->driver->ops->ioctl; - soc_pcm_ops.copy = platform->driver->ops->copy; - soc_pcm_ops.silence = platform->driver->ops->silence; - soc_pcm_ops.ack = platform->driver->ops->ack; - soc_pcm_ops.page = platform->driver->ops->page; + soc_pcm_ops->mmap = platform->driver->ops->mmap; + soc_pcm_ops->pointer = platform->driver->ops->pointer; + soc_pcm_ops->ioctl = platform->driver->ops->ioctl; + soc_pcm_ops->copy = platform->driver->ops->copy; + soc_pcm_ops->silence = platform->driver->ops->silence; + soc_pcm_ops->ack = platform->driver->ops->ack; + soc_pcm_ops->page = platform->driver->ops->page; } if (playback) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, soc_pcm_ops); if (capture) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, soc_pcm_ops); if (platform->driver->pcm_new) { ret = platform->driver->pcm_new(rtd); diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 0c12b98484b..4220bb0f273 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -58,7 +58,36 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) } EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); -static struct snd_soc_platform_driver dummy_platform; +static const struct snd_pcm_hardware dummy_dma_hardware = { + .formats = 0xffffffff, + .channels_min = 1, + .channels_max = UINT_MAX, + + /* Random values to keep userspace happy when checking constraints */ + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER, + .buffer_bytes_max = 128*1024, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = PAGE_SIZE*2, + .periods_min = 2, + .periods_max = 128, +}; + +static int dummy_dma_open(struct snd_pcm_substream *substream) +{ + snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); + + return 0; +} + +static struct snd_pcm_ops dummy_dma_ops = { + .open = dummy_dma_open, + .ioctl = snd_pcm_lib_ioctl, +}; + +static struct snd_soc_platform_driver dummy_platform = { + .ops = &dummy_dma_ops, +}; static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) { diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig index c6af1fd707f..ce1b773c351 100644 --- a/sound/soc/tegra/Kconfig +++ b/sound/soc/tegra/Kconfig @@ -47,3 +47,12 @@ config SND_SOC_TEGRA_TRIMSLICE help Say Y or M here if you want to add support for SoC audio on the TrimSlice platform. + +config SND_SOC_TEGRA_ALC5632 + tristate "SoC Audio support for Tegra boards using an ALC5632 codec" + depends on SND_SOC_TEGRA && I2C + select SND_SOC_TEGRA_I2S + select SND_SOC_ALC5632 + help + Say Y or M here if you want to add support for SoC audio on the + Toshiba AC100 netbook. diff --git a/sound/soc/tegra/Makefile b/sound/soc/tegra/Makefile index 4d943b3fe15..8e584b8fcfb 100644 --- a/sound/soc/tegra/Makefile +++ b/sound/soc/tegra/Makefile @@ -14,6 +14,8 @@ obj-$(CONFIG_SND_SOC_TEGRA_SPDIF) += snd-soc-tegra-spdif.o # Tegra machine Support snd-soc-tegra-wm8903-objs := tegra_wm8903.o snd-soc-tegra-trimslice-objs := trimslice.o +snd-soc-tegra-alc5632-objs := tegra_alc5632.o obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o +obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c new file mode 100644 index 00000000000..4a0e805c4ed --- /dev/null +++ b/sound/soc/tegra/tegra_alc5632.c @@ -0,0 +1,214 @@ +/* +* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver +* +* Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> +* +* Authors: Leon Romanovsky <leon@leon.nu> +* Andrey Danin <danindrey@mail.ru> +* Marc Dietrich <marvin24@gmx.de> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +*/ + +#include <asm/mach-types.h> + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/gpio.h> + +#include <sound/core.h> +#include <sound/jack.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> + +#include "../codecs/alc5632.h" + +#include "tegra_das.h" +#include "tegra_i2s.h" +#include "tegra_pcm.h" +#include "tegra_asoc_utils.h" + +#define DRV_NAME "tegra-alc5632" + +struct tegra_alc5632 { + struct tegra_asoc_utils_data util_data; +}; + +static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *card = codec->card; + struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); + int srate, mclk; + int err; + + srate = params_rate(params); + mclk = 512 * srate; + + err = tegra_asoc_utils_set_rate(&alc5632->util_data, srate, mclk); + if (err < 0) { + dev_err(card->dev, "Can't configure clocks\n"); + return err; + } + + err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, + SND_SOC_CLOCK_IN); + if (err < 0) { + dev_err(card->dev, "codec_dai clock not set\n"); + return err; + } + + return 0; +} + +static struct snd_soc_ops tegra_alc5632_asoc_ops = { + .hw_params = tegra_alc5632_asoc_hw_params, +}; + +static struct snd_soc_jack tegra_alc5632_hs_jack; + +static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Int Spk", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = { + /* Internal Speaker */ + {"Int Spk", NULL, "SPKOUT"}, + {"Int Spk", NULL, "SPKOUTN"}, + + /* Headset Mic */ + {"MIC1", NULL, "MICBIAS1"}, + {"MICBIAS1", NULL, "Headset Mic"}, + + /* Headset Stereophone */ + {"Headset Stereophone", NULL, "HPR"}, + {"Headset Stereophone", NULL, "HPL"}, +}; + +static const struct snd_kcontrol_new tegra_alc5632_controls[] = { + SOC_DAPM_PIN_SWITCH("Int Spk"), +}; + +static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, + &tegra_alc5632_hs_jack); + snd_soc_jack_add_pins(&tegra_alc5632_hs_jack, + ARRAY_SIZE(tegra_alc5632_hs_jack_pins), + tegra_alc5632_hs_jack_pins); + + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); + + return 0; +} + +static struct snd_soc_dai_link tegra_alc5632_dai = { + .name = "ALC5632", + .stream_name = "ALC5632 PCM", + .codec_name = "alc5632.0-001e", + .platform_name = "tegra-pcm-audio", + .cpu_dai_name = "tegra-i2s.0", + .codec_dai_name = "alc5632-hifi", + .init = tegra_alc5632_asoc_init, + .ops = &tegra_alc5632_asoc_ops, + .dai_fmt = SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBS_CFS, +}; + +static struct snd_soc_card snd_soc_tegra_alc5632 = { + .name = "tegra-alc5632", + .owner = THIS_MODULE, + .dai_link = &tegra_alc5632_dai, + .num_links = 1, + .controls = tegra_alc5632_controls, + .num_controls = ARRAY_SIZE(tegra_alc5632_controls), + .dapm_widgets = tegra_alc5632_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets), + .dapm_routes = tegra_alc5632_audio_map, + .num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map), + .fully_routed = true, +}; + +static __devinit int tegra_alc5632_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &snd_soc_tegra_alc5632; + struct tegra_alc5632 *alc5632; + int ret; + + alc5632 = devm_kzalloc(&pdev->dev, + sizeof(struct tegra_alc5632), GFP_KERNEL); + if (!alc5632) { + dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); + return -ENOMEM; + } + + ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); + if (ret) + return ret; + + card->dev = &pdev->dev; + platform_set_drvdata(pdev, card); + snd_soc_card_set_drvdata(card, alc5632); + + ret = snd_soc_register_card(card); + if (ret) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", + ret); + tegra_asoc_utils_fini(&alc5632->util_data); + return ret; + } + + return 0; +} + +static int __devexit tegra_alc5632_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); + + snd_soc_unregister_card(card); + + tegra_asoc_utils_fini(&alc5632->util_data); + + return 0; +} + +static struct platform_driver tegra_alc5632_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + .pm = &snd_soc_pm_ops, + }, + .probe = tegra_alc5632_probe, + .remove = __devexit_p(tegra_alc5632_remove), +}; +module_platform_driver(tegra_alc5632_driver); + +MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); +MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c index 3b55a44146a..3b3c1ba4d23 100644 --- a/sound/soc/tegra/tegra_das.c +++ b/sound/soc/tegra/tegra_das.c @@ -172,11 +172,11 @@ static int __devinit tegra_das_probe(struct platform_device *pdev) if (das) return -ENODEV; - das = kzalloc(sizeof(struct tegra_das), GFP_KERNEL); + das = devm_kzalloc(&pdev->dev, sizeof(struct tegra_das), GFP_KERNEL); if (!das) { dev_err(&pdev->dev, "Can't allocate tegra_das\n"); ret = -ENOMEM; - goto exit; + goto err; } das->dev = &pdev->dev; @@ -184,22 +184,35 @@ static int __devinit tegra_das_probe(struct platform_device *pdev) if (!res) { dev_err(&pdev->dev, "No memory resource\n"); ret = -ENODEV; - goto err_free; + goto err; } - region = request_mem_region(res->start, resource_size(res), - pdev->name); + region = devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), pdev->name); if (!region) { dev_err(&pdev->dev, "Memory region already claimed\n"); ret = -EBUSY; - goto err_free; + goto err; } - das->regs = ioremap(res->start, resource_size(res)); + das->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); if (!das->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err_release; + goto err; + } + + ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1, + TEGRA_DAS_DAP_SEL_DAC1); + if (ret) { + dev_err(&pdev->dev, "Can't set up DAS DAP connection\n"); + goto err; + } + ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1, + TEGRA_DAS_DAC_SEL_DAP1); + if (ret) { + dev_err(&pdev->dev, "Can't set up DAS DAC connection\n"); + goto err; } tegra_das_debug_add(das); @@ -208,58 +221,41 @@ static int __devinit tegra_das_probe(struct platform_device *pdev) return 0; -err_release: - release_mem_region(res->start, resource_size(res)); -err_free: - kfree(das); +err: das = NULL; -exit: return ret; } static int __devexit tegra_das_remove(struct platform_device *pdev) { - struct resource *res; - if (!das) return -ENODEV; - platform_set_drvdata(pdev, NULL); - tegra_das_debug_remove(das); - iounmap(das->regs); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - - kfree(das); das = NULL; return 0; } +static const struct of_device_id tegra_das_of_match[] __devinitconst = { + { .compatible = "nvidia,tegra20-das", }, + {}, +}; + static struct platform_driver tegra_das_driver = { .probe = tegra_das_probe, .remove = __devexit_p(tegra_das_remove), .driver = { .name = DRV_NAME, + .owner = THIS_MODULE, + .of_match_table = tegra_das_of_match, }, }; - -static int __init tegra_das_modinit(void) -{ - return platform_driver_register(&tegra_das_driver); -} -module_init(tegra_das_modinit); - -static void __exit tegra_das_modexit(void) -{ - platform_driver_unregister(&tegra_das_driver); -} -module_exit(tegra_das_modexit); +module_platform_driver(tegra_das_driver); MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra DAS driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_das_of_match); diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 6728fab8c41..33509de5254 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c @@ -36,13 +36,13 @@ #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/io.h> +#include <linux/of.h> #include <mach/iomap.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> -#include "tegra_das.h" #include "tegra_i2s.h" #define DRV_NAME "tegra-i2s" @@ -99,13 +99,11 @@ static const struct file_operations tegra_i2s_debug_fops = { .release = single_release, }; -static void tegra_i2s_debug_add(struct tegra_i2s *i2s, int id) +static void tegra_i2s_debug_add(struct tegra_i2s *i2s) { - char name[] = DRV_NAME ".0"; - - snprintf(name, sizeof(name), DRV_NAME".%1d", id); - i2s->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root, - i2s, &tegra_i2s_debug_fops); + i2s->debug = debugfs_create_file(i2s->dai.name, S_IRUGO, + snd_soc_debugfs_root, i2s, + &tegra_i2s_debug_fops); } static void tegra_i2s_debug_remove(struct tegra_i2s *i2s) @@ -306,93 +304,54 @@ static int tegra_i2s_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops tegra_i2s_dai_ops = { +static const struct snd_soc_dai_ops tegra_i2s_dai_ops = { .set_fmt = tegra_i2s_set_fmt, .hw_params = tegra_i2s_hw_params, .trigger = tegra_i2s_trigger, }; -static struct snd_soc_dai_driver tegra_i2s_dai[] = { - { - .name = DRV_NAME ".0", - .probe = tegra_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_96000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_96000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &tegra_i2s_dai_ops, - .symmetric_rates = 1, +static const struct snd_soc_dai_driver tegra_i2s_dai_template = { + .probe = tegra_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - { - .name = DRV_NAME ".1", - .probe = tegra_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_96000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_96000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &tegra_i2s_dai_ops, - .symmetric_rates = 1, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, + .ops = &tegra_i2s_dai_ops, + .symmetric_rates = 1, }; static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) { struct tegra_i2s * i2s; struct resource *mem, *memregion, *dmareq; + u32 of_dma[2]; + u32 dma_ch; int ret; - if ((pdev->id < 0) || - (pdev->id >= ARRAY_SIZE(tegra_i2s_dai))) { - dev_err(&pdev->dev, "ID %d out of range\n", pdev->id); - return -EINVAL; - } - - /* - * FIXME: Until a codec driver exists for the tegra DAS, hard-code a - * 1:1 mapping between audio controllers and audio ports. - */ - ret = tegra_das_connect_dap_to_dac(TEGRA_DAS_DAP_ID_1 + pdev->id, - TEGRA_DAS_DAP_SEL_DAC1 + pdev->id); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAP connection\n"); - return ret; - } - ret = tegra_das_connect_dac_to_dap(TEGRA_DAS_DAC_ID_1 + pdev->id, - TEGRA_DAS_DAC_SEL_DAP1 + pdev->id); - if (ret) { - dev_err(&pdev->dev, "Can't set up DAC connection\n"); - return ret; - } - - i2s = kzalloc(sizeof(struct tegra_i2s), GFP_KERNEL); + i2s = devm_kzalloc(&pdev->dev, sizeof(struct tegra_i2s), GFP_KERNEL); if (!i2s) { dev_err(&pdev->dev, "Can't allocate tegra_i2s\n"); ret = -ENOMEM; - goto exit; + goto err; } dev_set_drvdata(&pdev->dev, i2s); + i2s->dai = tegra_i2s_dai_template; + i2s->dai.name = dev_name(&pdev->dev); + i2s->clk_i2s = clk_get(&pdev->dev, NULL); if (IS_ERR(i2s->clk_i2s)) { dev_err(&pdev->dev, "Can't retrieve i2s clock\n"); ret = PTR_ERR(i2s->clk_i2s); - goto err_free; + goto err; } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -404,104 +363,93 @@ static __devinit int tegra_i2s_platform_probe(struct platform_device *pdev) dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!dmareq) { - dev_err(&pdev->dev, "No DMA resource\n"); - ret = -ENODEV; - goto err_clk_put; + if (of_property_read_u32_array(pdev->dev.of_node, + "nvidia,dma-request-selector", + of_dma, 2) < 0) { + dev_err(&pdev->dev, "No DMA resource\n"); + ret = -ENODEV; + goto err_clk_put; + } + dma_ch = of_dma[1]; + } else { + dma_ch = dmareq->start; } - memregion = request_mem_region(mem->start, resource_size(mem), - DRV_NAME); + memregion = devm_request_mem_region(&pdev->dev, mem->start, + resource_size(mem), DRV_NAME); if (!memregion) { dev_err(&pdev->dev, "Memory region already claimed\n"); ret = -EBUSY; goto err_clk_put; } - i2s->regs = ioremap(mem->start, resource_size(mem)); + i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); if (!i2s->regs) { dev_err(&pdev->dev, "ioremap failed\n"); ret = -ENOMEM; - goto err_release; + goto err_clk_put; } i2s->capture_dma_data.addr = mem->start + TEGRA_I2S_FIFO2; i2s->capture_dma_data.wrap = 4; i2s->capture_dma_data.width = 32; - i2s->capture_dma_data.req_sel = dmareq->start; + i2s->capture_dma_data.req_sel = dma_ch; i2s->playback_dma_data.addr = mem->start + TEGRA_I2S_FIFO1; i2s->playback_dma_data.wrap = 4; i2s->playback_dma_data.width = 32; - i2s->playback_dma_data.req_sel = dmareq->start; + i2s->playback_dma_data.req_sel = dma_ch; i2s->reg_ctrl = TEGRA_I2S_CTRL_FIFO_FORMAT_PACKED; - ret = snd_soc_register_dai(&pdev->dev, &tegra_i2s_dai[pdev->id]); + ret = snd_soc_register_dai(&pdev->dev, &i2s->dai); if (ret) { dev_err(&pdev->dev, "Could not register DAI: %d\n", ret); ret = -ENOMEM; - goto err_unmap; + goto err_clk_put; } - tegra_i2s_debug_add(i2s, pdev->id); + tegra_i2s_debug_add(i2s); return 0; -err_unmap: - iounmap(i2s->regs); -err_release: - release_mem_region(mem->start, resource_size(mem)); err_clk_put: clk_put(i2s->clk_i2s); -err_free: - kfree(i2s); -exit: +err: return ret; } static int __devexit tegra_i2s_platform_remove(struct platform_device *pdev) { struct tegra_i2s *i2s = dev_get_drvdata(&pdev->dev); - struct resource *res; snd_soc_unregister_dai(&pdev->dev); tegra_i2s_debug_remove(i2s); - iounmap(i2s->regs); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, resource_size(res)); - clk_put(i2s->clk_i2s); - kfree(i2s); - return 0; } +static const struct of_device_id tegra_i2s_of_match[] __devinitconst = { + { .compatible = "nvidia,tegra20-i2s", }, + {}, +}; + static struct platform_driver tegra_i2s_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, + .of_match_table = tegra_i2s_of_match, }, .probe = tegra_i2s_platform_probe, .remove = __devexit_p(tegra_i2s_platform_remove), }; - -static int __init snd_tegra_i2s_init(void) -{ - return platform_driver_register(&tegra_i2s_driver); -} -module_init(snd_tegra_i2s_init); - -static void __exit snd_tegra_i2s_exit(void) -{ - platform_driver_unregister(&tegra_i2s_driver); -} -module_exit(snd_tegra_i2s_exit); +module_platform_driver(tegra_i2s_driver); MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra I2S ASoC driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_i2s_of_match); diff --git a/sound/soc/tegra/tegra_i2s.h b/sound/soc/tegra/tegra_i2s.h index 2b38a096f46..15ce1e2e8bd 100644 --- a/sound/soc/tegra/tegra_i2s.h +++ b/sound/soc/tegra/tegra_i2s.h @@ -153,6 +153,7 @@ #define TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_TWELVE_SLOTS (TEGRA_I2S_FIFO_ATN_LVL_TWELVE_SLOTS << TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_SHIFT) struct tegra_i2s { + struct snd_soc_dai_driver dai; struct clk *clk_i2s; int clk_refs; struct tegra_pcm_dma_params capture_dma_data; diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index 436def1dfa3..c22431516ab 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c @@ -330,7 +330,6 @@ static u64 tegra_dma_mask = DMA_BIT_MASK(32); static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) { struct snd_card *card = rtd->card->snd_card; - struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; int ret = 0; @@ -339,14 +338,14 @@ static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; - if (dai->driver->playback.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { ret = tegra_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto err; } - if (dai->driver->capture.channels_min) { + if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { ret = tegra_pcm_preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) @@ -392,18 +391,7 @@ static struct platform_driver tegra_pcm_driver = { .probe = tegra_pcm_platform_probe, .remove = __devexit_p(tegra_pcm_platform_remove), }; - -static int __init snd_tegra_pcm_init(void) -{ - return platform_driver_register(&tegra_pcm_driver); -} -module_init(snd_tegra_pcm_init); - -static void __exit snd_tegra_pcm_exit(void) -{ - platform_driver_unregister(&tegra_pcm_driver); -} -module_exit(snd_tegra_pcm_exit); +module_platform_driver(tegra_pcm_driver); MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra PCM ASoC driver"); diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c index dd11d0c6347..475428cf270 100644 --- a/sound/soc/tegra/tegra_spdif.c +++ b/sound/soc/tegra/tegra_spdif.c @@ -226,7 +226,7 @@ static int tegra_spdif_probe(struct snd_soc_dai *dai) return 0; } -static struct snd_soc_dai_ops tegra_spdif_dai_ops = { +static const struct snd_soc_dai_ops tegra_spdif_dai_ops = { .hw_params = tegra_spdif_hw_params, .trigger = tegra_spdif_trigger, }; @@ -352,17 +352,7 @@ static struct platform_driver tegra_spdif_driver = { .remove = __devexit_p(tegra_spdif_platform_remove), }; -static int __init snd_tegra_spdif_init(void) -{ - return platform_driver_register(&tegra_spdif_driver); -} -module_init(snd_tegra_spdif_init); - -static void __exit snd_tegra_spdif_exit(void) -{ - platform_driver_unregister(&tegra_spdif_driver); -} -module_exit(snd_tegra_spdif_exit); +module_platform_driver(tegra_spdif_driver); MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra SPDIF ASoC driver"); diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index a81cf39257b..566655e23b7 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c @@ -34,6 +34,7 @@ #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/gpio.h> +#include <linux/of_gpio.h> #include <mach/tegra_wm8903_pdata.h> @@ -59,8 +60,9 @@ #define GPIO_HP_DET BIT(4) struct tegra_wm8903 { + struct tegra_wm8903_platform_data pdata; + struct platform_device *pcm_dev; struct tegra_asoc_utils_data util_data; - struct tegra_wm8903_platform_data *pdata; int gpio_requested; }; @@ -160,7 +162,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = machine->pdata; + struct tegra_wm8903_platform_data *pdata = &machine->pdata; if (!(machine->gpio_requested & GPIO_SPKR_EN)) return 0; @@ -177,7 +179,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_context *dapm = w->dapm; struct snd_soc_card *card = dapm->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = machine->pdata; + struct tegra_wm8903_platform_data *pdata = &machine->pdata; if (!(machine->gpio_requested & GPIO_HP_MUTE)) return 0; @@ -201,8 +203,8 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = { {"Int Spk", NULL, "RON"}, {"Int Spk", NULL, "LOP"}, {"Int Spk", NULL, "LON"}, - {"Mic Bias", NULL, "Mic Jack"}, - {"IN1L", NULL, "Mic Bias"}, + {"Mic Jack", NULL, "MICBIAS"}, + {"IN1L", NULL, "Mic Jack"}, }; static const struct snd_soc_dapm_route seaboard_audio_map[] = { @@ -212,8 +214,8 @@ static const struct snd_soc_dapm_route seaboard_audio_map[] = { {"Int Spk", NULL, "RON"}, {"Int Spk", NULL, "LOP"}, {"Int Spk", NULL, "LON"}, - {"Mic Bias", NULL, "Mic Jack"}, - {"IN1R", NULL, "Mic Bias"}, + {"Mic Jack", NULL, "MICBIAS"}, + {"IN1R", NULL, "Mic Jack"}, }; static const struct snd_soc_dapm_route kaen_audio_map[] = { @@ -223,8 +225,8 @@ static const struct snd_soc_dapm_route kaen_audio_map[] = { {"Int Spk", NULL, "RON"}, {"Int Spk", NULL, "LOP"}, {"Int Spk", NULL, "LON"}, - {"Mic Bias", NULL, "Mic Jack"}, - {"IN2R", NULL, "Mic Bias"}, + {"Mic Jack", NULL, "MICBIAS"}, + {"IN2R", NULL, "Mic Jack"}, }; static const struct snd_soc_dapm_route aebl_audio_map[] = { @@ -232,8 +234,8 @@ static const struct snd_soc_dapm_route aebl_audio_map[] = { {"Headphone Jack", NULL, "HPOUTL"}, {"Int Spk", NULL, "LINEOUTR"}, {"Int Spk", NULL, "LINEOUTL"}, - {"Mic Bias", NULL, "Mic Jack"}, - {"IN1R", NULL, "Mic Bias"}, + {"Mic Jack", NULL, "MICBIAS"}, + {"IN1R", NULL, "Mic Jack"}, }; static const struct snd_kcontrol_new tegra_wm8903_controls[] = { @@ -246,9 +248,36 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = machine->pdata; + struct tegra_wm8903_platform_data *pdata = &machine->pdata; + struct device_node *np = card->dev->of_node; int ret; + if (card->dev->platform_data) { + memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); + } else if (np) { + /* + * This part must be in init() rather than probe() in order to + * guarantee that the WM8903 has been probed, and hence its + * GPIO controller registered, which is a pre-condition for + * of_get_named_gpio() to be able to map the phandles in the + * properties to the controller node. Given this, all + * pdata handling is in init() for consistency. + */ + pdata->gpio_spkr_en = of_get_named_gpio(np, + "nvidia,spkr-en-gpios", 0); + pdata->gpio_hp_mute = of_get_named_gpio(np, + "nvidia,hp-mute-gpios", 0); + pdata->gpio_hp_det = of_get_named_gpio(np, + "nvidia,hp-det-gpios", 0); + pdata->gpio_int_mic_en = of_get_named_gpio(np, + "nvidia,int-mic-en-gpios", 0); + pdata->gpio_ext_mic_en = of_get_named_gpio(np, + "nvidia,ext-mic-en-gpios", 0); + } else { + dev_err(card->dev, "No platform data supplied\n"); + return -EINVAL; + } + if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { @@ -316,28 +345,7 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, 0); - snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); - - /* FIXME: Calculate automatically based on DAPM routes? */ - if (!machine_is_harmony()) - snd_soc_dapm_nc_pin(dapm, "IN1L"); - if (!machine_is_seaboard() && !machine_is_aebl()) - snd_soc_dapm_nc_pin(dapm, "IN1R"); - snd_soc_dapm_nc_pin(dapm, "IN2L"); - if (!machine_is_kaen()) - snd_soc_dapm_nc_pin(dapm, "IN2R"); - snd_soc_dapm_nc_pin(dapm, "IN3L"); - snd_soc_dapm_nc_pin(dapm, "IN3R"); - - if (machine_is_aebl()) { - snd_soc_dapm_nc_pin(dapm, "LON"); - snd_soc_dapm_nc_pin(dapm, "RON"); - snd_soc_dapm_nc_pin(dapm, "ROP"); - snd_soc_dapm_nc_pin(dapm, "LOP"); - } else { - snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); - snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); - } + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); return 0; } @@ -355,6 +363,7 @@ static struct snd_soc_dai_link tegra_wm8903_dai = { static struct snd_soc_card snd_soc_tegra_wm8903 = { .name = "tegra-wm8903", + .owner = THIS_MODULE, .dai_link = &tegra_wm8903_dai, .num_links = 1, @@ -362,51 +371,91 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = { .num_controls = ARRAY_SIZE(tegra_wm8903_controls), .dapm_widgets = tegra_wm8903_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(tegra_wm8903_dapm_widgets), + .fully_routed = true, }; static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) { struct snd_soc_card *card = &snd_soc_tegra_wm8903; struct tegra_wm8903 *machine; - struct tegra_wm8903_platform_data *pdata; int ret; - pdata = pdev->dev.platform_data; - if (!pdata) { + if (!pdev->dev.platform_data && !pdev->dev.of_node) { dev_err(&pdev->dev, "No platform data supplied\n"); return -EINVAL; } - machine = kzalloc(sizeof(struct tegra_wm8903), GFP_KERNEL); + machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), + GFP_KERNEL); if (!machine) { dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } - - machine->pdata = pdata; - - ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); - if (ret) - goto err_free_machine; + machine->pcm_dev = ERR_PTR(-EINVAL); card->dev = &pdev->dev; platform_set_drvdata(pdev, card); snd_soc_card_set_drvdata(card, machine); - if (machine_is_harmony()) { - card->dapm_routes = harmony_audio_map; - card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); - } else if (machine_is_seaboard()) { - card->dapm_routes = seaboard_audio_map; - card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); - } else if (machine_is_kaen()) { - card->dapm_routes = kaen_audio_map; - card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); + if (pdev->dev.of_node) { + ret = snd_soc_of_parse_card_name(card, "nvidia,model"); + if (ret) + goto err; + + ret = snd_soc_of_parse_audio_routing(card, + "nvidia,audio-routing"); + if (ret) + goto err; + + tegra_wm8903_dai.codec_name = NULL; + tegra_wm8903_dai.codec_of_node = of_parse_phandle( + pdev->dev.of_node, "nvidia,audio-codec", 0); + if (!tegra_wm8903_dai.codec_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,audio-codec' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + tegra_wm8903_dai.cpu_dai_name = NULL; + tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( + pdev->dev.of_node, "nvidia,i2s-controller", 0); + if (!tegra_wm8903_dai.cpu_dai_of_node) { + dev_err(&pdev->dev, + "Property 'nvidia,i2s-controller' missing or invalid\n"); + ret = -EINVAL; + goto err; + } + + machine->pcm_dev = platform_device_register_simple( + "tegra-pcm-audio", -1, NULL, 0); + if (IS_ERR(machine->pcm_dev)) { + dev_err(&pdev->dev, + "Can't instantiate tegra-pcm-audio\n"); + ret = PTR_ERR(machine->pcm_dev); + goto err; + } } else { - card->dapm_routes = aebl_audio_map; - card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); + if (machine_is_harmony()) { + card->dapm_routes = harmony_audio_map; + card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); + } else if (machine_is_seaboard()) { + card->dapm_routes = seaboard_audio_map; + card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); + } else if (machine_is_kaen()) { + card->dapm_routes = kaen_audio_map; + card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); + } else { + card->dapm_routes = aebl_audio_map; + card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); + } } + ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); + if (ret) + goto err_unregister; + ret = snd_soc_register_card(card); if (ret) { dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", @@ -418,8 +467,10 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) err_fini_utils: tegra_asoc_utils_fini(&machine->util_data); -err_free_machine: - kfree(machine); +err_unregister: + if (!IS_ERR(machine->pcm_dev)) + platform_device_unregister(machine->pcm_dev); +err: return ret; } @@ -427,7 +478,7 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); - struct tegra_wm8903_platform_data *pdata = machine->pdata; + struct tegra_wm8903_platform_data *pdata = &machine->pdata; if (machine->gpio_requested & GPIO_HP_DET) snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, @@ -446,35 +497,31 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev) snd_soc_unregister_card(card); tegra_asoc_utils_fini(&machine->util_data); - - kfree(machine); + if (!IS_ERR(machine->pcm_dev)) + platform_device_unregister(machine->pcm_dev); return 0; } +static const struct of_device_id tegra_wm8903_of_match[] __devinitconst = { + { .compatible = "nvidia,tegra-audio-wm8903", }, + {}, +}; + static struct platform_driver tegra_wm8903_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, .pm = &snd_soc_pm_ops, + .of_match_table = tegra_wm8903_of_match, }, .probe = tegra_wm8903_driver_probe, .remove = __devexit_p(tegra_wm8903_driver_remove), }; - -static int __init tegra_wm8903_modinit(void) -{ - return platform_driver_register(&tegra_wm8903_driver); -} -module_init(tegra_wm8903_modinit); - -static void __exit tegra_wm8903_modexit(void) -{ - platform_driver_unregister(&tegra_wm8903_driver); -} -module_exit(tegra_wm8903_modexit); +module_platform_driver(tegra_wm8903_driver); MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>"); MODULE_DESCRIPTION("Tegra+WM8903 machine ASoC driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); +MODULE_DEVICE_TABLE(of, tegra_wm8903_of_match); diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index b3a7efa6d96..2bdfc550cff 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c @@ -115,18 +115,6 @@ static const struct snd_soc_dapm_route trimslice_audio_map[] = { {"RLINEIN", NULL, "Line In"}, }; -static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_nc_pin(dapm, "LHPOUT"); - snd_soc_dapm_nc_pin(dapm, "RHPOUT"); - snd_soc_dapm_nc_pin(dapm, "MICIN"); - - return 0; -} - static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { .name = "TLV320AIC23", .stream_name = "AIC23", @@ -134,12 +122,12 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = { .platform_name = "tegra-pcm-audio", .cpu_dai_name = "tegra-i2s.0", .codec_dai_name = "tlv320aic23-hifi", - .init = trimslice_asoc_init, .ops = &trimslice_asoc_ops, }; static struct snd_soc_card snd_soc_trimslice = { .name = "tegra-trimslice", + .owner = THIS_MODULE, .dai_link = &trimslice_tlv320aic23_dai, .num_links = 1, @@ -147,6 +135,7 @@ static struct snd_soc_card snd_soc_trimslice = { .num_dapm_widgets = ARRAY_SIZE(trimslice_dapm_widgets), .dapm_routes = trimslice_audio_map, .num_dapm_routes = ARRAY_SIZE(trimslice_audio_map), + .fully_routed = true, }; static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) @@ -155,15 +144,17 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) struct tegra_trimslice *trimslice; int ret; - trimslice = kzalloc(sizeof(struct tegra_trimslice), GFP_KERNEL); + trimslice = devm_kzalloc(&pdev->dev, sizeof(struct tegra_trimslice), + GFP_KERNEL); if (!trimslice) { dev_err(&pdev->dev, "Can't allocate tegra_trimslice\n"); - return -ENOMEM; + ret = -ENOMEM; + goto err; } ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); if (ret) - goto err_free_trimslice; + goto err; card->dev = &pdev->dev; platform_set_drvdata(pdev, card); @@ -180,8 +171,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev) err_fini_utils: tegra_asoc_utils_fini(&trimslice->util_data); -err_free_trimslice: - kfree(trimslice); +err: return ret; } @@ -194,8 +184,6 @@ static int __devexit tegra_snd_trimslice_remove(struct platform_device *pdev) tegra_asoc_utils_fini(&trimslice->util_data); - kfree(trimslice); - return 0; } @@ -207,18 +195,7 @@ static struct platform_driver tegra_snd_trimslice_driver = { .probe = tegra_snd_trimslice_probe, .remove = __devexit_p(tegra_snd_trimslice_remove), }; - -static int __init snd_tegra_trimslice_init(void) -{ - return platform_driver_register(&tegra_snd_trimslice_driver); -} -module_init(snd_tegra_trimslice_init); - -static void __exit snd_tegra_trimslice_exit(void) -{ - platform_driver_unregister(&tegra_snd_trimslice_driver); -} -module_exit(snd_tegra_trimslice_exit); +module_platform_driver(tegra_snd_trimslice_driver); MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); MODULE_DESCRIPTION("Trimslice machine ASoC driver"); diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index a4e3f550184..28db4ca997c 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c @@ -223,18 +223,7 @@ static struct platform_driver txx9aclc_ac97_driver = { }, }; -static int __init txx9aclc_ac97_init(void) -{ - return platform_driver_register(&txx9aclc_ac97_driver); -} - -static void __exit txx9aclc_ac97_exit(void) -{ - platform_driver_unregister(&txx9aclc_ac97_driver); -} - -module_init(txx9aclc_ac97_init); -module_exit(txx9aclc_ac97_exit); +module_platform_driver(txx9aclc_ac97_driver); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index 9b5e283af51..b056a1431ed 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c @@ -32,6 +32,7 @@ static struct snd_soc_dai_link txx9aclc_generic_dai = { static struct snd_soc_card txx9aclc_generic_card = { .name = "Generic TXx9 ACLC Audio", + .owner = THIS_MODULE, .dai_link = &txx9aclc_generic_dai, .num_links = 1, }; diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index 3de99af8cb8..93931def0dc 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -438,17 +438,7 @@ static struct platform_driver txx9aclc_pcm_driver = { .remove = __devexit_p(txx9aclc_soc_platform_remove), }; -static int __init snd_txx9aclc_pcm_init(void) -{ - return platform_driver_register(&txx9aclc_pcm_driver); -} -module_init(snd_txx9aclc_pcm_init); - -static void __exit snd_txx9aclc_pcm_exit(void) -{ - platform_driver_unregister(&txx9aclc_pcm_driver); -} -module_exit(snd_txx9aclc_pcm_exit); +module_platform_driver(txx9aclc_pcm_driver); MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver"); diff --git a/sound/sound_core.c b/sound/sound_core.c index 6ce277860fd..c6e81fb928e 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -29,7 +29,7 @@ MODULE_DESCRIPTION("Core sound module"); MODULE_AUTHOR("Alan Cox"); MODULE_LICENSE("GPL"); -static char *sound_devnode(struct device *dev, mode_t *mode) +static char *sound_devnode(struct device *dev, umode_t *mode) { if (MAJOR(dev->devt) == SOUND_MAJOR) return NULL; diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index f036776380b..b63b3a86d3f 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -50,7 +50,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Sun AMD7930 soundcard."); diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 0e618f82808..f2eabd3f22f 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -40,7 +40,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ /* Enable this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Sun CS4231 soundcard."); @@ -2118,15 +2118,4 @@ static struct platform_driver cs4231_driver = { .remove = __devexit_p(cs4231_remove), }; -static int __init cs4231_init(void) -{ - return platform_driver_register(&cs4231_driver); -} - -static void __exit cs4231_exit(void) -{ - platform_driver_unregister(&cs4231_driver); -} - -module_init(cs4231_init); -module_exit(cs4231_exit); +module_platform_driver(cs4231_driver); diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 4a4f1d74033..a6b0deb7774 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -80,7 +80,7 @@ MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ /* Enable this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard."); @@ -2697,16 +2697,4 @@ static struct platform_driver dbri_sbus_driver = { .remove = __devexit_p(dbri_remove), }; -/* Probe for the dbri chip and then attach the driver. */ -static int __init dbri_init(void) -{ - return platform_driver_register(&dbri_sbus_driver); -} - -static void __exit dbri_exit(void) -{ - platform_driver_unregister(&dbri_sbus_driver); -} - -module_init(dbri_init); -module_exit(dbri_exit); +module_platform_driver(dbri_sbus_driver); diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index c7dca7b0b9f..8af92e3e9c1 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c @@ -35,7 +35,7 @@ MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; @@ -211,22 +211,11 @@ static struct usb_device_id device_table[] = { MODULE_DEVICE_TABLE(usb, device_table); -static struct usb_driver driver = { +static struct usb_driver usb_driver = { .name = "snd-usb-6fire", .probe = usb6fire_chip_probe, .disconnect = usb6fire_chip_disconnect, .id_table = device_table, }; -static int __init usb6fire_chip_init(void) -{ - return usb_register(&driver); -} - -static void __exit usb6fire_chip_cleanup(void) -{ - usb_deregister(&driver); -} - -module_init(usb6fire_chip_init); -module_exit(usb6fire_chip_cleanup); +module_usb_driver(usb_driver); diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 3eb605bd950..64aed432ae2 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c @@ -55,7 +55,7 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int snd_card_used[SNDRV_CARDS]; module_param_array(index, int, NULL, 0444); @@ -538,16 +538,5 @@ static struct usb_driver snd_usb_driver = { .id_table = snd_usb_id_table, }; -static int __init snd_module_init(void) -{ - return usb_register(&snd_usb_driver); -} - -static void __exit snd_module_exit(void) -{ - usb_deregister(&snd_usb_driver); -} - -module_init(snd_module_init) -module_exit(snd_module_exit) +module_usb_driver(snd_usb_driver); diff --git a/sound/usb/card.c b/sound/usb/card.c index 0f6dc0d457b..4a7be7b9833 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -78,14 +78,14 @@ MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ /* Vendor/product IDs for this card */ static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; static int nrpacks = 8; /* max. number of packets per urb */ -static int async_unlink = 1; +static bool async_unlink = 1; static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ -static int ignore_ctl_error; +static bool ignore_ctl_error; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 81c6edecd86..08dcce53720 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -17,6 +17,7 @@ #include <linux/gfp.h> #include <linux/init.h> +#include <linux/ratelimit.h> #include <linux/usb.h> #include <linux/usb/audio.h> @@ -458,8 +459,8 @@ static int retire_capture_urb(struct snd_usb_substream *subs, for (i = 0; i < urb->number_of_packets; i++) { cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; - if (urb->iso_frame_desc[i].status) { - snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); + if (urb->iso_frame_desc[i].status && printk_ratelimit()) { + snd_printdd("frame %d active: %d\n", i, urb->iso_frame_desc[i].status); // continue; } bytes = urb->iso_frame_desc[i].actual_length; diff --git a/sound/usb/format.c b/sound/usb/format.c index 89421d17657..e09aba19375 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -209,6 +209,8 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof return 0; } +#define MAX_UAC2_NR_RATES 1024 + /* * Helper function to walk the array of sample rate triplets reported by * the device. The problem is that we need to parse whole array first to @@ -226,7 +228,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, int min = combine_quad(&data[2 + 12 * i]); int max = combine_quad(&data[6 + 12 * i]); int res = combine_quad(&data[10 + 12 * i]); - int rate; + unsigned int rate; if ((max < 0) || (min < 0) || (res < 0) || (max < min)) continue; @@ -253,6 +255,10 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, fp->rates |= snd_pcm_rate_to_rate_bit(rate); nr_rates++; + if (nr_rates >= MAX_UAC2_NR_RATES) { + snd_printk(KERN_ERR "invalid uac2 rates\n"); + break; + } /* avoid endless loop */ if (res == 0) diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index c0609c21030..8b81cb54026 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -52,7 +52,7 @@ MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static unsigned int queue_length = 21; module_param_array(index, int, NULL, 0444); @@ -1387,16 +1387,4 @@ static struct usb_driver ua101_driver = { #endif }; -static int __init alsa_card_ua101_init(void) -{ - return usb_register(&ua101_driver); -} - -static void __exit alsa_card_ua101_exit(void) -{ - usb_deregister(&ua101_driver); - mutex_destroy(&devices_mutex); -} - -module_init(alsa_card_ua101_init); -module_exit(alsa_card_ua101_exit); +module_usb_driver(ua101_driver); diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 60f65ace747..ab23869c01b 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -765,10 +765,61 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) * interface to ALSA control for feature/mixer units */ +/* volume control quirks */ +static void volume_control_quirks(struct usb_mixer_elem_info *cval, + struct snd_kcontrol *kctl) +{ + switch (cval->mixer->chip->usb_id) { + case USB_ID(0x0471, 0x0101): + case USB_ID(0x0471, 0x0104): + case USB_ID(0x0471, 0x0105): + case USB_ID(0x0672, 0x1041): + /* quirk for UDA1321/N101. + * note that detection between firmware 2.1.1.7 (N101) + * and later 2.1.1.21 is not very clear from datasheets. + * I hope that the min value is -15360 for newer firmware --jk + */ + if (!strcmp(kctl->id.name, "PCM Playback Volume") && + cval->min == -15616) { + snd_printk(KERN_INFO + "set volume quirk for UDA1321/N101 chip\n"); + cval->max = -256; + } + break; + + case USB_ID(0x046d, 0x09a4): + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set volume quirk for QuickCam E3500\n"); + cval->min = 6080; + cval->max = 8768; + cval->res = 192; + } + break; + + case USB_ID(0x046d, 0x0808): + case USB_ID(0x046d, 0x0809): + case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ + case USB_ID(0x046d, 0x0991): + /* Most audio usb devices lie about volume resolution. + * Most Logitech webcams have res = 384. + * Proboly there is some logitech magic behind this number --fishor + */ + if (!strcmp(kctl->id.name, "Mic Capture Volume")) { + snd_printk(KERN_INFO + "set resolution quirk: cval->res = 384\n"); + cval->res = 384; + } + break; + + } +} + /* * retrieve the minimum and maximum values for the specified control */ -static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) +static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, + int default_min, struct snd_kcontrol *kctl) { /* for failsafe */ cval->min = default_min; @@ -844,6 +895,9 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) cval->initialized = 1; } + if (kctl) + volume_control_quirks(cval, kctl); + /* USB descriptions contain the dB scale in 1/256 dB unit * while ALSA TLV contains in 1/100 dB unit */ @@ -864,6 +918,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min) return 0; } +#define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) /* get a feature/mixer unit info */ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -882,7 +937,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ uinfo->value.integer.max = 1; } else { if (!cval->initialized) { - get_min_max(cval, 0); + get_min_max_with_quirks(cval, 0, kcontrol); if (cval->initialized && cval->dBmin >= cval->dBmax) { kcontrol->vd[0].access &= ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | @@ -1045,9 +1100,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, cval->ch_readonly = readonly_mask; } - /* get min/max values */ - get_min_max(cval, 0); - /* if all channels in the mask are marked read-only, make the control * read-only. set_cur_mix_value() will check the mask again and won't * issue write commands to read-only channels. */ @@ -1069,6 +1121,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); + /* get min/max values */ + get_min_max_with_quirks(cval, 0, kctl); + switch (control) { case UAC_FU_MUTE: case UAC_FU_VOLUME: @@ -1118,51 +1173,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, break; } - /* volume control quirks */ - switch (state->chip->usb_id) { - case USB_ID(0x0471, 0x0101): - case USB_ID(0x0471, 0x0104): - case USB_ID(0x0471, 0x0105): - case USB_ID(0x0672, 0x1041): - /* quirk for UDA1321/N101. - * note that detection between firmware 2.1.1.7 (N101) - * and later 2.1.1.21 is not very clear from datasheets. - * I hope that the min value is -15360 for newer firmware --jk - */ - if (!strcmp(kctl->id.name, "PCM Playback Volume") && - cval->min == -15616) { - snd_printk(KERN_INFO - "set volume quirk for UDA1321/N101 chip\n"); - cval->max = -256; - } - break; - - case USB_ID(0x046d, 0x09a4): - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set volume quirk for QuickCam E3500\n"); - cval->min = 6080; - cval->max = 8768; - cval->res = 192; - } - break; - - case USB_ID(0x046d, 0x0808): - case USB_ID(0x046d, 0x0809): - case USB_ID(0x046d, 0x0991): - /* Most audio usb devices lie about volume resolution. - * Most Logitech webcams have res = 384. - * Proboly there is some logitech magic behind this number --fishor - */ - if (!strcmp(kctl->id.name, "Mic Capture Volume")) { - snd_printk(KERN_INFO - "set resolution quirk: cval->res = 384\n"); - cval->res = 384; - } - break; - - } - range = (cval->max - cval->min) / cval->res; /* Are there devices with volume range more than 255? I use a bit more * to be sure. 384 is a resolution magic number found on Logitech diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index b61945f3af9..8edc5035fc8 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -269,6 +269,32 @@ YAMAHA_DEVICE(0x105a, NULL), YAMAHA_DEVICE(0x105b, NULL), YAMAHA_DEVICE(0x105c, NULL), YAMAHA_DEVICE(0x105d, NULL), +{ + USB_DEVICE(0x0499, 0x1503), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + /* .vendor_name = "Yamaha", */ + /* .product_name = "MOX6/MOX8", */ + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 3, + .type = QUIRK_MIDI_YAMAHA + }, + { + .ifnum = -1 + } + } + } +}, YAMAHA_DEVICE(0x2000, "DGP-7"), YAMAHA_DEVICE(0x2001, "DGP-5"), YAMAHA_DEVICE(0x2002, NULL), @@ -1633,6 +1659,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, { + /* Roland GAIA SH-01 */ + USB_DEVICE(0x0582, 0x0111), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Roland", + .product_name = "GAIA", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = (const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 1, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + { + .ifnum = 2, + .type = QUIRK_MIDI_FIXED_ENDPOINT, + .data = &(const struct snd_usb_midi_endpoint_info) { + .out_cables = 0x0003, + .in_cables = 0x0003 + } + }, + { + .ifnum = -1 + } + } + } +}, +{ USB_DEVICE(0x0582, 0x0113), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { /* .vendor_name = "BOSS", */ @@ -2305,6 +2362,16 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, +{ + USB_DEVICE_VENDOR_SPEC(0x0944, 0x0201), + .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { + .vendor_name = "KORG, Inc.", + /* .product_name = "ToneLab ST", */ + .ifnum = 3, + .type = QUIRK_MIDI_STANDARD_INTERFACE, + } +}, + /* AKAI devices */ { USB_DEVICE(0x09e8, 0x0062), diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 2e5bc734402..a3ddac0deff 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -137,12 +137,12 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, return -ENOMEM; } if (fp->nr_rates > 0) { - rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); + rate_table = kmemdup(fp->rate_table, + sizeof(int) * fp->nr_rates, GFP_KERNEL); if (!rate_table) { kfree(fp); return -ENOMEM; } - memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); fp->rate_table = rate_table; } @@ -224,10 +224,9 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, if (altsd->bNumEndpoints != 1) return -ENXIO; - fp = kmalloc(sizeof(*fp), GFP_KERNEL); + fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); if (!fp) return -ENOMEM; - memcpy(fp, &ua_format, sizeof(*fp)); fp->iface = altsd->bInterfaceNumber; fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 726c1a7b89b..c4fd3b1d959 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ /* Enable this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); @@ -772,16 +772,4 @@ static struct usb_driver snd_us122l_usb_driver = { .supports_autosuspend = 1 }; - -static int __init snd_us122l_module_init(void) -{ - return usb_register(&snd_us122l_usb_driver); -} - -static void __exit snd_us122l_module_exit(void) -{ - usb_deregister(&snd_us122l_usb_driver); -} - -module_init(snd_us122l_module_init) -module_exit(snd_us122l_module_exit) +module_usb_driver(snd_us122l_usb_driver); diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index c400ade3ff0..1e7a47a8660 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c @@ -674,7 +674,7 @@ dotry: inurb->transfer_buffer_length = inurb->number_of_packets * inurb->iso_frame_desc[0].length; - preempt_disable(); + if (u == 0) { int now; struct usb_device *dev = inurb->dev; @@ -686,19 +686,17 @@ dotry: } err = usb_submit_urb(inurb, GFP_ATOMIC); if (err < 0) { - preempt_enable(); snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])" " returned %i\n", u, err); return err; } err = usb_submit_urb(outurb, GFP_ATOMIC); if (err < 0) { - preempt_enable(); snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])" " returned %i\n", u, err); return err; } - preempt_enable(); + if (inurb->start_frame != outurb->start_frame) { snd_printd(KERN_DEBUG "u[%i] start_frames differ in:%u out:%u\n", diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index cbd37f2c76d..9af7c1f1741 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -154,7 +154,7 @@ MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ +static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ module_param_array(index, int, NULL, 0444); MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); @@ -459,15 +459,4 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) } } -static int __init snd_usX2Y_module_init(void) -{ - return usb_register(&snd_usX2Y_usb_driver); -} - -static void __exit snd_usX2Y_module_exit(void) -{ - usb_deregister(&snd_usX2Y_usb_driver); -} - -module_init(snd_usX2Y_module_init) -module_exit(snd_usX2Y_module_exit) +module_usb_driver(snd_usX2Y_usb_driver); |