Commit fa079ba8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-5.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "The only largish change in this pull request is about the revert of
  the recent max98090 and its relevant patches due to regressions.

  Other than that, all small fixes for ALSA core (covering KCSAN fuzzer
  warnings in ALSA sequencer and rawmidi), Intel SOF HD-audio fixes, AMD
  ACP fixes, usual HD-audio quirks, and various ASoC fixes"

* tag 'sound-5.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda: Use scnprintf() for printing texts for sysfs/procfs
  ALSA: hda/realtek - Apply quirk for yet another MSI laptop
  ASoC: sun8i-codec: Fix setting DAI data format
  ALSA: hda/realtek - Apply quirk for MSI GP63, too
  ASoC: amd: ACP needs to be powered off in BIOS.
  ASoC: hdmi-codec: set plugged_cb to NULL when component removing
  ASoC: dapm: remove snd_soc_dapm_put_enum_double_locked
  ASoC: max98090: revert invalid fix for handling SHDN
  ALSA: rawmidi: Avoid bit fields for state flags
  ALSA: seq: Fix concurrent access to queue current tick/time
  ALSA: seq: Avoid concurrent access to queue flags
  ASoC: codec2codec: avoid invalid/double-free of pcm runtime
  ASoC: amd: Buffer Size instead of MAX Buffer
  ASoC: SOF: Intel: hda: move i915 init earlier
  ASoC: SOF: Intel: hda: fix ordering bug in resume flow
  ALSA: hda: do not override bus codec_mask in link_get()
  ASoC: atmel: fix atmel_ssc_set_audio link failure
  ASoC: fsl_sai: Fix exiting path on probing failure
parents 0a44cac8 38553609
......@@ -77,9 +77,9 @@ struct snd_rawmidi_substream {
struct list_head list; /* list of all substream for given stream */
int stream; /* direction */
int number; /* substream number */
unsigned int opened: 1, /* open flag */
append: 1, /* append flag (merge more streams) */
active_sensing: 1; /* send active sensing when close */
bool opened; /* open flag */
bool append; /* append flag (merge more streams) */
bool active_sensing; /* send active sensing when close */
int use_count; /* use counter (for output) */
size_t bytes;
struct snd_rawmidi *rmidi;
......
......@@ -392,8 +392,6 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_put_enum_double_locked(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_dapm_info_pin_switch(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo);
int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
......
......@@ -580,7 +580,7 @@ static int update_timestamp_of_queue(struct snd_seq_event *event,
event->queue = queue;
event->flags &= ~SNDRV_SEQ_TIME_STAMP_MASK;
if (real_time) {
event->time.time = snd_seq_timer_get_cur_time(q->timer);
event->time.time = snd_seq_timer_get_cur_time(q->timer, true);
event->flags |= SNDRV_SEQ_TIME_STAMP_REAL;
} else {
event->time.tick = snd_seq_timer_get_cur_tick(q->timer);
......@@ -1659,7 +1659,7 @@ static int snd_seq_ioctl_get_queue_status(struct snd_seq_client *client,
tmr = queue->timer;
status->events = queue->tickq->cells + queue->timeq->cells;
status->time = snd_seq_timer_get_cur_time(tmr);
status->time = snd_seq_timer_get_cur_time(tmr, true);
status->tick = snd_seq_timer_get_cur_tick(tmr);
status->running = tmr->running;
......
......@@ -238,6 +238,8 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
{
unsigned long flags;
struct snd_seq_event_cell *cell;
snd_seq_tick_time_t cur_tick;
snd_seq_real_time_t cur_time;
if (q == NULL)
return;
......@@ -254,17 +256,18 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop)
__again:
/* Process tick queue... */
cur_tick = snd_seq_timer_get_cur_tick(q->timer);
for (;;) {
cell = snd_seq_prioq_cell_out(q->tickq,
&q->timer->tick.cur_tick);
cell = snd_seq_prioq_cell_out(q->tickq, &cur_tick);
if (!cell)
break;
snd_seq_dispatch_event(cell, atomic, hop);
}
/* Process time queue... */
cur_time = snd_seq_timer_get_cur_time(q->timer, false);
for (;;) {
cell = snd_seq_prioq_cell_out(q->timeq, &q->timer->cur_time);
cell = snd_seq_prioq_cell_out(q->timeq, &cur_time);
if (!cell)
break;
snd_seq_dispatch_event(cell, atomic, hop);
......@@ -392,6 +395,7 @@ int snd_seq_queue_check_access(int queueid, int client)
int snd_seq_queue_set_owner(int queueid, int client, int locked)
{
struct snd_seq_queue *q = queueptr(queueid);
unsigned long flags;
if (q == NULL)
return -EINVAL;
......@@ -401,8 +405,10 @@ int snd_seq_queue_set_owner(int queueid, int client, int locked)
return -EPERM;
}
spin_lock_irqsave(&q->owner_lock, flags);
q->locked = locked ? 1 : 0;
q->owner = client;
spin_unlock_irqrestore(&q->owner_lock, flags);
queue_access_unlock(q);
queuefree(q);
......@@ -539,15 +545,17 @@ void snd_seq_queue_client_termination(int client)
unsigned long flags;
int i;
struct snd_seq_queue *q;
bool matched;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
if ((q = queueptr(i)) == NULL)
continue;
spin_lock_irqsave(&q->owner_lock, flags);
if (q->owner == client)
matched = (q->owner == client);
if (matched)
q->klocked = 1;
spin_unlock_irqrestore(&q->owner_lock, flags);
if (q->owner == client) {
if (matched) {
if (q->timer->running)
snd_seq_timer_stop(q->timer);
snd_seq_timer_reset(q->timer);
......@@ -739,6 +747,8 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry,
int i, bpm;
struct snd_seq_queue *q;
struct snd_seq_timer *tmr;
bool locked;
int owner;
for (i = 0; i < SNDRV_SEQ_MAX_QUEUES; i++) {
if ((q = queueptr(i)) == NULL)
......@@ -750,9 +760,14 @@ void snd_seq_info_queues_read(struct snd_info_entry *entry,
else
bpm = 0;
spin_lock_irq(&q->owner_lock);
locked = q->locked;
owner = q->owner;
spin_unlock_irq(&q->owner_lock);
snd_iprintf(buffer, "queue %d: [%s]\n", q->queue, q->name);
snd_iprintf(buffer, "owned by client : %d\n", q->owner);
snd_iprintf(buffer, "lock status : %s\n", q->locked ? "Locked" : "Free");
snd_iprintf(buffer, "owned by client : %d\n", owner);
snd_iprintf(buffer, "lock status : %s\n", locked ? "Locked" : "Free");
snd_iprintf(buffer, "queued time events : %d\n", snd_seq_prioq_avail(q->timeq));
snd_iprintf(buffer, "queued tick events : %d\n", snd_seq_prioq_avail(q->tickq));
snd_iprintf(buffer, "timer state : %s\n", tmr->running ? "Running" : "Stopped");
......
......@@ -428,14 +428,15 @@ int snd_seq_timer_continue(struct snd_seq_timer *tmr)
}
/* return current 'real' time. use timeofday() to get better granularity. */
snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr,
bool adjust_ktime)
{
snd_seq_real_time_t cur_time;
unsigned long flags;
spin_lock_irqsave(&tmr->lock, flags);
cur_time = tmr->cur_time;
if (tmr->running) {
if (adjust_ktime && tmr->running) {
struct timespec64 tm;
ktime_get_ts64(&tm);
......@@ -452,7 +453,13 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
high PPQ values) */
snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr)
{
return tmr->tick.cur_tick;
snd_seq_tick_time_t cur_tick;
unsigned long flags;
spin_lock_irqsave(&tmr->lock, flags);
cur_tick = tmr->tick.cur_tick;
spin_unlock_irqrestore(&tmr->lock, flags);
return cur_tick;
}
......
......@@ -120,7 +120,8 @@ int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq);
int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position);
int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position);
int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base);
snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr);
snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr,
bool adjust_ktime);
snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr);
extern int seq_default_timer_class;
......
......@@ -254,6 +254,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all);
int snd_hdac_ext_bus_link_get(struct hdac_bus *bus,
struct hdac_ext_link *link)
{
unsigned long codec_mask;
int ret = 0;
mutex_lock(&bus->lock);
......@@ -280,9 +281,11 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus,
* HDA spec section 4.3 - Codec Discovery
*/
udelay(521);
bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
snd_hdac_chip_writew(bus, STATESTS, bus->codec_mask);
codec_mask = snd_hdac_chip_readw(bus, STATESTS);
dev_dbg(bus->dev, "codec_mask = 0x%lx\n", codec_mask);
snd_hdac_chip_writew(bus, STATESTS, codec_mask);
if (!bus->codec_mask)
bus->codec_mask = codec_mask;
}
mutex_unlock(&bus->lock);
......
......@@ -250,7 +250,7 @@ void snd_hdac_print_channel_allocation(int spk_alloc, char *buf, int buflen)
for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
if (spk_alloc & (1 << i))
j += snprintf(buf + j, buflen - j, " %s",
j += scnprintf(buf + j, buflen - j, " %s",
cea_speaker_allocation_names[i]);
}
buf[j] = '\0'; /* necessary when j == 0 */
......
......@@ -4022,7 +4022,7 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen)
for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
if (pcm & (AC_SUPPCM_BITS_8 << i))
j += snprintf(buf + j, buflen - j, " %d", bits[i]);
j += scnprintf(buf + j, buflen - j, " %d", bits[i]);
buf[j] = '\0'; /* necessary when j == 0 */
}
......
......@@ -360,7 +360,7 @@ static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen)
for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++)
if (pcm & (1 << i))
j += snprintf(buf + j, buflen - j, " %d",
j += scnprintf(buf + j, buflen - j, " %d",
alsa_rates[i]);
buf[j] = '\0'; /* necessary when j == 0 */
......
......@@ -222,7 +222,7 @@ static ssize_t init_verbs_show(struct device *dev,
int i, len = 0;
mutex_lock(&codec->user_mutex);
snd_array_for_each(&codec->init_verbs, i, v) {
len += snprintf(buf + len, PAGE_SIZE - len,
len += scnprintf(buf + len, PAGE_SIZE - len,
"0x%02x 0x%03x 0x%04x\n",
v->nid, v->verb, v->param);
}
......@@ -272,7 +272,7 @@ static ssize_t hints_show(struct device *dev,
int i, len = 0;
mutex_lock(&codec->user_mutex);
snd_array_for_each(&codec->hints, i, hint) {
len += snprintf(buf + len, PAGE_SIZE - len,
len += scnprintf(buf + len, PAGE_SIZE - len,
"%s = %s\n", hint->key, hint->val);
}
mutex_unlock(&codec->user_mutex);
......
......@@ -2447,7 +2447,9 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD),
SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
SND_PCI_QUIRK(0x1458, 0xa0b8, "Gigabyte AZ370-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
SND_PCI_QUIRK(0x1462, 0x1228, "MSI-GP63", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1276, "MSI-GL73", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x1293, "MSI-GP65", ALC1220_FIXUP_CLEVO_P950),
SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
SND_PCI_QUIRK(0x1462, 0xda57, "MSI Z270-Gaming", ALC1220_FIXUP_GB_DUAL_CODECS),
SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
......
......@@ -170,6 +170,7 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
struct snd_soc_card *card;
struct acp3x_platform_info *pinfo;
u32 ret, val, period_bytes, reg_val, ier_val, water_val;
u32 buf_size, buf_reg;
prtd = substream->private_data;
rtd = substream->runtime->private_data;
......@@ -183,6 +184,8 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
}
period_bytes = frames_to_bytes(substream->runtime,
substream->runtime->period_size);
buf_size = frames_to_bytes(substream->runtime,
substream->runtime->buffer_size);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
......@@ -196,6 +199,7 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
mmACP_BT_TX_INTR_WATERMARK_SIZE;
reg_val = mmACP_BTTDM_ITER;
ier_val = mmACP_BTTDM_IER;
buf_reg = mmACP_BT_TX_RINGBUFSIZE;
break;
case I2S_SP_INSTANCE:
default:
......@@ -203,6 +207,7 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
mmACP_I2S_TX_INTR_WATERMARK_SIZE;
reg_val = mmACP_I2STDM_ITER;
ier_val = mmACP_I2STDM_IER;
buf_reg = mmACP_I2S_TX_RINGBUFSIZE;
}
} else {
switch (rtd->i2s_instance) {
......@@ -211,6 +216,7 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
mmACP_BT_RX_INTR_WATERMARK_SIZE;
reg_val = mmACP_BTTDM_IRER;
ier_val = mmACP_BTTDM_IER;
buf_reg = mmACP_BT_RX_RINGBUFSIZE;
break;
case I2S_SP_INSTANCE:
default:
......@@ -218,9 +224,11 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
mmACP_I2S_RX_INTR_WATERMARK_SIZE;
reg_val = mmACP_I2STDM_IRER;
ier_val = mmACP_I2STDM_IER;
buf_reg = mmACP_I2S_RX_RINGBUFSIZE;
}
}
rv_writel(period_bytes, rtd->acp3x_base + water_val);
rv_writel(buf_size, rtd->acp3x_base + buf_reg);
val = rv_readl(rtd->acp3x_base + reg_val);
val = val | BIT(0);
rv_writel(val, rtd->acp3x_base + reg_val);
......
......@@ -110,7 +110,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
{
u16 page_idx;
u32 low, high, val, acp_fifo_addr, reg_fifo_addr;
u32 reg_ringbuf_size, reg_dma_size, reg_fifo_size;
u32 reg_dma_size, reg_fifo_size;
dma_addr_t addr;
addr = rtd->dma_addr;
......@@ -157,7 +157,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
switch (rtd->i2s_instance) {
case I2S_BT_INSTANCE:
reg_ringbuf_size = mmACP_BT_TX_RINGBUFSIZE;
reg_dma_size = mmACP_BT_TX_DMA_SIZE;
acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
BT_PB_FIFO_ADDR_OFFSET;
......@@ -169,7 +168,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
case I2S_SP_INSTANCE:
default:
reg_ringbuf_size = mmACP_I2S_TX_RINGBUFSIZE;
reg_dma_size = mmACP_I2S_TX_DMA_SIZE;
acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
SP_PB_FIFO_ADDR_OFFSET;
......@@ -181,7 +179,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
} else {
switch (rtd->i2s_instance) {
case I2S_BT_INSTANCE:
reg_ringbuf_size = mmACP_BT_RX_RINGBUFSIZE;
reg_dma_size = mmACP_BT_RX_DMA_SIZE;
acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
BT_CAPT_FIFO_ADDR_OFFSET;
......@@ -193,7 +190,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
case I2S_SP_INSTANCE:
default:
reg_ringbuf_size = mmACP_I2S_RX_RINGBUFSIZE;
reg_dma_size = mmACP_I2S_RX_DMA_SIZE;
acp_fifo_addr = ACP_SRAM_PTE_OFFSET +
SP_CAPT_FIFO_ADDR_OFFSET;
......@@ -203,7 +199,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
rtd->acp3x_base + mmACP_I2S_RX_RINGBUFADDR);
}
}
rv_writel(MAX_BUFFER, rtd->acp3x_base + reg_ringbuf_size);
rv_writel(DMA_SIZE, rtd->acp3x_base + reg_dma_size);
rv_writel(acp_fifo_addr, rtd->acp3x_base + reg_fifo_addr);
rv_writel(FIFO_SIZE, rtd->acp3x_base + reg_fifo_size);
......
......@@ -45,23 +45,6 @@ static int acp3x_power_on(void __iomem *acp3x_base)
return -ETIMEDOUT;
}
static int acp3x_power_off(void __iomem *acp3x_base)
{
u32 val;
int timeout;
rv_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
acp3x_base + mmACP_PGFSM_CONTROL);
timeout = 0;
while (++timeout < 500) {
val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS);
if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
return 0;
udelay(1);
}
return -ETIMEDOUT;
}
static int acp3x_reset(void __iomem *acp3x_base)
{
u32 val;
......@@ -115,12 +98,6 @@ static int acp3x_deinit(void __iomem *acp3x_base)
pr_err("ACP3x reset failed\n");
return ret;
}
/* power off */
ret = acp3x_power_off(acp3x_base);
if (ret) {
pr_err("ACP3x power off failed\n");
return ret;
}
return 0;
}
......
......@@ -10,11 +10,11 @@ config SND_ATMEL_SOC
if SND_ATMEL_SOC
config SND_ATMEL_SOC_PDC
tristate
bool
depends on HAS_DMA
config SND_ATMEL_SOC_DMA
tristate
bool
select SND_SOC_GENERIC_DMAENGINE_PCM
config SND_ATMEL_SOC_SSC
......
......@@ -6,8 +6,14 @@ snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
snd-soc-atmel-i2s-objs := atmel-i2s.o
snd-soc-mchp-i2s-mcc-objs := mchp-i2s-mcc.o
obj-$(CONFIG_SND_ATMEL_SOC_PDC) += snd-soc-atmel-pcm-pdc.o
obj-$(CONFIG_SND_ATMEL_SOC_DMA) += snd-soc-atmel-pcm-dma.o
# pdc and dma need to both be built-in if any user of
# ssc is built-in.
ifdef CONFIG_SND_ATMEL_SOC_PDC
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel-pcm-pdc.o
endif
ifdef CONFIG_SND_ATMEL_SOC_DMA
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel-pcm-dma.o
endif
obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
obj-$(CONFIG_SND_ATMEL_SOC_I2S) += snd-soc-atmel-i2s.o
obj-$(CONFIG_SND_MCHP_SOC_I2S_MCC) += snd-soc-mchp-i2s-mcc.o
......
......@@ -779,7 +779,17 @@ static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
return ret;
}
static void hdmi_remove(struct snd_soc_component *component)
{
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
if (hcp->hcd.ops->hook_plugged_cb)
hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
hcp->hcd.data, NULL, NULL);
}
static const struct snd_soc_component_driver hdmi_driver = {
.remove = hdmi_remove,
.dapm_widgets = hdmi_widgets,
.num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
.of_xlate_dai_id = hdmi_of_xlate_dai_id,
......
......@@ -5,150 +5,24 @@
* Copyright 2011-2012 Maxim Integrated Products
*/
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <sound/jack.h>
#include <sound/max98090.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/max98090.h>
#include "max98090.h"
static void max98090_shdn_save_locked(struct max98090_priv *max98090)
{
int shdn = 0;
/* saved_shdn, saved_count, SHDN are protected by card->dapm_mutex */
regmap_read(max98090->regmap, M98090_REG_DEVICE_SHUTDOWN, &shdn);
max98090->saved_shdn |= shdn;
++max98090->saved_count;
if (shdn)
regmap_write(max98090->regmap, M98090_REG_DEVICE_SHUTDOWN, 0x0);
}
static void max98090_shdn_restore_locked(struct max98090_priv *max98090)
{
/* saved_shdn, saved_count, SHDN are protected by card->dapm_mutex */
if (--max98090->saved_count == 0) {
if (max98090->saved_shdn) {
regmap_write(max98090->regmap,
M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK);
max98090->saved_shdn = 0;
}
}
}
static void max98090_shdn_save(struct max98090_priv *max98090)
{
mutex_lock_nested(&max98090->component->card->dapm_mutex,
SND_SOC_DAPM_CLASS_RUNTIME);
max98090_shdn_save_locked(max98090);
}
static void max98090_shdn_restore(struct max98090_priv *max98090)
{
max98090_shdn_restore_locked(max98090);
mutex_unlock(&max98090->component->card->dapm_mutex);
}
static int max98090_put_volsw(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct max98090_priv *max98090 =
snd_soc_component_get_drvdata(component);
int ret;
max98090_shdn_save(max98090);
ret = snd_soc_put_volsw(kcontrol, ucontrol);
max98090_shdn_restore(max98090);
return ret;
}
static int max98090_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_dapm_kcontrol_component(kcontrol);
struct max98090_priv *max98090 =
snd_soc_component_get_drvdata(component);
int ret;
max98090_shdn_save(max98090);
ret = snd_soc_dapm_put_enum_double_locked(kcontrol, ucontrol);
max98090_shdn_restore(max98090);
return ret;
}
static int max98090_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct max98090_priv *max98090 =
snd_soc_component_get_drvdata(component);
int ret;
max98090_shdn_save(max98090);
ret = snd_soc_put_enum_double(kcontrol, ucontrol);
max98090_shdn_restore(max98090);
return ret;
}
static int max98090_bytes_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component =
snd_soc_kcontrol_component(kcontrol);
struct max98090_priv *max98090 =
snd_soc_component_get_drvdata(component);
int ret;
max98090_shdn_save(max98090);
ret = snd_soc_bytes_put(kcontrol, ucontrol);
max98090_shdn_restore(max98090);
return ret;
}
static int max98090_dapm_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
struct max98090_priv *max98090 =
snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
case SND_SOC_DAPM_PRE_PMD:
max98090_shdn_save_locked(max98090);
break;
case SND_SOC_DAPM_POST_PMU:
case SND_SOC_DAPM_POST_PMD:
max98090_shdn_restore_locked(max98090);
break;
}
return 0;
}
/* Allows for sparsely populated register maps */
static const struct reg_default max98090_reg[] = {
{ 0x00, 0x00 }, /* 00 Software Reset */
......@@ -632,13 +506,10 @@ static SOC_ENUM_SINGLE_DECL(max98090_adchp_enum,
max98090_pwr_perf_text);
static const struct snd_kcontrol_new max98090_snd_controls[] = {
SOC_ENUM_EXT("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_ENUM("MIC Bias VCM Bandgap", max98090_vcmbandgap_enum),
SOC_SINGLE_EXT("DMIC MIC Comp Filter Config",
M98090_REG_DIGITAL_MIC_CONFIG,
M98090_DMIC_COMP_SHIFT, M98090_DMIC_COMP_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE("DMIC MIC Comp Filter Config", M98090_REG_DIGITAL_MIC_CONFIG,
M98090_DMIC_COMP_SHIFT, M98090_DMIC_COMP_NUM - 1, 0),
SOC_SINGLE_EXT_TLV("MIC1 Boost Volume",
M98090_REG_MIC1_INPUT_LEVEL, M98090_MIC_PA1EN_SHIFT,
......@@ -693,34 +564,24 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = {
M98090_AVR_SHIFT, M98090_AVR_NUM - 1, 1,
max98090_av_tlv),
SOC_ENUM_EXT("ADC Oversampling Rate", max98090_osr128_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE_EXT("ADC Quantizer Dither", M98090_REG_ADC_CONTROL,
M98090_ADCDITHER_SHIFT, M98090_ADCDITHER_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_ENUM_EXT("ADC High Performance Mode", max98090_adchp_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE_EXT("DAC Mono Mode", M98090_REG_IO_CONFIGURATION,
M98090_DMONO_SHIFT, M98090_DMONO_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("SDIN Mode", M98090_REG_IO_CONFIGURATION,
M98090_SDIEN_SHIFT, M98090_SDIEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("SDOUT Mode", M98090_REG_IO_CONFIGURATION,
M98090_SDOEN_SHIFT, M98090_SDOEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("SDOUT Hi-Z Mode", M98090_REG_IO_CONFIGURATION,
M98090_HIZOFF_SHIFT, M98090_HIZOFF_NUM - 1, 1,
snd_soc_get_volsw, max98090_put_volsw),
SOC_ENUM_EXT("Filter Mode", max98090_mode_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE_EXT("Record Path DC Blocking", M98090_REG_FILTER_CONFIG,
M98090_AHPF_SHIFT, M98090_AHPF_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("Playback Path DC Blocking", M98090_REG_FILTER_CONFIG,
M98090_DHPF_SHIFT, M98090_DHPF_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_ENUM("ADC Oversampling Rate", max98090_osr128_enum),
SOC_SINGLE("ADC Quantizer Dither", M98090_REG_ADC_CONTROL,
M98090_ADCDITHER_SHIFT, M98090_ADCDITHER_NUM - 1, 0),
SOC_ENUM("ADC High Performance Mode", max98090_adchp_enum),
SOC_SINGLE("DAC Mono Mode", M98090_REG_IO_CONFIGURATION,
M98090_DMONO_SHIFT, M98090_DMONO_NUM - 1, 0),
SOC_SINGLE("SDIN Mode", M98090_REG_IO_CONFIGURATION,
M98090_SDIEN_SHIFT, M98090_SDIEN_NUM - 1, 0),
SOC_SINGLE("SDOUT Mode", M98090_REG_IO_CONFIGURATION,
M98090_SDOEN_SHIFT, M98090_SDOEN_NUM - 1, 0),
SOC_SINGLE("SDOUT Hi-Z Mode", M98090_REG_IO_CONFIGURATION,
M98090_HIZOFF_SHIFT, M98090_HIZOFF_NUM - 1, 1),
SOC_ENUM("Filter Mode", max98090_mode_enum),
SOC_SINGLE("Record Path DC Blocking", M98090_REG_FILTER_CONFIG,
M98090_AHPF_SHIFT, M98090_AHPF_NUM - 1, 0),
SOC_SINGLE("Playback Path DC Blocking", M98090_REG_FILTER_CONFIG,
M98090_DHPF_SHIFT, M98090_DHPF_NUM - 1, 0),
SOC_SINGLE_TLV("Digital BQ Volume", M98090_REG_ADC_BIQUAD_LEVEL,
M98090_AVBQ_SHIFT, M98090_AVBQ_NUM - 1, 1, max98090_dv_tlv),
SOC_SINGLE_EXT_TLV("Digital Sidetone Volume",
......@@ -733,17 +594,13 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = {
SOC_SINGLE_TLV("Digital Volume", M98090_REG_DAI_PLAYBACK_LEVEL,
M98090_DV_SHIFT, M98090_DV_NUM - 1, 1,
max98090_dv_tlv),
SND_SOC_BYTES_E("EQ Coefficients", M98090_REG_EQUALIZER_BASE, 105,
snd_soc_bytes_get, max98090_bytes_put),
SOC_SINGLE_EXT("Digital EQ 3 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ3BANDEN_SHIFT, M98090_EQ3BANDEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("Digital EQ 5 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ5BANDEN_SHIFT, M98090_EQ5BANDEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE_EXT("Digital EQ 7 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ7BANDEN_SHIFT, M98090_EQ7BANDEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SND_SOC_BYTES("EQ Coefficients", M98090_REG_EQUALIZER_BASE, 105),
SOC_SINGLE("Digital EQ 3 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ3BANDEN_SHIFT, M98090_EQ3BANDEN_NUM - 1, 0),
SOC_SINGLE("Digital EQ 5 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ5BANDEN_SHIFT, M98090_EQ5BANDEN_NUM - 1, 0),
SOC_SINGLE("Digital EQ 7 Band Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_EQ7BANDEN_SHIFT, M98090_EQ7BANDEN_NUM - 1, 0),
SOC_SINGLE("Digital EQ Clipping Detection", M98090_REG_DAI_PLAYBACK_LEVEL_EQ,
M98090_EQCLPN_SHIFT, M98090_EQCLPN_NUM - 1,
1),
......@@ -751,34 +608,25 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = {
M98090_DVEQ_SHIFT, M98090_DVEQ_NUM - 1, 1,
max98090_dv_tlv),
SOC_SINGLE_EXT("ALC Enable", M98090_REG_DRC_TIMING,
M98090_DRCEN_SHIFT, M98090_DRCEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_ENUM_EXT("ALC Attack Time", max98090_drcatk_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_ENUM_EXT("ALC Release Time", max98090_drcrls_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE("ALC Enable", M98090_REG_DRC_TIMING,
M98090_DRCEN_SHIFT, M98090_DRCEN_NUM - 1, 0),
SOC_ENUM("ALC Attack Time", max98090_drcatk_enum),
SOC_ENUM("ALC Release Time", max98090_drcrls_enum),
SOC_SINGLE_TLV("ALC Make Up Volume", M98090_REG_DRC_GAIN,
M98090_DRCG_SHIFT, M98090_DRCG_NUM - 1, 0,
max98090_alcmakeup_tlv),
SOC_ENUM_EXT("ALC Compression Ratio", max98090_alccmp_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_ENUM_EXT("ALC Expansion Ratio", max98090_drcexp_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE_EXT_TLV("ALC Compression Threshold Volume",
SOC_ENUM("ALC Compression Ratio", max98090_alccmp_enum),
SOC_ENUM("ALC Expansion Ratio", max98090_drcexp_enum),
SOC_SINGLE_TLV("ALC Compression Threshold Volume",
M98090_REG_DRC_COMPRESSOR, M98090_DRCTHC_SHIFT,
M98090_DRCTHC_NUM - 1, 1,
snd_soc_get_volsw, max98090_put_volsw, max98090_alccomp_tlv),
SOC_SINGLE_EXT_TLV("ALC Expansion Threshold Volume",
M98090_DRCTHC_NUM - 1, 1, max98090_alccomp_tlv),
SOC_SINGLE_TLV("ALC Expansion Threshold Volume",
M98090_REG_DRC_EXPANDER, M98090_DRCTHE_SHIFT,
M98090_DRCTHE_NUM - 1, 1,
snd_soc_get_volsw, max98090_put_volsw, max98090_drcexp_tlv),
M98090_DRCTHE_NUM - 1, 1, max98090_drcexp_tlv),
SOC_ENUM_EXT("DAC HP Playback Performance Mode",
max98090_dac_perfmode_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_ENUM_EXT("DAC High Performance Mode", max98090_dachp_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_ENUM("DAC HP Playback Performance Mode",
max98090_dac_perfmode_enum),
SOC_ENUM("DAC High Performance Mode", max98090_dachp_enum),
SOC_SINGLE_TLV("Headphone Left Mixer Volume",
M98090_REG_HP_CONTROL, M98090_MIXHPLG_SHIFT,
......@@ -836,12 +684,9 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = {
SOC_SINGLE("Volume Adjustment Smoothing", M98090_REG_LEVEL_CONTROL,
M98090_VSENN_SHIFT, M98090_VSENN_NUM - 1, 1),
SND_SOC_BYTES_E("Biquad Coefficients",
M98090_REG_RECORD_BIQUAD_BASE, 15,
snd_soc_bytes_get, max98090_bytes_put),
SOC_SINGLE_EXT("Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_ADCBQEN_SHIFT, M98090_ADCBQEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SND_SOC_BYTES("Biquad Coefficients", M98090_REG_RECORD_BIQUAD_BASE, 15),
SOC_SINGLE("Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_ADCBQEN_SHIFT, M98090_ADCBQEN_NUM - 1, 0),
};
static const struct snd_kcontrol_new max98091_snd_controls[] = {
......@@ -850,12 +695,10 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = {
M98090_DMIC34_ZEROPAD_SHIFT,
M98090_DMIC34_ZEROPAD_NUM - 1, 0),
SOC_ENUM_EXT("Filter DMIC34 Mode", max98090_filter_dmic34mode_enum,
snd_soc_get_enum_double, max98090_put_enum_double),
SOC_SINGLE_EXT("DMIC34 DC Blocking", M98090_REG_FILTER_CONFIG,
SOC_ENUM("Filter DMIC34 Mode", max98090_filter_dmic34mode_enum),
SOC_SINGLE("DMIC34 DC Blocking", M98090_REG_FILTER_CONFIG,
M98090_FLT_DMIC34HPF_SHIFT,
M98090_FLT_DMIC34HPF_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
M98090_FLT_DMIC34HPF_NUM - 1, 0),
SOC_SINGLE_TLV("DMIC3 Boost Volume", M98090_REG_DMIC3_VOLUME,
M98090_DMIC_AV3G_SHIFT, M98090_DMIC_AV3G_NUM - 1, 0,
......@@ -873,9 +716,8 @@ static const struct snd_kcontrol_new max98091_snd_controls[] = {
SND_SOC_BYTES("DMIC34 Biquad Coefficients",
M98090_REG_DMIC34_BIQUAD_BASE, 15),
SOC_SINGLE_EXT("DMIC34 Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_DMIC34BQEN_SHIFT, M98090_DMIC34BQEN_NUM - 1, 0,
snd_soc_get_volsw, max98090_put_volsw),
SOC_SINGLE("DMIC34 Biquad Switch", M98090_REG_DSP_FILTER_ENABLE,
M98090_DMIC34BQEN_SHIFT, M98090_DMIC34BQEN_NUM - 1, 0),
SOC_SINGLE_TLV("DMIC34 BQ PreAttenuation Volume",
M98090_REG_DMIC34_BQ_PREATTEN, M98090_AV34BQ_SHIFT,
......@@ -929,6 +771,19 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
return 0;
}
static int max98090_shdn_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
if (event & SND_SOC_DAPM_POST_PMU)
max98090->shdn_pending = true;
return 0;
}
static const char *mic1_mux_text[] = { "IN12", "IN56" };
static SOC_ENUM_SINGLE_DECL(mic1_mux_enum,
......@@ -1029,14 +884,10 @@ static SOC_ENUM_SINGLE_DECL(ltenr_mux_enum,
lten_mux_text);
static const struct snd_kcontrol_new max98090_ltenl_mux =
SOC_DAPM_ENUM_EXT("LTENL Mux", ltenl_mux_enum,
snd_soc_dapm_get_enum_double,
max98090_dapm_put_enum_double);
SOC_DAPM_ENUM("LTENL Mux", ltenl_mux_enum);
static const struct snd_kcontrol_new max98090_ltenr_mux =
SOC_DAPM_ENUM_EXT("LTENR Mux", ltenr_mux_enum,
snd_soc_dapm_get_enum_double,
max98090_dapm_put_enum_double);
SOC_DAPM_ENUM("LTENR Mux", ltenr_mux_enum);
static const char *lben_mux_text[] = { "Normal", "Loopback" };
......@@ -1051,14 +902,10 @@ static SOC_ENUM_SINGLE_DECL(lbenr_mux_enum,
lben_mux_text);
static const struct snd_kcontrol_new max98090_lbenl_mux =
SOC_DAPM_ENUM_EXT("LBENL Mux", lbenl_mux_enum,
snd_soc_dapm_get_enum_double,
max98090_dapm_put_enum_double);
SOC_DAPM_ENUM("LBENL Mux", lbenl_mux_enum);
static const struct snd_kcontrol_new max98090_lbenr_mux =
SOC_DAPM_ENUM_EXT("LBENR Mux", lbenr_mux_enum,
snd_soc_dapm_get_enum_double,
max98090_dapm_put_enum_double);
SOC_DAPM_ENUM("LBENR Mux", lbenr_mux_enum);
static const char *stenl_mux_text[] = { "Normal", "Sidetone Left" };
......@@ -1225,25 +1072,21 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("IN56"),
SND_SOC_DAPM_SUPPLY("MICBIAS", M98090_REG_INPUT_ENABLE,
M98090_MBEN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_MBEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("SHDN", M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("SDIEN", M98090_REG_IO_CONFIGURATION,
M98090_SDIEN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_SDIEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("SDOEN", M98090_REG_IO_CONFIGURATION,
M98090_SDOEN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_SDOEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DMICL_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
M98090_DIGMICL_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_DIGMICL_SHIFT, 0, max98090_shdn_event,
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("DMICR_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
M98090_DIGMICR_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_DIGMICR_SHIFT, 0, max98090_shdn_event,
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("AHPF", M98090_REG_FILTER_CONFIG,
M98090_AHPF_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_AHPF_SHIFT, 0, NULL, 0),
/*
* Note: Sysclk and misc power supplies are taken care of by SHDN
......@@ -1273,12 +1116,10 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
&max98090_lineb_mixer_controls[0],
ARRAY_SIZE(max98090_lineb_mixer_controls)),
SND_SOC_DAPM_PGA_E("LINEA Input", M98090_REG_INPUT_ENABLE,
M98090_LINEAEN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("LINEB Input", M98090_REG_INPUT_ENABLE,
M98090_LINEBEN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA("LINEA Input", M98090_REG_INPUT_ENABLE,
M98090_LINEAEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("LINEB Input", M98090_REG_INPUT_ENABLE,
M98090_LINEBEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_MIXER("Left ADC Mixer", SND_SOC_NOPM, 0, 0,
&max98090_left_adc_mixer_controls[0],
......@@ -1289,11 +1130,11 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
ARRAY_SIZE(max98090_right_adc_mixer_controls)),
SND_SOC_DAPM_ADC_E("ADCL", NULL, M98090_REG_INPUT_ENABLE,
M98090_ADLEN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_ADLEN_SHIFT, 0, max98090_shdn_event,
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_ADC_E("ADCR", NULL, M98090_REG_INPUT_ENABLE,
M98090_ADREN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_ADREN_SHIFT, 0, max98090_shdn_event,
SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_AIF_OUT("AIFOUTL", "HiFi Capture", 0,
SND_SOC_NOPM, 0, 0),
......@@ -1321,12 +1162,10 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
SND_SOC_DAPM_AIF_IN("AIFINL", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIFINR", "HiFi Playback", 1, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_DAC_E("DACL", NULL, M98090_REG_OUTPUT_ENABLE,
M98090_DALEN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_DAC_E("DACR", NULL, M98090_REG_OUTPUT_ENABLE,
M98090_DAREN_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_DAC("DACL", NULL, M98090_REG_OUTPUT_ENABLE,
M98090_DALEN_SHIFT, 0),
SND_SOC_DAPM_DAC("DACR", NULL, M98090_REG_OUTPUT_ENABLE,
M98090_DAREN_SHIFT, 0),
SND_SOC_DAPM_MIXER("Left Headphone Mixer", SND_SOC_NOPM, 0, 0,
&max98090_left_hp_mixer_controls[0],
......@@ -1361,26 +1200,20 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
SND_SOC_DAPM_MUX("MIXHPRSEL Mux", SND_SOC_NOPM, 0, 0,
&max98090_mixhprsel_mux),
SND_SOC_DAPM_PGA_E("HP Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_HPLEN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("HP Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_HPREN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("SPK Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_SPLEN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("SPK Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_SPREN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("RCV Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_RCVLEN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA_E("RCV Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_RCVREN_SHIFT, 0, NULL, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA("HP Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_HPLEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("HP Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_HPREN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("SPK Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_SPLEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("SPK Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_SPREN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("RCV Left Out", M98090_REG_OUTPUT_ENABLE,
M98090_RCVLEN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_PGA("RCV Right Out", M98090_REG_OUTPUT_ENABLE,
M98090_RCVREN_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("HPL"),
SND_SOC_DAPM_OUTPUT("HPR"),
......@@ -1395,11 +1228,9 @@ static const struct snd_soc_dapm_widget max98091_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("DMIC4"),
SND_SOC_DAPM_SUPPLY("DMIC3_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
M98090_DIGMIC3_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_DIGMIC3_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DMIC4_ENA", M98090_REG_DIGITAL_MIC_ENABLE,
M98090_DIGMIC4_SHIFT, 0, max98090_dapm_event,
SND_SOC_DAPM_PRE_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
M98090_DIGMIC4_SHIFT, 0, NULL, 0),
};
static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
......@@ -1670,11 +1501,6 @@ static void max98090_configure_bclk(struct snd_soc_component *component)
return;
}
/*
* Master mode: no need to save and restore SHDN for the following
* sensitive registers.
*/
/* Check for supported PCLK to LRCLK ratios */
for (i = 0; i < ARRAY_SIZE(pclk_rates); i++) {
if ((pclk_rates[i] == max98090->sysclk) &&
......@@ -1761,14 +1587,12 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
/* Set to slave mode PLL - MAS mode off */
max98090_shdn_save(max98090);
snd_soc_component_write(component,
M98090_REG_CLOCK_RATIO_NI_MSB, 0x00);
snd_soc_component_write(component,
M98090_REG_CLOCK_RATIO_NI_LSB, 0x00);
snd_soc_component_update_bits(component, M98090_REG_CLOCK_MODE,
M98090_USE_M1_MASK, 0);
max98090_shdn_restore(max98090);
max98090->master = false;
break;
case SND_SOC_DAIFMT_CBM_CFM:
......@@ -1794,9 +1618,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
dev_err(component->dev, "DAI clock mode unsupported");
return -EINVAL;
}
max98090_shdn_save(max98090);
snd_soc_component_write(component, M98090_REG_MASTER_MODE, regval);
max98090_shdn_restore(max98090);
regval = 0;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
......@@ -1841,10 +1663,8 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai,
if (max98090->tdm_slots > 1)
regval ^= M98090_BCI_MASK;
max98090_shdn_save(max98090);
snd_soc_component_write(component,
M98090_REG_INTERFACE_FORMAT, regval);
max98090_shdn_restore(max98090);
}
return 0;
......@@ -1856,7 +1676,6 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
struct snd_soc_component *component = codec_dai->component;
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
struct max98090_cdata *cdata;
cdata = &max98090->dai[0];
if (slots < 0 || slots > 4)
......@@ -1866,7 +1685,6 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
max98090->tdm_width = slot_width;
if (max98090->tdm_slots > 1) {
max98090_shdn_save(max98090);
/* SLOTL SLOTR SLOTDLY */
snd_soc_component_write(component, M98090_REG_TDM_FORMAT,
0 << M98090_TDM_SLOTL_SHIFT |
......@@ -1877,7 +1695,6 @@ static int max98090_set_tdm_slot(struct snd_soc_dai *codec_dai,
snd_soc_component_update_bits(component, M98090_REG_TDM_CONTROL,
M98090_TDM_MASK,
M98090_TDM_MASK);
max98090_shdn_restore(max98090);
}
/*
......@@ -2077,7 +1894,6 @@ static int max98090_configure_dmic(struct max98090_priv *max98090,
dmic_freq = dmic_table[pclk_index].settings[micclk_index].freq;
dmic_comp = dmic_table[pclk_index].settings[micclk_index].comp[i];
max98090_shdn_save(max98090);
regmap_update_bits(max98090->regmap, M98090_REG_DIGITAL_MIC_ENABLE,
M98090_MICCLK_MASK,
micclk_index << M98090_MICCLK_SHIFT);
......@@ -2086,7 +1902,6 @@ static int max98090_configure_dmic(struct max98090_priv *max98090,
M98090_DMIC_COMP_MASK | M98090_DMIC_FREQ_MASK,
dmic_comp << M98090_DMIC_COMP_SHIFT |
dmic_freq << M98090_DMIC_FREQ_SHIFT);
max98090_shdn_restore(max98090);
return 0;
}
......@@ -2123,10 +1938,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
switch (params_width(params)) {
case 16:
max98090_shdn_save(max98090);
snd_soc_component_update_bits(component, M98090_REG_INTERFACE_FORMAT,
M98090_WS_MASK, 0);
max98090_shdn_restore(max98090);
break;
default:
return -EINVAL;
......@@ -2137,7 +1950,6 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
cdata->rate = max98090->lrclk;
max98090_shdn_save(max98090);
/* Update filter mode */
if (max98090->lrclk < 24000)
snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
......@@ -2153,7 +1965,6 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream,
else
snd_soc_component_update_bits(component, M98090_REG_FILTER_CONFIG,
M98090_DHF_MASK, M98090_DHF_MASK);
max98090_shdn_restore(max98090);
max98090_configure_dmic(max98090, max98090->dmic_freq, max98090->pclk,
max98090->lrclk);
......@@ -2184,7 +1995,6 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
* 0x02 (when master clk is 20MHz to 40MHz)..
* 0x03 (when master clk is 40MHz to 60MHz)..
*/
max98090_shdn_save(max98090);
if ((freq >= 10000000) && (freq <= 20000000)) {
snd_soc_component_write(component, M98090_REG_SYSTEM_CLOCK,
M98090_PSCLK_DIV1);
......@@ -2199,10 +2009,8 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai,
max98090->pclk = freq >> 2;
} else {
dev_err(component->dev, "Invalid master clock frequency\n");
max98090_shdn_restore(max98090);
return -EINVAL;
}
max98090_shdn_restore(max98090);
max98090->sysclk = freq;
......@@ -2314,12 +2122,10 @@ static void max98090_pll_work(struct max98090_priv *max98090)
*/
/* Toggle shutdown OFF then ON */
mutex_lock(&component->card->dapm_mutex);
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, 0);
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, M98090_SHDNN_MASK);
mutex_unlock(&component->card->dapm_mutex);
for (i = 0; i < 10; ++i) {
/* Give PLL time to lock */
......@@ -2642,12 +2448,7 @@ static int max98090_probe(struct snd_soc_component *component)
*/
snd_soc_component_read32(component, M98090_REG_DEVICE_STATUS);
/*
* SHDN should be 0 at the point, no need to save/restore for the
* following registers.
*
* High Performance is default
*/
/* High Performance is default */
snd_soc_component_update_bits(component, M98090_REG_DAC_CONTROL,
M98090_DACHP_MASK,
1 << M98090_DACHP_SHIFT);
......@@ -2658,12 +2459,7 @@ static int max98090_probe(struct snd_soc_component *component)
M98090_ADCHP_MASK,
1 << M98090_ADCHP_SHIFT);
/*
* SHDN should be 0 at the point, no need to save/restore for the
* following registers.
*
* Turn on VCM bandgap reference
*/
/* Turn on VCM bandgap reference */
snd_soc_component_write(component, M98090_REG_BIAS_CONTROL,
M98090_VCM_MODE_MASK);
......@@ -2695,9 +2491,25 @@ static void max98090_remove(struct snd_soc_component *component)
max98090->component = NULL;
}
static void max98090_seq_notifier(struct snd_soc_component *component,
enum snd_soc_dapm_type event, int subseq)
{
struct max98090_priv *max98090 = snd_soc_component_get_drvdata(component);
if (max98090->shdn_pending) {
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, 0);
msleep(40);
snd_soc_component_update_bits(component, M98090_REG_DEVICE_SHUTDOWN,
M98090_SHDNN_MASK, M98090_SHDNN_MASK);
max98090->shdn_pending = false;
}
}
static const struct snd_soc_component_driver soc_component_dev_max98090 = {
.probe = max98090_probe,
.remove = max98090_remove,
.seq_notifier = max98090_seq_notifier,
.set_bias_level = max98090_set_bias_level,
.idle_bias_on = 1,
.use_pmdown_time = 1,
......
......@@ -1539,8 +1539,7 @@ struct max98090_priv {
unsigned int pa2en;
unsigned int sidetone;
bool master;
int saved_count;
int saved_shdn;
bool shdn_pending;
};
int max98090_mic_detect(struct snd_soc_component *component,
......
......@@ -1020,12 +1020,24 @@ static int fsl_sai_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
&fsl_sai_dai, 1);
if (ret)
return ret;
goto err_pm_disable;
if (sai->soc_data->use_imx_pcm)
return imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
else
return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (sai->soc_data->use_imx_pcm) {
ret = imx_pcm_dma_init(pdev, IMX_SAI_DMABUF_SIZE);
if (ret)
goto err_pm_disable;
} else {
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
if (ret)
goto err_pm_disable;
}
return ret;
err_pm_disable:
pm_runtime_disable(&pdev->dev);
return ret;
}
static int fsl_sai_remove(struct platform_device *pdev)
......
......@@ -3441,8 +3441,17 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
static int __snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol, int locked)
/**
* snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to set the value of a dapm enumerated double mixer control.
*
* Returns 0 for success.
*/
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
struct snd_soc_card *card = dapm->card;
......@@ -3465,9 +3474,7 @@ static int __snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
mask |= e->mask << e->shift_r;
}
if (!locked)
mutex_lock_nested(&card->dapm_mutex,
SND_SOC_DAPM_CLASS_RUNTIME);
mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
change = dapm_kcontrol_set_value(kcontrol, val);
......@@ -3489,50 +3496,15 @@ static int __snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
card->update = NULL;
}
if (!locked)
mutex_unlock(&card->dapm_mutex);
mutex_unlock(&card->dapm_mutex);
if (ret > 0)
soc_dpcm_runtime_update(card);
return change;
}
/**
* snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to set the value of a dapm enumerated double mixer control.
*
* Returns 0 for success.
*/
int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
return __snd_soc_dapm_put_enum_double(kcontrol, ucontrol, 0);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
/**
* snd_soc_dapm_put_enum_double_locked - dapm enumerated double mixer set
* callback
* @kcontrol: mixer control
* @ucontrol: control element information
*
* Callback to set the value of a dapm enumerated double mixer control.
* Must acquire dapm_mutex before calling the function.
*
* Returns 0 for success.
*/
int snd_soc_dapm_put_enum_double_locked(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
dapm_assert_locked(snd_soc_dapm_kcontrol_dapm(kcontrol));
return __snd_soc_dapm_put_enum_double(kcontrol, ucontrol, 1);
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double_locked);
/**
* snd_soc_dapm_info_pin_switch - Info for a pin switch
*
......@@ -3916,9 +3888,6 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
runtime->rate = params_rate(params);
out:
if (ret < 0)
kfree(runtime);
kfree(params);
return ret;
}
......
......@@ -174,8 +174,10 @@ void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable)
{
struct hdac_bus *bus = sof_to_bus(sdev);
dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
if (HDA_IDISP_CODEC(bus->codec_mask)) {
dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
}
}
EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
......@@ -189,7 +191,8 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev)
if (ret < 0)
return ret;
hda_codec_i915_display_power(sdev, true);
/* codec_mask not yet known, power up for probe */
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
return 0;
}
......@@ -200,7 +203,8 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)
struct hdac_bus *bus = sof_to_bus(sdev);
int ret;
hda_codec_i915_display_power(sdev, false);
/* power down unconditionally */
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
ret = snd_hdac_i915_exit(bus);
......
......@@ -428,6 +428,9 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
return ret;
}
/* display codec can powered off after link reset */
hda_codec_i915_display_power(sdev, false);
return 0;
}
......@@ -439,6 +442,9 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
#endif
int ret;
/* display codec must be powered before link reset */
hda_codec_i915_display_power(sdev, true);
/*
* clear TCSEL to clear playback on some HD Audio
* codecs. PCI TCSEL is defined in the Intel manuals.
......@@ -482,6 +488,8 @@ int hda_dsp_resume(struct snd_sof_dev *sdev)
struct pci_dev *pci = to_pci_dev(sdev->dev);
if (sdev->s0_suspend) {
hda_codec_i915_display_power(sdev, true);
/* restore L1SEN bit */
if (hda->l1_support_changed)
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
......@@ -531,6 +539,9 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev)
int ret;
if (sdev->s0_suspend) {
/* we can't keep a wakeref to display driver at suspend */
hda_codec_i915_display_power(sdev, false);
/* enable L1SEN to make sure the system can enter S0Ix */
hda->l1_support_changed =
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
......
......@@ -286,6 +286,13 @@ static int hda_init(struct snd_sof_dev *sdev)
/* HDA base */
sdev->bar[HDA_DSP_HDA_BAR] = bus->remap_addr;
/* init i915 and HDMI codecs */
ret = hda_codec_i915_init(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n");
return ret;
}
/* get controller capabilities */
ret = hda_dsp_ctrl_get_caps(sdev);
if (ret < 0)
......@@ -353,15 +360,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
if (bus->ppcap)
dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n");
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* init i915 and HDMI codecs */
ret = hda_codec_i915_init(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n");
return ret;
}
#endif
/* Init HDA controller after i915 init */
ret = hda_dsp_ctrl_init_chip(sdev, true);
if (ret < 0) {
......@@ -381,7 +379,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);
if (!HDA_IDISP_CODEC(bus->codec_mask))
hda_codec_i915_display_power(sdev, false);
hda_codec_i915_exit(sdev);
/*
* we are done probing so decrement link counts
......@@ -611,6 +609,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev)
iounmap(sdev->bar[HDA_DSP_BAR]);
hdac_bus_unmap:
iounmap(bus->remap_addr);
hda_codec_i915_exit(sdev);
err:
return ret;
}
......
......@@ -80,6 +80,7 @@
#define SUN8I_SYS_SR_CTRL_AIF1_FS_MASK GENMASK(15, 12)
#define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8)
#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK GENMASK(3, 2)
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4)
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6)
#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
......@@ -241,7 +242,7 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
BIT(SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT),
SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT_MASK,
value << SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT);
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment