From b47a22290d581277be70e8a597824a4985d39e83 Mon Sep 17 00:00:00 2001 From: Mario Kicherer Date: Fri, 4 Apr 2014 20:40:50 +0200 Subject: ALSA: MIDI driver for Behringer BCD2000 USB device This patch adds initial support for the Behringer BCD2000 USB DJ controller. At the moment, only the MIDI part of the device is working, i.e. knobs, buttons and LEDs. I also plan to add support for the audio part, but I assume that this will require more effort than the rather simple MIDI interface. Progress can be tracked at https://github.com/anyc/snd-usb-bcd2000. Signed-off-by: Mario Kicherer Reviewed-by: Daniel Mack Reviewed-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/Kconfig | 13 ++ sound/usb/Makefile | 2 +- sound/usb/bcd2000/Makefile | 3 + sound/usb/bcd2000/bcd2000.c | 461 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 sound/usb/bcd2000/Makefile create mode 100644 sound/usb/bcd2000/bcd2000.c (limited to 'sound') diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index e05a86b7c0da..d393153c474f 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig @@ -147,5 +147,18 @@ config SND_USB_HIFACE To compile this driver as a module, choose M here: the module will be called snd-usb-hiface. +config SND_BCD2000 + tristate "Behringer BCD2000 MIDI driver" + select SND_RAWMIDI + help + Say Y here to include MIDI support for the Behringer BCD2000 DJ + controller. + + Audio support is still work-in-progress at + https://github.com/anyc/snd-usb-bcd2000 + + To compile this driver as a module, choose M here: the module + will be called snd-bcd2000. + endif # SND_USB diff --git a/sound/usb/Makefile b/sound/usb/Makefile index abe668f660d1..2b92f0dcbc4c 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile @@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o -obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ +obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ diff --git a/sound/usb/bcd2000/Makefile b/sound/usb/bcd2000/Makefile new file mode 100644 index 000000000000..f09ccc0af6ff --- /dev/null +++ b/sound/usb/bcd2000/Makefile @@ -0,0 +1,3 @@ +snd-bcd2000-y := bcd2000.o + +obj-$(CONFIG_SND_BCD2000) += snd-bcd2000.o \ No newline at end of file diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c new file mode 100644 index 000000000000..820d6ca8c458 --- /dev/null +++ b/sound/usb/bcd2000/bcd2000.c @@ -0,0 +1,461 @@ +/* + * Behringer BCD2000 driver + * + * Copyright (C) 2014 Mario Kicherer (dev@kicherer.org) + * + * 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PREFIX "snd-bcd2000: " +#define BUFSIZE 64 + +static struct usb_device_id id_table[] = { + { USB_DEVICE(0x1397, 0x00bd) }, + { }, +}; + +static unsigned char device_cmd_prefix[] = {0x03, 0x00}; + +static unsigned char bcd2000_init_sequence[] = { + 0x07, 0x00, 0x00, 0x00, 0x78, 0x48, 0x1c, 0x81, + 0xc4, 0x00, 0x00, 0x00, 0x5e, 0x53, 0x4a, 0xf7, + 0x18, 0xfa, 0x11, 0xff, 0x6c, 0xf3, 0x90, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x18, 0xfa, 0x11, 0xff, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf2, 0x34, 0x4a, 0xf7, + 0x18, 0xfa, 0x11, 0xff +}; + +struct bcd2000 { + struct usb_device *dev; + struct snd_card *card; + struct usb_interface *intf; + int card_index; + + int midi_out_active; + struct snd_rawmidi *rmidi; + struct snd_rawmidi_substream *midi_receive_substream; + struct snd_rawmidi_substream *midi_out_substream; + + unsigned char midi_in_buf[BUFSIZE]; + unsigned char midi_out_buf[BUFSIZE]; + + struct urb *midi_out_urb; + struct urb *midi_in_urb; + + struct usb_anchor anchor; +}; + +static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; +static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; + +static DEFINE_MUTEX(devices_mutex); +DECLARE_BITMAP(devices_used, SNDRV_CARDS); +static struct usb_driver bcd2000_driver; + +#ifdef CONFIG_SND_DEBUG +static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) +{ + print_hex_dump(KERN_DEBUG, prefix, + DUMP_PREFIX_NONE, 16, 1, + buf, len, false); +} +#else +static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) {} +#endif + +static int bcd2000_midi_input_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int bcd2000_midi_input_close(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +/* (de)register midi substream from client */ +static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct bcd2000 *bcd2k = substream->rmidi->private_data; + bcd2k->midi_receive_substream = up ? substream : NULL; +} + +static void bcd2000_midi_handle_input(struct bcd2000 *bcd2k, + const unsigned char *buf, unsigned int buf_len) +{ + unsigned int payload_length, tocopy; + struct snd_rawmidi_substream *midi_receive_substream; + + midi_receive_substream = ACCESS_ONCE(bcd2k->midi_receive_substream); + if (!midi_receive_substream) + return; + + bcd2000_dump_buffer(PREFIX "received from device: ", buf, buf_len); + + if (buf_len < 2) + return; + + payload_length = buf[0]; + + /* ignore packets without payload */ + if (payload_length == 0) + return; + + tocopy = min(payload_length, buf_len-1); + + bcd2000_dump_buffer(PREFIX "sending to userspace: ", + &buf[1], tocopy); + + snd_rawmidi_receive(midi_receive_substream, + &buf[1], tocopy); +} + +static void bcd2000_midi_send(struct bcd2000 *bcd2k) +{ + int len, ret; + struct snd_rawmidi_substream *midi_out_substream; + + BUILD_BUG_ON(sizeof(device_cmd_prefix) >= BUFSIZE); + + midi_out_substream = ACCESS_ONCE(bcd2k->midi_out_substream); + if (!midi_out_substream) + return; + + /* copy command prefix bytes */ + memcpy(bcd2k->midi_out_buf, device_cmd_prefix, + sizeof(device_cmd_prefix)); + + /* + * get MIDI packet and leave space for command prefix + * and payload length + */ + len = snd_rawmidi_transmit(midi_out_substream, + bcd2k->midi_out_buf + 3, BUFSIZE - 3); + + if (len < 0) + dev_err(&bcd2k->dev->dev, "%s: snd_rawmidi_transmit error %d\n", + __func__, len); + + if (len <= 0) + return; + + /* set payload length */ + bcd2k->midi_out_buf[2] = len; + bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE; + + bcd2000_dump_buffer(PREFIX "sending to device: ", + bcd2k->midi_out_buf, len+3); + + /* send packet to the BCD2000 */ + ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC); + if (ret < 0) + dev_err(&bcd2k->dev->dev, PREFIX + "%s (%p): usb_submit_urb() failed, ret=%d, len=%d\n", + __func__, midi_out_substream, ret, len); + else + bcd2k->midi_out_active = 1; +} + +static int bcd2000_midi_output_open(struct snd_rawmidi_substream *substream) +{ + return 0; +} + +static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream) +{ + struct bcd2000 *bcd2k = substream->rmidi->private_data; + + if (bcd2k->midi_out_active) { + usb_kill_urb(bcd2k->midi_out_urb); + bcd2k->midi_out_active = 0; + } + + return 0; +} + +/* (de)register midi substream from client */ +static void bcd2000_midi_output_trigger(struct snd_rawmidi_substream *substream, + int up) +{ + struct bcd2000 *bcd2k = substream->rmidi->private_data; + + if (up) { + bcd2k->midi_out_substream = substream; + /* check if there is data userspace wants to send */ + if (!bcd2k->midi_out_active) + bcd2000_midi_send(bcd2k); + } else { + bcd2k->midi_out_substream = NULL; + } +} + +static void bcd2000_output_complete(struct urb *urb) +{ + struct bcd2000 *bcd2k = urb->context; + + bcd2k->midi_out_active = 0; + + if (urb->status) + dev_warn(&urb->dev->dev, + PREFIX "output urb->status: %d\n", urb->status); + + if (urb->status == -ESHUTDOWN) + return; + + /* check if there is more data userspace wants to send */ + bcd2000_midi_send(bcd2k); +} + +static void bcd2000_input_complete(struct urb *urb) +{ + int ret; + struct bcd2000 *bcd2k = urb->context; + + if (urb->status) + dev_warn(&urb->dev->dev, + PREFIX "input urb->status: %i\n", urb->status); + + if (!bcd2k || urb->status == -ESHUTDOWN) + return; + + if (urb->actual_length > 0) + bcd2000_midi_handle_input(bcd2k, urb->transfer_buffer, + urb->actual_length); + + /* return URB to device */ + ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_ATOMIC); + if (ret < 0) + dev_err(&bcd2k->dev->dev, PREFIX + "%s: usb_submit_urb() failed, ret=%d\n", + __func__, ret); +} + +static struct snd_rawmidi_ops bcd2000_midi_output = { + .open = bcd2000_midi_output_open, + .close = bcd2000_midi_output_close, + .trigger = bcd2000_midi_output_trigger, +}; + +static struct snd_rawmidi_ops bcd2000_midi_input = { + .open = bcd2000_midi_input_open, + .close = bcd2000_midi_input_close, + .trigger = bcd2000_midi_input_trigger, +}; + +static void bcd2000_init_device(struct bcd2000 *bcd2k) +{ + int ret; + + init_usb_anchor(&bcd2k->anchor); + usb_anchor_urb(bcd2k->midi_out_urb, &bcd2k->anchor); + usb_anchor_urb(bcd2k->midi_in_urb, &bcd2k->anchor); + + /* copy init sequence into buffer */ + memcpy(bcd2k->midi_out_buf, bcd2000_init_sequence, 52); + bcd2k->midi_out_urb->transfer_buffer_length = 52; + + /* submit sequence */ + ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_KERNEL); + if (ret < 0) + dev_err(&bcd2k->dev->dev, PREFIX + "%s: usb_submit_urb() out failed, ret=%d: ", + __func__, ret); + else + bcd2k->midi_out_active = 1; + + /* pass URB to device to enable button and controller events */ + ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_KERNEL); + if (ret < 0) + dev_err(&bcd2k->dev->dev, PREFIX + "%s: usb_submit_urb() in failed, ret=%d: ", + __func__, ret); + + /* ensure initialization is finished */ + usb_wait_anchor_empty_timeout(&bcd2k->anchor, 1000); +} + +static int bcd2000_init_midi(struct bcd2000 *bcd2k) +{ + int ret; + struct snd_rawmidi *rmidi; + + ret = snd_rawmidi_new(bcd2k->card, bcd2k->card->shortname, 0, + 1, /* output */ + 1, /* input */ + &rmidi); + + if (ret < 0) + return ret; + + strlcpy(rmidi->name, bcd2k->card->shortname, sizeof(rmidi->name)); + + rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; + rmidi->private_data = bcd2k; + + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, + &bcd2000_midi_output); + + rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; + snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, + &bcd2000_midi_input); + + bcd2k->rmidi = rmidi; + + bcd2k->midi_in_urb = usb_alloc_urb(0, GFP_KERNEL); + bcd2k->midi_out_urb = usb_alloc_urb(0, GFP_KERNEL); + + if (!bcd2k->midi_in_urb || !bcd2k->midi_out_urb) { + dev_err(&bcd2k->dev->dev, PREFIX "usb_alloc_urb failed\n"); + return -ENOMEM; + } + + usb_fill_int_urb(bcd2k->midi_in_urb, bcd2k->dev, + usb_rcvintpipe(bcd2k->dev, 0x81), + bcd2k->midi_in_buf, BUFSIZE, + bcd2000_input_complete, bcd2k, 1); + + usb_fill_int_urb(bcd2k->midi_out_urb, bcd2k->dev, + usb_sndintpipe(bcd2k->dev, 0x1), + bcd2k->midi_out_buf, BUFSIZE, + bcd2000_output_complete, bcd2k, 1); + + bcd2000_init_device(bcd2k); + + return 0; +} + +static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k, + struct usb_interface *interface) +{ + /* usb_kill_urb not necessary, urb is aborted automatically */ + + usb_free_urb(bcd2k->midi_out_urb); + usb_free_urb(bcd2k->midi_in_urb); + + if (bcd2k->intf) { + usb_set_intfdata(bcd2k->intf, NULL); + bcd2k->intf = NULL; + } +} + +static int bcd2000_probe(struct usb_interface *interface, + const struct usb_device_id *usb_id) +{ + struct snd_card *card; + struct bcd2000 *bcd2k; + unsigned int card_index; + char usb_path[32]; + int err; + + mutex_lock(&devices_mutex); + + for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) + if (!test_bit(card_index, devices_used)) + break; + + if (card_index >= SNDRV_CARDS) { + mutex_unlock(&devices_mutex); + return -ENOENT; + } + + err = snd_card_new(&interface->dev, index[card_index], id[card_index], + THIS_MODULE, sizeof(*bcd2k), &card); + if (err < 0) { + mutex_unlock(&devices_mutex); + return err; + } + + bcd2k = card->private_data; + bcd2k->dev = interface_to_usbdev(interface); + bcd2k->card = card; + bcd2k->card_index = card_index; + bcd2k->intf = interface; + + snd_card_set_dev(card, &interface->dev); + + strncpy(card->driver, "snd-bcd2000", sizeof(card->driver)); + strncpy(card->shortname, "BCD2000", sizeof(card->shortname)); + usb_make_path(bcd2k->dev, usb_path, sizeof(usb_path)); + snprintf(bcd2k->card->longname, sizeof(bcd2k->card->longname), + "Behringer BCD2000 at %s", + usb_path); + + err = bcd2000_init_midi(bcd2k); + if (err < 0) + goto probe_error; + + err = snd_card_register(card); + if (err < 0) + goto probe_error; + + usb_set_intfdata(interface, bcd2k); + set_bit(card_index, devices_used); + + mutex_unlock(&devices_mutex); + return 0; + +probe_error: + dev_info(&bcd2k->dev->dev, PREFIX "error during probing"); + bcd2000_free_usb_related_resources(bcd2k, interface); + snd_card_free(card); + mutex_unlock(&devices_mutex); + return err; +} + +static void bcd2000_disconnect(struct usb_interface *interface) +{ + struct bcd2000 *bcd2k = usb_get_intfdata(interface); + + if (!bcd2k) + return; + + mutex_lock(&devices_mutex); + + /* make sure that userspace cannot create new requests */ + snd_card_disconnect(bcd2k->card); + + bcd2000_free_usb_related_resources(bcd2k, interface); + + clear_bit(bcd2k->card_index, devices_used); + + snd_card_free_when_closed(bcd2k->card); + + mutex_unlock(&devices_mutex); +} + +static struct usb_driver bcd2000_driver = { + .name = "snd-bcd2000", + .probe = bcd2000_probe, + .disconnect = bcd2000_disconnect, + .id_table = id_table, +}; + +module_usb_driver(bcd2000_driver); + +MODULE_DEVICE_TABLE(usb, id_table); +MODULE_AUTHOR("Mario Kicherer, dev@kicherer.org"); +MODULE_DESCRIPTION("Behringer BCD2000 driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9374f375ab8b91a394487ef0707d827dcdeb8139 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Sat, 5 Apr 2014 12:11:48 +0100 Subject: ASoC: wm5110: Add in OSR controls for OUT5/6 There are no OSR controls on outputs 1-4 on wm5110, however when these were removed the ones on output 5 and 6 were also accidentally removed, but those actually exist. This patch adds these controls back in. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..83a7e2f91ece 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -367,6 +367,11 @@ SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL, SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL, ARIZONA_HP3_SC_ENA_SHIFT, 1, 0), +SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, + ARIZONA_OUT5_OSR_SHIFT, 1, 0), +SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L, + ARIZONA_OUT6_OSR_SHIFT, 1, 0), + SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, -- cgit v1.2.3 From a39f75f7907fa3a708751dc283e3ab3e7da526b8 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:23 +0800 Subject: ASoC: core: Move the default regmap I/O setting to snd_soc_register_codec() Add the default regmap I/O setting to snd_soc_register_codec() while the CODEC is initialising, which will be called by CODEC driver device probe(), and then we can make XXX_set_cache_io() go away entirely from each CODEC ASoC probe. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 28 ++++++++++++++++++---------- sound/soc/soc-io.c | 9 +++------ 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..2f62436026d2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -754,6 +754,7 @@ struct snd_soc_codec_driver { unsigned int freq_in, unsigned int freq_out); /* codec IO */ + struct regmap *(*get_regmap)(struct device *); unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); int (*display_register)(struct snd_soc_codec *, char *, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..5071a3a0ac83 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1137,16 +1137,6 @@ static int soc_probe_codec(struct snd_soc_card *card, codec->dapm.idle_bias_off = driver->idle_bias_off; - if (!codec->write && dev_get_regmap(codec->dev, NULL)) { - /* Set the default I/O up try regmap */ - ret = snd_soc_codec_set_cache_io(codec, NULL); - if (ret < 0) { - dev_err(codec->dev, - "Failed to set cache I/O: %d\n", ret); - goto err_probe; - } - } - if (driver->probe) { ret = driver->probe(codec); if (ret < 0) { @@ -4263,6 +4253,7 @@ int snd_soc_register_codec(struct device *dev, int num_dai) { struct snd_soc_codec *codec; + struct regmap *regmap; int ret, i; dev_dbg(dev, "codec register %s\n", dev_name(dev)); @@ -4294,6 +4285,23 @@ int snd_soc_register_codec(struct device *dev, codec->num_dai = num_dai; mutex_init(&codec->mutex); + if (!codec->write) { + if (codec_drv->get_regmap) + regmap = codec_drv->get_regmap(dev); + else + regmap = dev_get_regmap(dev, NULL); + + if (regmap) { + ret = snd_soc_codec_set_cache_io(codec, regmap); + if (ret && ret != -ENOTSUPP) { + dev_err(codec->dev, + "Failed to set cache I/O:%d\n", + ret); + return ret; + } + } + } + for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); fixup_codec_formats(&dai_drv[i].capture); diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 260efc8466fc..6480e8f29310 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -60,14 +60,11 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, { int ret; - /* Device has made its own regmap arrangements */ if (!regmap) - codec->control_data = dev_get_regmap(codec->dev, NULL); - else - codec->control_data = regmap; + return -EINVAL; - if (IS_ERR(codec->control_data)) - return PTR_ERR(codec->control_data); + /* Device has made its own regmap arrangements */ + codec->control_data = regmap; codec->write = hw_write; codec->read = hw_read; -- cgit v1.2.3 From bbc0bd7fd3f671096625b5cbde97e12e3e2dba8f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:24 +0800 Subject: ASoC: 88pm860x: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b07e17160f94..dc9e6b94e645 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1327,10 +1327,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) pm860x->codec = codec; - ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap); - if (ret) - return ret; - for (i = 0; i < 4; i++) { ret = request_threaded_irq(pm860x->irq[i], NULL, pm860x_codec_handler, IRQF_ONESHOT, @@ -1362,10 +1358,18 @@ static int pm860x_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *pm860x_get_regmap(struct device *dev) +{ + struct pm860x_priv *pm860x = dev_get_drvdata(dev); + + return pm860x->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_pm860x = { .probe = pm860x_probe, .remove = pm860x_remove, .set_bias_level = pm860x_set_bias_level, + .get_regmap = pm860x_get_regmap, .controls = pm860x_snd_controls, .num_controls = ARRAY_SIZE(pm860x_snd_controls), -- cgit v1.2.3 From 49101a25acd69cf36192888392c518a299c091af Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:25 +0800 Subject: ASoC: cq93vc: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/cq93vc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1e25c7af853b..5e5518d20311 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -139,8 +139,6 @@ static int cq93vc_probe(struct snd_soc_codec *codec) davinci_vc->cq93vc.codec = codec; - snd_soc_codec_set_cache_io(codec, davinci_vc->regmap); - /* Off, with power on */ cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -154,11 +152,19 @@ static int cq93vc_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *cq93vc_get_regmap(struct device *dev) +{ + struct davinci_vc *davinci_vc = codec->dev->platform_data; + + return davinci_vc->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { .set_bias_level = cq93vc_set_bias_level, .probe = cq93vc_probe, .remove = cq93vc_remove, .resume = cq93vc_resume, + .get_regmap = cq93vc_get_regmap, .controls = cq93vc_snd_controls, .num_controls = ARRAY_SIZE(cq93vc_snd_controls), }; -- cgit v1.2.3 From d957f1651ed2976e18c75c5644a92ed471c3ae9e Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:26 +0800 Subject: ASoC: mc13783: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2c59b1fb69dc..8c0cec392dec 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -608,14 +608,6 @@ static struct snd_kcontrol_new mc13783_control_list[] = { static int mc13783_probe(struct snd_soc_codec *codec) { struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = snd_soc_codec_set_cache_io(codec, - dev_get_regmap(codec->dev->parent, NULL)); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - return ret; - } /* these are the reset values */ mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); @@ -735,9 +727,15 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { } }; +struct regmap *mc13783_get_regmap(struct device *dev) +{ + return dev_get_regmap(dev->parent, NULL); +} + static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { .probe = mc13783_probe, .remove = mc13783_remove, + .get_regmap = mc13783_get_regmap, .controls = mc13783_control_list, .num_controls = ARRAY_SIZE(mc13783_control_list), .dapm_widgets = mc13783_dapm_widgets, -- cgit v1.2.3 From 83905ef3cbd0025830e9db65bf5ce7db721e39a7 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:27 +0800 Subject: ASoC: si476x: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Andrey Smirnov Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 244c097cd905..961b7e8ac0da 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -208,13 +208,6 @@ out: return err; } -static int si476x_codec_probe(struct snd_soc_codec *codec) -{ - struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL); - - return snd_soc_codec_set_cache_io(codec, regmap); -} - static struct snd_soc_dai_ops si476x_dai_ops = { .hw_params = si476x_codec_hw_params, .set_fmt = si476x_codec_set_dai_fmt, @@ -238,8 +231,13 @@ static struct snd_soc_dai_driver si476x_dai = { .ops = &si476x_dai_ops, }; +struct regmap *si476x_get_regmap(struct device *dev) +{ + return dev_get_regmap(dev->parent, NULL); +} + static struct snd_soc_codec_driver soc_codec_dev_si476x = { - .probe = si476x_codec_probe, + .get_regmap = si476x_get_regmap, .dapm_widgets = si476x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), .dapm_routes = si476x_dapm_routes, -- cgit v1.2.3 From c8b02acd45e4b30aef2a86526e6844071cfd41bf Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:28 +0800 Subject: ASoC: wm5102: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index dcf1d12cfef8..aa60ba23b017 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1760,10 +1760,6 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); int ret; - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; - ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); if (ret != 0) return ret; @@ -1802,9 +1798,17 @@ static unsigned int wm5102_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; +struct regmap *wm5102_get_regmap(struct device *dev) +{ + struct wm5102_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { .probe = wm5102_codec_probe, .remove = wm5102_codec_remove, + .get_regmap = wm5102_get_regmap, .idle_bias_off = true, -- cgit v1.2.3 From 6e4842d30c2eea928b6df6adfe9db49ec971f32d Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:29 +0800 Subject: ASoC: wm5110: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..4be5f990a9d6 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1589,10 +1589,6 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) priv->core.arizona->dapm = &codec->dapm; - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; - arizona_init_spk(codec); arizona_init_gpio(codec); @@ -1633,9 +1629,17 @@ static unsigned int wm5110_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_6R, }; +struct regmap *wm5110_get_regmap(struct device *dev) +{ + struct wm5110_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { .probe = wm5110_codec_probe, .remove = wm5110_codec_remove, + .get_regmap = wm5110_get_regmap, .idle_bias_off = true, -- cgit v1.2.3 From aec0eb50e5f71f6c28cc0a4739b34ec109fe1a56 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:30 +0800 Subject: ASoC: wm8350: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8350.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 757256bf7672..6b31a9f83137 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1505,8 +1505,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; - snd_soc_codec_set_cache_io(codec, wm8350->regmap); - /* Put the codec into reset if it wasn't already */ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1608,11 +1606,19 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8350_get_regmap(struct device *dev) +{ + struct wm8350 *wm8350 = dev_get_platdata(dev); + + return wm8350->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { .probe = wm8350_codec_probe, .remove = wm8350_codec_remove, .suspend = wm8350_suspend, .resume = wm8350_resume, + .get_regmap = wm8350_get_regmap, .set_bias_level = wm8350_set_bias_level, .controls = wm8350_snd_controls, -- cgit v1.2.3 From 4504badea3a3edd0d114b51a866cd98b4ff626b0 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:31 +0800 Subject: ASoC: wm8400: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8400.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 146564feaea0..e6410f2e8cac 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1318,8 +1318,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) priv->wm8400 = wm8400; priv->codec = codec; - snd_soc_codec_set_cache_io(codec, wm8400->regmap); - ret = devm_regulator_bulk_get(wm8400->dev, ARRAY_SIZE(power), &power[0]); if (ret != 0) { @@ -1361,11 +1359,19 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8400_get_regmap(struct device *dev) +{ + struct wm8400 *wm8400 = dev_get_platdata(dev); + + return wm8400->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { .probe = wm8400_codec_probe, .remove = wm8400_codec_remove, .suspend = wm8400_suspend, .resume = wm8400_resume, + .get_regmap = wm8400_get_regmap, .set_bias_level = wm8400_set_bias_level, .controls = wm8400_snd_controls, -- cgit v1.2.3 From c0b6f59b7036c0cb7e0d03240fcb095104855ab9 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:32 +0800 Subject: ASoC: wm8994: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..daa4edcfe14a 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3999,8 +3999,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->hubs.codec = codec; - snd_soc_codec_set_cache_io(codec, control->regmap); - mutex_init(&wm8994->accdet_lock); INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, wm1811_jackdet_bootstrap); @@ -4434,11 +4432,19 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) return 0; } +struct regmap *wm8994_get_regmap(struct device *dev) +{ + struct wm8994 *control = dev_get_drvdata(dev->parent); + + return control->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .probe = wm8994_codec_probe, .remove = wm8994_codec_remove, .suspend = wm8994_codec_suspend, .resume = wm8994_codec_resume, + .get_regmap = wm8994_get_regmap, .set_bias_level = wm8994_set_bias_level, }; -- cgit v1.2.3 From 964eafb1d59b7c270982d144882c64b93c67eb03 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Wed, 26 Mar 2014 13:40:33 +0800 Subject: ASoC: wm8997: Remove the set_cache_io() entirely from ASoC probe. As we can set the CODEC I/O while snd_soc_register_codec(), so the calling of set_cache_io() from CODEC ASoC probe could be removed entirely. And then we can set the CODEC I/O in the device probe instead of CODEC ASoC probe as earily as possible. Signed-off-by: Xiubo Li Acked-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 004186b6bd48..3d50621b070c 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1051,11 +1051,6 @@ static struct snd_soc_dai_driver wm8997_dai[] = { static int wm8997_codec_probe(struct snd_soc_codec *codec) { struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); - if (ret != 0) - return ret; arizona_init_spk(codec); @@ -1086,9 +1081,17 @@ static unsigned int wm8997_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; +struct regmap *wm8997_get_regmap(struct device *dev) +{ + struct wm8997_priv *priv = dev_get_drvdata(dev); + + return priv->core.arizona->regmap; +} + static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { .probe = wm8997_codec_probe, .remove = wm8997_codec_remove, + .get_regmap = wm8997_get_regmap, .idle_bias_off = true, -- cgit v1.2.3 From 7a34b1c1dff720dd8dcf63e2b0e5fc15a8f7208f Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Thu, 3 Apr 2014 07:53:59 +0800 Subject: ASoC: codec: fix the sparse check warnings. Some thing Likes: reproduce: make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> sound/soc/codecs/wm8997.c:1084:15: sparse: symbol \ 'wm8997_get_regmap' was not declared. Should it be static? Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 2 +- sound/soc/codecs/cq93vc.c | 2 +- sound/soc/codecs/mc13783.c | 2 +- sound/soc/codecs/si476x.c | 2 +- sound/soc/codecs/wm5102.c | 2 +- sound/soc/codecs/wm5110.c | 2 +- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8400.c | 2 +- sound/soc/codecs/wm8994.c | 2 +- sound/soc/codecs/wm8997.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index dc9e6b94e645..f073b6feac94 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1358,7 +1358,7 @@ static int pm860x_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *pm860x_get_regmap(struct device *dev) +static struct regmap *pm860x_get_regmap(struct device *dev) { struct pm860x_priv *pm860x = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 5e5518d20311..5ee48c8e4849 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -152,7 +152,7 @@ static int cq93vc_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *cq93vc_get_regmap(struct device *dev) +static struct regmap *cq93vc_get_regmap(struct device *dev) { struct davinci_vc *davinci_vc = codec->dev->platform_data; diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 8c0cec392dec..9029e20514e1 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -727,7 +727,7 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { } }; -struct regmap *mc13783_get_regmap(struct device *dev) +static struct regmap *mc13783_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 961b7e8ac0da..f26befb0c297 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -231,7 +231,7 @@ static struct snd_soc_dai_driver si476x_dai = { .ops = &si476x_dai_ops, }; -struct regmap *si476x_get_regmap(struct device *dev) +static struct regmap *si476x_get_regmap(struct device *dev) { return dev_get_regmap(dev->parent, NULL); } diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index aa60ba23b017..7a046536ea68 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -1798,7 +1798,7 @@ static unsigned int wm5102_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; -struct regmap *wm5102_get_regmap(struct device *dev) +static struct regmap *wm5102_get_regmap(struct device *dev) { struct wm5102_priv *priv = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4be5f990a9d6..97eb1bc5bea7 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -1629,7 +1629,7 @@ static unsigned int wm5110_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_6R, }; -struct regmap *wm5110_get_regmap(struct device *dev) +static struct regmap *wm5110_get_regmap(struct device *dev) { struct wm5110_priv *priv = dev_get_drvdata(dev); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 6b31a9f83137..1bd14b64a6c0 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1606,7 +1606,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8350_get_regmap(struct device *dev) +static struct regmap *wm8350_get_regmap(struct device *dev) { struct wm8350 *wm8350 = dev_get_platdata(dev); diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index e6410f2e8cac..5880d223e161 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -1359,7 +1359,7 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8400_get_regmap(struct device *dev) +static struct regmap *wm8400_get_regmap(struct device *dev) { struct wm8400 *wm8400 = dev_get_platdata(dev); diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index daa4edcfe14a..6f336da856c5 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4432,7 +4432,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) return 0; } -struct regmap *wm8994_get_regmap(struct device *dev) +static struct regmap *wm8994_get_regmap(struct device *dev) { struct wm8994 *control = dev_get_drvdata(dev->parent); diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 3d50621b070c..09c4150840a3 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -1081,7 +1081,7 @@ static unsigned int wm8997_digital_vu[] = { ARIZONA_DAC_DIGITAL_VOLUME_5R, }; -struct regmap *wm8997_get_regmap(struct device *dev) +static struct regmap *wm8997_get_regmap(struct device *dev) { struct wm8997_priv *priv = dev_get_drvdata(dev); -- cgit v1.2.3 From ea53bf77d147e7e560ac007fdaa30fb98c37c712 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:04 +0100 Subject: ASoC: Add snd_soc_kcontrol_codec() helper function For CODEC controls snd_kcontrol_chip() currently returns a pointer to the CODEC that registered the control. With the upcoming consolidation of platform and CODEC controls this will change. Prepare for this by introducing the snd_soc_kcontrol_codec() helper function that will hide the implementation details of how the CODEC for a control can be obtained. This will allow us to change this easily in the future. The patch also updates all CODEC drivers to use the new helper function. Signed-off-by: Lars-Peter Clausen Acked-by: Charles Keepax Signed-off-by: Mark Brown --- include/sound/soc.h | 14 ++++++++++++++ sound/soc/codecs/88pm860x-codec.c | 8 ++++---- sound/soc/codecs/ab8500-codec.c | 12 ++++++------ sound/soc/codecs/adav80x.c | 4 ++-- sound/soc/codecs/ak4641.c | 4 ++-- sound/soc/codecs/cs4270.c | 2 +- sound/soc/codecs/cs4271.c | 4 ++-- sound/soc/codecs/cs42l51.c | 4 ++-- sound/soc/codecs/da7210.c | 4 ++-- sound/soc/codecs/da7213.c | 4 ++-- sound/soc/codecs/da732x.c | 4 ++-- sound/soc/codecs/da9055.c | 2 +- sound/soc/codecs/lm4857.c | 4 ++-- sound/soc/codecs/max9768.c | 4 ++-- sound/soc/codecs/max98088.c | 12 ++++++------ sound/soc/codecs/max98090.c | 4 ++-- sound/soc/codecs/max98095.c | 16 ++++++++-------- sound/soc/codecs/pcm1681.c | 4 ++-- sound/soc/codecs/rt5631.c | 4 ++-- sound/soc/codecs/sgtl5000.c | 4 ++-- sound/soc/codecs/sta32x.c | 4 ++-- sound/soc/codecs/tas5086.c | 4 ++-- sound/soc/codecs/tlv320aic23.c | 4 ++-- sound/soc/codecs/tlv320dac33.c | 4 ++-- sound/soc/codecs/twl4030.c | 10 +++++----- sound/soc/codecs/twl6040.c | 8 ++++---- sound/soc/codecs/wl1273.c | 12 ++++++------ sound/soc/codecs/wm2000.c | 8 ++++---- sound/soc/codecs/wm8350.c | 4 ++-- sound/soc/codecs/wm8400.c | 2 +- sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8731.c | 4 ++-- sound/soc/codecs/wm8753.c | 4 ++-- sound/soc/codecs/wm8804.c | 4 ++-- sound/soc/codecs/wm8903.c | 4 ++-- sound/soc/codecs/wm8904.c | 14 +++++++------- sound/soc/codecs/wm8955.c | 4 ++-- sound/soc/codecs/wm8958-dsp2.c | 32 ++++++++++++++++---------------- sound/soc/codecs/wm8960.c | 4 ++-- sound/soc/codecs/wm8962.c | 8 ++++---- sound/soc/codecs/wm8983.c | 4 ++-- sound/soc/codecs/wm8985.c | 4 ++-- sound/soc/codecs/wm8990.c | 2 +- sound/soc/codecs/wm8991.c | 2 +- sound/soc/codecs/wm8994.c | 10 +++++----- sound/soc/codecs/wm8996.c | 4 ++-- sound/soc/codecs/wm9081.c | 4 ++-- sound/soc/codecs/wm_adsp.c | 4 ++-- sound/soc/codecs/wm_hubs.c | 2 +- 49 files changed, 154 insertions(+), 140 deletions(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..e150030b754d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1228,6 +1228,20 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec) return snd_soc_component_is_active(&codec->component); } +/** + * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control + * @kcontrol: The control for which to get the CODEC + * + * Note: This function will only work correctly if the control has been + * registered with snd_soc_add_codec_controls() or via table based setup of + * snd_soc_codec_driver. Otherwise the behavior is undefined. + */ +static inline struct snd_soc_codec *snd_soc_kcontrol_codec( + struct snd_kcontrol *kcontrol) +{ + return snd_kcontrol_chip(kcontrol); +} + int snd_soc_util_init(void); void snd_soc_util_exit(void); diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b07e17160f94..b18cafa5a858 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -276,7 +276,7 @@ static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; int val[2], val2[2], i; @@ -300,7 +300,7 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; int err; @@ -333,7 +333,7 @@ static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -353,7 +353,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 1ad92cbf0b24..1fb4402bf72d 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -1139,7 +1139,7 @@ static void anc_configure(struct snd_soc_codec *codec, static int sid_status_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); mutex_lock(&codec->mutex); @@ -1153,7 +1153,7 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol, static int sid_status_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); unsigned int param, sidconf, val; int status = 1; @@ -1208,7 +1208,7 @@ out: static int anc_status_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); mutex_lock(&codec->mutex); @@ -1221,7 +1221,7 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol, static int anc_status_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); struct device *dev = codec->dev; bool apply_fir, apply_iir; @@ -1306,7 +1306,7 @@ static int filter_control_info(struct snd_kcontrol *kcontrol, static int filter_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; @@ -1322,7 +1322,7 @@ static int filter_control_get(struct snd_kcontrol *kcontrol, static int filter_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct filter_control *fc = (struct filter_control *)kcontrol->private_value; unsigned int i; diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 5062e34ee8dc..cf170b5ef426 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -315,7 +315,7 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec) static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int deemph = ucontrol->value.enumerated.item[0]; @@ -330,7 +330,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = adav80x->deemph; diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 868c0e2da1ec..7afe8f482088 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c @@ -74,7 +74,7 @@ static int ak4641_set_deemph(struct snd_soc_codec *codec) static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; @@ -89,7 +89,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = ak4641->deemph; diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 3920e6264948..9947a9583679 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -438,7 +438,7 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); int left = !ucontrol->value.integer.value[0]; int right = !ucontrol->value.integer.value[1]; diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index aef4965750c7..93cec52f4733 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c @@ -284,7 +284,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec) static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = cs4271->deemph; @@ -294,7 +294,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); cs4271->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..23acaa0263dc 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -55,7 +55,7 @@ struct cs42l51_private { static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3; switch (value) { @@ -83,7 +83,7 @@ static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned char val; switch (ucontrol->value.integer.value[0]) { diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 137e8ebc092c..21810e5f3321 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -335,7 +335,7 @@ static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel, static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); if (ucontrol->value.integer.value[0]) { /* Check if noise suppression is enabled */ @@ -358,7 +358,7 @@ static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u8 val; if (ucontrol->value.integer.value[0]) { diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 738fa18a50d2..9ec577f0edb4 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c @@ -345,7 +345,7 @@ static void da7213_alc_calib(struct snd_soc_codec *codec) static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); int ret; @@ -361,7 +361,7 @@ static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); /* Force ALC offset calibration if enabling ALC */ diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 48f3fef68484..2fae31cb0067 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c @@ -332,7 +332,7 @@ static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum, static int da732x_hpf_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; unsigned int reg = enum_ctrl->reg; unsigned int sel = ucontrol->value.integer.value[0]; @@ -360,7 +360,7 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol, static int da732x_hpf_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; unsigned int reg = enum_ctrl->reg; int val; diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 4ff06b50fbba..ad19cc56702b 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c @@ -484,7 +484,7 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u8 reg_val, adc_left, adc_right, mic_left, mic_right; int avg_left_data, avg_right_data, offset_l, offset_r; diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 4f048db9f55f..a924bb9d7886 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c @@ -49,7 +49,7 @@ static const struct reg_default lm4857_default_regs[] = { static int lm4857_get_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = lm4857->mode; @@ -60,7 +60,7 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol, static int lm4857_set_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); uint8_t value = ucontrol->value.integer.value[0]; diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index ec481fc428c7..e1c196a41930 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c @@ -43,7 +43,7 @@ static struct reg_default max9768_default_regs[] = { static int max9768_get_gpio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); int val = gpio_get_value_cansleep(max9768->mute_gpio); @@ -55,7 +55,7 @@ static int max9768_get_gpio(struct snd_kcontrol *kcontrol, static int max9768_set_gpio(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ef7cf89f5623..9134982807b5 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -635,7 +635,7 @@ static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum, static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -649,7 +649,7 @@ static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98088->mic1pre; @@ -659,7 +659,7 @@ static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -673,7 +673,7 @@ static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98088->mic2pre; @@ -1750,7 +1750,7 @@ static void max98088_setup_eq2(struct snd_soc_codec *codec) static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); struct max98088_pdata *pdata = max98088->pdata; int channel = max98088_get_channel(codec, kcontrol->id.name); @@ -1782,7 +1782,7 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); int channel = max98088_get_channel(codec, kcontrol->id.name); struct max98088_cdata *cdata; diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..49d12387ac2f 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -426,7 +426,7 @@ static const unsigned int max98090_rcv_lout_tlv[] = { static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; @@ -466,7 +466,7 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 03f0536e6f61..5d4c621dbf99 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c @@ -612,7 +612,7 @@ static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum, static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -626,7 +626,7 @@ static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98095->mic1pre; @@ -636,7 +636,7 @@ static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); unsigned int sel = ucontrol->value.integer.value[0]; @@ -650,7 +650,7 @@ static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = max98095->mic2pre; @@ -1737,7 +1737,7 @@ static int max98095_get_eq_channel(const char *name) static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct max98095_pdata *pdata = max98095->pdata; int channel = max98095_get_eq_channel(kcontrol->id.name); @@ -1801,7 +1801,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); int channel = max98095_get_eq_channel(kcontrol->id.name); struct max98095_cdata *cdata; @@ -1891,7 +1891,7 @@ static int max98095_get_bq_channel(struct snd_soc_codec *codec, static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); struct max98095_pdata *pdata = max98095->pdata; int channel = max98095_get_bq_channel(codec, kcontrol->id.name); @@ -1952,7 +1952,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); int channel = max98095_get_bq_channel(codec, kcontrol->id.name); struct max98095_cdata *cdata; diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index e427544183d7..a722a023c262 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c @@ -115,7 +115,7 @@ static int pcm1681_set_deemph(struct snd_soc_codec *codec) static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->deemph; @@ -126,7 +126,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); priv->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index d4c229f0233f..30e234708579 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c @@ -188,7 +188,7 @@ static unsigned int mic_bst_tlv[] = { static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = rt5631->dmic_used_flag; @@ -199,7 +199,7 @@ static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); rt5631->dmic_used_flag = ucontrol->value.integer.value[0]; diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index d3ed1be5a186..b56caefcf664 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c @@ -296,7 +296,7 @@ static int dac_info_volsw(struct snd_kcontrol *kcontrol, static int dac_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg; int l; int r; @@ -349,7 +349,7 @@ static int dac_get_volsw(struct snd_kcontrol *kcontrol, static int dac_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg; int l; int r; diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 12577749b17b..0579d187135b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c @@ -243,7 +243,7 @@ static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol, static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; unsigned int cfud; @@ -272,7 +272,7 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, 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 snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index a895a5e4bdf2..d48491a4a19d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c @@ -272,7 +272,7 @@ static int tas5086_set_deemph(struct snd_soc_codec *codec) static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->deemph; @@ -283,7 +283,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); priv->deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 20864ee8793b..686b8b85b956 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -82,7 +82,7 @@ static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0); static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u16 val, reg; val = (ucontrol->value.integer.value[0] & 0x07); @@ -105,7 +105,7 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); u16 val; val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0); diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 6bfc8a17331b..517055ab65ef 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -442,7 +442,7 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w, static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = dac33->fifo_mode; @@ -453,7 +453,7 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); int ret = 0; diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 975e0f760ac1..69e12a311ba2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -830,7 +830,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; @@ -859,7 +859,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; @@ -888,7 +888,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -915,7 +915,7 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; unsigned int shift = mc->shift; @@ -956,7 +956,7 @@ static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum, static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); if (twl4030->configured) { diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index bd3a20647fdf..0f6067f04e29 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -484,7 +484,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->hs_power_mode; @@ -495,7 +495,7 @@ static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int high_perf = ucontrol->value.enumerated.item[0]; int ret = 0; @@ -512,7 +512,7 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = priv->pll_power_mode; @@ -523,7 +523,7 @@ static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); priv->pll_power_mode = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 6be5f80b65f1..4ead0dc02b87 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -172,7 +172,7 @@ out: static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wl1273->mode; @@ -190,7 +190,7 @@ static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); if (wl1273->mode == ucontrol->value.integer.value[0]) @@ -214,7 +214,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: enter.\n", __func__); @@ -227,7 +227,7 @@ static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); int val, r = 0; @@ -251,7 +251,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: enter.\n", __func__); @@ -264,7 +264,7 @@ static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); int r; diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 83a2c872925c..a4c352cc3464 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -607,7 +607,7 @@ 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 snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->anc_active; @@ -618,7 +618,7 @@ 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 snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int anc_active = ucontrol->value.enumerated.item[0]; int ret; @@ -640,7 +640,7 @@ 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 snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); ucontrol->value.enumerated.item[0] = wm2000->spk_ena; @@ -651,7 +651,7 @@ 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 snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); int val = ucontrol->value.enumerated.item[0]; int ret; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 757256bf7672..42a72b2404d5 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -302,7 +302,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out = NULL; struct soc_mixer_control *mc = @@ -345,7 +345,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out1 = &wm8350_priv->out1; struct wm8350_output *out2 = &wm8350_priv->out2; diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 146564feaea0..edfdbcd9d316 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -93,7 +93,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index af7ed8b5d4e1..7665ff6aea6d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -252,7 +252,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); unsigned int reg = mc->reg; unsigned int reg2 = mc->rreg; diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index d74f43975b90..763b265d9528 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -119,7 +119,7 @@ static int wm8731_set_deemph(struct snd_soc_codec *codec) static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8731->deemph; @@ -130,7 +130,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; int ret = 0; diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index cbb8d55052a4..53e57b4049a8 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -234,7 +234,7 @@ SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase), static int wm8753_get_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8753->dai_func; @@ -244,7 +244,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol, static int wm8753_set_dai(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); u16 ioctl; diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index ee76f0fb4299..589455c3bfcd 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -106,7 +106,7 @@ static int txsrc_get(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); src = snd_soc_read(codec, WM8804_SPDTX4); if (src & 0x40) ucontrol->value.integer.value[0] = 1; @@ -122,7 +122,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec; unsigned int src, txpwr; - codec = snd_kcontrol_chip(kcontrol); + codec = snd_soc_kcontrol_codec(kcontrol); if (ucontrol->value.integer.value[0] != 0 && ucontrol->value.integer.value[0] != 1) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b0084a127d18..b84940c359a1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -439,7 +439,7 @@ static int wm8903_set_deemph(struct snd_soc_codec *codec) static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8903->deemph; @@ -450,7 +450,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; int ret = 0; diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 49c35c36935e..f7c549949c54 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -391,7 +391,7 @@ static void wm8904_set_drc(struct snd_soc_codec *codec) static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; int value = ucontrol->value.integer.value[0]; @@ -409,7 +409,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; @@ -462,7 +462,7 @@ static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); struct wm8904_pdata *pdata = wm8904->pdata; int value = ucontrol->value.integer.value[0]; @@ -480,7 +480,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; @@ -520,7 +520,7 @@ static int wm8904_set_deemph(struct snd_soc_codec *codec) static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8904->deemph; @@ -530,7 +530,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; @@ -570,7 +570,7 @@ static SOC_ENUM_SINGLE_DECL(hpf_mode, WM8904_ADC_DIGITAL_0, 5, static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int val; int ret; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index fecd4e4f4c57..7e443c4f6f85 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -390,7 +390,7 @@ static int wm8955_set_deemph(struct snd_soc_codec *codec) static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8955->deemph; @@ -400,7 +400,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 7ac2e511403c..b2ebb104d879 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c @@ -456,7 +456,7 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -478,7 +478,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; @@ -500,7 +500,7 @@ static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int mbc = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; @@ -512,7 +512,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int mbc = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) @@ -546,7 +546,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -568,7 +568,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; @@ -579,7 +579,7 @@ static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -601,7 +601,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; @@ -623,7 +623,7 @@ static int wm8958_vss_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int vss = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; @@ -635,7 +635,7 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int vss = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) @@ -684,7 +684,7 @@ static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int hpf = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (hpf < 3) @@ -699,7 +699,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int hpf = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (hpf < 3) { @@ -746,7 +746,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; int value = ucontrol->value.integer.value[0]; @@ -768,7 +768,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; @@ -790,7 +790,7 @@ static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int eq = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; @@ -802,7 +802,7 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int eq = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d04e9cad445c..a145d0431b63 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -178,7 +178,7 @@ static int wm8960_set_deemph(struct snd_soc_codec *codec) static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); ucontrol->value.enumerated.item[0] = wm8960->deemph; @@ -188,7 +188,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); int deemph = ucontrol->value.enumerated.item[0]; diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 5522d2566c67..37986c84cbff 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1552,7 +1552,7 @@ static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int shift = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift); @@ -1564,7 +1564,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { int shift = kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); int old = wm8962->dsp2_ena; int ret = 0; @@ -1602,7 +1602,7 @@ out: static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int ret; /* Apply the update (if any) */ @@ -1632,7 +1632,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int ret; /* Apply the update (if any) */ diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 2b9bfa53efbf..19d5baa38f5c 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c @@ -552,7 +552,7 @@ static const struct snd_soc_dapm_route wm8983_audio_map[] = { static int eqmode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); @@ -567,7 +567,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, static int eqmode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int regpwr2, regpwr3; unsigned int reg_eq; diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 5473dc969585..ad23ffb8346c 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -526,7 +526,7 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { static int eqmode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); @@ -541,7 +541,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, static int eqmode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int regpwr2, regpwr3; unsigned int reg_eq; diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c413c1991453..b5c1f0f07058 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -132,7 +132,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int reg = mc->reg; diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 844cc4a60d66..b8fd284fc0c0 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c @@ -154,7 +154,7 @@ static const unsigned int out_sidetone_tlv[] = { static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int reg = kcontrol->private_value & 0xff; int ret; u16 val; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..3eb390be7dee 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -298,7 +298,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, { struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); int mask, ret; /* Can't enable both ADC and DAC paths simultaneously */ @@ -355,7 +355,7 @@ static int wm8994_get_drc(const char *name) static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; @@ -378,7 +378,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int drc = wm8994_get_drc(kcontrol->id.name); @@ -462,7 +462,7 @@ static int wm8994_get_retune_mobile_block(const char *name) static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994 *control = wm8994->wm8994; struct wm8994_pdata *pdata = &control->pdata; @@ -485,7 +485,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int block = wm8994_get_retune_mobile_block(kcontrol->id.name); diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index c6cbb3b8ace9..69266332760e 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c @@ -412,7 +412,7 @@ static int wm8996_get_retune_mobile_block(const char *name) static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); struct wm8996_pdata *pdata = &wm8996->pdata; int block = wm8996_get_retune_mobile_block(kcontrol->id.name); @@ -434,7 +434,7 @@ static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); int block = wm8996_get_retune_mobile_block(kcontrol->id.name); diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index d18eff31fbbc..185eb97769e7 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -340,7 +340,7 @@ static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6, static int speaker_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg; reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); @@ -361,7 +361,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol, static int speaker_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT); unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bb5f7b4e3ebb..d9686dcd024c 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -242,7 +242,7 @@ struct wm_coeff_ctl { static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); @@ -254,7 +254,7 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index b6209662ab13..916817fe6632 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -337,7 +337,7 @@ static void enable_dc_servo(struct snd_soc_codec *codec) static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); int ret; -- cgit v1.2.3 From f6272ff8a5f42c614f4a338013f5323979121e0f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:05 +0100 Subject: ASoC: Add snd_soc_kcontrol_platform() helper function For platform controls snd_kcontrol_chip() currently returns a pointer to the platform that registered the control. With the upcoming consolidation of platform and CODEC controls this will change. Prepare for this by introducing the snd_soc_kcontrol_platform() helper function that will hide the implementation details of how the platform for a control can be obtained. This will allow us to change this easily in the future. The patch also updates all platforms to use this new helper function. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 14 ++++++++++++++ sound/soc/intel/sst-haswell-pcm.c | 8 ++++---- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index e150030b754d..14e7457e2347 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1242,6 +1242,20 @@ static inline struct snd_soc_codec *snd_soc_kcontrol_codec( return snd_kcontrol_chip(kcontrol); } +/** + * snd_soc_kcontrol_platform() - Returns the platform that registerd the control + * @kcontrol: The control for which to get the platform + * + * Note: This function will only work correctly if the control has been + * registered with snd_soc_add_platform_controls() or via table based setup of + * a snd_soc_platform_driver. Otherwise the behavior is undefined. + */ +static inline struct snd_soc_codec *snd_soc_kcontrol_platform( + struct snd_kcontrol *kcontrol) +{ + return snd_kcontrol_chip(kcontrol); +} + int snd_soc_util_init(void); void snd_soc_util_exit(void); diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 0a32dd13a23d..67a5eb3c6196 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c @@ -136,7 +136,7 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value) static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct hsw_priv_data *pdata = @@ -174,7 +174,7 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; struct hsw_priv_data *pdata = @@ -206,7 +206,7 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, static int hsw_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; u32 volume; @@ -231,7 +231,7 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol, static int hsw_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); + struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); struct sst_hsw *hsw = pdata->hsw; unsigned int volume = 0; -- cgit v1.2.3 From 6137a5ca326dac848b35bcbdc44b2ff890273375 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:06 +0100 Subject: ASoC: Prepare SOC_SINGLE_XR_SX controls for regmap SOC_SINGLE_XR_SX controls currently only work with CODECs that set the 'reg_word_size' field in their snd_soc_codec_driver struct. Going forward support for ASoC level IO will eventually be removed and all drivers will be converted to regmap. Preparing for the transition this patch adds support for CODECs using regmap for IO to the SOC_SINGLE_XR_SX control. We already have the val_bytes field in the CODEC struct which holds the number of bytes per word, but it is only initialized when regmap is used. Also initialize it for drivers still using legacy IO and update the SOC_SINGLE_XR_SX handlers to use it. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..935c59418b19 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3343,7 +3343,7 @@ int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; - unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; + unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE; unsigned int regwmask = (1<invert; unsigned long mask = (1UL<nbits)-1; @@ -3389,7 +3389,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); unsigned int regbase = mc->regbase; unsigned int regcount = mc->regcount; - unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; + unsigned int regwshift = codec->val_bytes * BITS_PER_BYTE; unsigned int regwmask = (1<invert; unsigned long mask = (1UL<nbits)-1; @@ -4292,6 +4292,7 @@ int snd_soc_register_codec(struct device *dev, codec->dev = dev; codec->driver = codec_drv; codec->num_dai = num_dai; + codec->val_bytes = codec_drv->reg_word_size; mutex_init(&codec->mutex); for (i = 0; i < num_dai; i++) { -- cgit v1.2.3 From 96241c83293de346037b9a85e321f52ace210926 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:07 +0100 Subject: ASoC: Move IO functions to soc-io.c soc-core.c is getting quite crowded. Move all IO related functions that are still in soc-core.c to soc-io.c Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 144 --------------------------------------------------- sound/soc/soc-io.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 144 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 935c59418b19..5c0ed3931285 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2033,38 +2033,6 @@ int snd_soc_codec_writable_register(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); -int snd_soc_platform_read(struct snd_soc_platform *platform, - unsigned int reg) -{ - unsigned int ret; - - if (!platform->driver->read) { - dev_err(platform->dev, "ASoC: platform has no read back\n"); - return -1; - } - - ret = platform->driver->read(platform, reg); - dev_dbg(platform->dev, "read %x => %x\n", reg, ret); - trace_snd_soc_preg_read(platform, reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_platform_read); - -int snd_soc_platform_write(struct snd_soc_platform *platform, - unsigned int reg, unsigned int val) -{ - if (!platform->driver->write) { - dev_err(platform->dev, "ASoC: platform has no write back\n"); - return -1; - } - - dev_dbg(platform->dev, "write %x = %x\n", reg, val); - trace_snd_soc_preg_write(platform, reg, val); - return platform->driver->write(platform, reg, val); -} -EXPORT_SYMBOL_GPL(snd_soc_platform_write); - /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec @@ -2283,118 +2251,6 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) } EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); -unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) -{ - unsigned int ret; - - ret = codec->read(codec, reg); - dev_dbg(codec->dev, "read %x => %x\n", reg, ret); - trace_snd_soc_reg_read(codec, reg, ret); - - return ret; -} -EXPORT_SYMBOL_GPL(snd_soc_read); - -unsigned int snd_soc_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val) -{ - dev_dbg(codec->dev, "write %x = %x\n", reg, val); - trace_snd_soc_reg_write(codec, reg, val); - return codec->write(codec, reg, val); -} -EXPORT_SYMBOL_GPL(snd_soc_write); - -/** - * snd_soc_update_bits - update codec register bits - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Writes new register value. - * - * Returns 1 for change, 0 for no change, or negative error code. - */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned int mask, unsigned int value) -{ - bool change; - unsigned int old, new; - int ret; - - if (codec->using_regmap) { - ret = regmap_update_bits_check(codec->control_data, reg, - mask, value, &change); - } else { - ret = snd_soc_read(codec, reg); - if (ret < 0) - return ret; - - old = ret; - new = (old & ~mask) | (value & mask); - change = old != new; - if (change) - ret = snd_soc_write(codec, reg, new); - } - - if (ret < 0) - return ret; - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_update_bits); - -/** - * snd_soc_update_bits_locked - update codec register bits - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Writes new register value, and takes the codec mutex. - * - * Returns 1 for change else 0. - */ -int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, - unsigned int value) -{ - int change; - - mutex_lock(&codec->mutex); - change = snd_soc_update_bits(codec, reg, mask, value); - mutex_unlock(&codec->mutex); - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); - -/** - * snd_soc_test_bits - test register for change - * @codec: audio codec - * @reg: codec register - * @mask: register mask - * @value: new value - * - * Tests a register with a new value and checks if the new value is - * different from the old value. - * - * Returns 1 for change else 0. - */ -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, - unsigned int mask, unsigned int value) -{ - int change; - unsigned int old, new; - - old = snd_soc_read(codec, reg); - new = (old & ~mask) | value; - change = old != new; - - return change; -} -EXPORT_SYMBOL_GPL(snd_soc_test_bits); - /** * snd_soc_cnew - create new control * @_template: control template diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 260efc8466fc..bfd7206c178f 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -19,6 +19,150 @@ #include +unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) +{ + unsigned int ret; + + ret = codec->read(codec, reg); + dev_dbg(codec->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_reg_read(codec, reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_read); + +unsigned int snd_soc_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val) +{ + dev_dbg(codec->dev, "write %x = %x\n", reg, val); + trace_snd_soc_reg_write(codec, reg, val); + return codec->write(codec, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_write); + +/** + * snd_soc_update_bits - update codec register bits + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Writes new register value. + * + * Returns 1 for change, 0 for no change, or negative error code. + */ +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, + unsigned int mask, unsigned int value) +{ + bool change; + unsigned int old, new; + int ret; + + if (codec->using_regmap) { + ret = regmap_update_bits_check(codec->control_data, reg, + mask, value, &change); + } else { + ret = snd_soc_read(codec, reg); + if (ret < 0) + return ret; + + old = ret; + new = (old & ~mask) | (value & mask); + change = old != new; + if (change) + ret = snd_soc_write(codec, reg, new); + } + + if (ret < 0) + return ret; + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_update_bits); + +/** + * snd_soc_update_bits_locked - update codec register bits + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Writes new register value, and takes the codec mutex. + * + * Returns 1 for change else 0. + */ +int snd_soc_update_bits_locked(struct snd_soc_codec *codec, + unsigned short reg, unsigned int mask, + unsigned int value) +{ + int change; + + mutex_lock(&codec->mutex); + change = snd_soc_update_bits(codec, reg, mask, value); + mutex_unlock(&codec->mutex); + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); + +/** + * snd_soc_test_bits - test register for change + * @codec: audio codec + * @reg: codec register + * @mask: register mask + * @value: new value + * + * Tests a register with a new value and checks if the new value is + * different from the old value. + * + * Returns 1 for change else 0. + */ +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, + unsigned int mask, unsigned int value) +{ + int change; + unsigned int old, new; + + old = snd_soc_read(codec, reg); + new = (old & ~mask) | value; + change = old != new; + + return change; +} +EXPORT_SYMBOL_GPL(snd_soc_test_bits); + +int snd_soc_platform_read(struct snd_soc_platform *platform, + unsigned int reg) +{ + unsigned int ret; + + if (!platform->driver->read) { + dev_err(platform->dev, "ASoC: platform has no read back\n"); + return -1; + } + + ret = platform->driver->read(platform, reg); + dev_dbg(platform->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_preg_read(platform, reg, ret); + + return ret; +} +EXPORT_SYMBOL_GPL(snd_soc_platform_read); + +int snd_soc_platform_write(struct snd_soc_platform *platform, + unsigned int reg, unsigned int val) +{ + if (!platform->driver->write) { + dev_err(platform->dev, "ASoC: platform has no write back\n"); + return -1; + } + + dev_dbg(platform->dev, "write %x = %x\n", reg, val); + trace_snd_soc_preg_write(platform, reg, val); + return platform->driver->write(platform, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_platform_write); + #ifdef CONFIG_REGMAP static int hw_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) -- cgit v1.2.3 From 20a0ec27ea11af0251ffeb5ee2b96cc5c72cb517 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:09 +0100 Subject: ASoC: Remove IO register modifier callbacks There are no ASoC drivers left that use them and new drivers are supposed to use regmap for this. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 14 --------- sound/soc/soc-cache.c | 2 -- sound/soc/soc-core.c | 80 ++++++--------------------------------------------- 3 files changed, 8 insertions(+), 88 deletions(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 14e7457e2347..a355d0f9a6f9 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -393,12 +393,6 @@ int devm_snd_soc_register_component(struct device *dev, const struct snd_soc_component_driver *cmpnt_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_component(struct device *dev); -int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, - unsigned int reg); -int snd_soc_codec_readable_register(struct snd_soc_codec *codec, - unsigned int reg); -int snd_soc_codec_writable_register(struct snd_soc_codec *codec, - unsigned int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, struct regmap *regmap); int snd_soc_cache_sync(struct snd_soc_codec *codec); @@ -692,9 +686,6 @@ struct snd_soc_codec { struct list_head list; struct list_head card_list; int num_dai; - int (*volatile_register)(struct snd_soc_codec *, unsigned int); - int (*readable_register)(struct snd_soc_codec *, unsigned int); - int (*writable_register)(struct snd_soc_codec *, unsigned int); /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ @@ -756,11 +747,6 @@ struct snd_soc_codec_driver { /* codec IO */ unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); - int (*display_register)(struct snd_soc_codec *, char *, - size_t, unsigned int); - int (*volatile_register)(struct snd_soc_codec *, unsigned int); - int (*readable_register)(struct snd_soc_codec *, unsigned int); - int (*writable_register)(struct snd_soc_codec *, unsigned int); unsigned int reg_cache_size; short reg_cache_step; short reg_word_size; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index bfed3e4c45ff..3fa77d5f9b75 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -162,8 +162,6 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) i, codec_drv->reg_word_size) == val) continue; - WARN_ON(!snd_soc_codec_writable_register(codec, i)); - ret = snd_soc_write(codec, i, val); if (ret) return ret; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5c0ed3931285..41bd24348520 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -154,22 +154,15 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf, step = codec->driver->reg_cache_step; for (i = 0; i < codec->driver->reg_cache_size; i += step) { - if (!snd_soc_codec_readable_register(codec, i)) - continue; - if (codec->driver->display_register) { - count += codec->driver->display_register(codec, buf + count, - PAGE_SIZE - count, i); - } else { - /* only support larger than PAGE_SIZE bytes debugfs - * entries for the default case */ - if (p >= pos) { - if (total + len >= count - 1) - break; - format_register_str(codec, i, buf + total, len); - total += len; - } - p += len; + /* only support larger than PAGE_SIZE bytes debugfs + * entries for the default case */ + if (p >= pos) { + if (total + len >= count - 1) + break; + format_register_str(codec, i, buf + total, len); + total += len; } + p += len; } total = min(total, count - 1); @@ -1979,60 +1972,6 @@ static struct platform_driver soc_driver = { .remove = soc_remove, }; -/** - * snd_soc_codec_volatile_register: Report if a register is volatile. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indiciating if a CODEC register is volatile. - */ -int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->volatile_register) - return codec->volatile_register(codec, reg); - else - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); - -/** - * snd_soc_codec_readable_register: Report if a register is readable. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indicating if a CODEC register is readable. - */ -int snd_soc_codec_readable_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->readable_register) - return codec->readable_register(codec, reg); - else - return 1; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register); - -/** - * snd_soc_codec_writable_register: Report if a register is writable. - * - * @codec: CODEC to query. - * @reg: Register to query. - * - * Boolean function indicating if a CODEC register is writable. - */ -int snd_soc_codec_writable_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - if (codec->writable_register) - return codec->writable_register(codec, reg); - else - return 1; -} -EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); - /** * snd_soc_new_ac97_codec - initailise AC97 device * @codec: audio codec @@ -4136,9 +4075,6 @@ int snd_soc_register_codec(struct device *dev, codec->write = codec_drv->write; codec->read = codec_drv->read; - codec->volatile_register = codec_drv->volatile_register; - codec->readable_register = codec_drv->readable_register; - codec->writable_register = codec_drv->writable_register; codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; -- cgit v1.2.3 From 98e639fb8a3ed1bf2bd512626c3cfc2992a57113 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:11 +0100 Subject: ASoC: Track which components have been registered with snd_soc_register_component() snd_soc_unregister_component() takes the parent device of the component as a parameter and then looks up the component based on this. This is a problem if multiple components are registered for the same parent device. Currently drivers do not do this, but some drivers register a CPU DAI component and a platform for the same parent device. This will become a problem once platforms are also made components. To make sure that snd_soc_unregister_component() will not accidentally unregister the platform in such a case only consider components that were registered with snd_soc_register_component(). This is only meant as short term stopgap solution to be able to continue componentisation. Long term we'll need something different. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index a355d0f9a6f9..f8a79c17628e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -662,6 +662,7 @@ struct snd_soc_component { unsigned int active; unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ + unsigned int registered_as_component:1; struct list_head list; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 41bd24348520..3314efb365e3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3879,6 +3879,7 @@ int snd_soc_register_component(struct device *dev, } cmpnt->ignore_pmdown_time = true; + cmpnt->registered_as_component = true; return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL, dai_drv, num_dai, true); @@ -3894,7 +3895,7 @@ void snd_soc_unregister_component(struct device *dev) struct snd_soc_component *cmpnt; list_for_each_entry(cmpnt, &component_list, list) { - if (dev == cmpnt->dev) + if (dev == cmpnt->dev && cmpnt->registered_as_component) goto found; } return; -- cgit v1.2.3 From b37f1d123c69c0d7730704d65b83eaac780c0e3b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 18 Mar 2014 09:02:12 +0100 Subject: ASoC: Let snd_soc_platform subclass snd_soc_component There is an increasing amount of code that is very similar between platforms, CODECS and other components. Making platforms a component will allow us to share this code. For now the patch just adds component and component_driver fields to the platform and platform_driver structs and registers the platform as a component. Followup patches will be used to consolidate code between the different types of components. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 16 ++++++++++++++++ sound/soc/soc-core.c | 14 ++++++++++++++ 2 files changed, 30 insertions(+) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index f8a79c17628e..94a2dc20ad6e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -778,6 +778,7 @@ struct snd_soc_platform_driver { int (*remove)(struct snd_soc_platform *); int (*suspend)(struct snd_soc_dai *dai); int (*resume)(struct snd_soc_dai *dai); + struct snd_soc_component_driver component_driver; /* pcm creation and destruction */ int (*pcm_new)(struct snd_soc_pcm_runtime *); @@ -831,6 +832,8 @@ struct snd_soc_platform { struct list_head list; struct list_head card_list; + struct snd_soc_component component; + struct snd_soc_dapm_context dapm; #ifdef CONFIG_DEBUG_FS @@ -1107,6 +1110,19 @@ static inline struct snd_soc_codec *snd_soc_component_to_codec( return container_of(component, struct snd_soc_codec, component); } +/** + * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in + * @component: The component to cast to a platform + * + * This function must only be used on components that are known to be platforms. + * Otherwise the behavior is undefined. + */ +static inline struct snd_soc_platform *snd_soc_component_to_platform( + struct snd_soc_component *component) +{ + return container_of(component, struct snd_soc_platform, component); +} + /* codec IO */ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); unsigned int snd_soc_write(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3314efb365e3..a95c7e524dfc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3921,6 +3921,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_component); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv) { + int ret; + /* create platform component name */ platform->name = fmt_single_name(dev, &platform->id); if (platform->name == NULL) @@ -3933,6 +3935,16 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->dapm.stream_event = platform_drv->stream_event; mutex_init(&platform->mutex); + /* register component */ + ret = __snd_soc_register_component(dev, &platform->component, + &platform_drv->component_driver, + NULL, NULL, 0, false); + if (ret < 0) { + dev_err(platform->component.dev, + "ASoC: Failed to register component: %d\n", ret); + return ret; + } + mutex_lock(&client_mutex); list_add(&platform->list, &platform_list); mutex_unlock(&client_mutex); @@ -3974,6 +3986,8 @@ EXPORT_SYMBOL_GPL(snd_soc_register_platform); */ void snd_soc_remove_platform(struct snd_soc_platform *platform) { + snd_soc_unregister_component(platform->dev); + mutex_lock(&client_mutex); list_del(&platform->list); mutex_unlock(&client_mutex); -- cgit v1.2.3 From 261edc7013a7435e40fd5ebb3682eac6fc3c15ea Mon Sep 17 00:00:00 2001 From: Nariman Poushin Date: Mon, 31 Mar 2014 15:47:12 +0100 Subject: ASoC: core: Fail probe if we fail to add dai widgets Signed-off-by: Nariman Poushin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..d5710fc79b49 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1132,8 +1132,15 @@ static int soc_probe_codec(struct snd_soc_card *card, driver->num_dapm_widgets); /* Create DAPM widgets for each DAI stream */ - list_for_each_entry(dai, &codec->component.dai_list, list) - snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); + list_for_each_entry(dai, &codec->component.dai_list, list) { + ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); + + if (ret != 0) { + dev_err(codec->dev, + "Failed to create DAI widgets %d\n", ret); + goto err_probe; + } + } codec->dapm.idle_bias_off = driver->idle_bias_off; -- cgit v1.2.3 From b318ad503698160183fe5e0752b9a1bb3e558026 Mon Sep 17 00:00:00 2001 From: Nariman Poushin Date: Tue, 1 Apr 2014 13:59:33 +0100 Subject: ASoC: core: Fail codec probe if we fail to add controls Signed-off-by: Nariman Poushin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d5710fc79b49..777453158347 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1127,9 +1127,17 @@ static int soc_probe_codec(struct snd_soc_card *card, soc_init_codec_debugfs(codec); - if (driver->dapm_widgets) - snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, - driver->num_dapm_widgets); + if (driver->dapm_widgets) { + ret = snd_soc_dapm_new_controls(&codec->dapm, + driver->dapm_widgets, + driver->num_dapm_widgets); + + if (ret != 0) { + dev_err(codec->dev, + "Failed to create new controls %d\n", ret); + goto err_probe; + } + } /* Create DAPM widgets for each DAI stream */ list_for_each_entry(dai, &codec->component.dai_list, list) { -- cgit v1.2.3 From 1a39019e939f620f39a1b914231ab6ba9013b208 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Tue, 8 Apr 2014 11:18:10 +0800 Subject: ASoC: core: Allow snd_soc_update_bits use 32 bits register Change reg's type from unsigned short to unsigned int. So that we can use 32 bits reg value in snd_soc_update_bits. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- include/sound/soc.h | 6 +++--- sound/soc/soc-core.c | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..4ed706bf11d1 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -469,12 +469,12 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, #endif /* codec register bit access */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, + unsigned int reg, unsigned int mask, unsigned int value); -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value); int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 777453158347..7f0a9297e420 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2330,7 +2330,7 @@ EXPORT_SYMBOL_GPL(snd_soc_write); * * Returns 1 for change, 0 for no change, or negative error code. */ -int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value) { bool change; @@ -2371,7 +2371,7 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits); * Returns 1 for change else 0. */ int snd_soc_update_bits_locked(struct snd_soc_codec *codec, - unsigned short reg, unsigned int mask, + unsigned int reg, unsigned int mask, unsigned int value) { int change; @@ -2396,7 +2396,7 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); * * Returns 1 for change else 0. */ -int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, +int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, unsigned int mask, unsigned int value) { int change; @@ -2911,7 +2911,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, int min = mc->min; int mask = (1 << (fls(min + max) - 1)) - 1; int err = 0; - unsigned short val, val_mask, val2 = 0; + unsigned int val, val_mask, val2 = 0; val_mask = mask << shift; val = (ucontrol->value.integer.value[0] + min) & mask; -- cgit v1.2.3 From 1a95d8d09ef7e40563afd587cce52868e3d076a0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 18 Mar 2014 15:20:37 +0200 Subject: ASoC: davinci-pcm: Add empty functions for !CONFIG_SND_DAVINCI_SOC builds To save drivers using davinci-pcm and edma-pcm the need to fiddle with !CONFIG_SND_DAVINCI_SOC in their code. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-pcm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fbb710c76c08..5fd4737ab398 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -29,7 +29,17 @@ struct davinci_pcm_dma_params { unsigned int fifo_level; }; +#if IS_ENABLED(CONFIG_SND_DAVINCI_SOC) int davinci_soc_platform_register(struct device *dev); void davinci_soc_platform_unregister(struct device *dev); +#else +static inline int davinci_soc_platform_register(struct device *dev) +{ + return 0; +} +static inline void davinci_soc_platform_unregister(struct device *dev) +{ +} +#endif /* CONFIG_SND_DAVINCI_SOC */ #endif -- cgit v1.2.3 From d5902f693698076e5bda44cbfa999e9c02bb83ab Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:07 +0300 Subject: ASoC: davinci-mcasp: Assign the dma_data earlier in dai_probe callback Set up the playback_dma_data/capture_dma_data for the dai at probe time since the generic dmaengine PCM stack needs to have access to this information early. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 4f75cac462d1..b4c5cf58b030 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -716,22 +716,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, return ret; } -static int davinci_mcasp_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); - - if (mcasp->version == MCASP_VERSION_4) - snd_soc_dai_set_dma_data(dai, substream, - &mcasp->dma_data[substream->stream]); - else - snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); - - return 0; -} - 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, .set_fmt = davinci_mcasp_set_dai_fmt, @@ -739,6 +724,25 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .set_sysclk = davinci_mcasp_set_sysclk, }; +static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) +{ + struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); + + if (mcasp->version == MCASP_VERSION_4) { + /* Using dmaengine PCM */ + dai->playback_dma_data = + &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; + dai->capture_dma_data = + &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; + } else { + /* Using davinci-pcm */ + dai->playback_dma_data = mcasp->dma_params; + dai->capture_dma_data = mcasp->dma_params; + } + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int davinci_mcasp_suspend(struct snd_soc_dai *dai) { @@ -792,6 +796,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) static struct snd_soc_dai_driver davinci_mcasp_dai[] = { { .name = "davinci-mcasp.0", + .probe = davinci_mcasp_dai_probe, .suspend = davinci_mcasp_suspend, .resume = davinci_mcasp_resume, .playback = { @@ -811,6 +816,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { }, { .name = "davinci-mcasp.1", + .probe = davinci_mcasp_dai_probe, .playback = { .channels_min = 1, .channels_max = 384, -- cgit v1.2.3 From f5b02b4a2cb7eaa223ddaba8e4338b31bcdaf369 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:08 +0300 Subject: ASoC: davinci-mcasp: Fix debug typo in davinci_mcasp_hw_params() requred -> required Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index b4c5cf58b030..eb46dc69248f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -620,7 +620,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, if (mcasp->bclk_master) { unsigned int bclk_freq = snd_soc_params_to_bclk(params); if (mcasp->sysclk_freq % bclk_freq != 0) { - dev_err(mcasp->dev, "Can't produce requred BCLK\n"); + dev_err(mcasp->dev, "Can't produce required BCLK\n"); return -EINVAL; } davinci_mcasp_set_clkdiv( -- cgit v1.2.3 From 0bf0e8aeceaf4b12524559fce9c6b91a90b63381 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:09 +0300 Subject: ASoC: davinci-mcasp: Simplify and clean up the AFIFO configuration code We can have more linear code flow by using variables in mcasp_common_hw_param() related to the AFIFO configuration. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 48 +++++++++++++++++++-------------------- sound/soc/davinci/davinci-mcasp.h | 1 + 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index eb46dc69248f..aa063a4e7b0c 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -37,6 +37,8 @@ #include "davinci-pcm.h" #include "davinci-mcasp.h" +#define MCASP_MAX_AFIFO_DEPTH 64 + struct davinci_mcasp_context { u32 txfmtctl; u32 rxfmtctl; @@ -469,9 +471,9 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int i; u8 tx_ser = 0; u8 rx_ser = 0; - u8 ser; u8 slots = mcasp->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; + u8 active_serializers, numevt; u32 reg; /* Default configuration */ if (mcasp->version != MCASP_VERSION_4) @@ -505,36 +507,34 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, } } - if (stream == SNDRV_PCM_STREAM_PLAYBACK) - ser = tx_ser; - else - ser = rx_ser; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { + active_serializers = tx_ser; + numevt = mcasp->txnumevt; + reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; + } else { + active_serializers = rx_ser; + numevt = mcasp->rxnumevt; + reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; + } - if (ser < max_active_serializers) { + if (active_serializers < max_active_serializers) { dev_warn(mcasp->dev, "stream has more channels (%d) than are " - "enabled in mcasp (%d)\n", channels, ser * slots); + "enabled in mcasp (%d)\n", channels, + active_serializers * slots); return -EINVAL; } - if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (mcasp->txnumevt * tx_ser > 64) - mcasp->txnumevt = 1; - - reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; - mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK); - mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8), - NUMEVT_MASK); - } + /* AFIFO is not in use */ + if (!numevt) + return 0; - if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { - if (mcasp->rxnumevt * rx_ser > 64) - mcasp->rxnumevt = 1; + if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) + numevt = active_serializers; - reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; - mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK); - mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8), - NUMEVT_MASK); - } + /* Configure the AFIFO */ + numevt *= active_serializers; + mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); + mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); return 0; } diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 8fed757d6087..98fbc451892a 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h @@ -283,6 +283,7 @@ */ #define FIFO_ENABLE BIT(16) #define NUMEVT_MASK (0xFF << 8) +#define NUMEVT(x) (((x) & 0xFF) << 8) #define NUMDMA_MASK (0xFF) #endif /* DAVINCI_MCASP_H */ -- cgit v1.2.3 From 5f04c603a52d4951e6f6b2f059049e7c5ee93db7 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:10 +0300 Subject: ASoC: davinci-mcasp: Configure the AFIFO and DMA burst size at the same place Move the dma_params->fifo_level and dma_data->maxburst configuration to the mcasp_common_hw_param() function where we configure the AFIFO registers. It makes the code regarding to AFIFO and DMA configuration more easy to follow since it is now clear how the AFIFO and how the DMA is going to be configured. Previously this has been done in two functions using a bit different calculation form - which ended up with the same result in both case at the end, but it was confusing. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index aa063a4e7b0c..ab4fa1291795 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -468,6 +468,8 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int channels) { + struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; + struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; int i; u8 tx_ser = 0; u8 rx_ser = 0; @@ -524,9 +526,14 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return -EINVAL; } + /* AFIFO is not in use */ - if (!numevt) + if (!numevt) { + /* Configure the burst size for platform drivers */ + dma_params->fifo_level = 0; + dma_data->maxburst = 0; return 0; + } if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) numevt = active_serializers; @@ -536,6 +543,10 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); + /* Configure the burst size for platform drivers */ + dma_params->fifo_level = numevt; + dma_data->maxburst = numevt; + return 0; } @@ -607,12 +618,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[substream->stream]; - struct snd_dmaengine_dai_dma_data *dma_data = - &mcasp->dma_data[substream->stream]; int word_length; - u8 fifo_level; - u8 slots = mcasp->tdm_slots; - u8 active_serializers; int channels = params_channels(params); int ret; @@ -671,21 +677,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - /* Calculate FIFO level */ - active_serializers = (channels + slots - 1) / slots; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - fifo_level = mcasp->txnumevt * active_serializers; - else - fifo_level = mcasp->rxnumevt * active_serializers; - - if (mcasp->version == MCASP_VERSION_2 && !fifo_level) + if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level) dma_params->acnt = 4; else dma_params->acnt = dma_params->data_type; - dma_params->fifo_level = fifo_level; - dma_data->maxburst = fifo_level; - davinci_config_channel_size(mcasp, word_length); return 0; -- cgit v1.2.3 From dd093a0f1962fb71e8852411f03fec7290027a90 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:11 +0300 Subject: ASoC: davinic-mcasp: Adopt the AFIFO/DMA configuration to the stream (dynamic depth) Configure the AFIFO numevt parameter based on the requested tx/rx_numevt, active serializers and period size in words. In this way McASP can adopt it's (and the DMA) configuration runtime and can pick the most optimal setup which satisfy the parameters. This way we do not need to place any constraint on the stream itself, allowing application greater freedom on how they want to set up ALSA. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index ab4fa1291795..9454d123f4bb 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -466,7 +466,7 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, } static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, - int channels) + int period_words, int channels) { struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; @@ -475,7 +475,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, u8 rx_ser = 0; u8 slots = mcasp->tdm_slots; u8 max_active_serializers = (channels + slots - 1) / slots; - u8 active_serializers, numevt; + int active_serializers, numevt, n; u32 reg; /* Default configuration */ if (mcasp->version != MCASP_VERSION_4) @@ -526,7 +526,6 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return -EINVAL; } - /* AFIFO is not in use */ if (!numevt) { /* Configure the burst size for platform drivers */ @@ -535,11 +534,26 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, return 0; } - if (numevt * active_serializers > MCASP_MAX_AFIFO_DEPTH) + if (period_words % active_serializers) { + dev_err(mcasp->dev, "Invalid combination of period words and " + "active serializers: %d, %d\n", period_words, + active_serializers); + return -EINVAL; + } + + /* + * Calculate the optimal AFIFO depth for platform side: + * The number of words for numevt need to be in steps of active + * serializers. + */ + n = numevt % active_serializers; + if (n) + numevt += (active_serializers - n); + while (period_words % numevt && numevt > 0) + numevt -= active_serializers; + if (numevt <= 0) numevt = active_serializers; - /* Configure the AFIFO */ - numevt *= active_serializers; mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); @@ -620,6 +634,7 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, &mcasp->dma_params[substream->stream]; int word_length; int channels = params_channels(params); + int period_size = params_period_size(params); int ret; /* If mcasp is BCLK master we need to set BCLK divider */ @@ -633,7 +648,8 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); } - ret = mcasp_common_hw_param(mcasp, substream->stream, channels); + ret = mcasp_common_hw_param(mcasp, substream->stream, + period_size * channels, channels); if (ret) return ret; -- cgit v1.2.3 From 33445643c3146fa43af3e9aa1cce08da9fe03157 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 1 Apr 2014 15:55:12 +0300 Subject: ASoC: davinci-mcasp: Fine tune and correct the DMA burst configuration When the AFIFO is not enabled but more than one serializers are used the DMA need to transfer number of words equal to active serializers when a DMA request is generated. When configuring the burst for the DMA avoid using value '1' for the burst since it is going to enable additional logic in the DMA drivers. Burst '1' means that the DMA should send/receive one word per DMA requests. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 9454d123f4bb..196158f2d1c4 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -529,8 +529,19 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, /* AFIFO is not in use */ if (!numevt) { /* Configure the burst size for platform drivers */ - dma_params->fifo_level = 0; - dma_data->maxburst = 0; + if (active_serializers > 1) { + /* + * If more than one serializers are in use we have one + * DMA request to provide data for all serializers. + * For example if three serializers are enabled the DMA + * need to transfer three words per DMA request. + */ + dma_params->fifo_level = active_serializers; + dma_data->maxburst = active_serializers; + } else { + dma_params->fifo_level = 0; + dma_data->maxburst = 0; + } return 0; } @@ -558,6 +569,8 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); /* Configure the burst size for platform drivers */ + if (numevt == 1) + numevt = 0; dma_params->fifo_level = numevt; dma_data->maxburst = numevt; -- cgit v1.2.3 From 6dfa9a4e6aacba70bff24c47871ac9aba3e76020 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:42 +0300 Subject: ASoC: davinci-mcasp: Format data delay configuration enhancement Use intermediate variable for the data delay needed for the specific format and write the register after the format configuration at once. This will help to control the number of lines as support for more formats going to be added. Also fixes a case when we switch between two formats with different delay requirements. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 196158f2d1c4..f0c98653bfe7 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -271,6 +271,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, { struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); int ret = 0; + u32 data_delay; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -278,18 +279,25 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + + /* No delay after FS */ + data_delay = 0; break; default: /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* make 1st data bit occur one ACLK cycle after the frame sync */ - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); + /* 1st data bit occur one ACLK cycle after the frame sync */ + data_delay = 1; break; } + mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay), + FSXDLY(3)); + mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay), + FSRDLY(3)); + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: /* codec is clock and frame slave */ -- cgit v1.2.3 From 188edc59c297fcd971d6a4ae5f5f5dacff7b315b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:43 +0300 Subject: ASoC: davinci-mcasp: Support for DSP_A format DSP_A is like DSP_B mode but with one bit delay after the FS. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index f0c98653bfe7..58b6d47cc8f8 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -275,6 +275,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + + /* 1st data bit occur one ACLK cycle after the frame sync */ + data_delay = 1; + break; case SND_SOC_DAIFMT_DSP_B: case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); -- cgit v1.2.3 From 83f12503bd1fb18d3fd460871660b34faf671918 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:44 +0300 Subject: ASoC: davinci-mcasp: Move the FS polarity change out from the switch case FS polarity can be either rising or falling edge in McASP. Instead of accessing the registers in every switch/case set a flag and write the registers after the switch for the invert configuration. This change will help when adding support for more formats also. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 58b6d47cc8f8..113e74c9479f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -272,6 +272,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); int ret = 0; u32 data_delay; + bool fs_pol_rising; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -351,39 +352,39 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_IB_NF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = true; break; case SND_SOC_DAIFMT_NB_IF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = false; break; case SND_SOC_DAIFMT_IB_IF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = false; break; case SND_SOC_DAIFMT_NB_NF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); - mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); - mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + fs_pol_rising = true; break; default: ret = -EINVAL; - break; + goto out; + } + + if (fs_pol_rising) { + mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); + } else { + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); } out: pm_runtime_put_sync(mcasp->dev); -- cgit v1.2.3 From ffd950f75dd71f13194b5d5c8ec67926a1996102 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:45 +0300 Subject: ASoC: davinci-mcasp: Add support for I2S format The FS needs to be inverted in McASP compared to other supported formats. Use a flag to indicate if the FS needs to be inverted. At the same time fail when non supported format is asked since the default case was anyways configuring McASP to a not valid format. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 113e74c9479f..d4d640004bed 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -273,6 +273,7 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, int ret = 0; u32 data_delay; bool fs_pol_rising; + bool inv_fs = false; pm_runtime_get_sync(mcasp->dev); switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -291,14 +292,19 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* No delay after FS */ data_delay = 0; break; - default: + case SND_SOC_DAIFMT_I2S: /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; + /* FS need to be inverted */ + inv_fs = true; break; + default: + ret = -EINVAL; + goto out; } mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay), @@ -379,6 +385,9 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, goto out; } + if (inv_fs) + fs_pol_rising = !fs_pol_rising; + if (fs_pol_rising) { mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); -- cgit v1.2.3 From 423761e0cab39c98f0fd9387ea44b98c2a4ca6fa Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:46 +0300 Subject: ASoC: davinci-mcasp: Support for LEFT_J format Configuration for LEFT_J format. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index d4d640004bed..2b6722024fbd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -302,6 +302,13 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* FS need to be inverted */ inv_fs = true; break; + case SND_SOC_DAIFMT_LEFT_J: + /* configure a full-word SYNC pulse (LRCLK) */ + mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); + mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); + /* No delay after FS */ + data_delay = 0; + break; default: ret = -EINVAL; goto out; -- cgit v1.2.3 From 3c25f916d378da6f06874abfc5c18e5a40e2d8c0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 14:31:47 +0300 Subject: ASoC: davinci-mcasp: Remove excess empty lines from davinci_mcasp_set_dai_fmt() To make the code look uniform. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 2b6722024fbd..8007fcf428d9 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -280,7 +280,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_DSP_A: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; break; @@ -288,7 +287,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_AC97: mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* No delay after FS */ data_delay = 0; break; @@ -296,7 +294,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* configure a full-word SYNC pulse (LRCLK) */ mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); - /* 1st data bit occur one ACLK cycle after the frame sync */ data_delay = 1; /* FS need to be inverted */ @@ -356,7 +353,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); mcasp->bclk_master = 0; break; - default: ret = -EINVAL; goto out; @@ -368,25 +364,21 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = true; break; - case SND_SOC_DAIFMT_NB_IF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = false; break; - case SND_SOC_DAIFMT_IB_IF: mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = false; break; - case SND_SOC_DAIFMT_NB_NF: mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); fs_pol_rising = true; break; - default: ret = -EINVAL; goto out; -- cgit v1.2.3 From eba9e06f0ceb2ea3342e72577b244d8b02645396 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 16 Mar 2014 08:21:34 +0400 Subject: ASoC: fsl: Separation of the main audio options and boards This patch provide separation of the main audio options and boards. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 338a91642471..0b4315d5af77 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,3 +1,5 @@ +menu "SoC Audio for Freescale CPUs" + config SND_SOC_FSL_SAI tristate select REGMAP_MMIO @@ -18,13 +20,27 @@ config SND_SOC_FSL_ESAI config SND_SOC_FSL_UTILS tristate -menuconfig SND_POWERPC_SOC +config SND_SOC_IMX_PCM_DMA + tristate + select SND_SOC_GENERIC_DMAENGINE_PCM + +config SND_SOC_IMX_AUDMUX + tristate + +config SND_POWERPC_SOC tristate "SoC Audio for Freescale PowerPC CPUs" depends on FSL_SOC || PPC_MPC52xx help Say Y or M if you want to add support for codecs attached to the PowerPC CPUs. +config SND_IMX_SOC + tristate "SoC Audio for Freescale i.MX CPUs" + depends on ARCH_MXC || COMPILE_TEST + help + Say Y or M if you want to add support for codecs attached to + the i.MX CPUs. + if SND_POWERPC_SOC config SND_MPC52xx_DMA @@ -33,6 +49,8 @@ config SND_MPC52xx_DMA config SND_SOC_POWERPC_DMA tristate +comment "SoC Audio support for Freescale PPC boards:" + config SND_SOC_MPC8610_HPCD tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" # I2C is necessary for the CS4270 driver @@ -110,13 +128,6 @@ config SND_MPC52xx_SOC_EFIKA endif # SND_POWERPC_SOC -menuconfig SND_IMX_SOC - tristate "SoC Audio for Freescale i.MX CPUs" - depends on ARCH_MXC || COMPILE_TEST - help - Say Y or M if you want to add support for codecs attached to - the i.MX CPUs. - if SND_IMX_SOC config SND_SOC_IMX_SSI @@ -127,12 +138,7 @@ config SND_SOC_IMX_PCM_FIQ tristate select FIQ -config SND_SOC_IMX_PCM_DMA - tristate - select SND_SOC_GENERIC_DMAENGINE_PCM - -config SND_SOC_IMX_AUDMUX - tristate +comment "SoC Audio support for Freescale i.MX boards:" config SND_MXC_SOC_WM1133_EV1 tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" @@ -225,3 +231,5 @@ config SND_SOC_IMX_MC13783 select SND_SOC_IMX_PCM_DMA endif # SND_IMX_SOC + +endmenu -- cgit v1.2.3 From 204dec93eaaba3a7afdc09aa3c3f6d08c773a367 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 16 Mar 2014 08:21:35 +0400 Subject: ASoC: fsl: Allow to select individual common options This patch allow to select individual common sound options and as a result allow using sound cards/codecs based on DT description. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 0b4315d5af77..7a7eaf32158f 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -1,16 +1,28 @@ menu "SoC Audio for Freescale CPUs" +comment "Common SoC Audio options for Freescale CPUs:" + config SND_SOC_FSL_SAI tristate select REGMAP_MMIO select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_FSL_SSI - tristate + tristate "Synchronous Serial Interface module support" + help + Say Y if you want to add Synchronous Serial Interface (SSI) + support for the Freescale CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_SOC_FSL_SPDIF - tristate + tristate "Sony/Philips Digital Interface module support" select REGMAP_MMIO + help + Say Y if you want to add Sony/Philips Digital Interface (SPDIF) + support for the Freescale CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_SOC_FSL_ESAI tristate @@ -25,7 +37,12 @@ config SND_SOC_IMX_PCM_DMA select SND_SOC_GENERIC_DMAENGINE_PCM config SND_SOC_IMX_AUDMUX - tristate + tristate "Digital Audio Mux module support" + help + Say Y if you want to add Digital Audio Mux (AUDMUX) support + for the ARM i.MX CPUs. + This option is only useful for out-of-tree drivers since + in-tree drivers select it automatically. config SND_POWERPC_SOC tristate "SoC Audio for Freescale PowerPC CPUs" -- cgit v1.2.3 From 413312aa17ceefe7003ad690778ab72f023128f0 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 28 Mar 2014 19:39:25 +0800 Subject: ASoC: fsl_sai: Improve fsl_sai_isr() This patch improves fsl_sai_isr() in these ways: 1, Add comment for mask fetching code. 2, Return IRQ_NONE if the IRQ is not for the device. 3, Use regmap_write() instead of regmap_update_bits(). Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 64 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 19 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 56da8c8c5960..7194d9280020 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -30,62 +30,88 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) { struct fsl_sai *sai = (struct fsl_sai *)devid; struct device *dev = &sai->pdev->dev; - u32 xcsr, mask; + u32 flags, xcsr, mask; + bool irq_none = true; - /* Only handle those what we enabled */ + /* + * Both IRQ status bits and IRQ mask bits are in the xCSR but + * different shifts. And we here create a mask only for those + * IRQs that we activated. + */ mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; /* Tx IRQ */ regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); - xcsr &= mask; + flags = xcsr & mask; - if (xcsr & FSL_SAI_CSR_WSF) + if (flags) + irq_none = false; + else + goto irq_rx; + + if (flags & FSL_SAI_CSR_WSF) dev_dbg(dev, "isr: Start of Tx word detected\n"); - if (xcsr & FSL_SAI_CSR_SEF) + if (flags & FSL_SAI_CSR_SEF) dev_warn(dev, "isr: Tx Frame sync error detected\n"); - if (xcsr & FSL_SAI_CSR_FEF) { + if (flags & FSL_SAI_CSR_FEF) { dev_warn(dev, "isr: Transmit underrun detected\n"); /* FIFO reset for safety */ xcsr |= FSL_SAI_CSR_FR; } - if (xcsr & FSL_SAI_CSR_FWF) + if (flags & FSL_SAI_CSR_FWF) dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); - if (xcsr & FSL_SAI_CSR_FRF) + if (flags & FSL_SAI_CSR_FRF) dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, - FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); + flags &= FSL_SAI_CSR_xF_W_MASK; + xcsr &= ~FSL_SAI_CSR_xF_MASK; + + if (flags) + regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); +irq_rx: /* Rx IRQ */ regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); - xcsr &= mask; + flags = xcsr & mask; - if (xcsr & FSL_SAI_CSR_WSF) + if (flags) + irq_none = false; + else + goto out; + + if (flags & FSL_SAI_CSR_WSF) dev_dbg(dev, "isr: Start of Rx word detected\n"); - if (xcsr & FSL_SAI_CSR_SEF) + if (flags & FSL_SAI_CSR_SEF) dev_warn(dev, "isr: Rx Frame sync error detected\n"); - if (xcsr & FSL_SAI_CSR_FEF) { + if (flags & FSL_SAI_CSR_FEF) { dev_warn(dev, "isr: Receive overflow detected\n"); /* FIFO reset for safety */ xcsr |= FSL_SAI_CSR_FR; } - if (xcsr & FSL_SAI_CSR_FWF) + if (flags & FSL_SAI_CSR_FWF) dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); - if (xcsr & FSL_SAI_CSR_FRF) + if (flags & FSL_SAI_CSR_FRF) dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, - FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); + flags &= FSL_SAI_CSR_xF_W_MASK; + xcsr &= ~FSL_SAI_CSR_xF_MASK; - return IRQ_HANDLED; + if (flags) + regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); + +out: + if (irq_none) + return IRQ_NONE; + else + return IRQ_HANDLED; } static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, -- cgit v1.2.3 From e6b398465821fb8e08d208bd4ef2b5b73ce87b58 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 11:17:06 +0800 Subject: ASoC: fsl_sai: Fix buggy configurations in trigger() The current trigger() has two crucial problems: 1) The DMA request enabling operations (FSL_SAI_CSR_FRDE) for Tx and Rx are now totally exclusive: It would fail to run simultaneous Tx-Rx cases. 2) The TERE disabling operation depends on an incorrect condition -- active reference count that only gets increased in snd_pcm_open() and decreased in snd_pcm_close(): The TERE would never get cleared. So this patch overwrites the trigger function by following these rules: A) We continue to support tx-async-while-rx-sync-to-tx case alone, which's originally limited by this fsl_sai driver, but we make the code easy to modify for the further support of the opposite case. B) We enable both TE and RE for PLAYBACK stream or CAPTURE stream but only enabling the DMA request bit (FSL_SAI_CSR_FRDE) of the current direction due to the requirement of SAI -- For tx-async-while-rx-sync-to-tx case, the receiver is enabled only when both the transmitter and receiver are enabled. Tested cases: a) aplay test.wav -d5 b) arecord -r44100 -c2 -fS16_LE test.wav -d5 c) arecord -r44100 -c2 -fS16_LE -d5 | aplay d) (aplay test2.wav &); sleep 1; arecord -r44100 -c2 -fS16_LE test.wav -d1 e) (arecord -r44100 -c2 -fS16_LE test.wav -d5 &); sleep 1; aplay test.wav -d1 Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 35 +++++++++++++++++------------------ sound/soc/fsl/fsl_sai.h | 10 ++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 7194d9280020..80cca7bb2a11 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -365,6 +365,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 tcsr, rcsr; /* @@ -379,14 +380,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - tcsr |= FSL_SAI_CSR_FRDE; - rcsr &= ~FSL_SAI_CSR_FRDE; - } else { - rcsr |= FSL_SAI_CSR_FRDE; - tcsr &= ~FSL_SAI_CSR_FRDE; - } - /* * It is recommended that the transmitter is the last enabled * and the first disabled. @@ -395,22 +388,28 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - tcsr |= FSL_SAI_CSR_TERE; - rcsr |= FSL_SAI_CSR_TERE; + if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, + FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, + FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); + } - regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); - regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (!(cpu_dai->playback_active || cpu_dai->capture_active)) { - tcsr &= ~FSL_SAI_CSR_TERE; - rcsr &= ~FSL_SAI_CSR_TERE; + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_FRDE, 0); + + if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, + FSL_SAI_CSR_TERE, 0); + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, + FSL_SAI_CSR_TERE, 0); } - - regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); - regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); break; default: return -EINVAL; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index a264185c7138..64b6fe72cd08 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -35,6 +35,16 @@ #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ +#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) +#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) +#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) +#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) +#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) +#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) +#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) +#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) +#define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) + /* SAI Transmit/Recieve Control Register */ #define FSL_SAI_CSR_TERE BIT(31) #define FSL_SAI_CSR_FR BIT(25) -- cgit v1.2.3 From 8abba5d64835c636d97ac0009ab7430ed832cb93 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 11:17:07 +0800 Subject: ASoC: fsl_sai: Separately enable interrupts for Tx and Rx streams We only enable one side interrupt for each stream since over/underrun on the opposite stream would be resulted from what we previously did, enabling TERE but remaining FRDE disabled, even though the xrun on the opposite direction will not break the current stream. Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 8 ++++++-- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 80cca7bb2a11..21de5bd1c9c5 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -395,6 +395,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); } + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); break; @@ -403,6 +405,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, case SNDRV_PCM_TRIGGER_PAUSE_PUSH: regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_FRDE, 0); + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), + FSL_SAI_CSR_xIE_MASK, 0); if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { regmap_update_bits(sai->regmap, FSL_SAI_TCSR, @@ -463,8 +467,8 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS); - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS); + regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); + regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_TX * 2); regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 64b6fe72cd08..be26d46ee737 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -58,6 +58,7 @@ #define FSL_SAI_CSR_FWF BIT(17) #define FSL_SAI_CSR_FRF BIT(16) #define FSL_SAI_CSR_xIE_SHIFT 8 +#define FSL_SAI_CSR_xIE_MASK (0x1f << FSL_SAI_CSR_xIE_SHIFT) #define FSL_SAI_CSR_WSIE BIT(12) #define FSL_SAI_CSR_SEIE BIT(11) #define FSL_SAI_CSR_FEIE BIT(10) -- cgit v1.2.3 From c754064453e0d48043bd6a111f5c1f8ef1b75f7e Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 1 Apr 2014 19:34:09 +0800 Subject: ASoC: fsl_sai: Add imx6sx platform support The next coming i.MX6 Solo X SoC also contains SAI module while we use imp_pcm_init() for i.MX platform. So this patch adds one compatible route for imx6sx and updates the DT doc accordingly. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-sai.txt | 2 +- sound/soc/fsl/fsl_sai.c | 12 ++++++++++-- sound/soc/fsl/fsl_sai.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 98611a6761c0..35c09fe5847a 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -7,7 +7,7 @@ codec/DSP interfaces. Required properties: -- compatible: Compatible list, contains "fsl,vf610-sai". +- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". - reg: Offset and length of the register set for the device. - clocks: Must contain an entry for each entry in clock-names. - clock-names : Must include the "sai" entry. diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 21de5bd1c9c5..dde084273c64 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -22,6 +22,7 @@ #include #include "fsl_sai.h" +#include "imx-pcm.h" #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ FSL_SAI_CSR_FEIE) @@ -592,6 +593,9 @@ static int fsl_sai_probe(struct platform_device *pdev) sai->pdev = pdev; + if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai")) + sai->sai_on_imx = true; + sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); if (sai->big_endian_regs) fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; @@ -634,12 +638,16 @@ static int fsl_sai_probe(struct platform_device *pdev) if (ret) return ret; - return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, - SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); + if (sai->sai_on_imx) + return imx_pcm_dma_init(pdev); + else + return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, + SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); } static const struct of_device_id fsl_sai_ids[] = { { .compatible = "fsl,vf610-sai", }, + { .compatible = "fsl,imx6sx-sai", }, { /* sentinel */ } }; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index be26d46ee737..677670d62fcd 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -130,6 +130,7 @@ struct fsl_sai { bool big_endian_regs; bool big_endian_data; bool is_dsp_mode; + bool sai_on_imx; struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; -- cgit v1.2.3 From ca3e35c7a37cb59b12a1839d03c621cf8fa9a3d9 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Thu, 10 Apr 2014 23:26:15 +0800 Subject: ASoC: fsl_sai: Add clock controls for SAI The SAI mainly has the following clocks: bus clock control and configure registers and to generate synchronous interrupts and DMA requests. mclk1, mclk2, mclk3 to generate the bit clock when the receiver or transmitter is configured for an internally generated bit clock. So this patch adds these clocks and their clock controls to the driver. [ To concern the old DTB cases, I've added a bit of extra code to make the driver compatible with them. And by marking clock NULL if failed to get, the clk_prepare() or clk_get_rate() would easily return 0 so no further path should be broken. -- by Nicolin ] Signed-off-by: Nicolin Chen Acked-by: Xiubo Li Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl-sai.txt | 9 +++-- sound/soc/fsl/fsl_sai.c | 38 ++++++++++++++++++++-- sound/soc/fsl/fsl_sai.h | 4 +++ 3 files changed, 46 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 35c09fe5847a..0f4e23828190 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -10,7 +10,8 @@ Required properties: - compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". - reg: Offset and length of the register set for the device. - clocks: Must contain an entry for each entry in clock-names. -- clock-names : Must include the "sai" entry. +- clock-names : Must include the "bus" for register access and "mclk1" "mclk2" + "mclk3" for bit clock and frame clock providing. - dmas : Generic dma devicetree binding as described in Documentation/devicetree/bindings/dma/dma.txt. - dma-names : Two dmas have to be defined, "tx" and "rx". @@ -30,8 +31,10 @@ sai2: sai@40031000 { reg = <0x40031000 0x1000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai2_1>; - clocks = <&clks VF610_CLK_SAI2>; - clock-names = "sai"; + clocks = <&clks VF610_CLK_PLATFORM_BUS>, + <&clks VF610_CLK_SAI2>, + <&clks 0>, <&clks 0>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; dma-names = "tx", "rx"; dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index dde084273c64..1c93282fbd26 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -427,7 +427,15 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + struct device *dev = &sai->pdev->dev; u32 reg; + int ret; + + ret = clk_prepare_enable(sai->bus_clk); + if (ret) { + dev_err(dev, "failed to enable bus clock: %d\n", ret); + return ret; + } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) reg = FSL_SAI_TCR3; @@ -453,6 +461,8 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, ~FSL_SAI_CR3_TRCE); + + clk_disable_unprepare(sai->bus_clk); } static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { @@ -585,7 +595,8 @@ static int fsl_sai_probe(struct platform_device *pdev) struct fsl_sai *sai; struct resource *res; void __iomem *base; - int irq, ret; + char tmp[8]; + int irq, ret, i; sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); if (!sai) @@ -608,12 +619,35 @@ static int fsl_sai_probe(struct platform_device *pdev) return PTR_ERR(base); sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, - "sai", base, &fsl_sai_regmap_config); + "bus", base, &fsl_sai_regmap_config); + + /* Compatible with old DTB cases */ + if (IS_ERR(sai->regmap)) + sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, + "sai", base, &fsl_sai_regmap_config); if (IS_ERR(sai->regmap)) { dev_err(&pdev->dev, "regmap init failed\n"); return PTR_ERR(sai->regmap); } + /* No error out for old DTB cases but only mark the clock NULL */ + sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(sai->bus_clk)) { + dev_err(&pdev->dev, "failed to get bus clock: %ld\n", + PTR_ERR(sai->bus_clk)); + sai->bus_clk = NULL; + } + + for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { + sprintf(tmp, "mclk%d", i + 1); + sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); + if (IS_ERR(sai->mclk_clk[i])) { + dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", + i + 1, PTR_ERR(sai->mclk_clk[i])); + sai->mclk_clk[i] = NULL; + } + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 677670d62fcd..0e6c9f595d75 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -119,6 +119,8 @@ #define FSL_SAI_CLK_MAST2 2 #define FSL_SAI_CLK_MAST3 3 +#define FSL_SAI_MCLK_MAX 3 + /* SAI data transfer numbers per DMA request */ #define FSL_SAI_MAXBURST_TX 6 #define FSL_SAI_MAXBURST_RX 6 @@ -126,6 +128,8 @@ struct fsl_sai { struct platform_device *pdev; struct regmap *regmap; + struct clk *bus_clk; + struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; bool big_endian_regs; bool big_endian_data; -- cgit v1.2.3 From 2b0db996ba2d9b833c2bd2d73cbf301abe11c60e Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 15 Mar 2014 13:44:09 +0100 Subject: ASoC: fsl-ssi: Remove fsl_ssi_setup fsl_ssi_set_dai_fmt() manages most of the register setup routines now. fsl_ssi_setup() makes the same as fsl_ssi_set_dai_fmt() but it relies on DT properties. In most cases the settings of fsl_ssi_setup() are already overwritten by fsl_ssi_set_dai_fmt() when it is called by the soc-core when a sound card is added. As these settings depend on the combination of codec and cpu DAI, this should really be done by sound cards. This patch removes fsl_ssi_setup() and adds the missing register setups to fsl_ssi_set_dai_fmt(). It also removes all calls to fsl_ssi_setup(). Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 143 +++++++++++++----------------------------------- 1 file changed, 39 insertions(+), 104 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..144934eb9463 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -642,96 +642,6 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); } -static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) -{ - struct ccsr_ssi __iomem *ssi = ssi_private->ssi; - u8 wm; - int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; - - fsl_ssi_setup_reg_vals(ssi_private); - - if (ssi_private->imx_ac97) - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; - else - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; - - /* - * Section 16.5 of the MPC8610 reference manual says that the SSI needs - * to be disabled before updating the registers we set here. - */ - write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); - - /* - * Program the SSI into I2S Slave Non-Network Synchronous mode. Also - * enable the transmit and receive FIFO. - * - * FIXME: Little-endian samples require a different shift dir - */ - write_ssi_mask(&ssi->scr, - CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, - CCSR_SSI_SCR_TFR_CLK_DIS | - ssi_private->i2s_mode | - (synchronous ? CCSR_SSI_SCR_SYN : 0)); - - write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI | - CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr); - - write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI | - CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr); - - /* - * The DC and PM bits are only used if the SSI is the clock master. - */ - - /* - * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't - * use FIFO 1. We program the transmit water to signal a DMA transfer - * if there are only two (or fewer) elements left in the FIFO. Two - * elements equals one frame (left channel, right channel). This value, - * however, depends on the depth of the transmit buffer. - * - * We set the watermark on the same level as the DMA burstsize. For - * fiq it is probably better to use the biggest possible watermark - * size. - */ - if (ssi_private->use_dma) - wm = ssi_private->fifo_depth - 2; - else - wm = ssi_private->fifo_depth; - - write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | - CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), - &ssi->sfcsr); - - /* - * For ac97 interrupts are enabled with the startup of the substream - * because it is also running without an active substream. Normally SSI - * is only enabled when there is a substream. - */ - if (ssi_private->imx_ac97) - fsl_ssi_setup_ac97(ssi_private); - - /* - * Set a default slot number so that there is no need for those common - * cases like I2S mode to call the extra set_tdm_slot() any more. - */ - if (!ssi_private->imx_ac97) { - write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); - write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, - CCSR_SSI_SxCCR_DC(2)); - } - - if (ssi_private->use_dual_fifo) { - write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); - write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); - write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); - } - - return 0; -} - - /** * fsl_ssi_startup: create a new substream * @@ -748,12 +658,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, snd_soc_dai_get_drvdata(rtd->cpu_dai); unsigned long flags; - /* First, we only do fsl_ssi_setup() when SSI is going to be active. - * Second, fsl_ssi_setup was already called by ac97_init earlier if - * the driver is in ac97 mode. - */ if (!dai->active && !ssi_private->imx_ac97) { - fsl_ssi_setup(ssi_private); spin_lock_irqsave(&ssi_private->baudclk_lock, flags); ssi_private->baudclk_locked = false; spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); @@ -835,6 +740,9 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); struct ccsr_ssi __iomem *ssi = ssi_private->ssi; u32 strcr = 0, stcr, srcr, scr, mask; + u8 wm; + + fsl_ssi_setup_reg_vals(ssi_private); scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); scr |= CCSR_SSI_SCR_NET; @@ -857,7 +765,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) default: return -EINVAL; } - scr |= ssi_private->i2s_mode; /* Data on rising edge of bclk, frame low, 1clk before data */ strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | @@ -877,9 +784,13 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TXBIT0; break; + case SND_SOC_DAIFMT_AC97: + ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL; + break; default: return -EINVAL; } + scr |= ssi_private->i2s_mode; /* DAI clock inversion */ switch (fmt & SND_SOC_DAIFMT_INV_MASK) { @@ -929,6 +840,38 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) write_ssi(srcr, &ssi->srcr); write_ssi(scr, &ssi->scr); + /* + * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't + * use FIFO 1. We program the transmit water to signal a DMA transfer + * if there are only two (or fewer) elements left in the FIFO. Two + * elements equals one frame (left channel, right channel). This value, + * however, depends on the depth of the transmit buffer. + * + * We set the watermark on the same level as the DMA burstsize. For + * fiq it is probably better to use the biggest possible watermark + * size. + */ + if (ssi_private->use_dma) + wm = ssi_private->fifo_depth - 2; + else + wm = ssi_private->fifo_depth; + + write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | + CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), + &ssi->sfcsr); + + if (ssi_private->use_dual_fifo) { + write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, + CCSR_SSI_SRCR_RFEN1); + write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, + CCSR_SSI_STCR_TFEN1); + write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, + CCSR_SSI_SCR_TCH_EN); + } + + if (fmt & SND_SOC_DAIFMT_AC97) + fsl_ssi_setup_ac97(ssi_private); + return 0; } @@ -1184,11 +1127,6 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { static struct fsl_ssi_private *fsl_ac97_data; -static void fsl_ssi_ac97_init(void) -{ - fsl_ssi_setup(fsl_ac97_data); -} - static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) { @@ -1547,9 +1485,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) } done: - if (ssi_private->imx_ac97) - fsl_ssi_ac97_init(); - return 0; error_dai: -- cgit v1.2.3 From 07a28dbe7ad8e72868239450ff796c90e621d46f Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sat, 15 Mar 2014 13:44:10 +0100 Subject: ASoC: fsl-ssi: Fix i2s_mode variable setup In fsl_ssi_hw_params() we update the I2S and NET bits using the i2s_mode variable. The fsl_ssi_set_dai_fmt() function only writes the i2s-mode to the i2s_mode variable and not the NET bit. This fixes it by adding that bit to i2s_mode. Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 144934eb9463..fdb123d6817c 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -745,7 +745,6 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) fsl_ssi_setup_reg_vals(ssi_private); scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); - scr |= CCSR_SSI_SCR_NET; mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | @@ -753,14 +752,15 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) stcr = read_ssi(&ssi->stcr) & ~mask; srcr = read_ssi(&ssi->srcr) & ~mask; + ssi_private->i2s_mode = CCSR_SSI_SCR_NET; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; break; case SND_SOC_DAIFMT_CBM_CFM: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; break; default: return -EINVAL; @@ -785,7 +785,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) CCSR_SSI_STCR_TXBIT0; break; case SND_SOC_DAIFMT_AC97: - ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL; + ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL; break; default: return -EINVAL; -- cgit v1.2.3 From 74a1672068c7f52f1525a5fca17cdc1ed6961239 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:30 +0100 Subject: ASoC: ams-delta: Convert to table based DAPM and control setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/ams-delta.c | 64 +++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 43 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 56a5219c0a00..2ac0a0c3b570 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -38,7 +38,6 @@ #include "omap-mcbsp.h" #include "../codecs/cx20442.h" - /* Board specific DAPM widgets */ static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { /* Handset */ @@ -90,17 +89,23 @@ static const unsigned short ams_delta_audio_mode_pins[] = { static unsigned short ams_delta_audio_agc; +/* + * Used for passing a codec structure pointer + * from the board initialization code to the tty line discipline. + */ +static struct snd_soc_codec *cx20442_codec; + static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ - if (!codec->hw_write) + if (!cx20442_codec->hw_write) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->items) @@ -166,8 +171,8 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; unsigned short pins, mode; pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << @@ -270,12 +275,6 @@ static void cx81801_timeout(unsigned long data) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); } -/* - * Used for passing a codec structure pointer - * from the board initialization code to the tty line discipline. - */ -static struct snd_soc_codec *cx20442_codec; - /* Line discipline .open() */ static int cx81801_open(struct tty_struct *tty) { @@ -302,7 +301,7 @@ static int cx81801_open(struct tty_struct *tty) static void cx81801_close(struct tty_struct *tty) { struct snd_soc_codec *codec = tty->disc_data; - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_dapm_context *dapm = &codec->card->dapm; del_timer_sync(&cx81801_timer); @@ -475,15 +474,14 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = &card->dapm; int ret; /* Codec is ready, now add/activate board specific controls */ /* Store a pointer to the codec structure for tty ldisc use */ - cx20442_codec = codec; + cx20442_codec = rtd->codec; /* Set up digital mute if not provided by the codec */ if (!codec_dai->driver->ops) { @@ -520,25 +518,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } - /* Add board specific DAPM widgets and routes */ - ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, - ARRAY_SIZE(ams_delta_dapm_widgets)); - if (ret) { - dev_warn(card->dev, - "Failed to register DAPM controls, " - "will continue without any.\n"); - return 0; - } - - ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, - ARRAY_SIZE(ams_delta_audio_map)); - if (ret) { - dev_warn(card->dev, - "Failed to set up DAPM routes, " - "will continue with codec default map.\n"); - return 0; - } - /* Set up initial pin constellation */ snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); snd_soc_dapm_enable_pin(dapm, "Earpiece"); @@ -547,14 +526,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_disable_pin(dapm, "AGCIN"); snd_soc_dapm_disable_pin(dapm, "AGCOUT"); - /* Add virtual switch */ - ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls, - ARRAY_SIZE(ams_delta_audio_controls)); - if (ret) - dev_warn(card->dev, - "Failed to register audio mode control, " - "will continue without it.\n"); - return 0; } @@ -576,6 +547,13 @@ static struct snd_soc_card ams_delta_audio_card = { .owner = THIS_MODULE, .dai_link = &ams_delta_dai_link, .num_links = 1, + + .controls = ams_delta_audio_controls, + .num_controls = ARRAY_SIZE(ams_delta_audio_controls), + .dapm_widgets = ams_delta_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ams_delta_dapm_widgets), + .dapm_routes = ams_delta_audio_map, + .num_dapm_routes = ARRAY_SIZE(ams_delta_audio_map), }; /* Module init/exit */ -- cgit v1.2.3 From 81fc5dd4d19faa3dda886910cb8fdad639fa828b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:33 +0100 Subject: ASoC: omap: rx51: Convert to table based control and DAPM setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/rx51.c | 47 +++++++---------------------------------------- 1 file changed, 7 insertions(+), 40 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 7fb3d4b10370..2b4641123142 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -237,9 +237,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), SND_SOC_DAPM_MIC("HS Mic", NULL), SND_SOC_DAPM_LINE("FM Transmitter", NULL), -}; - -static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = { SND_SOC_DAPM_SPK("Earphone", NULL), }; @@ -253,9 +250,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"DMic Rate 64", NULL, "Mic Bias"}, {"Mic Bias", NULL, "DMic"}, -}; -static const struct snd_soc_dapm_route audio_mapb[] = { {"b LINE2R", NULL, "MONO_LOUT"}, {"Earphone", NULL, "b HPLOUT"}, @@ -281,9 +276,6 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { SOC_ENUM_EXT("Jack Function", rx51_enum[2], rx51_get_jack, rx51_set_jack), SOC_DAPM_PIN_SWITCH("FM Transmitter"), -}; - -static const struct snd_kcontrol_new aic34_rx51_controlsb[] = { SOC_DAPM_PIN_SWITCH("Earphone"), }; @@ -298,19 +290,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "MIC3R"); snd_soc_dapm_nc_pin(dapm, "LINE1R"); - /* Add RX-51 specific controls */ - err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls, - ARRAY_SIZE(aic34_rx51_controls)); - if (err < 0) - return err; - - /* Add RX-51 specific widgets */ - snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets, - ARRAY_SIZE(aic34_dapm_widgets)); - - /* Set up RX-51 specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - err = tpa6130a2_add_controls(codec); if (err < 0) return err; @@ -333,24 +312,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; } -static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm) -{ - int err; - - err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb, - ARRAY_SIZE(aic34_rx51_controlsb)); - if (err < 0) - return err; - - err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb, - ARRAY_SIZE(aic34_dapm_widgetsb)); - if (err < 0) - return 0; - - return snd_soc_dapm_add_routes(dapm, audio_mapb, - ARRAY_SIZE(audio_mapb)); -} - /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link rx51_dai[] = { { @@ -371,7 +332,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = { { .name = "TLV320AIC34b", .codec_name = "tlv320aic3x-codec.2-0019", - .init = rx51_aic34b_init, }, }; @@ -392,6 +352,13 @@ static struct snd_soc_card rx51_sound_card = { .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), .codec_conf = rx51_codec_conf, .num_configs = ARRAY_SIZE(rx51_codec_conf), + + .controls = aic34_rx51_controls, + .num_controls = ARRAY_SIZE(aic34_rx51_controls), + .dapm_widgets = aic34_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), }; static struct platform_device *rx51_snd_device; -- cgit v1.2.3 From b2e69054ea1a36f2c1ace15a55240937aa091cba Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 12 Mar 2014 15:27:34 +0100 Subject: ASoC: omap3pandora: Convert to table based DAPM setup Use table based setup to register the controls and DAPM widgets and routes. This on one hand makes the code a bit shorter and cleaner and on the other hand the board level DAPM elements get registered in the card's DAPM context rather than in the CODEC's DAPM context. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/omap/omap3pandora.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index cf604a2faa18..02181bb70400 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -121,7 +121,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, * |A| <~~clk~~+ * |P| <--- TWL4030 <--------- Line In and MICs */ -static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { +static const struct snd_soc_dapm_widget omap3pandora_dapm_widgets[] = { SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0, omap3pandora_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -130,22 +130,18 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), -}; -static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { SND_SOC_DAPM_MIC("Mic (internal)", NULL), SND_SOC_DAPM_MIC("Mic (external)", NULL), SND_SOC_DAPM_LINE("Line In", NULL), }; -static const struct snd_soc_dapm_route omap3pandora_out_map[] = { +static const struct snd_soc_dapm_route omap3pandora_map[] = { {"PCM DAC", NULL, "APLL Enable"}, {"Headphone Amplifier", NULL, "PCM DAC"}, {"Line Out", NULL, "PCM DAC"}, {"Headphone Jack", NULL, "Headphone Amplifier"}, -}; -static const struct snd_soc_dapm_route omap3pandora_in_map[] = { {"AUXL", NULL, "Line In"}, {"AUXR", NULL, "Line In"}, @@ -160,7 +156,6 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* All TWL4030 output pins are floating */ snd_soc_dapm_nc_pin(dapm, "EARPIECE"); @@ -174,20 +169,13 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "HFR"); snd_soc_dapm_nc_pin(dapm, "VIBRA"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets, - ARRAY_SIZE(omap3pandora_out_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, - ARRAY_SIZE(omap3pandora_out_map)); + return 0; } static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* Not comnnected */ snd_soc_dapm_nc_pin(dapm, "HSMIC"); @@ -195,13 +183,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, - ARRAY_SIZE(omap3pandora_in_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, - ARRAY_SIZE(omap3pandora_in_map)); + return 0; } static struct snd_soc_ops omap3pandora_ops = { @@ -241,6 +223,11 @@ static struct snd_soc_card snd_soc_card_omap3pandora = { .owner = THIS_MODULE, .dai_link = omap3pandora_dai, .num_links = ARRAY_SIZE(omap3pandora_dai), + + .dapm_widgets = omap3pandora_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(omap3pandora_dapm_widgets), + .dapm_routes = omap3pandora_map, + .num_dapm_routes = ARRAY_SIZE(omap3pandora_map), }; static struct platform_device *omap3pandora_snd_device; -- cgit v1.2.3 From 4c9185be5e8eefd10b0f172e794b108697d86985 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 27 Mar 2014 15:55:47 +0800 Subject: ASoC: rt5640: Move cache sync() to resume() The patch fixes the defect in case of resume which doesn't sync the cache. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..4a7bd0a16912 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1890,11 +1890,9 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, static int rt5640_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); switch (level) { case SND_SOC_BIAS_STANDBY: if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { - regcache_cache_only(rt5640->regmap, false); snd_soc_update_bits(codec, RT5640_PWR_ANLG1, RT5640_PWR_VREF1 | RT5640_PWR_MB | RT5640_PWR_BG | RT5640_PWR_VREF2, @@ -1904,7 +1902,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, RT5640_PWR_ANLG1, RT5640_PWR_FV1 | RT5640_PWR_FV2, RT5640_PWR_FV1 | RT5640_PWR_FV2); - regcache_sync(rt5640->regmap); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); snd_soc_update_bits(codec, RT5640_MICBIAS, @@ -1979,6 +1976,9 @@ static int rt5640_resume(struct snd_soc_codec *codec) msleep(400); } + regcache_cache_only(rt5640->regmap, false); + regcache_sync(rt5640->regmap); + return 0; } #else -- cgit v1.2.3 From 9bccae733b8d0e281729464267191103c09b3d13 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 27 Mar 2014 19:34:51 +0800 Subject: ASoC: rt5640: Correct the judgement of data length The patch corrects the judgement of data length. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 4a7bd0a16912..f0717db3e935 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1622,16 +1622,16 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", bclk_ms, pre_div, dai->id); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: + switch (params_width(params)) { + case 16: break; - case SNDRV_PCM_FORMAT_S20_3LE: + case 20: val_len |= RT5640_I2S_DL_20; break; - case SNDRV_PCM_FORMAT_S24_LE: + case 24: val_len |= RT5640_I2S_DL_24; break; - case SNDRV_PCM_FORMAT_S8: + case 8: val_len |= RT5640_I2S_DL_8; break; default: -- cgit v1.2.3 From 71d97a7943017faf03707836d00a260a108f4c89 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 10:46:18 +0800 Subject: ASoC: rt5640: Use the platform data for DMIC settings The patch uses the platform data for DMIC settings. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- include/sound/rt5640.h | 4 +++ sound/soc/codecs/rt5640.c | 77 ++++++++++++++--------------------------------- 2 files changed, 27 insertions(+), 54 deletions(-) (limited to 'sound') diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h index 27cc75ed67f8..59d26dd81e45 100644 --- a/include/sound/rt5640.h +++ b/include/sound/rt5640.h @@ -16,6 +16,10 @@ struct rt5640_platform_data { bool in1_diff; bool in2_diff; + bool dmic_en; + bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */ + bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */ + int ldo1_en; /* GPIO for LDO1_EN */ }; diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index f0717db3e935..6ede622ad44f 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -872,54 +872,6 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP, static const struct snd_kcontrol_new rt5640_sdi_mux = SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); -static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, - RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK, - RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA); - snd_soc_update_bits(codec, RT5640_DMIC, - RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK | - RT5640_DMIC_1_DP_MASK, - RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING | - RT5640_DMIC_1_DP_IN1P); - break; - - default: - return 0; - } - - return 0; -} - -static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, - RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK, - RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA); - snd_soc_update_bits(codec, RT5640_DMIC, - RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK | - RT5640_DMIC_2_DP_MASK, - RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING | - RT5640_DMIC_2_DP_IN1N); - break; - - default: - return 0; - } - - return 0; -} - static void hp_amp_power_on(struct snd_soc_codec *codec) { struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); @@ -1054,12 +1006,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, set_dmic_clk, SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, - RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event, - SND_SOC_DAPM_PRE_PMU), - SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, - RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event, - SND_SOC_DAPM_PRE_PMU), + SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, RT5640_DMIC_1_EN_SFT, 0, + NULL, 0), + SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, RT5640_DMIC_2_EN_SFT, 0, + NULL, 0), /* Boost */ SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2, RT5640_PWR_BST1_BIT, 0, NULL, 0), @@ -2187,6 +2137,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, RT5640_IN_DF2, RT5640_IN_DF2); + if (rt5640->pdata.dmic_en) { + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); + + if (rt5640->pdata.dmic1_data_pin) { + regmap_update_bits(rt5640->regmap, RT5640_DMIC, + RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3); + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA); + } + + if (rt5640->pdata.dmic2_data_pin) { + regmap_update_bits(rt5640->regmap, RT5640_DMIC, + RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4); + regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, + RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA); + } + } + rt5640->hp_mute = 1; ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, -- cgit v1.2.3 From 2f2a714c1bed2702e5abf55381c03ccdf7b0fd06 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:25 +0800 Subject: ASoC: rt5640: Remove the pre-allocated size of reg_default In order to prevent the redundant memory usage, the pre-allocated size of reg_default should be remove. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 6ede622ad44f..84ee7ef8eb17 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -59,7 +59,7 @@ static struct reg_default init_list[] = { }; #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) -static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = { +static const struct reg_default rt5640_reg[] = { { 0x00, 0x000e }, { 0x01, 0xc8c8 }, { 0x02, 0xc8c8 }, -- cgit v1.2.3 From 218a3f963822aca1d38b0175b6454fe53d15c2dd Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:26 +0800 Subject: ASoC: rt5640: Rename the function of clock checking In order to identify clearly, the patch renames the function "check_sysclk1_source" to "is_sys_clk_from_pll". Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 84ee7ef8eb17..19634d0992bc 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -480,7 +480,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, return idx; } -static int check_sysclk1_source(struct snd_soc_dapm_widget *source, +static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { unsigned int val; @@ -1273,22 +1273,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, {"Stereo ADC MIXL", NULL, "Stereo Filter"}, - {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, + {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, {"Stereo ADC MIXR", NULL, "Stereo Filter"}, - {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, + {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, {"Mono ADC MIXL", NULL, "Mono Left Filter"}, - {"Mono Left Filter", NULL, "PLL1", check_sysclk1_source}, + {"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, {"Mono ADC MIXR", NULL, "Mono Right Filter"}, - {"Mono Right Filter", NULL, "PLL1", check_sysclk1_source}, + {"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll}, {"IF2 ADC L", NULL, "Mono ADC MIXL"}, {"IF2 ADC R", NULL, "Mono ADC MIXR"}, @@ -1377,13 +1377,13 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, {"DAC L1", NULL, "Stereo DAC MIXL"}, - {"DAC L1", NULL, "PLL1", check_sysclk1_source}, + {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R1", NULL, "Stereo DAC MIXR"}, - {"DAC R1", NULL, "PLL1", check_sysclk1_source}, + {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC L2", NULL, "Mono DAC MIXL"}, - {"DAC L2", NULL, "PLL1", check_sysclk1_source}, + {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R2", NULL, "Mono DAC MIXR"}, - {"DAC R2", NULL, "PLL1", check_sysclk1_source}, + {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, {"SPK MIXL", "INL Switch", "INL VOL"}, -- cgit v1.2.3 From acf04e639bba2270fd07e161fa984234591ef43b Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:27 +0800 Subject: ASoC: rt5640: Remove the unused or incorrect setting of clock source The patch removes the unused or incorrect setting of clock source. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 8 +------- sound/soc/codecs/rt5640.h | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 19634d0992bc..4c866135e40f 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -487,7 +487,7 @@ static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, val = snd_soc_read(source->codec, RT5640_GLB_CLK); val &= RT5640_SCLK_SRC_MASK; - if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T) + if (val == RT5640_SCLK_SRC_PLL1) return 1; else return 0; @@ -1694,12 +1694,6 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, case RT5640_SCLK_S_PLL1: reg_val |= RT5640_SCLK_SRC_PLL1; break; - case RT5640_SCLK_S_PLL1_TK: - reg_val |= RT5640_SCLK_SRC_PLL1T; - break; - case RT5640_SCLK_S_RCCLK: - reg_val |= RT5640_SCLK_SRC_RCCLK; - break; default: dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); return -EINVAL; diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 5e8df25a13f3..cbd07b5f8060 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -976,8 +976,6 @@ #define RT5640_SCLK_SRC_SFT 14 #define RT5640_SCLK_SRC_MCLK (0x0 << 14) #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) -#define RT5640_SCLK_SRC_PLL1T (0x2 << 14) -#define RT5640_SCLK_SRC_RCCLK (0x3 << 14) /* 15MHz */ #define RT5640_PLL1_SRC_MASK (0x3 << 12) #define RT5640_PLL1_SRC_SFT 12 #define RT5640_PLL1_SRC_MCLK (0x0 << 12) -- cgit v1.2.3 From bc49e462cd6ded128cc6dbb6775de4a4c3d6bbc8 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:28 +0800 Subject: ASoC: rt5640: Remove the unused field in private data The patch removes the unused field in private data. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index cbd07b5f8060..d7bd525caf85 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -2095,7 +2095,6 @@ struct rt5640_priv { int pll_in; int pll_out; - int dmic_en; bool hp_mute; }; -- cgit v1.2.3 From 3441e524293c5e8d640488e343f2eb2bcc944108 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Fri, 28 Mar 2014 20:28:29 +0800 Subject: ASoC: rt5640: Remove the unnecessary parentheses The patch removes the unnecessary parentheses. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 4c866135e40f..b6a02c16f100 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -2110,7 +2110,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, } regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); - if ((val != RT5640_DEVICE_ID)) { + if (val != RT5640_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %x is not rt5640/39\n", val); return -ENODEV; -- cgit v1.2.3 From 09caf300540c4a610dbe6e46afdab18f365be7e7 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Mon, 31 Mar 2014 10:21:10 +0800 Subject: ASoC: rt5640: Change the setting method of idle_bias_off The patch moves the idle_bias_off setting to struct "soc_codec_dev_rt5640". Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index b6a02c16f100..a7db7ef38cfc 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1879,7 +1879,6 @@ static int rt5640_probe(struct snd_soc_codec *codec) rt5640->codec = codec; - codec->dapm.idle_bias_off = 1; rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); @@ -1988,6 +1987,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { .suspend = rt5640_suspend, .resume = rt5640_resume, .set_bias_level = rt5640_set_bias_level, + .idle_bias_off = true, .controls = rt5640_snd_controls, .num_controls = ARRAY_SIZE(rt5640_snd_controls), .dapm_widgets = rt5640_dapm_widgets, -- cgit v1.2.3 From 022d21f004c14db2151d08143a544b292324d099 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Tue, 8 Apr 2014 19:40:00 +0800 Subject: ASoC: rt5640: add rt5639 support This patch adds the rt5639 support Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 286 ++++++++++++++++++++++++++++++++++------------ sound/soc/codecs/rt5640.h | 3 + 2 files changed, 213 insertions(+), 76 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a7db7ef38cfc..a20781eda719 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -398,18 +398,13 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), - /* MONO Output Control */ - SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, - RT5640_L_MUTE_SFT, 1, 1), + /* DAC Digital Volume */ SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL, RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1), SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv), - SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, - RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, - 175, 0, dac_vol_tlv), /* IN1/IN2 Control */ SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, RT5640_BST_SFT1, 8, 0, bst_tlv), @@ -441,6 +436,15 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum), }; +static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = { + /* MONO Output Control */ + SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, RT5640_L_MUTE_SFT, + 1, 1), + + SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, + RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv), +}; + /** * set_dmic_clk - Set parameter of dmic. * @@ -554,6 +558,20 @@ static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = { RT5640_M_ANC_DAC_R_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_sto_dac_l_mix[] = { + SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_L1_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_L2_SFT, 1, 1), +}; + +static const struct snd_kcontrol_new rt5639_sto_dac_r_mix[] = { + SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_R1_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER, + RT5640_M_DAC_R2_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = { SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER, RT5640_M_DAC_L1_MONO_L_SFT, 1, 1), @@ -676,6 +694,30 @@ static const struct snd_kcontrol_new rt5640_out_r_mix[] = { RT5640_M_DAC_R1_OM_R_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_out_l_mix[] = { + SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER, + RT5640_M_BST1_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER, + RT5640_M_IN_L_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER, + RT5640_M_RM_L_OM_L_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER, + RT5640_M_DAC_L1_OM_L_SFT, 1, 1), +}; + +static const struct snd_kcontrol_new rt5639_out_r_mix[] = { + SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_BST4_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_BST1_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER, + RT5640_M_IN_R_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER, + RT5640_M_RM_R_OM_R_SFT, 1, 1), + SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER, + RT5640_M_DAC_R1_OM_R_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_spo_l_mix[] = { SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER, RT5640_M_DAC_R1_SPM_L_SFT, 1, 1), @@ -707,6 +749,13 @@ static const struct snd_kcontrol_new rt5640_hpo_mix[] = { RT5640_M_HPVOL_HM_SFT, 1, 1), }; +static const struct snd_kcontrol_new rt5639_hpo_mix[] = { + SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER, + RT5640_M_DAC1_HM_SFT, 1, 1), + SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER, + RT5640_M_HPVOL_HM_SFT, 1, 1), +}; + static const struct snd_kcontrol_new rt5640_lout_mix[] = { SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER, RT5640_M_DAC_L1_LM_SFT, 1, 1), @@ -1096,26 +1145,15 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), - /* Audio DSP */ - SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), - /* ANC */ - SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), + /* Output Side */ /* DAC mixer before sound effect */ SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)), SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)), - /* DAC2 channel Mux */ - SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, - &rt5640_dac_l2_mux), - SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, - &rt5640_dac_r2_mux), + /* DAC Mixer */ - SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, - rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), - SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, - rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)), SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, @@ -1127,21 +1165,14 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { /* DACs */ SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L1_BIT, 0), - SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, - RT5640_PWR_DAC_L2_BIT, 0), SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R1_BIT, 0), - SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, - RT5640_PWR_DAC_R2_BIT, 0), + /* SPK/OUT Mixer */ SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT, 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)), - SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, - 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), - SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, - 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), /* Ouput Volume */ SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL, RT5640_PWR_SV_L_BIT, 0, NULL, 0), @@ -1160,16 +1191,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)), SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)), - SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, - rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), - SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, - rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0, rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)), - SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, - rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), - SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, - RT5640_PWR_MA_BIT, 0, NULL, 0), SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, @@ -1201,10 +1224,69 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("HPOR"), SND_SOC_DAPM_OUTPUT("LOUTL"), SND_SOC_DAPM_OUTPUT("LOUTR"), +}; + +static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { + /* Audio DSP */ + SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), + /* ANC */ + SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* DAC2 channel Mux */ + SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_l2_mux), + SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_r2_mux), + + SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, + rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), + SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, + rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), + + SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R2_BIT, + 0), + SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L2_BIT, + 0), + + SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, + 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), + SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, + 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), + + SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, + rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), + SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, + rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), + + SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, + rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), + SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, + RT5640_PWR_MA_BIT, 0, NULL, 0), + SND_SOC_DAPM_OUTPUT("MONOP"), SND_SOC_DAPM_OUTPUT("MONON"), }; +static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = { + SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, + rt5639_sto_dac_l_mix, ARRAY_SIZE(rt5639_sto_dac_l_mix)), + SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, + rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)), + + SND_SOC_DAPM_SUPPLY("DAC L2 Filter", RT5640_PWR_DIG1, + RT5640_PWR_DAC_L2_BIT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC R2 Filter", RT5640_PWR_DIG1, + RT5640_PWR_DAC_R2_BIT, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, + 0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)), + SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, + 0, rt5639_out_r_mix, ARRAY_SIZE(rt5639_out_r_mix)), + + SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, + rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), + SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, + rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), +}; + static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"IN1P", NULL, "LDO2"}, {"IN2P", NULL, "LDO2"}, @@ -1346,71 +1428,38 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, - {"ANC", NULL, "Stereo ADC MIXL"}, - {"ANC", NULL, "Stereo ADC MIXR"}, - - {"Audio DSP", NULL, "DAC MIXL"}, - {"Audio DSP", NULL, "DAC MIXR"}, - - {"DAC L2 Mux", "IF2", "IF2 DAC L"}, - {"DAC L2 Mux", "Base L/R", "Audio DSP"}, - - {"DAC R2 Mux", "IF2", "IF2 DAC R"}, - {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, - {"Stereo DAC MIXL", "ANC Switch", "ANC"}, {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, - {"Stereo DAC MIXR", "ANC Switch", "ANC"}, {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, - {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, - {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, - {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, - {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, {"DAC L1", NULL, "Stereo DAC MIXL"}, {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, {"DAC R1", NULL, "Stereo DAC MIXR"}, {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, - {"DAC L2", NULL, "Mono DAC MIXL"}, - {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, - {"DAC R2", NULL, "Mono DAC MIXR"}, - {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, {"SPK MIXL", "INL Switch", "INL VOL"}, {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, - {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, {"SPK MIXR", "INR Switch", "INR VOL"}, {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, - {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, - {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, {"OUT MIXL", "BST1 Switch", "BST1"}, {"OUT MIXL", "INL Switch", "INL VOL"}, {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, - {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, - {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, - {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, {"OUT MIXR", "BST2 Switch", "BST2"}, {"OUT MIXR", "BST1 Switch", "BST1"}, {"OUT MIXR", "INR Switch", "INR VOL"}, {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, - {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, - {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, {"SPKVOL L", NULL, "SPK MIXL"}, @@ -1429,11 +1478,9 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, {"SPOR MIX", "BST1 Switch", "BST1"}, - {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, {"HPO MIX L", NULL, "HP L Amp"}, - {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, {"HPO MIX R", NULL, "HP R Amp"}, @@ -1443,12 +1490,6 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, - {"Mono MIX", "DAC R2 Switch", "DAC R2"}, - {"Mono MIX", "DAC L2 Switch", "DAC L2"}, - {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, - {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, - {"Mono MIX", "BST1 Switch", "BST1"}, - {"HP Amp", NULL, "HPO MIX L"}, {"HP Amp", NULL, "HPO MIX R"}, @@ -1473,11 +1514,82 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { {"HPOR", NULL, "HP R Playback"}, {"LOUTL", NULL, "LOUT MIX"}, {"LOUTR", NULL, "LOUT MIX"}, +}; + +static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = { + {"ANC", NULL, "Stereo ADC MIXL"}, + {"ANC", NULL, "Stereo ADC MIXR"}, + + {"Audio DSP", NULL, "DAC MIXL"}, + {"Audio DSP", NULL, "DAC MIXR"}, + + {"DAC L2 Mux", "IF2", "IF2 DAC L"}, + {"DAC L2 Mux", "Base L/R", "Audio DSP"}, + + {"DAC R2 Mux", "IF2", "IF2 DAC R"}, + + {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + {"Stereo DAC MIXL", "ANC Switch", "ANC"}, + {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"Stereo DAC MIXR", "ANC Switch", "ANC"}, + + {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, + + {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, + + {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, + {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, + + {"DAC L2", NULL, "Mono DAC MIXL"}, + {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, + {"DAC R2", NULL, "Mono DAC MIXR"}, + {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, + + {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, + {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, + + {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, + {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, + + {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, + {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, + + {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, + {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, + + {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, + {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, + + {"Mono MIX", "DAC R2 Switch", "DAC R2"}, + {"Mono MIX", "DAC L2 Switch", "DAC L2"}, + {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, + {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, + {"Mono MIX", "BST1 Switch", "BST1"}, + {"MONOP", NULL, "Mono MIX"}, {"MONON", NULL, "Mono MIX"}, {"MONOP", NULL, "Improve MONO Amp Drv"}, }; +static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = { + {"Stereo DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"Stereo DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, + + {"Mono DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"Mono DAC MIXL", "DAC R2 Switch", "IF2 DAC R"}, + + {"Mono DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, + {"Mono DAC MIXR", "DAC L2 Switch", "IF2 DAC L"}, + + {"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"}, + {"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"}, + + {"IF2 DAC L", NULL, "DAC L2 Filter"}, + {"IF2 DAC R", NULL, "DAC R2 Filter"}, +}; + static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) { int ret = 0, val; @@ -1885,6 +1997,28 @@ static int rt5640_probe(struct snd_soc_codec *codec) snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); + switch (snd_soc_read(codec, RT5640_RESET)) { + case RT5640_RESET_ID: + snd_soc_add_codec_controls(codec, + rt5640_specific_snd_controls, + ARRAY_SIZE(rt5640_specific_snd_controls)); + snd_soc_dapm_new_controls(&codec->dapm, + rt5640_specific_dapm_widgets, + ARRAY_SIZE(rt5640_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5640_specific_dapm_routes, + ARRAY_SIZE(rt5640_specific_dapm_routes)); + break; + case RT5639_RESET_ID: + snd_soc_dapm_new_controls(&codec->dapm, + rt5639_specific_dapm_widgets, + ARRAY_SIZE(rt5639_specific_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, + rt5639_specific_dapm_routes, + ARRAY_SIZE(rt5639_specific_dapm_routes)); + break; + } + return 0; } diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index d7bd525caf85..3b50459a83b4 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -14,6 +14,9 @@ #include +#define RT5639_RESET_ID 0x0008 +#define RT5640_RESET_ID 0x000c + /* Info */ #define RT5640_RESET 0x00 #define RT5640_VENDOR_ID 0xfd -- cgit v1.2.3 From b0c278469777b75d0af3b5718369084acb71c344 Mon Sep 17 00:00:00 2001 From: Oder Chiou Date: Thu, 10 Apr 2014 10:57:34 +0800 Subject: ASoC: rt5640: Add the string "rt5639" to the list of I2C device IDs The patch adds the string "rt5639" to the list of I2C device IDs. Signed-off-by: Oder Chiou Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index a20781eda719..6674372be12c 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -1,5 +1,5 @@ /* - * rt5640.c -- RT5640 ALSA SoC audio codec driver + * rt5640.c -- RT5640/RT5639 ALSA SoC audio codec driver * * Copyright 2011 Realtek Semiconductor Corp. * Author: Johnny Hsu @@ -2148,6 +2148,7 @@ static const struct regmap_config rt5640_regmap = { static const struct i2c_device_id rt5640_i2c_id[] = { { "rt5640", 0 }, + { "rt5639", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); @@ -2316,6 +2317,6 @@ static struct i2c_driver rt5640_i2c_driver = { }; module_i2c_driver(rt5640_i2c_driver); -MODULE_DESCRIPTION("ASoC RT5640 driver"); +MODULE_DESCRIPTION("ASoC RT5640/RT5639 driver"); MODULE_AUTHOR("Johnny Hsu "); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From b87704cef258a4f44ab1386a70b7628ec3cefd36 Mon Sep 17 00:00:00 2001 From: Rongjun Ying Date: Thu, 20 Mar 2014 15:46:19 +0800 Subject: ASoC: sirf: Move the tx rx enable from port to codec, that will not need register sharing The port driver only used to register component and dmaengine pcm. Signed-off-by: Rongjun Ying Signed-off-by: Mark Brown --- sound/soc/codecs/sirf-audio-codec.c | 74 ++++++++++++++++++++++--- sound/soc/codecs/sirf-audio-codec.h | 50 +++++++++++++++++ sound/soc/sirf/sirf-audio-port.c | 107 ------------------------------------ sound/soc/sirf/sirf-audio-port.h | 62 --------------------- 4 files changed, 116 insertions(+), 177 deletions(-) delete mode 100644 sound/soc/sirf/sirf-audio-port.h (limited to 'sound') diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 58e7c1f23771..c5177bc5df82 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { {"Mic input mode mux", "Differential", "MICIN1"}, }; +static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); +} + +static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); +} + +static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, + int channels) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, + AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + if (channels == 1) + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); + else + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); +} + +static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); +} + static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_soc_codec *codec = dai->codec; - u32 val = 0; + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; /* * This is a workaround, When stop playback, @@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (playback) { + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, 0); + sirf_audio_codec_tx_disable(sirf_audio_codec); + } else + sirf_audio_codec_rx_disable(sirf_audio_codec); break; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) - val = IC_HSLEN | IC_HSREN; + if (playback) { + sirf_audio_codec_tx_enable(sirf_audio_codec); + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); + } else + sirf_audio_codec_rx_enable(sirf_audio_codec, + substream->runtime->channels); break; default: return -EINVAL; } - if (playback) - snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, val); return 0; } @@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = AUDIO_IC_CODEC_CTRL3, + .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, .cache_type = REGCACHE_NONE, }; diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h index d4c187b8e54a..ba1adc03839f 100644 --- a/sound/soc/codecs/sirf-audio-codec.h +++ b/sound/soc/codecs/sirf-audio-codec.h @@ -72,4 +72,54 @@ #define IC_RXPGAR 0x7B #define IC_RXPGAL 0x7B +#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F +#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 + +#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_SC_OFFSET) +#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_LC_OFFSET) +#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_HC_OFFSET) + +#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F +#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 + +#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_SC_OFFSET) +#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_LC_OFFSET) +#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_HC_OFFSET) +#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) +#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) + +#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) +#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) +#define AUDIO_PORT_IC_TXFIFO_STS (0x0104) +#define AUDIO_PORT_IC_TXFIFO_INT (0x0108) +#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) + +#define AUDIO_PORT_IC_RXFIFO_OP (0x0110) +#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) +#define AUDIO_PORT_IC_RXFIFO_STS (0x0118) +#define AUDIO_PORT_IC_RXFIFO_INT (0x011C) +#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) + +#define AUDIO_FIFO_START (1 << 0) +#define AUDIO_FIFO_RESET (1 << 1) + +#define AUDIO_FIFO_FULL (1 << 0) +#define AUDIO_FIFO_EMPTY (1 << 1) +#define AUDIO_FIFO_OFLOW (1 << 2) +#define AUDIO_FIFO_UFLOW (1 << 3) + +#define IC_TX_ENABLE (0x03) +#define IC_RX_ENABLE_MONO (0x01) +#define IC_RX_ENABLE_STEREO (0x03) + #endif /*__SIRF_AUDIO_CODEC_H*/ diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c index b04a53f2b4f6..b4afa31b2bc1 100644 --- a/sound/soc/sirf/sirf-audio-port.c +++ b/sound/soc/sirf/sirf-audio-port.c @@ -6,60 +6,15 @@ * Licensed under GPLv2 or later. */ #include -#include -#include #include #include -#include "sirf-audio-port.h" - struct sirf_audio_port { struct regmap *regmap; struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data; }; -static void sirf_audio_port_tx_enable(struct sirf_audio_port *port) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, - IC_TX_ENABLE, IC_TX_ENABLE); -} - -static void sirf_audio_port_tx_disable(struct sirf_audio_port *port) -{ - regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, - IC_TX_ENABLE, ~IC_TX_ENABLE); -} - -static void sirf_audio_port_rx_enable(struct sirf_audio_port *port, - int channels) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); - regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); - regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); - regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, - AUDIO_FIFO_START, AUDIO_FIFO_START); - if (channels == 1) - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); - else - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); -} - -static void sirf_audio_port_rx_disable(struct sirf_audio_port *port) -{ - regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, - IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); -} static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) { @@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) return 0; } -static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (playback) - sirf_audio_port_tx_disable(port); - else - sirf_audio_port_rx_disable(port); - break; - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) - sirf_audio_port_tx_enable(port); - else - sirf_audio_port_rx_enable(port, - substream->runtime->channels); - break; - default: - return -EINVAL; - } - - return 0; -} - -static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = { - .trigger = sirf_audio_port_trigger, -}; - static struct snd_soc_dai_driver sirf_audio_port_dai = { .probe = sirf_audio_port_dai_probe, .name = "sirf-audio-port", @@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = { .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &sirf_audio_port_dai_ops, }; static const struct snd_soc_component_driver sirf_audio_port_component = { .name = "sirf-audio-port", }; -static const struct regmap_config sirf_audio_port_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, - .cache_type = REGCACHE_NONE, -}; - static int sirf_audio_port_probe(struct platform_device *pdev) { int ret; struct sirf_audio_port *port; - void __iomem *base; - struct resource *mem_res; port = devm_kzalloc(&pdev->dev, sizeof(struct sirf_audio_port), GFP_KERNEL); if (!port) return -ENOMEM; - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "no mem resource?\n"); - return -ENODEV; - } - - base = devm_ioremap(&pdev->dev, mem_res->start, - resource_size(mem_res)); - if (base == NULL) - return -ENOMEM; - - port->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &sirf_audio_port_regmap_config); - if (IS_ERR(port->regmap)) - return PTR_ERR(port->regmap); - ret = devm_snd_soc_register_component(&pdev->dev, &sirf_audio_port_component, &sirf_audio_port_dai, 1); if (ret) diff --git a/sound/soc/sirf/sirf-audio-port.h b/sound/soc/sirf/sirf-audio-port.h deleted file mode 100644 index f32dc54f4499..000000000000 --- a/sound/soc/sirf/sirf-audio-port.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * SiRF Audio port controllers define - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#ifndef _SIRF_AUDIO_PORT_H -#define _SIRF_AUDIO_PORT_H - -#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F -#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 -#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 -#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 - -#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_SC_OFFSET) -#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_LC_OFFSET) -#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_TX_FIFO_HC_OFFSET) - -#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F -#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 -#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 -#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 - -#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_SC_OFFSET) -#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_LC_OFFSET) -#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ - << AUDIO_PORT_RX_FIFO_HC_OFFSET) -#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) -#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) - -#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) -#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) -#define AUDIO_PORT_IC_TXFIFO_STS (0x0104) -#define AUDIO_PORT_IC_TXFIFO_INT (0x0108) -#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) - -#define AUDIO_PORT_IC_RXFIFO_OP (0x0110) -#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) -#define AUDIO_PORT_IC_RXFIFO_STS (0x0118) -#define AUDIO_PORT_IC_RXFIFO_INT (0x011C) -#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) - -#define AUDIO_FIFO_START (1 << 0) -#define AUDIO_FIFO_RESET (1 << 1) - -#define AUDIO_FIFO_FULL (1 << 0) -#define AUDIO_FIFO_EMPTY (1 << 1) -#define AUDIO_FIFO_OFLOW (1 << 2) -#define AUDIO_FIFO_UFLOW (1 << 3) - -#define IC_TX_ENABLE (0x03) -#define IC_RX_ENABLE_MONO (0x01) -#define IC_RX_ENABLE_STEREO (0x03) - -#endif /*__SIRF_AUDIO_PORT_H*/ -- cgit v1.2.3 From 2439ea1f0f8f4cc98dfae0d1cd5ba88f6c3ee9ad Mon Sep 17 00:00:00 2001 From: Sven Brandau Date: Wed, 2 Apr 2014 10:25:05 +0200 Subject: ASoC: sta350: Add codec driver The TI STA350 is an integrated 2.1-channel power amplifier that is controllable over I2C. This patch adds an ASoC driver for it. At a glance, this chip is very similar to the STA320 for which a driver already exists. In details, however, the register maps contain subtle differences which made a whole new driver easier to write and maintain. [daniel@zonque.org: cleanups, DT property rework, rebased on asoc-next] Signed-off-by: Sven Brandau Signed-off-by: Daniel Mack Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/st,sta350.txt | 107 ++ include/sound/sta350.h | 52 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/sta350.c | 1266 ++++++++++++++++++++ sound/soc/codecs/sta350.h | 228 ++++ 6 files changed, 1660 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/st,sta350.txt create mode 100644 include/sound/sta350.h create mode 100644 sound/soc/codecs/sta350.c create mode 100644 sound/soc/codecs/sta350.h (limited to 'sound') diff --git a/Documentation/devicetree/bindings/sound/st,sta350.txt b/Documentation/devicetree/bindings/sound/st,sta350.txt new file mode 100644 index 000000000000..950188891abd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/st,sta350.txt @@ -0,0 +1,107 @@ +STA350 audio CODEC + +The driver for this device only supports I2C. + +Required properties: + + - compatible: "st,sta350" + - reg: the I2C address of the device for I2C + - reset-gpios: a GPIO spec for the reset pin. If specified, it will be + deasserted before communication to the codec starts. + + - power-down-gpios: a GPIO spec for the power down pin. If specified, + it will be deasserted before communication to the codec + starts. + + - vdd-dig-supply: regulator spec, providing 3.3V + - vdd-pll-supply: regulator spec, providing 3.3V + - vcc-supply: regulator spec, providing 5V - 26V + +Optional properties: + + - st,output-conf: number, Selects the output configuration: + 0: 2-channel (full-bridge) power, 2-channel data-out + 1: 2 (half-bridge). 1 (full-bridge) on-board power + 2: 2 Channel (Full-Bridge) Power, 1 Channel FFX + 3: 1 Channel Mono-Parallel + If parameter is missing, mode 0 will be enabled. + + - st,ch1-output-mapping: Channel 1 output mapping + - st,ch2-output-mapping: Channel 2 output mapping + - st,ch3-output-mapping: Channel 3 output mapping + 0: Channel 1 + 1: Channel 2 + 2: Channel 3 + If parameter is missing, channel 1 is choosen. + + - st,thermal-warning-recover: + If present, thermal warning recovery is enabled. + + - st,thermal-warning-adjustment: + If present, thermal warning adjustment is enabled. + + - st,fault-detect-recovery: + If present, then fault recovery will be enabled. + + - st,ffx-power-output-mode: string + The FFX power output mode selects how the FFX output timing is + configured. Must be one of these values: + - "drop-compensation" + - "tapered-compensation" + - "full-power-mode" + - "variable-drop-compensation" (default) + + - st,drop-compensation-ns: number + Only required for "st,ffx-power-output-mode" == + "variable-drop-compensation". + Specifies the drop compensation in nanoseconds. + The value must be in the range of 0..300, and only + multiples of 20 are allowed. Default is 140ns. + + - st,overcurrent-warning-adjustment: + If present, overcurrent warning adjustment is enabled. + + - st,max-power-use-mpcc: + If present, then MPCC bits are used for MPC coefficients, + otherwise standard MPC coefficients are used. + + - st,max-power-corr: + If present, power bridge correction for THD reduction near maximum + power output is enabled. + + - st,am-reduction-mode: + If present, FFX mode runs in AM reduction mode, otherwise normal + FFX mode is used. + + - st,odd-pwm-speed-mode: + If present, PWM speed mode run on odd speed mode (341.3 kHz) on all + channels. If not present, normal PWM spped mode (384 kHz) will be used. + + - st,distortion-compensation: + If present, distortion compensation variable uses DCC coefficient. + If not present, preset DC coefficient is used. + + - st,invalid-input-detect-mute: + If not present, automatic invalid input detect mute is enabled. + + + +Example: + +codec: sta350@38 { + compatible = "st,sta350"; + reg = <0x1c>; + reset-gpios = <&gpio1 19 0>; + power-down-gpios = <&gpio1 16 0>; + st,output-conf = <0x3>; // set output to 2-channel + // (full-bridge) power, + // 2-channel data-out + st,ch1-output-mapping = <0>; // set channel 1 output ch 1 + st,ch2-output-mapping = <0>; // set channel 2 output ch 1 + st,ch3-output-mapping = <0>; // set channel 3 output ch 1 + st,max-power-correction; // enables power bridge + // correction for THD reduction + // near maximum power output + st,invalid-input-detect-mute; // mute if no valid digital + // audio signal is provided. +}; diff --git a/include/sound/sta350.h b/include/sound/sta350.h new file mode 100644 index 000000000000..3a3298106b22 --- /dev/null +++ b/include/sound/sta350.h @@ -0,0 +1,52 @@ +/* + * Platform data for ST STA350 ASoC codec driver. + * + * Copyright: 2014 Raumfeld GmbH + * Author: Sven Brandau + * + * 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. + */ +#ifndef __LINUX_SND__STA350_H +#define __LINUX_SND__STA350_H + +#define STA350_OCFG_2CH 0 +#define STA350_OCFG_2_1CH 1 +#define STA350_OCFG_1CH 3 + +#define STA350_OM_CH1 0 +#define STA350_OM_CH2 1 +#define STA350_OM_CH3 2 + +#define STA350_THERMAL_ADJUSTMENT_ENABLE 1 +#define STA350_THERMAL_RECOVERY_ENABLE 2 +#define STA350_FAULT_DETECT_RECOVERY_BYPASS 1 + +#define STA350_FFX_PM_DROP_COMP 0 +#define STA350_FFX_PM_TAPERED_COMP 1 +#define STA350_FFX_PM_FULL_POWER 2 +#define STA350_FFX_PM_VARIABLE_DROP_COMP 3 + + +struct sta350_platform_data { + u8 output_conf; + u8 ch1_output_mapping; + u8 ch2_output_mapping; + u8 ch3_output_mapping; + u8 ffx_power_output_mode; + u8 drop_compensation_ns; + unsigned int thermal_warning_recovery:1; + unsigned int thermal_warning_adjustment:1; + unsigned int fault_detect_recovery:1; + unsigned int oc_warning_adjustment:1; + unsigned int max_power_use_mpcc:1; + unsigned int max_power_correction:1; + unsigned int am_reduction_mode:1; + unsigned int odd_pwm_speed_mode:1; + unsigned int distortion_compensation:1; + unsigned int invalid_input_detect_mute:1; +}; + +#endif /* __LINUX_SND__STA350_H */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..c7b853f520cf 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -80,6 +80,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_SSM2602_SPI if SPI_MASTER select SND_SOC_SSM2602_I2C if I2C select SND_SOC_STA32X if I2C + select SND_SOC_STA350 if I2C select SND_SOC_STA529 if I2C select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TAS5086 if I2C @@ -435,6 +436,10 @@ config SND_SOC_SSM2602_I2C config SND_SOC_STA32X tristate +config SND_SOC_STA350 + tristate "STA350 speaker amplifier" + depends on I2C + config SND_SOC_STA529 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..efdb4d060201 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -74,6 +74,7 @@ snd-soc-ssm2602-objs := ssm2602.o snd-soc-ssm2602-spi-objs := ssm2602-spi.o snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o snd-soc-sta32x-objs := sta32x.o +snd-soc-sta350-objs := sta350.o snd-soc-sta529-objs := sta529.o snd-soc-stac9766-objs := stac9766.o snd-soc-tas5086-objs := tas5086.o @@ -221,6 +222,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o +obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c new file mode 100644 index 000000000000..552e92a6b770 --- /dev/null +++ b/sound/soc/codecs/sta350.c @@ -0,0 +1,1266 @@ +/* + * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system + * + * Copyright: 2014 Raumfeld GmbH + * Author: Sven Brandau + * + * based on code from: + * Raumfeld GmbH + * Johannes Stezenbach + * Wolfson Microelectronics PLC. + * Mark Brown + * Freescale Semiconductor, Inc. + * Timur Tabi + * + * 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. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "sta350.h" + +#define STA350_RATES (SNDRV_PCM_RATE_32000 | \ + SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | \ + SNDRV_PCM_RATE_88200 | \ + SNDRV_PCM_RATE_96000 | \ + SNDRV_PCM_RATE_176400 | \ + SNDRV_PCM_RATE_192000) + +#define STA350_FORMATS \ + (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ + SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ + SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + +/* Power-up register defaults */ +static const struct reg_default sta350_regs[] = { + { 0x0, 0x63 }, + { 0x1, 0x80 }, + { 0x2, 0xdf }, + { 0x3, 0x40 }, + { 0x4, 0xc2 }, + { 0x5, 0x5c }, + { 0x6, 0x00 }, + { 0x7, 0xff }, + { 0x8, 0x60 }, + { 0x9, 0x60 }, + { 0xa, 0x60 }, + { 0xb, 0x00 }, + { 0xc, 0x00 }, + { 0xd, 0x00 }, + { 0xe, 0x00 }, + { 0xf, 0x40 }, + { 0x10, 0x80 }, + { 0x11, 0x77 }, + { 0x12, 0x6a }, + { 0x13, 0x69 }, + { 0x14, 0x6a }, + { 0x15, 0x69 }, + { 0x16, 0x00 }, + { 0x17, 0x00 }, + { 0x18, 0x00 }, + { 0x19, 0x00 }, + { 0x1a, 0x00 }, + { 0x1b, 0x00 }, + { 0x1c, 0x00 }, + { 0x1d, 0x00 }, + { 0x1e, 0x00 }, + { 0x1f, 0x00 }, + { 0x20, 0x00 }, + { 0x21, 0x00 }, + { 0x22, 0x00 }, + { 0x23, 0x00 }, + { 0x24, 0x00 }, + { 0x25, 0x00 }, + { 0x26, 0x00 }, + { 0x27, 0x2a }, + { 0x28, 0xc0 }, + { 0x29, 0xf3 }, + { 0x2a, 0x33 }, + { 0x2b, 0x00 }, + { 0x2c, 0x0c }, + { 0x31, 0x00 }, + { 0x36, 0x00 }, + { 0x37, 0x00 }, + { 0x38, 0x00 }, + { 0x39, 0x01 }, + { 0x3a, 0xee }, + { 0x3b, 0xff }, + { 0x3c, 0x7e }, + { 0x3d, 0xc0 }, + { 0x3e, 0x26 }, + { 0x3f, 0x00 }, + { 0x48, 0x00 }, + { 0x49, 0x00 }, + { 0x4a, 0x00 }, + { 0x4b, 0x04 }, + { 0x4c, 0x00 }, +}; + +static const struct regmap_range sta350_write_regs_range[] = { + regmap_reg_range(STA350_CONFA, STA350_AUTO2), + regmap_reg_range(STA350_C1CFG, STA350_FDRC2), + regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), + regmap_reg_range(STA350_NSHAPE, STA350_MISC2), +}; + +static const struct regmap_range sta350_read_regs_range[] = { + regmap_reg_range(STA350_CONFA, STA350_AUTO2), + regmap_reg_range(STA350_C1CFG, STA350_STATUS), + regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), + regmap_reg_range(STA350_NSHAPE, STA350_MISC2), +}; + +static const struct regmap_range sta350_volatile_regs_range[] = { + regmap_reg_range(STA350_CFADDR2, STA350_CFUD), + regmap_reg_range(STA350_STATUS, STA350_STATUS), +}; + +static const struct regmap_access_table sta350_write_regs = { + .yes_ranges = sta350_write_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_write_regs_range), +}; + +static const struct regmap_access_table sta350_read_regs = { + .yes_ranges = sta350_read_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_read_regs_range), +}; + +static const struct regmap_access_table sta350_volatile_regs = { + .yes_ranges = sta350_volatile_regs_range, + .n_yes_ranges = ARRAY_SIZE(sta350_volatile_regs_range), +}; + +/* regulator power supply names */ +static const char * const sta350_supply_names[] = { + "vdd-dig", /* digital supply, 3.3V */ + "vdd-pll", /* pll supply, 3.3V */ + "vcc" /* power amp supply, 5V - 26V */ +}; + +/* codec private data */ +struct sta350_priv { + struct regmap *regmap; + struct regulator_bulk_data supplies[ARRAY_SIZE(sta350_supply_names)]; + struct sta350_platform_data *pdata; + + unsigned int mclk; + unsigned int format; + + u32 coef_shadow[STA350_COEF_COUNT]; + int shutdown; + + struct gpio_desc *gpiod_nreset; + struct gpio_desc *gpiod_power_down; + + struct mutex coeff_lock; +}; + +static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1); +static const DECLARE_TLV_DB_SCALE(tone_tlv, -1200, 200, 0); + +static const char * const sta350_drc_ac[] = { + "Anti-Clipping", "Dynamic Range Compression" +}; +static const char * const sta350_auto_gc_mode[] = { + "User", "AC no clipping", "AC limited clipping (10%)", + "DRC nighttime listening mode" +}; +static const char * const sta350_auto_xo_mode[] = { + "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", + "200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", + "340Hz", "360Hz" +}; +static const char * const sta350_binary_output[] = { + "FFX 3-state output - normal operation", "Binary output" +}; +static const char * const sta350_limiter_select[] = { + "Limiter Disabled", "Limiter #1", "Limiter #2" +}; +static const char * const sta350_limiter_attack_rate[] = { + "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024", + "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752", + "0.0645", "0.0564", "0.0501", "0.0451" +}; +static const char * const sta350_limiter_release_rate[] = { + "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299", + "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137", + "0.0134", "0.0117", "0.0110", "0.0104" +}; +static const char * const sta350_noise_shaper_type[] = { + "Third order", "Fourth order" +}; + +static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_attack_tlv, + 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0), + 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_release_tlv, + 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0), + 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0), + 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_attack_tlv, + 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0), + 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0), + 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0), +); + +static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_release_tlv, + 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), + 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0), + 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0), + 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0), + 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), +); + +static SOC_ENUM_SINGLE_DECL(sta350_drc_ac_enum, + STA350_CONFD, STA350_CONFD_DRC_SHIFT, + sta350_drc_ac); +static SOC_ENUM_SINGLE_DECL(sta350_noise_shaper_enum, + STA350_CONFE, STA350_CONFE_NSBW_SHIFT, + sta350_noise_shaper_type); +static SOC_ENUM_SINGLE_DECL(sta350_auto_gc_enum, + STA350_AUTO1, STA350_AUTO1_AMGC_SHIFT, + sta350_auto_gc_mode); +static SOC_ENUM_SINGLE_DECL(sta350_auto_xo_enum, + STA350_AUTO2, STA350_AUTO2_XO_SHIFT, + sta350_auto_xo_mode); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch1_enum, + STA350_C1CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch2_enum, + STA350_C2CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch3_enum, + STA350_C3CFG, STA350_CxCFG_BO_SHIFT, + sta350_binary_output); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch1_enum, + STA350_C1CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch2_enum, + STA350_C2CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch3_enum, + STA350_C3CFG, STA350_CxCFG_LS_SHIFT, + sta350_limiter_select); +static SOC_ENUM_SINGLE_DECL(sta350_limiter1_attack_rate_enum, + STA350_L1AR, STA350_LxA_SHIFT, + sta350_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter2_attack_rate_enum, + STA350_L2AR, STA350_LxA_SHIFT, + sta350_limiter_attack_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter1_release_rate_enum, + STA350_L1AR, STA350_LxR_SHIFT, + sta350_limiter_release_rate); +static SOC_ENUM_SINGLE_DECL(sta350_limiter2_release_rate_enum, + STA350_L2AR, STA350_LxR_SHIFT, + sta350_limiter_release_rate); + +/* + * byte array controls for setting biquad, mixer, scaling coefficients; + * for biquads all five coefficients need to be set in one go, + * mixer and pre/postscale coefs can be set individually; + * each coef is 24bit, the bytes are ordered in the same way + * as given in the STA350 data sheet (big endian; b1, b2, a1, a2, b0) + */ + +static int sta350_coefficient_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + int numcoef = kcontrol->private_value >> 16; + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = 3 * numcoef; + return 0; +} + +static int sta350_coefficient_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int numcoef = kcontrol->private_value >> 16; + int index = kcontrol->private_value & 0xffff; + unsigned int cfud, val; + int i, ret = 0; + + mutex_lock(&sta350->coeff_lock); + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + /* + * chip documentation does not say if the bits are self clearing, + * so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + + regmap_write(sta350->regmap, STA350_CFADDR2, index); + if (numcoef == 1) { + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x04); + } else if (numcoef == 5) { + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x08); + } else { + ret = -EINVAL; + goto exit_unlock; + } + + for (i = 0; i < 3 * numcoef; i++) { + regmap_read(sta350->regmap, STA350_B1CF1 + i, &val); + ucontrol->value.bytes.data[i] = val; + } + +exit_unlock: + mutex_unlock(&sta350->coeff_lock); + + return ret; +} + +static int sta350_coefficient_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int numcoef = kcontrol->private_value >> 16; + int index = kcontrol->private_value & 0xffff; + unsigned int cfud; + int i; + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + /* + * chip documentation does not say if the bits are self clearing, + * so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + + regmap_write(sta350->regmap, STA350_CFADDR2, index); + for (i = 0; i < numcoef && (index + i < STA350_COEF_COUNT); i++) + sta350->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++) + regmap_write(sta350->regmap, STA350_B1CF1 + i, + ucontrol->value.bytes.data[i]); + if (numcoef == 1) + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); + else if (numcoef == 5) + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x02); + else + return -EINVAL; + + return 0; +} + +static int sta350_sync_coef_shadow(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int cfud; + int i; + + /* preserve reserved bits in STA350_CFUD */ + regmap_read(sta350->regmap, STA350_CFUD, &cfud); + cfud &= 0xf0; + + for (i = 0; i < STA350_COEF_COUNT; i++) { + regmap_write(sta350->regmap, STA350_CFADDR2, i); + regmap_write(sta350->regmap, STA350_B1CF1, + (sta350->coef_shadow[i] >> 16) & 0xff); + regmap_write(sta350->regmap, STA350_B1CF2, + (sta350->coef_shadow[i] >> 8) & 0xff); + regmap_write(sta350->regmap, STA350_B1CF3, + (sta350->coef_shadow[i]) & 0xff); + /* + * chip documentation does not say if the bits are + * self-clearing, so do it explicitly + */ + regmap_write(sta350->regmap, STA350_CFUD, cfud); + regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); + } + return 0; +} + +static int sta350_cache_sync(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int mute; + int rc; + + /* mute during register sync */ + regmap_read(sta350->regmap, STA350_CFUD, &mute); + regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE); + sta350_sync_coef_shadow(codec); + rc = regcache_sync(sta350->regmap); + regmap_write(sta350->regmap, STA350_MMUTE, mute); + return rc; +} + +#define SINGLE_COEF(xname, index) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = sta350_coefficient_info, \ + .get = sta350_coefficient_get,\ + .put = sta350_coefficient_put, \ + .private_value = index | (1 << 16) } + +#define BIQUAD_COEFS(xname, index) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = sta350_coefficient_info, \ + .get = sta350_coefficient_get,\ + .put = sta350_coefficient_put, \ + .private_value = index | (5 << 16) } + +static const struct snd_kcontrol_new sta350_snd_controls[] = { +SOC_SINGLE_TLV("Master Volume", STA350_MVOL, 0, 0xff, 1, mvol_tlv), +/* VOL */ +SOC_SINGLE_TLV("Ch1 Volume", STA350_C1VOL, 0, 0xff, 1, chvol_tlv), +SOC_SINGLE_TLV("Ch2 Volume", STA350_C2VOL, 0, 0xff, 1, chvol_tlv), +SOC_SINGLE_TLV("Ch3 Volume", STA350_C3VOL, 0, 0xff, 1, chvol_tlv), +/* CONFD */ +SOC_SINGLE("High Pass Filter Bypass Switch", + STA350_CONFD, STA350_CONFD_HPB_SHIFT, 1, 1), +SOC_SINGLE("De-emphasis Filter Switch", + STA350_CONFD, STA350_CONFD_DEMP_SHIFT, 1, 0), +SOC_SINGLE("DSP Bypass Switch", + STA350_CONFD, STA350_CONFD_DSPB_SHIFT, 1, 0), +SOC_SINGLE("Post-scale Link Switch", + STA350_CONFD, STA350_CONFD_PSL_SHIFT, 1, 0), +SOC_SINGLE("Biquad Coefficient Link Switch", + STA350_CONFD, STA350_CONFD_BQL_SHIFT, 1, 0), +SOC_ENUM("Compressor/Limiter Switch", sta350_drc_ac_enum), +SOC_ENUM("Noise Shaper Bandwidth", sta350_noise_shaper_enum), +SOC_SINGLE("Zero-detect Mute Enable Switch", + STA350_CONFD, STA350_CONFD_ZDE_SHIFT, 1, 0), +SOC_SINGLE("Submix Mode Switch", + STA350_CONFD, STA350_CONFD_SME_SHIFT, 1, 0), +/* CONFE */ +SOC_SINGLE("Zero Cross Switch", STA350_CONFE, STA350_CONFE_ZCE_SHIFT, 1, 0), +SOC_SINGLE("Soft Ramp Switch", STA350_CONFE, STA350_CONFE_SVE_SHIFT, 1, 0), +/* MUTE */ +SOC_SINGLE("Master Switch", STA350_MMUTE, STA350_MMUTE_MMUTE_SHIFT, 1, 1), +SOC_SINGLE("Ch1 Switch", STA350_MMUTE, STA350_MMUTE_C1M_SHIFT, 1, 1), +SOC_SINGLE("Ch2 Switch", STA350_MMUTE, STA350_MMUTE_C2M_SHIFT, 1, 1), +SOC_SINGLE("Ch3 Switch", STA350_MMUTE, STA350_MMUTE_C3M_SHIFT, 1, 1), +/* AUTOx */ +SOC_ENUM("Automode GC", sta350_auto_gc_enum), +SOC_ENUM("Automode XO", sta350_auto_xo_enum), +/* CxCFG */ +SOC_SINGLE("Ch1 Tone Control Bypass Switch", + STA350_C1CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), +SOC_SINGLE("Ch2 Tone Control Bypass Switch", + STA350_C2CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), +SOC_SINGLE("Ch1 EQ Bypass Switch", + STA350_C1CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), +SOC_SINGLE("Ch2 EQ Bypass Switch", + STA350_C2CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), +SOC_SINGLE("Ch1 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_SINGLE("Ch2 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_SINGLE("Ch3 Master Volume Bypass Switch", + STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), +SOC_ENUM("Ch1 Binary Output Select", sta350_binary_output_ch1_enum), +SOC_ENUM("Ch2 Binary Output Select", sta350_binary_output_ch2_enum), +SOC_ENUM("Ch3 Binary Output Select", sta350_binary_output_ch3_enum), +SOC_ENUM("Ch1 Limiter Select", sta350_limiter_ch1_enum), +SOC_ENUM("Ch2 Limiter Select", sta350_limiter_ch2_enum), +SOC_ENUM("Ch3 Limiter Select", sta350_limiter_ch3_enum), +/* TONE */ +SOC_SINGLE_RANGE_TLV("Bass Tone Control Volume", + STA350_TONE, STA350_TONE_BTC_SHIFT, 1, 13, 0, tone_tlv), +SOC_SINGLE_RANGE_TLV("Treble Tone Control Volume", + STA350_TONE, STA350_TONE_TTC_SHIFT, 1, 13, 0, tone_tlv), +SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta350_limiter1_attack_rate_enum), +SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta350_limiter2_attack_rate_enum), +SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta350_limiter1_release_rate_enum), +SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta350_limiter2_release_rate_enum), + +/* + * depending on mode, the attack/release thresholds have + * two different enum definitions; provide both + */ +SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", + STA350_L1ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_ac_attack_tlv), +SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", + STA350_L2ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_ac_attack_tlv), +SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", + STA350_L1ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_ac_release_tlv), +SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", + STA350_L2ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_ac_release_tlv), +SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", + STA350_L1ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_drc_attack_tlv), +SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", + STA350_L2ATRT, STA350_LxA_SHIFT, + 16, 0, sta350_limiter_drc_attack_tlv), +SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", + STA350_L1ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_drc_release_tlv), +SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", + STA350_L2ATRT, STA350_LxR_SHIFT, + 16, 0, sta350_limiter_drc_release_tlv), + +BIQUAD_COEFS("Ch1 - Biquad 1", 0), +BIQUAD_COEFS("Ch1 - Biquad 2", 5), +BIQUAD_COEFS("Ch1 - Biquad 3", 10), +BIQUAD_COEFS("Ch1 - Biquad 4", 15), +BIQUAD_COEFS("Ch2 - Biquad 1", 20), +BIQUAD_COEFS("Ch2 - Biquad 2", 25), +BIQUAD_COEFS("Ch2 - Biquad 3", 30), +BIQUAD_COEFS("Ch2 - Biquad 4", 35), +BIQUAD_COEFS("High-pass", 40), +BIQUAD_COEFS("Low-pass", 45), +SINGLE_COEF("Ch1 - Prescale", 50), +SINGLE_COEF("Ch2 - Prescale", 51), +SINGLE_COEF("Ch1 - Postscale", 52), +SINGLE_COEF("Ch2 - Postscale", 53), +SINGLE_COEF("Ch3 - Postscale", 54), +SINGLE_COEF("Thermal warning - Postscale", 55), +SINGLE_COEF("Ch1 - Mix 1", 56), +SINGLE_COEF("Ch1 - Mix 2", 57), +SINGLE_COEF("Ch2 - Mix 1", 58), +SINGLE_COEF("Ch2 - Mix 2", 59), +SINGLE_COEF("Ch3 - Mix 1", 60), +SINGLE_COEF("Ch3 - Mix 2", 61), +}; + +static const struct snd_soc_dapm_widget sta350_dapm_widgets[] = { +SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), +SND_SOC_DAPM_OUTPUT("LEFT"), +SND_SOC_DAPM_OUTPUT("RIGHT"), +SND_SOC_DAPM_OUTPUT("SUB"), +}; + +static const struct snd_soc_dapm_route sta350_dapm_routes[] = { + { "LEFT", NULL, "DAC" }, + { "RIGHT", NULL, "DAC" }, + { "SUB", NULL, "DAC" }, + { "DAC", NULL, "Playback" }, +}; + +/* MCLK interpolation ratio per fs */ +static struct { + int fs; + int ir; +} interpolation_ratios[] = { + { 32000, 0 }, + { 44100, 0 }, + { 48000, 0 }, + { 88200, 1 }, + { 96000, 1 }, + { 176400, 2 }, + { 192000, 2 }, +}; + +/* MCLK to fs clock ratios */ +static int mcs_ratio_table[3][6] = { + { 768, 512, 384, 256, 128, 576 }, + { 384, 256, 192, 128, 64, 0 }, + { 192, 128, 96, 64, 32, 0 }, +}; + +/** + * sta350_set_dai_sysclk - configure MCLK + * @codec_dai: the codec DAI + * @clk_id: the clock ID (ignored) + * @freq: the MCLK input frequency + * @dir: the clock direction (ignored) + * + * The value of MCLK is used to determine which sample rates are supported + * by the STA350, based on the mcs_ratio_table. + * + * This function must be called by the machine driver's 'startup' function, + * otherwise the list of supported sample rates will not be available in + * time for ALSA. + */ +static int sta350_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 sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(codec->dev, "mclk=%u\n", freq); + sta350->mclk = freq; + + return 0; +} + +/** + * sta350_set_dai_fmt - configure the codec for the selected audio format + * @codec_dai: the codec DAI + * @fmt: a SND_SOC_DAIFMT_x value indicating the data format + * + * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the + * codec accordingly. + */ +static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + unsigned int confb = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + sta350->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + confb |= STA350_CONFB_C2IM; + break; + case SND_SOC_DAIFMT_NB_IF: + confb |= STA350_CONFB_C1IM; + break; + default: + return -EINVAL; + } + + return regmap_update_bits(sta350->regmap, STA350_CONFB, + STA350_CONFB_C1IM | STA350_CONFB_C2IM, confb); +} + +/** + * sta350_hw_params - program the STA350 with the given hardware parameters. + * @substream: the audio stream + * @params: the hardware parameters to set + * @dai: the SOC DAI (ignored) + * + * This function programs the hardware with the values provided. + * Specifically, the sample rate and the data format. + */ +static int sta350_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int i, mcs = -EINVAL, ir = -EINVAL; + unsigned int confa, confb; + unsigned int rate, ratio; + int ret; + + if (!sta350->mclk) { + dev_err(codec->dev, + "sta350->mclk is unset. Unable to determine ratio\n"); + return -EIO; + } + + rate = params_rate(params); + ratio = sta350->mclk / rate; + dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio); + + for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) { + if (interpolation_ratios[i].fs == rate) { + ir = interpolation_ratios[i].ir; + break; + } + } + + if (ir < 0) { + dev_err(codec->dev, "Unsupported samplerate: %u\n", rate); + return -EINVAL; + } + + for (i = 0; i < 6; i++) { + if (mcs_ratio_table[ir][i] == ratio) { + mcs = i; + break; + } + } + + if (mcs < 0) { + dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio); + return -EINVAL; + } + + confa = (ir << STA350_CONFA_IR_SHIFT) | + (mcs << STA350_CONFA_MCS_SHIFT); + confb = 0; + + switch (params_width(params)) { + case 24: + dev_dbg(codec->dev, "24bit\n"); + /* fall through */ + case 32: + dev_dbg(codec->dev, "24bit or 32bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x0; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x1; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0x2; + break; + } + + break; + case 20: + dev_dbg(codec->dev, "20bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x4; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x5; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0x6; + break; + } + + break; + case 18: + dev_dbg(codec->dev, "18bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x8; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0x9; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0xa; + break; + } + + break; + case 16: + dev_dbg(codec->dev, "16bit\n"); + switch (sta350->format) { + case SND_SOC_DAIFMT_I2S: + confb |= 0x0; + break; + case SND_SOC_DAIFMT_LEFT_J: + confb |= 0xd; + break; + case SND_SOC_DAIFMT_RIGHT_J: + confb |= 0xe; + break; + } + + break; + default: + return -EINVAL; + } + + ret = regmap_update_bits(sta350->regmap, STA350_CONFA, + STA350_CONFA_MCS_MASK | STA350_CONFA_IR_MASK, + confa); + if (ret < 0) + return ret; + + ret = regmap_update_bits(sta350->regmap, STA350_CONFB, + STA350_CONFB_SAI_MASK | STA350_CONFB_SAIFB, + confb); + if (ret < 0) + return ret; + + return 0; +} + +static int sta350_startup_sequence(struct sta350_priv *sta350) +{ + if (sta350->gpiod_power_down) + gpiod_set_value(sta350->gpiod_power_down, 1); + + if (sta350->gpiod_nreset) { + gpiod_set_value(sta350->gpiod_nreset, 0); + mdelay(1); + gpiod_set_value(sta350->gpiod_nreset, 1); + mdelay(1); + } + + return 0; +} + +/** + * sta350_set_bias_level - DAPM callback + * @codec: the codec device + * @level: DAPM power level + * + * This is called by ALSA to put the codec into low power mode + * or to wake it up. If the codec is powered off completely + * all registers must be restored after power on. + */ +static int sta350_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + int ret; + + dev_dbg(codec->dev, "level = %d\n", level); + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* Full power on */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, + STA350_CONFF_PWDN | STA350_CONFF_EAPD); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable( + ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + sta350_startup_sequence(sta350); + sta350_cache_sync(codec); + } + + /* Power down */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, + 0); + + break; + + case SND_SOC_BIAS_OFF: + /* The chip runs through the power down sequence for us */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_PWDN | STA350_CONFF_EAPD, 0); + + /* power down: low */ + if (sta350->gpiod_power_down) + gpiod_set_value(sta350->gpiod_power_down, 0); + + if (sta350->gpiod_nreset) + gpiod_set_value(sta350->gpiod_nreset, 0); + + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), + sta350->supplies); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +static const struct snd_soc_dai_ops sta350_dai_ops = { + .hw_params = sta350_hw_params, + .set_sysclk = sta350_set_dai_sysclk, + .set_fmt = sta350_set_dai_fmt, +}; + +static struct snd_soc_dai_driver sta350_dai = { + .name = "sta350-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = STA350_RATES, + .formats = STA350_FORMATS, + }, + .ops = &sta350_dai_ops, +}; + +#ifdef CONFIG_PM +static int sta350_suspend(struct snd_soc_codec *codec) +{ + sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int sta350_resume(struct snd_soc_codec *codec) +{ + sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define sta350_suspend NULL +#define sta350_resume NULL +#endif + +static int sta350_probe(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + struct sta350_platform_data *pdata = sta350->pdata; + int i, ret = 0, thermal = 0; + + ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + return ret; + } + + ret = sta350_startup_sequence(sta350); + if (ret < 0) { + dev_err(codec->dev, "Failed to startup device\n"); + return ret; + } + + /* CONFA */ + if (!pdata->thermal_warning_recovery) + thermal |= STA350_CONFA_TWAB; + if (!pdata->thermal_warning_adjustment) + thermal |= STA350_CONFA_TWRB; + if (!pdata->fault_detect_recovery) + thermal |= STA350_CONFA_FDRB; + regmap_update_bits(sta350->regmap, STA350_CONFA, + STA350_CONFA_TWAB | STA350_CONFA_TWRB | + STA350_CONFA_FDRB, + thermal); + + /* CONFC */ + regmap_update_bits(sta350->regmap, STA350_CONFC, + STA350_CONFC_OM_MASK, + pdata->ffx_power_output_mode + << STA350_CONFC_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_CONFC, + STA350_CONFC_CSZ_MASK, + pdata->drop_compensation_ns + << STA350_CONFC_CSZ_SHIFT); + regmap_update_bits(sta350->regmap, + STA350_CONFC, + STA350_CONFC_OCRB, + pdata->oc_warning_adjustment ? + STA350_CONFC_OCRB : 0); + + /* CONFE */ + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_MPCV, + pdata->max_power_use_mpcc ? + STA350_CONFE_MPCV : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_MPC, + pdata->max_power_correction ? + STA350_CONFE_MPC : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_AME, + pdata->am_reduction_mode ? + STA350_CONFE_AME : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_PWMS, + pdata->odd_pwm_speed_mode ? + STA350_CONFE_PWMS : 0); + regmap_update_bits(sta350->regmap, STA350_CONFE, + STA350_CONFE_DCCV, + pdata->distortion_compensation ? + STA350_CONFE_DCCV : 0); + /* CONFF */ + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_IDE, + pdata->invalid_input_detect_mute ? + STA350_CONFF_IDE : 0); + regmap_update_bits(sta350->regmap, STA350_CONFF, + STA350_CONFF_OCFG_MASK, + pdata->output_conf + << STA350_CONFF_OCFG_SHIFT); + + /* channel to output mapping */ + regmap_update_bits(sta350->regmap, STA350_C1CFG, + STA350_CxCFG_OM_MASK, + pdata->ch1_output_mapping + << STA350_CxCFG_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_C2CFG, + STA350_CxCFG_OM_MASK, + pdata->ch2_output_mapping + << STA350_CxCFG_OM_SHIFT); + regmap_update_bits(sta350->regmap, STA350_C3CFG, + STA350_CxCFG_OM_MASK, + pdata->ch3_output_mapping + << STA350_CxCFG_OM_SHIFT); + + /* initialize coefficient shadow RAM with reset values */ + for (i = 4; i <= 49; i += 5) + sta350->coef_shadow[i] = 0x400000; + for (i = 50; i <= 54; i++) + sta350->coef_shadow[i] = 0x7fffff; + sta350->coef_shadow[55] = 0x5a9df7; + sta350->coef_shadow[56] = 0x7fffff; + sta350->coef_shadow[59] = 0x7fffff; + sta350->coef_shadow[60] = 0x400000; + sta350->coef_shadow[61] = 0x400000; + + sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); + + return 0; +} + +static int sta350_remove(struct snd_soc_codec *codec) +{ + struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); + + sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); + regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); + + return 0; +} + +static const struct snd_soc_codec_driver sta350_codec = { + .probe = sta350_probe, + .remove = sta350_remove, + .suspend = sta350_suspend, + .resume = sta350_resume, + .set_bias_level = sta350_set_bias_level, + .controls = sta350_snd_controls, + .num_controls = ARRAY_SIZE(sta350_snd_controls), + .dapm_widgets = sta350_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), + .dapm_routes = sta350_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), +}; + +static const struct regmap_config sta350_regmap = { + .reg_bits = 8, + .val_bits = 8, + .max_register = STA350_MISC2, + .reg_defaults = sta350_regs, + .num_reg_defaults = ARRAY_SIZE(sta350_regs), + .cache_type = REGCACHE_RBTREE, + .wr_table = &sta350_write_regs, + .rd_table = &sta350_read_regs, + .volatile_table = &sta350_volatile_regs, +}; + +#ifdef CONFIG_OF +static const struct of_device_id st350_dt_ids[] = { + { .compatible = "st,sta350", }, + { } +}; +MODULE_DEVICE_TABLE(of, st350_dt_ids); + +static const char * const sta350_ffx_modes[] = { + [STA350_FFX_PM_DROP_COMP] = "drop-compensation", + [STA350_FFX_PM_TAPERED_COMP] = "tapered-compensation", + [STA350_FFX_PM_FULL_POWER] = "full-power-mode", + [STA350_FFX_PM_VARIABLE_DROP_COMP] = "variable-drop-compensation", +}; + +static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) +{ + struct device_node *np = dev->of_node; + struct sta350_platform_data *pdata; + const char *ffx_power_mode; + u16 tmp; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + of_property_read_u8(np, "st,output-conf", + &pdata->output_conf); + of_property_read_u8(np, "st,ch1-output-mapping", + &pdata->ch1_output_mapping); + of_property_read_u8(np, "st,ch2-output-mapping", + &pdata->ch2_output_mapping); + of_property_read_u8(np, "st,ch3-output-mapping", + &pdata->ch3_output_mapping); + + if (of_get_property(np, "st,thermal-warning-recovery", NULL)) + pdata->thermal_warning_recovery = 1; + if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) + pdata->thermal_warning_adjustment = 1; + if (of_get_property(np, "st,fault-detect-recovery", NULL)) + pdata->fault_detect_recovery = 1; + + pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP; + if (!of_property_read_string(np, "st,ffx-power-output-mode", + &ffx_power_mode)) { + int i, mode = -EINVAL; + + for (i = 0; i < ARRAY_SIZE(sta350_ffx_modes); i++) + if (!strcasecmp(ffx_power_mode, sta350_ffx_modes[i])) + mode = i; + + if (mode < 0) + dev_warn(dev, "Unsupported ffx output mode: %s\n", + ffx_power_mode); + else + pdata->ffx_power_output_mode = mode; + } + + tmp = 140; + of_property_read_u16(np, "st,drop-compensation-ns", &tmp); + pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; + + if (of_get_property(np, "st,overcurrent-warning-adjustment", NULL)) + pdata->oc_warning_adjustment = 1; + + /* CONFE */ + if (of_get_property(np, "st,max-power-use-mpcc", NULL)) + pdata->max_power_use_mpcc = 1; + + if (of_get_property(np, "st,max-power-correction", NULL)) + pdata->max_power_correction = 1; + + if (of_get_property(np, "st,am-reduction-mode", NULL)) + pdata->am_reduction_mode = 1; + + if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) + pdata->odd_pwm_speed_mode = 1; + + if (of_get_property(np, "st,distortion-compensation", NULL)) + pdata->distortion_compensation = 1; + + /* CONFF */ + if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) + pdata->invalid_input_detect_mute = 1; + + sta350->pdata = pdata; + + return 0; +} +#endif + +static int sta350_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct device *dev = &i2c->dev; + struct sta350_priv *sta350; + int ret, i; + + sta350 = devm_kzalloc(dev, sizeof(struct sta350_priv), GFP_KERNEL); + if (!sta350) + return -ENOMEM; + + mutex_init(&sta350->coeff_lock); + sta350->pdata = dev_get_platdata(dev); + +#ifdef CONFIG_OF + if (dev->of_node) { + ret = sta350_probe_dt(dev, sta350); + if (ret < 0) + return ret; + } +#endif + + /* GPIOs */ + sta350->gpiod_nreset = devm_gpiod_get(dev, "reset"); + if (IS_ERR(sta350->gpiod_nreset)) { + ret = PTR_ERR(sta350->gpiod_nreset); + if (ret != -ENOENT && ret != -ENOSYS) + return ret; + + sta350->gpiod_nreset = NULL; + } else { + gpiod_direction_output(sta350->gpiod_nreset, 0); + } + + sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down"); + if (IS_ERR(sta350->gpiod_power_down)) { + ret = PTR_ERR(sta350->gpiod_power_down); + if (ret != -ENOENT && ret != -ENOSYS) + return ret; + + sta350->gpiod_power_down = NULL; + } else { + gpiod_direction_output(sta350->gpiod_power_down, 0); + } + + /* regulators */ + for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++) + sta350->supplies[i].supply = sta350_supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sta350->supplies), + sta350->supplies); + if (ret < 0) { + dev_err(dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + sta350->regmap = devm_regmap_init_i2c(i2c, &sta350_regmap); + if (IS_ERR(sta350->regmap)) { + ret = PTR_ERR(sta350->regmap); + dev_err(dev, "Failed to init regmap: %d\n", ret); + return ret; + } + + i2c_set_clientdata(i2c, sta350); + + ret = snd_soc_register_codec(dev, &sta350_codec, &sta350_dai, 1); + if (ret < 0) + dev_err(dev, "Failed to register codec (%d)\n", ret); + + return ret; +} + +static int sta350_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + return 0; +} + +static const struct i2c_device_id sta350_i2c_id[] = { + { "sta350", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, sta350_i2c_id); + +static struct i2c_driver sta350_i2c_driver = { + .driver = { + .name = "sta350", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(st350_dt_ids), + }, + .probe = sta350_i2c_probe, + .remove = sta350_i2c_remove, + .id_table = sta350_i2c_id, +}; + +module_i2c_driver(sta350_i2c_driver); + +MODULE_DESCRIPTION("ASoC STA350 driver"); +MODULE_AUTHOR("Sven Brandau "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/sta350.h b/sound/soc/codecs/sta350.h new file mode 100644 index 000000000000..c3248f0fad2c --- /dev/null +++ b/sound/soc/codecs/sta350.h @@ -0,0 +1,228 @@ +/* + * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system + * + * Copyright: 2011 Raumfeld GmbH + * Author: Sven Brandau + * + * based on code from: + * Raumfeld GmbH + * Johannes Stezenbach + * Wolfson Microelectronics PLC. + * Mark Brown + * + * 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. + */ +#ifndef _ASOC_STA_350_H +#define _ASOC_STA_350_H + +/* STA50 register addresses */ + +#define STA350_REGISTER_COUNT 0x4D +#define STA350_COEF_COUNT 62 + +#define STA350_CONFA 0x00 +#define STA350_CONFB 0x01 +#define STA350_CONFC 0x02 +#define STA350_CONFD 0x03 +#define STA350_CONFE 0x04 +#define STA350_CONFF 0x05 +#define STA350_MMUTE 0x06 +#define STA350_MVOL 0x07 +#define STA350_C1VOL 0x08 +#define STA350_C2VOL 0x09 +#define STA350_C3VOL 0x0a +#define STA350_AUTO1 0x0b +#define STA350_AUTO2 0x0c +#define STA350_AUTO3 0x0d +#define STA350_C1CFG 0x0e +#define STA350_C2CFG 0x0f +#define STA350_C3CFG 0x10 +#define STA350_TONE 0x11 +#define STA350_L1AR 0x12 +#define STA350_L1ATRT 0x13 +#define STA350_L2AR 0x14 +#define STA350_L2ATRT 0x15 +#define STA350_CFADDR2 0x16 +#define STA350_B1CF1 0x17 +#define STA350_B1CF2 0x18 +#define STA350_B1CF3 0x19 +#define STA350_B2CF1 0x1a +#define STA350_B2CF2 0x1b +#define STA350_B2CF3 0x1c +#define STA350_A1CF1 0x1d +#define STA350_A1CF2 0x1e +#define STA350_A1CF3 0x1f +#define STA350_A2CF1 0x20 +#define STA350_A2CF2 0x21 +#define STA350_A2CF3 0x22 +#define STA350_B0CF1 0x23 +#define STA350_B0CF2 0x24 +#define STA350_B0CF3 0x25 +#define STA350_CFUD 0x26 +#define STA350_MPCC1 0x27 +#define STA350_MPCC2 0x28 +#define STA350_DCC1 0x29 +#define STA350_DCC2 0x2a +#define STA350_FDRC1 0x2b +#define STA350_FDRC2 0x2c +#define STA350_STATUS 0x2d +/* reserved: 0x2d - 0x30 */ +#define STA350_EQCFG 0x31 +#define STA350_EATH1 0x32 +#define STA350_ERTH1 0x33 +#define STA350_EATH2 0x34 +#define STA350_ERTH2 0x35 +#define STA350_CONFX 0x36 +#define STA350_SVCA 0x37 +#define STA350_SVCB 0x38 +#define STA350_RMS0A 0x39 +#define STA350_RMS0B 0x3a +#define STA350_RMS0C 0x3b +#define STA350_RMS1A 0x3c +#define STA350_RMS1B 0x3d +#define STA350_RMS1C 0x3e +#define STA350_EVOLRES 0x3f +/* reserved: 0x40 - 0x47 */ +#define STA350_NSHAPE 0x48 +#define STA350_CTXB4B1 0x49 +#define STA350_CTXB7B5 0x4a +#define STA350_MISC1 0x4b +#define STA350_MISC2 0x4c + +/* 0x00 CONFA */ +#define STA350_CONFA_MCS_MASK 0x03 +#define STA350_CONFA_MCS_SHIFT 0 +#define STA350_CONFA_IR_MASK 0x18 +#define STA350_CONFA_IR_SHIFT 3 +#define STA350_CONFA_TWRB BIT(5) +#define STA350_CONFA_TWAB BIT(6) +#define STA350_CONFA_FDRB BIT(7) + +/* 0x01 CONFB */ +#define STA350_CONFB_SAI_MASK 0x0f +#define STA350_CONFB_SAI_SHIFT 0 +#define STA350_CONFB_SAIFB BIT(4) +#define STA350_CONFB_DSCKE BIT(5) +#define STA350_CONFB_C1IM BIT(6) +#define STA350_CONFB_C2IM BIT(7) + +/* 0x02 CONFC */ +#define STA350_CONFC_OM_MASK 0x03 +#define STA350_CONFC_OM_SHIFT 0 +#define STA350_CONFC_CSZ_MASK 0x3c +#define STA350_CONFC_CSZ_SHIFT 2 +#define STA350_CONFC_OCRB BIT(7) + +/* 0x03 CONFD */ +#define STA350_CONFD_HPB_SHIFT 0 +#define STA350_CONFD_DEMP_SHIFT 1 +#define STA350_CONFD_DSPB_SHIFT 2 +#define STA350_CONFD_PSL_SHIFT 3 +#define STA350_CONFD_BQL_SHIFT 4 +#define STA350_CONFD_DRC_SHIFT 5 +#define STA350_CONFD_ZDE_SHIFT 6 +#define STA350_CONFD_SME_SHIFT 7 + +/* 0x04 CONFE */ +#define STA350_CONFE_MPCV BIT(0) +#define STA350_CONFE_MPCV_SHIFT 0 +#define STA350_CONFE_MPC BIT(1) +#define STA350_CONFE_MPC_SHIFT 1 +#define STA350_CONFE_NSBW BIT(2) +#define STA350_CONFE_NSBW_SHIFT 2 +#define STA350_CONFE_AME BIT(3) +#define STA350_CONFE_AME_SHIFT 3 +#define STA350_CONFE_PWMS BIT(4) +#define STA350_CONFE_PWMS_SHIFT 4 +#define STA350_CONFE_DCCV BIT(5) +#define STA350_CONFE_DCCV_SHIFT 5 +#define STA350_CONFE_ZCE BIT(6) +#define STA350_CONFE_ZCE_SHIFT 6 +#define STA350_CONFE_SVE BIT(7) +#define STA350_CONFE_SVE_SHIFT 7 + +/* 0x05 CONFF */ +#define STA350_CONFF_OCFG_MASK 0x03 +#define STA350_CONFF_OCFG_SHIFT 0 +#define STA350_CONFF_IDE BIT(2) +#define STA350_CONFF_BCLE BIT(3) +#define STA350_CONFF_LDTE BIT(4) +#define STA350_CONFF_ECLE BIT(5) +#define STA350_CONFF_PWDN BIT(6) +#define STA350_CONFF_EAPD BIT(7) + +/* 0x06 MMUTE */ +#define STA350_MMUTE_MMUTE 0x01 +#define STA350_MMUTE_MMUTE_SHIFT 0 +#define STA350_MMUTE_C1M 0x02 +#define STA350_MMUTE_C1M_SHIFT 1 +#define STA350_MMUTE_C2M 0x04 +#define STA350_MMUTE_C2M_SHIFT 2 +#define STA350_MMUTE_C3M 0x08 +#define STA350_MMUTE_C3M_SHIFT 3 +#define STA350_MMUTE_LOC_MASK 0xC0 +#define STA350_MMUTE_LOC_SHIFT 6 + +/* 0x0b AUTO1 */ +#define STA350_AUTO1_AMGC_MASK 0x30 +#define STA350_AUTO1_AMGC_SHIFT 4 + +/* 0x0c AUTO2 */ +#define STA350_AUTO2_AMAME 0x01 +#define STA350_AUTO2_AMAM_MASK 0x0e +#define STA350_AUTO2_AMAM_SHIFT 1 +#define STA350_AUTO2_XO_MASK 0xf0 +#define STA350_AUTO2_XO_SHIFT 4 + +/* 0x0d AUTO3 */ +#define STA350_AUTO3_PEQ_MASK 0x1f +#define STA350_AUTO3_PEQ_SHIFT 0 + +/* 0x0e 0x0f 0x10 CxCFG */ +#define STA350_CxCFG_TCB_SHIFT 0 +#define STA350_CxCFG_EQBP_SHIFT 1 +#define STA350_CxCFG_VBP_SHIFT 2 +#define STA350_CxCFG_BO_SHIFT 3 +#define STA350_CxCFG_LS_SHIFT 4 +#define STA350_CxCFG_OM_MASK 0xc0 +#define STA350_CxCFG_OM_SHIFT 6 + +/* 0x11 TONE */ +#define STA350_TONE_BTC_SHIFT 0 +#define STA350_TONE_TTC_SHIFT 4 + +/* 0x12 0x13 0x14 0x15 limiter attack/release */ +#define STA350_LxA_SHIFT 0 +#define STA350_LxR_SHIFT 4 + +/* 0x26 CFUD */ +#define STA350_CFUD_W1 0x01 +#define STA350_CFUD_WA 0x02 +#define STA350_CFUD_R1 0x04 +#define STA350_CFUD_RA 0x08 + + +/* biquad filter coefficient table offsets */ +#define STA350_C1_BQ_BASE 0 +#define STA350_C2_BQ_BASE 20 +#define STA350_CH_BQ_NUM 4 +#define STA350_BQ_NUM_COEF 5 +#define STA350_XO_HP_BQ_BASE 40 +#define STA350_XO_LP_BQ_BASE 45 +#define STA350_C1_PRESCALE 50 +#define STA350_C2_PRESCALE 51 +#define STA350_C1_POSTSCALE 52 +#define STA350_C2_POSTSCALE 53 +#define STA350_C3_POSTSCALE 54 +#define STA350_TW_POSTSCALE 55 +#define STA350_C1_MIX1 56 +#define STA350_C1_MIX2 57 +#define STA350_C2_MIX1 58 +#define STA350_C2_MIX2 59 +#define STA350_C3_MIX1 60 +#define STA350_C3_MIX2 61 + +#endif /* _ASOC_STA_350_H */ -- cgit v1.2.3 From ccffbd27af95700f6e46f5300fcc96c0cda9f178 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:08 +0530 Subject: ASoC: pcm512x: Use CONFIG_PM_RUNTIME macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following compilation warnings: sound/soc/codecs/pcm512x.c:520:12: warning: ‘pcm512x_suspend’ defined but not used [-Wunused-function] sound/soc/codecs/pcm512x.c:545:12: warning: ‘pcm512x_resume’ defined but not used [-Wunused-function] Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/pcm512x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 4b4c0c7bb918..51124202f765 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -517,6 +517,7 @@ void pcm512x_remove(struct device *dev) } EXPORT_SYMBOL_GPL(pcm512x_remove); +#ifdef CONFIG_PM_RUNTIME static int pcm512x_suspend(struct device *dev) { struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); @@ -578,6 +579,7 @@ static int pcm512x_resume(struct device *dev) return 0; } +#endif const struct dev_pm_ops pcm512x_pm_ops = { SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) -- cgit v1.2.3 From a6b34312b027833de87c31e63a5d06b07186bacf Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:09 +0530 Subject: ASoC: hdmi: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/hdmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 9cb1c7d3e1dc..1087fd5f9917 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #define DRV_NAME "hdmi-audio-codec" -- cgit v1.2.3 From 6e1f29d4ef1c13ab87fe785fe6e1213d57232a31 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:10 +0530 Subject: ASoC: max98090: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..4959e762f88a 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From affb74ad299631666e5bf1f455e3baa7035ea58f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:11 +0530 Subject: ASoC: rt5640: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..635363cb73e9 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 0faabc4f4c31deb73077e9f77989406e2fc49c77 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:12 +0530 Subject: ASoC: tlv320aic23: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic23-i2c.c | 1 + sound/soc/codecs/tlv320aic31xx.c | 1 + 2 files changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c index b73c94ebcc2a..f13701995482 100644 --- a/sound/soc/codecs/tlv320aic23-i2c.c +++ b/sound/soc/codecs/tlv320aic23-i2c.c @@ -13,6 +13,7 @@ #include #include +#include #include #include diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index fa158cfe9b32..b93d500e960b 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From ee5e4534f7b39aaf1256d3de14f412489d5879df Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Fri, 4 Apr 2014 11:29:13 +0530 Subject: ASoC: tpa6130a2: Include of.h of_match_ptr is defined in of.h. Include it explicitly. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- sound/soc/codecs/tpa6130a2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index b27c396037d4..8fc5a647453b 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "tpa6130a2.h" -- cgit v1.2.3 From 12023a9af8f6602e09d9276d3476f6861ca0f127 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:25 +0100 Subject: ASoC: core: Add helpers for codec and codec_dai search Add dedicated helpers for codec and codec_dai search in preparation for DAI-multicodec. It will help reducing the extra indentation that will be introduced by the iteration over multiple codecs. Previous implementation unnecessarily kept searching for a matching codec in the remaining register codecs even if it was already found. Fix that by returning in case of matching. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 79 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 32 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..674da7049db4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -854,14 +854,47 @@ EXPORT_SYMBOL_GPL(snd_soc_resume); static const struct snd_soc_dai_ops null_dai_ops = { }; +static struct snd_soc_codec *soc_find_codec(const struct device_node *codec_of_node, + const char *codec_name) +{ + struct snd_soc_codec *codec; + + list_for_each_entry(codec, &codec_list, list) { + if (codec_of_node) { + if (codec->dev->of_node != codec_of_node) + continue; + } else { + if (strcmp(codec->name, codec_name)) + continue; + } + + return codec; + } + + return NULL; +} + +static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, + const char *codec_dai_name) +{ + struct snd_soc_dai *codec_dai; + + list_for_each_entry(codec_dai, &codec->component.dai_list, list) { + if (!strcmp(codec_dai->name, codec_dai_name)) { + return codec_dai; + } + } + + return NULL; +} + static int soc_bind_dai_link(struct snd_soc_card *card, int num) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; struct snd_soc_component *component; - struct snd_soc_codec *codec; struct snd_soc_platform *platform; - struct snd_soc_dai *codec_dai, *cpu_dai; + struct snd_soc_dai *cpu_dai; const char *platform_name; dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); @@ -889,42 +922,24 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) return -EPROBE_DEFER; } - /* Find CODEC from registered CODECs */ - list_for_each_entry(codec, &codec_list, list) { - 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, &codec->component.dai_list, list) { - if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) { - rtd->codec_dai = codec_dai; - break; - } - } - - if (!rtd->codec_dai) { - dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", - dai_link->codec_dai_name); - return -EPROBE_DEFER; - } - } - + /* Find CODEC from registered list */ + rtd->codec = soc_find_codec(dai_link->codec_of_node, + dai_link->codec_name); if (!rtd->codec) { dev_err(card->dev, "ASoC: CODEC %s not registered\n", dai_link->codec_name); return -EPROBE_DEFER; } + /* Find CODEC DAI from registered list */ + rtd->codec_dai = soc_find_codec_dai(rtd->codec, + dai_link->codec_dai_name); + if (!rtd->codec_dai) { + dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", + dai_link->codec_dai_name); + return -EPROBE_DEFER; + } + /* if there's no platform we match on the empty platform */ platform_name = dai_link->platform_name; if (!platform_name && !dai_link->platform_of_node) -- cgit v1.2.3 From b0aa88af23155b18efb8c18ace963fa75778561a Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:26 +0100 Subject: ASoC: core: Add helpers for codec DAI probe & remove Add helper functions for codec DAI probe and remove in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 74 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 27 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 674da7049db4..1e4945d614a4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1010,21 +1010,10 @@ static void soc_remove_codec(struct snd_soc_codec *codec) module_put(codec->dev->driver->owner); } -static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) +static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) { - struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; int err; - /* 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); - rtd->dev_registered = 0; - } - - /* remove the CODEC DAI */ if (codec_dai && codec_dai->probed && codec_dai->driver->remove_order == order) { if (codec_dai->driver->remove) { @@ -1037,6 +1026,24 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) codec_dai->probed = 0; list_del(&codec_dai->card_list); } +} + +static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) +{ + struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; + struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; + int err; + + /* 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); + rtd->dev_registered = 0; + } + + /* remove the CODEC DAI */ + soc_remove_codec_dai(codec_dai, order); /* remove the cpu_dai */ if (cpu_dai && cpu_dai->probed && @@ -1381,6 +1388,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, return 0; } +static int soc_probe_codec_dai(struct snd_soc_card *card, + struct snd_soc_dai *codec_dai, + int order) +{ + int ret; + + if (!codec_dai->probed && codec_dai->driver->probe_order == order) { + if (codec_dai->driver->probe) { + ret = codec_dai->driver->probe(codec_dai); + if (ret < 0) { + dev_err(codec_dai->dev, + "ASoC: failed to probe CODEC DAI %s: %d\n", + codec_dai->name, ret); + return ret; + } + } + + /* mark codec_dai as probed and add to card dai list */ + codec_dai->probed = 1; + list_add(&codec_dai->card_list, &card->dai_dev_list); + } + + return 0; +} + static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; @@ -1430,21 +1462,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } /* probe the CODEC DAI */ - if (!codec_dai->probed && codec_dai->driver->probe_order == order) { - if (codec_dai->driver->probe) { - ret = codec_dai->driver->probe(codec_dai); - if (ret < 0) { - dev_err(codec_dai->dev, - "ASoC: failed to probe CODEC DAI %s: %d\n", - codec_dai->name, ret); - return ret; - } - } - - /* mark codec_dai as probed and add to card dai list */ - codec_dai->probed = 1; - list_add(&codec_dai->card_list, &card->dai_dev_list); - } + ret = soc_probe_codec_dai(card, codec_dai, order); + if (ret) + return ret; /* complete DAI probe during last probe */ if (order != SND_SOC_COMP_ORDER_LAST) -- cgit v1.2.3 From 2436a723f3e1fbca517c9318efe9af5ecf7cbcbb Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:27 +0100 Subject: ASoC: core: Add helper for DAI widgets linking Add a helper for DAI widgets linking in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 64 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1e4945d614a4..4c0f7dccbd83 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1413,6 +1413,42 @@ static int soc_probe_codec_dai(struct snd_soc_card *card, return 0; } +static int soc_link_dai_widgets(struct snd_soc_card *card, + struct snd_soc_dai_link *dai_link, + struct snd_soc_dai *cpu_dai, + struct snd_soc_dai *codec_dai) +{ + struct snd_soc_dapm_widget *play_w, *capture_w; + int ret; + + /* link the DAI widgets */ + play_w = codec_dai->playback_widget; + capture_w = cpu_dai->capture_widget; + if (play_w && capture_w) { + ret = snd_soc_dapm_new_pcm(card, dai_link->params, + capture_w, play_w); + if (ret != 0) { + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", + play_w->name, capture_w->name, ret); + return ret; + } + } + + play_w = cpu_dai->playback_widget; + capture_w = codec_dai->capture_widget; + if (play_w && capture_w) { + ret = snd_soc_dapm_new_pcm(card, dai_link->params, + capture_w, play_w); + if (ret != 0) { + dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", + play_w->name, capture_w->name, ret); + return ret; + } + } + + return 0; +} + static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; @@ -1421,7 +1457,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) 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_soc_dapm_widget *play_w, *capture_w; int ret; dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", @@ -1502,29 +1537,10 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) codec2codec_close_delayed_work); /* link the DAI widgets */ - play_w = codec_dai->playback_widget; - capture_w = cpu_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } - - play_w = cpu_dai->playback_widget; - capture_w = codec_dai->capture_widget; - if (play_w && capture_w) { - ret = snd_soc_dapm_new_pcm(card, dai_link->params, - capture_w, play_w); - if (ret != 0) { - dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", - play_w->name, capture_w->name, ret); - return ret; - } - } + ret = soc_link_dai_widgets(card, dai_link, + cpu_dai, codec_dai); + if (ret) + return ret; } } -- cgit v1.2.3 From 02c9c7b91c2831b7f4e43c9931007e46f856b659 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 21 Mar 2014 16:27:28 +0100 Subject: ASoC: core: Add function for ac97 codec registration Add codec registration specific function in preparation for DAI-multicodec support. No functional change. Signed-off-by: Misael Lopez Cruz [fparent@baylibre.com: Adapt to 3.14+] Signed-off-by: Fabien Parent Signed-off-by: Benoit Cousson Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4c0f7dccbd83..42c5835ba92f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1552,14 +1552,15 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) } #ifdef CONFIG_SND_SOC_AC97_BUS -static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +static int soc_register_ac97_codec(struct snd_soc_codec *codec, + struct snd_soc_dai *codec_dai) { int ret; /* Only instantiate AC97 if not already done by the adaptor * for the generic AC97 subsystem. */ - if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) { + if (codec_dai->driver->ac97_control && !codec->ac97_registered) { /* * It is possible that the AC97 device is already registered to * the device subsystem. This happens when the device is created @@ -1568,28 +1569,38 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) * * In those cases we don't try to register the device again. */ - if (!rtd->codec->ac97_created) + if (!codec->ac97_created) return 0; - ret = soc_ac97_dev_register(rtd->codec); + ret = soc_ac97_dev_register(codec); if (ret < 0) { - dev_err(rtd->codec->dev, + dev_err(codec->dev, "ASoC: AC97 device register failed: %d\n", ret); return ret; } - rtd->codec->ac97_registered = 1; + codec->ac97_registered = 1; } return 0; } -static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec) +static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + return soc_register_ac97_codec(rtd->codec, rtd->codec_dai); +} + +static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) { if (codec->ac97_registered) { soc_ac97_dev_unregister(codec); codec->ac97_registered = 0; } } + +static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) +{ + soc_unregister_ac97_codec(rtd->codec); +} #endif static int soc_check_aux_dev(struct snd_soc_card *card, int num) @@ -1888,7 +1899,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) dev_err(card->dev, "ASoC: failed to register AC97: %d\n", ret); while (--i >= 0) - soc_unregister_ac97_dai_link(card->rtd[i].codec); + soc_unregister_ac97_dai_link(&card->rtd[i]); goto probe_aux_dev_err; } } @@ -2324,7 +2335,7 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) { mutex_lock(&codec->mutex); #ifdef CONFIG_SND_SOC_AC97_BUS - soc_unregister_ac97_dai_link(codec); + soc_unregister_ac97_codec(codec); #endif kfree(codec->ac97->bus); kfree(codec->ac97); -- cgit v1.2.3 From 84bd187996777924b70fe6fb39ccaa34e0b57565 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:56 +0200 Subject: ASoC: adau1373: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adau1373.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 877f5737bb6b..1ff7d4d027e9 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c @@ -519,8 +519,7 @@ static const struct snd_kcontrol_new adau1373_controls[] = { SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), - SOC_VALUE_ENUM("Bass Clip Level Threshold", - adau1373_bass_clip_level_enum), + SOC_ENUM("Bass Clip Level Threshold", adau1373_bass_clip_level_enum), SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, @@ -580,7 +579,7 @@ static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum, adau1373_decimator_text); static const struct snd_kcontrol_new adau1373_decimator_mux = - SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); + SOC_DAPM_ENUM("Decimator Mux", adau1373_decimator_enum); static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), @@ -694,7 +693,7 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), - SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, &adau1373_decimator_mux), SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), -- cgit v1.2.3 From 48fa3636340f78d10352dd333e79946de0a96fe6 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:57 +0200 Subject: ASoC: adav80x: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/adav80x.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 5062e34ee8dc..4d41bbc611e0 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c @@ -172,14 +172,14 @@ static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3); static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3); static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum); + SOC_DAPM_ENUM("Route", adav80x_aux_capture_enum); static const struct snd_kcontrol_new adav80x_capture_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum); + SOC_DAPM_ENUM("Route", adav80x_capture_enum); static const struct snd_kcontrol_new adav80x_dac_mux_ctrl = - SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum); + SOC_DAPM_ENUM("Route", adav80x_dac_enum); #define ADAV80X_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1), -- cgit v1.2.3 From 355e3a08485249868d892c82e9250c0f6e4d0ceb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:58 +0200 Subject: ASoC: arizona: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/arizona.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 16df0f913353..05ae17f5bca3 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h @@ -107,7 +107,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; #define ARIZONA_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define ARIZONA_MUX_ENUMS(name, base_reg) \ static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ @@ -128,7 +128,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) #define ARIZONA_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define ARIZONA_MUX_WIDGETS(name, name_str) \ ARIZONA_MUX(name_str " Input", &name##_mux) -- cgit v1.2.3 From aae1137b998a1a4508a2f2b27604351a5ced2427 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:30:59 +0200 Subject: ASoC: max98090: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/max98090.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..1fd31efa6664 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c @@ -875,7 +875,7 @@ static const char *dmic_mux_text[] = { "ADC", "DMIC" }; static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); static const struct snd_kcontrol_new max98090_dmic_mux = - SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); + SOC_DAPM_ENUM("DMIC Mux", dmic_mux_enum); static const char *max98090_micpre_text[] = { "Off", "On" }; @@ -1175,8 +1175,7 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = { SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM, 0, 0, &max98090_mic2_mux), - SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM, - 0, 0, &max98090_dmic_mux), + SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &max98090_dmic_mux), SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event, -- cgit v1.2.3 From 36bc38a7c1c6869a71739c4f9bf1c16e8168ae88 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:00 +0200 Subject: ASoC: mc13783: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/mc13783.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2c59b1fb69dc..ed5c5a41169b 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c @@ -409,7 +409,7 @@ static const char * const adcl_enum_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); static const struct snd_kcontrol_new left_input_mux = - SOC_DAPM_ENUM_VIRT("Route", adcl_enum); + SOC_DAPM_ENUM("Route", adcl_enum); static const char * const adcr_enum_text[] = { "MC1R", "MC2", "RXINR", "TXIN", @@ -418,7 +418,7 @@ static const char * const adcr_enum_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); static const struct snd_kcontrol_new right_input_mux = - SOC_DAPM_ENUM_VIRT("Route", adcr_enum); + SOC_DAPM_ENUM("Route", adcr_enum); static const struct snd_kcontrol_new samp_ctl = SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); @@ -478,9 +478,9 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl), SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl), - SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, &left_input_mux), - SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, + SND_SOC_DAPM_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, &right_input_mux), SND_SOC_DAPM_MUX("Speaker Amp Source MUX", SND_SOC_NOPM, 0, 0, -- cgit v1.2.3 From 54581be7da3d50aab8322fcfeff14c1aa1dafa86 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:01 +0200 Subject: ASoC: pcm512x: Replace usage deprecated SOC_VALUE_ENUM macro SOC_VALUE_ENUM is deprecated and merely an alias for SOC_ENUM. Replace the deprecated macro so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/pcm512x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 4b4c0c7bb918..381d22ce6f76 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c @@ -269,7 +269,7 @@ SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, PCM512x_RQMR_SHIFT, 1, 1), SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), -SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program), +SOC_ENUM("DSP Program", pcm512x_dsp_program), SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), -- cgit v1.2.3 From 712fb1c27dce4e3fe9338f27ed0f8684fe9d5597 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:02 +0200 Subject: ASoC: rt5640: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/rt5640.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..1b452e3b449a 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -824,7 +824,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); static const struct snd_kcontrol_new rt5640_dac_l2_mux = - SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); + SOC_DAPM_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); static const char * const rt5640_dac_r2_src[] = { "IF2", @@ -859,7 +859,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum, rt5640_dai_iis_map_values); static const struct snd_kcontrol_new rt5640_dai_mux = - SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); + SOC_DAPM_ENUM("DAI select", rt5640_dai_iis_map_enum); /* SDI select */ static const char * const rt5640_sdi_sel[] = { -- cgit v1.2.3 From 7eb364ab196d522cdde744010c4e02c2fe62f6fc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:03 +0200 Subject: ASoC: wm2200: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm2200.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 2e721e06671b..cdea9d9c1631 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c @@ -1083,7 +1083,7 @@ static int wm2200_mixer_values[] = { #define WM2200_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define WM2200_MIXER_ENUMS(name, base_reg) \ static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ @@ -1207,7 +1207,7 @@ WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); #define WM2200_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define WM2200_MIXER_WIDGETS(name, name_str) \ WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ -- cgit v1.2.3 From cda8866952f209d5e9de077c9ea7cb20a22e41ea Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:04 +0200 Subject: ASoC: wm5100: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index eca983fad891..91a9ea2a2056 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c @@ -390,7 +390,7 @@ static int wm5100_mixer_values[] = { #define WM5100_MUX_CTL_DECL(name) \ const struct snd_kcontrol_new name##_mux = \ - SOC_DAPM_VALUE_ENUM("Route", name##_enum) + SOC_DAPM_ENUM("Route", name##_enum) #define WM5100_MIXER_ENUMS(name, base_reg) \ static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ @@ -448,7 +448,7 @@ WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE); WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE); #define WM5100_MUX(name, ctrl) \ - SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) + SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) #define WM5100_MIXER_WIDGETS(name, name_str) \ WM5100_MUX(name_str " Input 1", &name##_in1_mux), \ -- cgit v1.2.3 From 6b2cab02a39d2d1badf93c44e989ffcb9c3c1363 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:05 +0200 Subject: ASoC: wm5102: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index dcf1d12cfef8..12d244b8f281 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -970,7 +970,7 @@ static const struct soc_enum wm5102_aec_loopback = wm5102_aec_loopback_values); static const struct snd_kcontrol_new wm5102_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm5102_aec_loopback); static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -1204,7 +1204,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5102_aec_loopback_mux), -- cgit v1.2.3 From 696d3affa012a439f9e6be1e60cc68ce06d736d1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:06 +0200 Subject: ASoC: wm5110: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..32e503211eec 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -324,13 +324,13 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), -SOC_VALUE_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), -SOC_VALUE_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), -SOC_VALUE_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), -SOC_VALUE_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), -SOC_VALUE_ENUM("ASRC RATE 1", arizona_asrc_rate1), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), +SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), +SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), +SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), +SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1), ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), @@ -592,7 +592,7 @@ static const struct soc_enum wm5110_aec_loopback = wm5110_aec_loopback_values); static const struct snd_kcontrol_new wm5110_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback); static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -774,7 +774,7 @@ SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3, SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3, ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm5110_aec_loopback_mux), -- cgit v1.2.3 From fb7d79e56f6b0b7ce2d0ae3366d6a0e59145e37d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:07 +0200 Subject: ASoC: wm8988: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8988.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 3a1ae4f5164d..d3fea46d58e8 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -268,7 +268,7 @@ static const struct soc_enum wm8988_lline_enum = wm8988_line_texts, wm8988_line_values); static const struct snd_kcontrol_new wm8988_left_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + SOC_DAPM_ENUM("Route", wm8988_lline_enum); static const struct soc_enum wm8988_rline_enum = SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, @@ -276,7 +276,7 @@ static const struct soc_enum wm8988_rline_enum = wm8988_line_texts, wm8988_line_values); static const struct snd_kcontrol_new wm8988_right_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); + SOC_DAPM_ENUM("Route", wm8988_lline_enum); /* Left Mixer */ static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { @@ -304,7 +304,7 @@ static const struct soc_enum wm8988_lpga_enum = wm8988_pga_sel, wm8988_pga_val); static const struct snd_kcontrol_new wm8988_left_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum); + SOC_DAPM_ENUM("Route", wm8988_lpga_enum); /* Right PGA Mux */ static const struct soc_enum wm8988_rpga_enum = @@ -313,7 +313,7 @@ static const struct soc_enum wm8988_rpga_enum = wm8988_pga_sel, wm8988_pga_val); static const struct snd_kcontrol_new wm8988_right_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum); + SOC_DAPM_ENUM("Route", wm8988_rpga_enum); /* Differential Mux */ static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; -- cgit v1.2.3 From 0a822c1e3bfd00e7a9a5d81ac5887defdd5d4e64 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:08 +0200 Subject: ASoC: wm5102: Replace usage deprecated SOC_VALUE_ENUM macro SOC_VALUE_ENUM is deprecated and merely an alias for SOC_EMUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm5102.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 12d244b8f281..cbe52861b19b 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c @@ -764,8 +764,8 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -814,9 +814,9 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), -SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), -SOC_VALUE_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), +SOC_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), +SOC_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), +SOC_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE, ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0), -- cgit v1.2.3 From 37d203055e3516e891fb23a40d61a54b65a60d81 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:09 +0200 Subject: ASoC: wm8994: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX, SND_SOC_DAPM_VIRT_MUX_E and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX, SND_SOC_DAPM_MUX_E and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..309c97d89dbb 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1347,10 +1347,10 @@ static const char *adc_mux_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); static const struct snd_kcontrol_new adcl_mux = - SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); + SOC_DAPM_ENUM("ADCL Mux", adc_enum); static const struct snd_kcontrol_new adcr_mux = - SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); + SOC_DAPM_ENUM("ADCR Mux", adc_enum); static const struct snd_kcontrol_new left_speaker_mixer[] = { SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0), @@ -1651,15 +1651,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_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, +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_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, +SND_SOC_DAPM_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_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), +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), }; static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { -- cgit v1.2.3 From b8eecc19708dcf36b30058a1e86206480c09efc4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:10 +0200 Subject: ASoC: wm8995: Replace usage deprecated MUX/ENUM macros SND_SOC_DAPM_VIRT_MUX and SOC_DAPM_ENUM_VIRT are deprecated and merely an alias for SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8995.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index d3152cf5bd56..863a2c38bcb5 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -885,10 +885,10 @@ static const char *adc_mux_text[] = { static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); static const struct snd_kcontrol_new adcl_mux = - SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); + SOC_DAPM_ENUM("ADCL Mux", adc_enum); static const struct snd_kcontrol_new adcr_mux = - SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); + SOC_DAPM_ENUM("ADCR Mux", adc_enum); static const char *spk_src_text[] = { "DAC1L", "DAC1R", "DAC2L", "DAC2R" @@ -948,10 +948,8 @@ static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 0, WM8995_POWER_MANAGEMENT_3, 10, 0), - SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, - &adcl_mux), - SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, - &adcr_mux), + SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, &adcl_mux), + SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0), SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0), -- cgit v1.2.3 From e13dd8ce39a89c7a7d8ec025b266337b42eeaafc Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 14 Apr 2014 21:31:11 +0200 Subject: ASoC: wm8997: Replace usage deprecated MUX/ENUM macros SOC_VALUE_ENUM, SND_SOC_DAPM_VALUE_MUX and SOC_DAPM_VALUE_ENUM are deprecated and merely an alias for SOC_ENUM, SND_SOC_DAPM_MUX and SOC_DAPM_ENUM. Replace the deprecated macros so we can eventually remove their definition. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 004186b6bd48..e45bbc0f15b2 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -245,8 +245,8 @@ SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), -SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_VALUE("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_VALUE("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -286,8 +286,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), -SOC_VALUE_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), +SOC_VALUE("HPOUT1 OSR", wm8997_hpout_osr[0]), +SOC_VALUE("EPOUT OSR", wm8997_hpout_osr[1]), SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), @@ -405,7 +405,7 @@ static const struct soc_enum wm8997_aec_loopback = wm8997_aec_loopback_values); static const struct snd_kcontrol_new wm8997_aec_loopback_mux = - SOC_DAPM_VALUE_ENUM("AEC Loopback", wm8997_aec_loopback); + SOC_DAPM_ENUM("AEC Loopback", wm8997_aec_loopback); static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, @@ -604,7 +604,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE, ARIZONA_SLIMRX8_ENA_SHIFT, 0), -SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, +SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, &wm8997_aec_loopback_mux), -- cgit v1.2.3 From 40448e5e977b59a4753fce3619f537b63fcedc02 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 4 Apr 2014 15:56:30 +0300 Subject: ASoC: davinci-mcasp: Do not touch 0x04 register above McASP_VERSION_2 This register is not defined in TI81xx and on AM335x/AM437x it is the SYSCONFIG register which should not be touched by drivers since it is related to PM and handled by the generic PM code. This register write was there since the first time the davinci-mcasp driver was appeared in the kernel. The reason why it did not caused any issues on AM335x/AM437x is that it sets bit 1 in SYSCONFIG register which in turn will enable the smart-idle mode. This is the default mode and this is the mode McASP should be in also when in use. On TI81xx the register is not defined. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/davinci/davinci-mcasp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 8007fcf428d9..af92d3e8671d 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -502,7 +502,7 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, int active_serializers, numevt, n; u32 reg; /* Default configuration */ - if (mcasp->version != MCASP_VERSION_4) + if (mcasp->version < MCASP_VERSION_3) mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); /* All PINS as McASP */ -- cgit v1.2.3 From f84526cfae46672308a361333c76b724384b61ee Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 11 Apr 2014 22:10:00 +0800 Subject: ASoC: fsl_sai: Fix incorrect condition check in trigger() Patch ASoC: fsl_sai: Fix buggy configurations in trigger() doesn't entirely fix the condition: FRDE of the current substream direction is being cleared while the code is still using the non-updated one. Thus this patch fixes this issue by checking the opposite one's FRDE alone since the current one's is absolutely disabled. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 1c93282fbd26..a25e8884b09d 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -409,7 +409,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), FSL_SAI_CSR_xIE_MASK, 0); - if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { + /* Check if the opposite FRDE is also disabled */ + if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { regmap_update_bits(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_TERE, 0); regmap_update_bits(sai->regmap, FSL_SAI_RCSR, -- cgit v1.2.3 From 3e185238a37d1f0a37a1d910344cdcff578bf333 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:26 +0800 Subject: ASoC: esai: use the precise definition of 'ret'. Use the precise definition of 'ret', which will be used for the error check. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index c8e5db1414d7..67d5417e0933 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -209,8 +209,9 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, struct clk *clksrc = esai_priv->extalclk; bool tx = clk_id <= ESAI_HCKT_EXTAL; bool in = dir == SND_SOC_CLOCK_IN; - u32 ret, ratio, ecr = 0; + u32 ratio, ecr = 0; unsigned long clk_rate; + int ret; /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ esai_priv->sck_div[tx] = true; @@ -432,8 +433,8 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int fsl_esai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - int ret; struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); + int ret; /* * Some platforms might use the same bit to gate all three or two of @@ -491,7 +492,8 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 width = snd_pcm_format_width(params_format(params)); u32 channels = params_channels(params); - u32 bclk, mask, val, ret; + u32 bclk, mask, val; + int ret; bclk = params_rate(params) * esai_priv->slot_width * 2; -- cgit v1.2.3 From add180ed780e9031d65e7c94cad936e719401acf Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:27 +0800 Subject: ASoC: spdif: Sort the header files alphabetically. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 6452ca83d889..173553c6dc55 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -13,18 +13,18 @@ * kind, whether express or implied. */ -#include +#include #include #include -#include -#include +#include #include #include #include +#include #include -#include #include +#include #include "fsl_spdif.h" #include "imx-pcm.h" -- cgit v1.2.3 From b21cc2f5fdfe22429501cd7040db0b2b2a9b29de Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:28 +0800 Subject: ASoC: esai: Add VF610+ compatibles support. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 67d5417e0933..b49b78df2f5b 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -818,6 +818,7 @@ static int fsl_esai_probe(struct platform_device *pdev) static const struct of_device_id fsl_esai_dt_ids[] = { { .compatible = "fsl,imx35-esai", }, + { .compatible = "fsl,vf610-esai", }, {} }; MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); -- cgit v1.2.3 From 1014fad0fca91181acc68396d84573e4ae301380 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Fri, 4 Apr 2014 15:10:29 +0800 Subject: ASoC: spdif: Add VF610+ compatibles support. Signed-off-by: Xiubo Li Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 173553c6dc55..daa6198ae41f 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -1186,6 +1186,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) static const struct of_device_id fsl_spdif_dt_ids[] = { { .compatible = "fsl,imx35-spdif", }, + { .compatible = "fsl,vf610-spdif", }, {} }; MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); -- cgit v1.2.3 From 2a266f8b2ae790454edb79cb8c707c9305e0307a Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 11 Apr 2014 18:30:09 +0800 Subject: ASoC: fsl_sai: Use FSL_SAI_xXR() and regmap_update_bits() to simplify code By doing this, the driver can drop around 50 lines and become neater. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 101 ++++++++++++------------------------------------ 1 file changed, 25 insertions(+), 76 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index a25e8884b09d..c5a0e8af8226 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -119,16 +119,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int fsl_dir) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr2, reg_cr2; - - if (fsl_dir == FSL_FMT_TRANSMITTER) - reg_cr2 = FSL_SAI_TCR2; - else - reg_cr2 = FSL_SAI_RCR2; - - regmap_read(sai->regmap, reg_cr2, &val_cr2); - - val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; + bool tx = fsl_dir == FSL_FMT_TRANSMITTER; + u32 val_cr2 = 0; switch (clk_id) { case FSL_SAI_CLK_BUS: @@ -147,7 +139,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, return -EINVAL; } - regmap_write(sai->regmap, reg_cr2, val_cr2); + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), + FSL_SAI_CR2_MSEL_MASK, val_cr2); return 0; } @@ -179,22 +172,10 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, unsigned int fmt, int fsl_dir) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr2, val_cr4, reg_cr2, reg_cr4; - - if (fsl_dir == FSL_FMT_TRANSMITTER) { - reg_cr2 = FSL_SAI_TCR2; - reg_cr4 = FSL_SAI_TCR4; - } else { - reg_cr2 = FSL_SAI_RCR2; - reg_cr4 = FSL_SAI_RCR4; - } + bool tx = fsl_dir == FSL_FMT_TRANSMITTER; + u32 val_cr2 = 0, val_cr4 = 0; - regmap_read(sai->regmap, reg_cr2, &val_cr2); - regmap_read(sai->regmap, reg_cr4, &val_cr4); - - if (sai->big_endian_data) - val_cr4 &= ~FSL_SAI_CR4_MF; - else + if (!sai->big_endian_data) val_cr4 |= FSL_SAI_CR4_MF; /* DAI mode */ @@ -215,7 +196,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); break; case SND_SOC_DAIFMT_DSP_A: /* @@ -225,7 +205,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * data word. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~FSL_SAI_CR4_FSP; val_cr4 |= FSL_SAI_CR4_FSE; sai->is_dsp_mode = true; break; @@ -235,7 +214,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, * frame sync asserts with the first bit of the frame. */ val_cr2 |= FSL_SAI_CR2_BCP; - val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); sai->is_dsp_mode = true; break; case SND_SOC_DAIFMT_RIGHT_J: @@ -273,23 +251,22 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, val_cr4 |= FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBM_CFM: - val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; - val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBS_CFM: val_cr2 |= FSL_SAI_CR2_BCD_MSTR; - val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; break; case SND_SOC_DAIFMT_CBM_CFS: - val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; val_cr4 |= FSL_SAI_CR4_FSD_MSTR; break; default: return -EINVAL; } - regmap_write(sai->regmap, reg_cr2, val_cr2); - regmap_write(sai->regmap, reg_cr4, val_cr4); + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), + FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), + FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | + FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); return 0; } @@ -316,29 +293,10 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr; + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; unsigned int channels = params_channels(params); u32 word_width = snd_pcm_format_width(params_format(params)); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - reg_cr4 = FSL_SAI_TCR4; - reg_cr5 = FSL_SAI_TCR5; - reg_mr = FSL_SAI_TMR; - } else { - reg_cr4 = FSL_SAI_RCR4; - reg_cr5 = FSL_SAI_RCR5; - reg_mr = FSL_SAI_RMR; - } - - regmap_read(sai->regmap, reg_cr4, &val_cr4); - regmap_read(sai->regmap, reg_cr4, &val_cr5); - - val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; - val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; - - val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; - val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; - val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; + u32 val_cr4 = 0, val_cr5 = 0; if (!sai->is_dsp_mode) val_cr4 |= FSL_SAI_CR4_SYWD(word_width); @@ -346,18 +304,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, val_cr5 |= FSL_SAI_CR5_WNW(word_width); val_cr5 |= FSL_SAI_CR5_W0W(word_width); - val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; if (sai->big_endian_data) val_cr5 |= FSL_SAI_CR5_FBT(0); else val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); val_cr4 |= FSL_SAI_CR4_FRSZ(channels); - val_mr = ~0UL - ((1 << channels) - 1); - regmap_write(sai->regmap, reg_cr4, val_cr4); - regmap_write(sai->regmap, reg_cr5, val_cr5); - regmap_write(sai->regmap, reg_mr, val_mr); + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), + FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, + val_cr4); + regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), + FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | + FSL_SAI_CR5_FBT_MASK, val_cr5); + regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); return 0; } @@ -428,8 +388,8 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct device *dev = &sai->pdev->dev; - u32 reg; int ret; ret = clk_prepare_enable(sai->bus_clk); @@ -438,12 +398,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, return ret; } - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = FSL_SAI_TCR3; - else - reg = FSL_SAI_RCR3; - - regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, FSL_SAI_CR3_TRCE); return 0; @@ -453,15 +408,9 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); - u32 reg; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = FSL_SAI_TCR3; - else - reg = FSL_SAI_RCR3; + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; - regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, - ~FSL_SAI_CR3_TRCE); + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); clk_disable_unprepare(sai->bus_clk); } -- cgit v1.2.3 From 9de98da2a7531ec9dedfbe95d69ee55237bbd9d5 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 15 Apr 2014 07:46:05 +0200 Subject: ASoC: wm8997: Fix compile error The macro's name is SOC_ENUM, not SOC_VALUE. Fixes: e13dd8ce ("ASoC: wm8997: Replace usage deprecated MUX/ENUM macros") Reported-by: Stephen Rothwell Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/wm8997.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index e45bbc0f15b2..a5dcdcb3ee24 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c @@ -245,8 +245,8 @@ SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), -SOC_VALUE("ISRC1 FSL", arizona_isrc_fsl[0]), -SOC_VALUE("ISRC2 FSL", arizona_isrc_fsl[1]), +SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), +SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), @@ -286,8 +286,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, 0xbf, 0, digital_tlv), -SOC_VALUE("HPOUT1 OSR", wm8997_hpout_osr[0]), -SOC_VALUE("EPOUT OSR", wm8997_hpout_osr[1]), +SOC_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), +SOC_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), -- cgit v1.2.3 From 9c72a04ca78606bf10211efa93b3332c710afc65 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 15 Apr 2014 12:02:02 +0100 Subject: ASoC: fsl: Add explicit include of of.h Hopefully fixing a build failure reported by Stephen Rothwell - though quite why the other OF headers don't include this as well I'm not sure. Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..2fbbd8416c00 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From f3046f86b8a455ae55b8d465cd34938006361096 Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Sun, 13 Apr 2014 19:56:36 +0200 Subject: ASoC: Intel: Fix incorrect sizeof() in sst_hsw_stream_get_volume() Fix an incorrect sizeof() usage in sst_hsw_stream_get_volume(). sst_dsp_read() is called to read into a variable of type u32, but is passed sizeof(u32 *) for argument 'size_t bytes'. Detected by Coverity: CID 1195260. Signed-off-by: Christian Engelmayer Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index f46bb4ddde6f..455a1857c441 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream return -EINVAL; sst_dsp_read(hsw->dsp, volume, - stream->reply.volume_register_address[channel], sizeof(volume)); + stream->reply.volume_register_address[channel], + sizeof(*volume)); return 0; } -- cgit v1.2.3 From dd1b94bf4920cc12545883faa43c014efbf61b1e Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Sun, 13 Apr 2014 22:46:31 +0200 Subject: ASoC: Intel: Fix a self assignment in sst_mem_block_alloc_scratch() Remove a self assignment in sst_mem_block_alloc_scratch(). When calculating buffer sizes there is no need for statements without effect. Detected by Coverity: CID 1195249. Signed-off-by: Christian Engelmayer Signed-off-by: Mark Brown --- sound/soc/intel/sst-firmware.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index f7687107cf7f..f24619adc3d1 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c @@ -505,9 +505,7 @@ struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp) /* calculate required scratch size */ list_for_each_entry(sst_module, &dsp->module_list, list) { - if (scratch->s.size > sst_module->s.size) - scratch->s.size = scratch->s.size; - else + if (scratch->s.size < sst_module->s.size) scratch->s.size = sst_module->s.size; } -- cgit v1.2.3 From 4b973ee05673497de678338c00ade803e45f9bfa Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 15 Apr 2014 19:38:56 +0200 Subject: ALSA: sound/atmel/ac97c.c: Convert to module_platform_driver This reduces some boilerplate code. Signed-off-by: Alexander Stein Acked-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Takashi Iwai --- sound/atmel/ac97c.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'sound') diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 05ec049c9faf..a04d23174dc2 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c @@ -1198,6 +1198,7 @@ static int atmel_ac97c_remove(struct platform_device *pdev) } static struct platform_driver atmel_ac97c_driver = { + .probe = atmel_ac97c_probe, .remove = atmel_ac97c_remove, .driver = { .name = "atmel_ac97c", @@ -1205,19 +1206,7 @@ static struct platform_driver atmel_ac97c_driver = { .pm = ATMEL_AC97C_PM_OPS, }, }; - -static int __init atmel_ac97c_init(void) -{ - return platform_driver_probe(&atmel_ac97c_driver, - atmel_ac97c_probe); -} -module_init(atmel_ac97c_init); - -static void __exit atmel_ac97c_exit(void) -{ - platform_driver_unregister(&atmel_ac97c_driver); -} -module_exit(atmel_ac97c_exit); +module_platform_driver(atmel_ac97c_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for Atmel AC97 controller"); -- cgit v1.2.3 From 00d90154404ae6218730068d25bf2faad3186631 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 16 Apr 2014 08:18:35 -0600 Subject: ALSA: pcm: 'BUG:' message unnecessarily triggers kerneloops BugLink: http://bugs.launchpad.net/bugs/1305480 The kerneloops-daemon scans dmesg for common crash signatures, among which is 'BUG:'. The message emitted by the PCM library is really a warning, so the most expedient thing to do seems to be to change the string. Signed-off-by: Tim Gardner Signed-off-by: Takashi Iwai --- sound/core/pcm_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ce83def9f43b..9acc77eae487 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -345,7 +345,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, snd_pcm_debug_name(substream, name, sizeof(name)); xrun_log_show(substream); pcm_err(substream->pcm, - "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n", + "XRUN: %s, pos = %ld, buffer size = %ld, period size = %ld\n", name, pos, runtime->buffer_size, runtime->period_size); } -- cgit v1.2.3 From a1253ef6d3fabfe60838cd417b0624ab53df285e Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Tue, 15 Apr 2014 15:49:33 -0500 Subject: ASoC: cs42l51: split i2c from codec driver This patch removes the i2c bus code from the codec driver and creates seperate i2c driver. Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 6 +++- sound/soc/codecs/Makefile | 2 ++ sound/soc/codecs/cs42l51-i2c.c | 59 +++++++++++++++++++++++++++++++++ sound/soc/codecs/cs42l51.c | 75 +++++++++++------------------------------- sound/soc/codecs/cs42l51.h | 5 +++ 5 files changed, 90 insertions(+), 57 deletions(-) create mode 100644 sound/soc/codecs/cs42l51-i2c.c (limited to 'sound') diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..5279ef41597d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -39,7 +39,7 @@ config SND_SOC_ALL_CODECS 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_CS42L51_I2C if I2C select SND_SOC_CS42L52 if I2C select SND_SOC_CS42L73 if I2C select SND_SOC_CS4270 if I2C @@ -280,6 +280,10 @@ config SND_SOC_CQ0093VC config SND_SOC_CS42L51 tristate +config SND_SOC_CS42L51_I2C + tristate + select SND_SOC_CS42L51 + config SND_SOC_CS42L52 tristate "Cirrus Logic CS42L52 CODEC" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..e06f10032344 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -26,6 +26,7 @@ snd-soc-ak5386-objs := ak5386.o snd-soc-arizona-objs := arizona.o snd-soc-cq93vc-objs := cq93vc.o snd-soc-cs42l51-objs := cs42l51.o +snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o snd-soc-cs42l73-objs := cs42l73.o snd-soc-cs4270-objs := cs4270.o @@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o +obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c new file mode 100644 index 000000000000..cee51ae177c1 --- /dev/null +++ b/sound/soc/codecs/cs42l51-i2c.c @@ -0,0 +1,59 @@ +/* + * cs42l56.c -- CS42L51 ALSA SoC I2C audio driver + * + * Copyright 2014 CirrusLogic, Inc. + * + * Author: Brian Austin + * + * 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 +#include +#include + +#include "cs42l51.h" + +static struct i2c_device_id cs42l51_i2c_id[] = { + {"cs42l51", 0}, + {} +}; +MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); + +static int cs42l51_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct regmap_config config; + + config = cs42l51_regmap; + config.val_bits = 8; + config.reg_bits = 8; + + return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config)); +} + +static int cs42l51_i2c_remove(struct i2c_client *i2c) +{ + snd_soc_unregister_codec(&i2c->dev); + + return 0; +} + +static struct i2c_driver cs42l51_i2c_driver = { + .driver = { + .name = "cs42l51", + .owner = THIS_MODULE, + }, + .probe = cs42l51_i2c_probe, + .remove = cs42l51_i2c_remove, + .id_table = cs42l51_i2c_id, +}; + +module_i2c_driver(cs42l51_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS42L51 I2C Driver"); +MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..46abd3e02f14 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include "cs42l51.h" @@ -483,7 +482,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { .ops = &cs42l51_dai_ops, }; -static int cs42l51_probe(struct snd_soc_codec *codec) +static int cs42l51_codec_probe(struct snd_soc_codec *codec) { int ret, reg; @@ -504,7 +503,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) } static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { - .probe = cs42l51_probe, + .probe = cs42l51_codec_probe, .controls = cs42l51_snd_controls, .num_controls = ARRAY_SIZE(cs42l51_snd_controls), @@ -514,91 +513,55 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), }; -static const struct regmap_config cs42l51_regmap = { - .reg_bits = 8, - .val_bits = 8, - +const struct regmap_config cs42l51_regmap = { .max_register = CS42L51_CHARGE_FREQ, .cache_type = REGCACHE_RBTREE, }; +EXPORT_SYMBOL_GPL(cs42l51_regmap); -static int cs42l51_i2c_probe(struct i2c_client *i2c_client, - const struct i2c_device_id *id) +int cs42l51_probe(struct device *dev, struct regmap *regmap) { struct cs42l51_private *cs42l51; - struct regmap *regmap; unsigned int val; int ret; - regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", - ret); - return ret; - } + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private), + GFP_KERNEL); + if (!cs42l51) + return -ENOMEM; + + dev_set_drvdata(dev, cs42l51); /* Verify that we have a CS42L51 */ ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); if (ret < 0) { - dev_err(&i2c_client->dev, "failed to read I2C\n"); + dev_err(dev, "failed to read I2C\n"); goto error; } if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { - dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); + dev_err(dev, "Invalid chip id: %x\n", val); ret = -ENODEV; goto error; } + dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", val & 0xFF); - dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", - val & 7); - - cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), - GFP_KERNEL); - if (!cs42l51) - return -ENOMEM; - - i2c_set_clientdata(i2c_client, cs42l51); - - ret = snd_soc_register_codec(&i2c_client->dev, + ret = snd_soc_register_codec(dev, &soc_codec_device_cs42l51, &cs42l51_dai, 1); error: return ret; } - -static int cs42l51_i2c_remove(struct i2c_client *client) -{ - snd_soc_unregister_codec(&client->dev); - return 0; -} - -static const struct i2c_device_id cs42l51_id[] = { - {"cs42l51", 0}, - {} -}; -MODULE_DEVICE_TABLE(i2c, cs42l51_id); +EXPORT_SYMBOL_GPL(cs42l51_probe); static const struct of_device_id cs42l51_of_match[] = { { .compatible = "cirrus,cs42l51", }, { } }; MODULE_DEVICE_TABLE(of, cs42l51_of_match); - -static struct i2c_driver cs42l51_i2c_driver = { - .driver = { - .name = "cs42l51-codec", - .owner = THIS_MODULE, - .of_match_table = cs42l51_of_match, - }, - .id_table = cs42l51_id, - .probe = cs42l51_i2c_probe, - .remove = cs42l51_i2c_remove, -}; - -module_i2c_driver(cs42l51_i2c_driver); - MODULE_AUTHOR("Arnaud Patard "); MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index 2beeb171db4b..641ef18435b3 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h @@ -18,6 +18,11 @@ #ifndef _CS42L51_H #define _CS42L51_H +struct device; + +extern const struct regmap_config cs42l51_regmap; +int cs42l51_probe(struct device *dev, struct regmap *regmap); + #define CS42L51_CHIP_ID 0x1B #define CS42L51_CHIP_REV_A 0x00 #define CS42L51_CHIP_REV_B 0x01 -- cgit v1.2.3 From 7b3b302615c3ab9c111d0238107d741146dda701 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:16 +0200 Subject: ALSA: lx_core: Remove unused defines Commit f9367f3fbe3c ("ALSA: lx6464es: Remove unused function in pci/lx6464es/lx_core.c") removed the lx_dsp_es_check_pipeline function that was the only user of these defines. Since they're useless now, simply remove them. Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 2d8e95e9fbe5..6a1d90a308ea 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -429,11 +429,6 @@ int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) return ret; } -#define CSES_TIMEOUT 100 /* microseconds */ -#define CSES_CE 0x0001 -#define CSES_BROADCAST 0x0002 -#define CSES_UPDATE_LDSV 0x0004 - #define PIPE_INFO_TO_CMD(capture, pipe) \ ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET) -- cgit v1.2.3 From c546ca95f58b53839e9eb9dbdf25b369605e5077 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:17 +0200 Subject: ALSA: lx_core: Switch to using BIT macro Move to using the BIT macro for a few defines. It also allows to discard the french comment that was saying exactly what the BIT macro is now pointing out. Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 6a1d90a308ea..652f6dfc7e1a 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -24,6 +24,7 @@ /* #define RMH_DEBUG 1 */ +#include #include #include #include @@ -966,9 +967,9 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, /* interrupt handling */ #define PCX_IRQ_NONE 0 -#define IRQCS_ACTIVE_PCIDB 0x00002000L /* Bit nø 13 */ -#define IRQCS_ENABLE_PCIIRQ 0x00000100L /* Bit nø 08 */ -#define IRQCS_ENABLE_PCIDB 0x00000200L /* Bit nø 09 */ +#define IRQCS_ACTIVE_PCIDB BIT(13) +#define IRQCS_ENABLE_PCIIRQ BIT(8) +#define IRQCS_ENABLE_PCIDB BIT(9) static u32 lx_interrupt_test_ack(struct lx6464es *chip) { -- cgit v1.2.3 From 68e440bb48a35c65756471e3cb952ed7fb7cef5b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:18 +0200 Subject: ALSA: lx_core: Fix dev_dbg typo Commit be4e6d3c0fa0 ("ALSA: lx6464es: Use standard printk helpers") converted the custom printk helpers that were used before to standard dev_* functions. One of the dev_dbg calls had a typo, that was hidden away by an #if 0 .. #endif Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 652f6dfc7e1a..9e0acba82751 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -1197,7 +1197,7 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) #if 0 if (irqsrc & MASK_SYS_STATUS_EOBI) - dev_dgg(chip->card->dev, "interrupt: EOBI\n"); + dev_dbg(chip->card->dev, "interrupt: EOBI\n"); if (irqsrc & MASK_SYS_STATUS_EOBO) dev_dbg(chip->card->dev, "interrupt: EOBO\n"); -- cgit v1.2.3 From 4899210263a010b34d492d781e0d4fea82655c48 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:19 +0200 Subject: ALSA: lx_core: Remove dead code Some code was never compiled because hidden between an #if 0 .. #endif structure, and even when removing these, it was never actually used elsewhere. Remove it entirely. Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 9e0acba82751..0ad6358b5fe2 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -1041,10 +1041,6 @@ static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc, u64 orun_mask; u64 urun_mask; -#if 0 - int has_underrun = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0; - int has_overrun = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0; -#endif int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0; int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0; -- cgit v1.2.3 From 8e6320064c3350cd8610cd23d4ef5c6926e33e48 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:20 +0200 Subject: ALSA: lx_core: Remove useless #if 0 .. #endif The code contained in these sections are only dev_dbg calls, that are already removed whenever DEBUG isn't defined. Remove the redundant constructs. Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 0ad6358b5fe2..7c070864dc62 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -515,7 +515,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, *r_needed += 1; } -#if 0 dev_dbg(chip->card->dev, "CMD_08_ASK_BUFFERS: needed %d, freed %d\n", *r_needed, *r_freed); @@ -526,7 +525,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, chip->rmh.stat[i], chip->rmh.stat[i] & MASK_DATA_SIZE); } -#endif } spin_unlock_irqrestore(&chip->msg_lock, flags); @@ -1191,7 +1189,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) if (irqsrc & MASK_SYS_STATUS_CMD_DONE) goto exit; -#if 0 if (irqsrc & MASK_SYS_STATUS_EOBI) dev_dbg(chip->card->dev, "interrupt: EOBI\n"); @@ -1203,7 +1200,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) if (irqsrc & MASK_SYS_STATUS_ORUN) dev_dbg(chip->card->dev, "interrupt: ORUN\n"); -#endif if (async_pending) { u64 notified_in_pipe_mask = 0; @@ -1230,7 +1226,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) } if (async_escmd) { -#if 0 /* backdoor for ethersound commands * * for now, we do not need this @@ -1238,7 +1233,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) * */ dev_dbg(chip->card->dev, "interrupt requests escmd handling\n"); -#endif } exit: -- cgit v1.2.3 From 38137a064199a02630f136ce7bb1580d5d3fedeb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 17 Apr 2014 11:51:21 +0200 Subject: ALSA: lx_core: Translate comments from french to english For some reason, some of the comments were actually in poorly encoded french. Translate them in english like they should have been in the first place. Signed-off-by: Maxime Ripard Signed-off-by: Takashi Iwai --- sound/pci/lx6464es/lx_core.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sound') diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 7c070864dc62..e8f38e5df10a 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -1024,17 +1024,17 @@ static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc, int err; u32 stat[9]; /* answer from CMD_04_GET_EVENT */ - /* On peut optimiser pour ne pas lire les evenements vides - * les mots de réponse sont dans l'ordre suivant : - * Stat[0] mot de status général - * Stat[1] fin de buffer OUT pF - * Stat[2] fin de buffer OUT pf - * Stat[3] fin de buffer IN pF - * Stat[4] fin de buffer IN pf - * Stat[5] underrun poid fort - * Stat[6] underrun poid faible - * Stat[7] overrun poid fort - * Stat[8] overrun poid faible + /* We can optimize this to not read dumb events. + * Answer words are in the following order: + * Stat[0] general status + * Stat[1] end of buffer OUT pF + * Stat[2] end of buffer OUT pf + * Stat[3] end of buffer IN pF + * Stat[4] end of buffer IN pf + * Stat[5] MSB underrun + * Stat[6] LSB underrun + * Stat[7] MSB overrun + * Stat[8] LSB overrun * */ u64 orun_mask; -- cgit v1.2.3 From cab27258b1fdaad6380c971917b22d8d54abb7f5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 17 Apr 2014 13:42:54 +0100 Subject: ASoC: wm_adsp: Remove uneeded semicolon Reported-by: kbuild test robot Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bb5f7b4e3ebb..53e3ab5fa0de 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -1625,7 +1625,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, break; default: break; - }; + } return 0; } -- cgit v1.2.3 From 3477501274b79a904a4195b675bb74caa57d2e14 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Thu, 17 Apr 2014 20:12:56 +0800 Subject: ASoC: dapm: Allow update_bits use 32 bits reg This patch change reg's type from unsigned short to int. Signed-off-by: Bard Liao Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c8a780d0d057..f4ba7b40a6ab 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -426,7 +426,7 @@ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) } static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, - unsigned short reg, unsigned int mask, unsigned int value) + int reg, unsigned int mask, unsigned int value) { bool change; unsigned int old, new; -- cgit v1.2.3 From 1025c05f727be33e065bb502a223637681c7991d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 17 Apr 2014 16:35:43 +0800 Subject: ASoC: cs42l51: Fix mask for REVID The REVID mask was changed by commit a1253ef6d3fa "ASoC: cs42l51: split i2c from codec driver". Fix it. Signed-off-by: Axel Lin Acked-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l51.c | 3 ++- sound/soc/codecs/cs42l51.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 46abd3e02f14..6aa69e5aaa3f 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -548,7 +548,8 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap) ret = -ENODEV; goto error; } - dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", val & 0xFF); + dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", + val & CS42L51_CHIP_REV_MASK); ret = snd_soc_register_codec(dev, &soc_codec_device_cs42l51, &cs42l51_dai, 1); diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index 641ef18435b3..8c55bf384bc6 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h @@ -26,6 +26,7 @@ int cs42l51_probe(struct device *dev, struct regmap *regmap); #define CS42L51_CHIP_ID 0x1B #define CS42L51_CHIP_REV_A 0x00 #define CS42L51_CHIP_REV_B 0x01 +#define CS42L51_CHIP_REV_MASK 0x07 #define CS42L51_CHIP_REV_ID 0x01 #define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b)) -- cgit v1.2.3 From b7580cde704920da69e50d133cea16eca77ff3bd Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Tue, 15 Apr 2014 22:39:01 +0200 Subject: ASoC: core: use PTR_ERR instead of PTR_RET PTR_RET is deprecated. PTR_ERR_OR_ZERO should be used instead. However, we already know that IS_ERR is true, and thus PTR_ERR_OR_ZERO would never yield zero, so we can use PTR_ERR here. Signed-off-by: Christoph Jaeger Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 78f0c51c6c83..7f8efea5c5b1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2075,28 +2075,28 @@ static int snd_soc_ac97_parse_pinctl(struct device *dev, p = devm_pinctrl_get(dev); if (IS_ERR(p)) { dev_err(dev, "Failed to get pinctrl\n"); - return PTR_RET(p); + return PTR_ERR(p); } cfg->pctl = p; state = pinctrl_lookup_state(p, "ac97-reset"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-reset\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_reset = state; state = pinctrl_lookup_state(p, "ac97-warm-reset"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_warm_reset = state; state = pinctrl_lookup_state(p, "ac97-running"); if (IS_ERR(state)) { dev_err(dev, "Can't find pinctrl state ac97-running\n"); - return PTR_RET(state); + return PTR_ERR(state); } cfg->pstate_run = state; -- cgit v1.2.3 From 8931bf6208776292b1b888dd8534229f63e2eaa2 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:11 +0300 Subject: ASoC: Add resource managed snd_soc_register_platform() Simplify error handling and remove repetitive (and rarely executed) code for unregistration by providing a devm_snd_soc_register_platform() platform. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- include/sound/soc.h | 2 ++ sound/soc/soc-devres.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) (limited to 'sound') diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..34c34d6e095c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -377,6 +377,8 @@ int snd_soc_resume(struct device *dev); int snd_soc_poweroff(struct device *dev); int snd_soc_register_platform(struct device *dev, const struct snd_soc_platform_driver *platform_drv); +int devm_snd_soc_register_platform(struct device *dev, + const struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, const struct snd_soc_platform_driver *platform_drv); diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 7ac745df1412..e94aa0277250 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c @@ -52,6 +52,40 @@ int devm_snd_soc_register_component(struct device *dev, } EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); +static void devm_platform_release(struct device *dev, void *res) +{ + snd_soc_unregister_platform(*(struct device **)res); +} + +/** + * devm_snd_soc_register_platform - resource managed platform registration + * @dev: Device used to manage platform + * @platform: platform to register + * + * Register a platform driver with automatic unregistration when the device is + * unregistered. + */ +int devm_snd_soc_register_platform(struct device *dev, + const struct snd_soc_platform_driver *platform_drv) +{ + struct device **ptr; + int ret; + + ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = snd_soc_register_platform(dev, platform_drv); + if (ret == 0) { + *ptr = dev; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} + static void devm_card_release(struct device *dev, void *res) { snd_soc_unregister_card(*(struct snd_soc_card **)res); -- cgit v1.2.3 From f6563b31fb4878fddc846d2012bcee9c5f260d11 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:13 +0300 Subject: ASoC: omap-mcpdm: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2f5b1536477e..e984b0485e92 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -265,9 +265,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, } mutex_unlock(&mcpdm->mutex); - snd_soc_dai_set_dma_data(dai, substream, - &mcpdm->dma_data[substream->stream]); - return 0; } @@ -406,6 +403,11 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = MCPDM_UP_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, + &mcpdm->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcpdm->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return ret; } -- cgit v1.2.3 From 335b06515eda252b36aa9063596f740a903c1e35 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:14 +0300 Subject: ASoC: omap-mcpdm: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcpdm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index e984b0485e92..d8ebb52645a9 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -42,6 +42,7 @@ #include #include "omap-mcpdm.h" +#include "omap-pcm.h" struct mcpdm_link_config { u32 link_mask; /* channel mask for the direction */ @@ -462,6 +463,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) { struct omap_mcpdm *mcpdm; struct resource *res; + int ret; mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); if (!mcpdm) @@ -492,9 +494,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; - return devm_snd_soc_register_component(&pdev->dev, + ret = devm_snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, &omap_mcpdm_dai, 1); + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static const struct of_device_id omap_mcpdm_of_match[] = { -- cgit v1.2.3 From 3fe856b3127744ce30d4369ba760459b6ac9f820 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:15 +0300 Subject: ASoC: omap-mcbsp: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6c19bba23570..4525190d5599 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -149,9 +149,6 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); } - snd_soc_dai_set_dma_data(cpu_dai, substream, - &mcbsp->dma_data[substream->stream]); - return err; } @@ -559,6 +556,10 @@ static int omap_mcbsp_probe(struct snd_soc_dai *dai) pm_runtime_enable(mcbsp->dev); + snd_soc_dai_init_dma_data(dai, + &mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return 0; } -- cgit v1.2.3 From 64241425b8eaf46c971b6ba400c21f71979e6782 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:16 +0300 Subject: ASoC: omap-mcbsp: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-mcbsp.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 4525190d5599..af2764adf252 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -38,6 +38,7 @@ #include #include "mcbsp.h" #include "omap-mcbsp.h" +#include "omap-pcm.h" #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) @@ -800,11 +801,15 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mcbsp); ret = omap_mcbsp_init(pdev); - if (!ret) - return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, - &omap_mcbsp_dai, 1); + if (ret) + return ret; - return ret; + ret = snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, + &omap_mcbsp_dai, 1); + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static int asoc_mcbsp_remove(struct platform_device *pdev) -- cgit v1.2.3 From fe7b5868809a89a7316eef064f0bb7796aa8c225 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:12 +0300 Subject: ASoC: omap-pcm: Support for binding the platform driver to dai devices With the new calls it is going to be possible to bind the platform driver to a dai device which makes it easier for us in a long run to handle DT boots, and opens the possibility to move machine driver to generic simple card. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-pcm.c | 6 ++++++ sound/soc/omap/omap-pcm.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 sound/soc/omap/omap-pcm.h (limited to 'sound') diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07b8b7bc9d20..c3711b582d5f 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -232,6 +232,12 @@ static struct snd_soc_platform_driver omap_soc_platform = { .pcm_free = omap_pcm_free_dma_buffers, }; +int omap_pcm_platform_register(struct device *dev) +{ + return devm_snd_soc_register_platform(dev, &omap_soc_platform); +} +EXPORT_SYMBOL_GPL(omap_pcm_platform_register); + static int omap_pcm_probe(struct platform_device *pdev) { return snd_soc_register_platform(&pdev->dev, diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h new file mode 100644 index 000000000000..c1d2f31d71e9 --- /dev/null +++ b/sound/soc/omap/omap-pcm.h @@ -0,0 +1,30 @@ +/* + * omap-pcm.h - OMAP PCM driver + * + * Copyright (C) 2014 Texas Instruments, Inc. + * + * Author: Peter Ujfalusi + * + * 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. + */ + +#ifndef __OMAP_PCM_H__ +#define __OMAP_PCM_H__ + +#if IS_ENABLED(CONFIG_SND_OMAP_SOC) +int omap_pcm_platform_register(struct device *dev); +#else +static inline int omap_pcm_platform_register(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_SND_OMAP_SOC */ + +#endif /* __OMAP_PCM_H__ */ -- cgit v1.2.3 From 3802a259272e48870b8d7e02c4fc28f938a699cb Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:17 +0300 Subject: ASoC: omap-dmic: Assign the dai DMA data at earlier time Assign the dai dma data at dai driver probe time, not in startup. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 1bd531d718f9..7fb7703264fa 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -113,7 +113,6 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_unlock(&dmic->mutex); - snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); return ret; } @@ -417,6 +416,9 @@ static int omap_dmic_probe(struct snd_soc_dai *dai) /* Configure DMIC threshold value */ dmic->threshold = OMAP_DMIC_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, NULL, &dmic->dma_data); + return 0; } -- cgit v1.2.3 From 18d7cfea28fe7e06047abef40a18db2643a427be Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:18 +0300 Subject: ASoC: omap-dmic: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-dmic.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sound') diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 7fb7703264fa..53da041896c4 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -42,6 +42,7 @@ #include #include "omap-dmic.h" +#include "omap-pcm.h" struct omap_dmic { struct device *dev; @@ -494,6 +495,10 @@ static int asoc_dmic_probe(struct platform_device *pdev) if (ret) goto err_put_clk; + ret = omap_pcm_platform_register(&pdev->dev); + if (ret) + goto err_put_clk; + return 0; err_put_clk: -- cgit v1.2.3 From 9769824cf9ca4bb877146dbec2695bdbf577c499 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 16 Apr 2014 15:46:19 +0300 Subject: ASoC: omap-hdmi: Bind the platform driver to the dai driver when loading Use the same device for the platform driver when registering as the dai driver. This will enable us to clean up some DT booted cases. Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/omap/omap-hdmi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index ced3b88b44d4..32614b49653c 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -36,6 +36,7 @@ #include