1
0
Fork 0

Merge branch 'asoc-5.3' into asoc-linus

alistair/sunxi64-5.4-dsi
Mark Brown 2019-09-09 14:55:18 +01:00
commit 6652ddbb5d
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
33 changed files with 459 additions and 161 deletions

View File

@ -246,8 +246,8 @@ static struct platform_device latch2_gpio_device = {
#define LATCH2_PIN_SCARD_CMDVCC 11 #define LATCH2_PIN_SCARD_CMDVCC 11
#define LATCH2_PIN_MODEM_NRESET 12 #define LATCH2_PIN_MODEM_NRESET 12
#define LATCH2_PIN_MODEM_CODEC 13 #define LATCH2_PIN_MODEM_CODEC 13
#define LATCH2_PIN_AUDIO_MUTE 14 #define LATCH2_PIN_HANDSFREE_MUTE 14
#define LATCH2_PIN_HOOKFLASH 15 #define LATCH2_PIN_HANDSET_MUTE 15
static struct regulator_consumer_supply modem_nreset_consumers[] = { static struct regulator_consumer_supply modem_nreset_consumers[] = {
REGULATOR_SUPPLY("RESET#", "serial8250.1"), REGULATOR_SUPPLY("RESET#", "serial8250.1"),
@ -476,6 +476,10 @@ static struct gpiod_lookup_table ams_delta_audio_gpio_table = {
"hook_switch", 0), "hook_switch", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC, GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC,
"modem_codec", 0), "modem_codec", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSFREE_MUTE,
"handsfree_mute", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_HANDSET_MUTE,
"handset_mute", 0),
{ }, { },
}, },
}; };
@ -590,8 +594,6 @@ static int gpiochip_match_by_label(struct gpio_chip *chip, void *data)
static struct gpiod_hog ams_delta_gpio_hogs[] = { static struct gpiod_hog ams_delta_gpio_hogs[] = {
GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout", GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT, "keybrd_dataout",
GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW), GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW),
GPIO_HOG(LATCH2_LABEL, LATCH2_PIN_AUDIO_MUTE, "audio_mute",
GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW),
{}, {},
}; };

View File

@ -402,6 +402,9 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
struct snd_soc_dapm_widget *snd_soc_dapm_new_control( struct snd_soc_dapm_widget *snd_soc_dapm_new_control(
struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget); const struct snd_soc_dapm_widget *widget);
struct snd_soc_dapm_widget *snd_soc_dapm_new_control_unlocked(
struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm,
struct snd_soc_dai *dai); struct snd_soc_dai *dai);
int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card); int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card);

View File

@ -10,7 +10,7 @@ config SND_SOC_AMD_CZ_DA7219MX98357_MACH
select SND_SOC_MAX98357A select SND_SOC_MAX98357A
select SND_SOC_ADAU7002 select SND_SOC_ADAU7002
select REGULATOR select REGULATOR
depends on SND_SOC_AMD_ACP && I2C depends on SND_SOC_AMD_ACP && I2C && GPIOLIB
help help
This option enables machine driver for DA7219 and MAX9835. This option enables machine driver for DA7219 and MAX9835.

View File

@ -670,8 +670,13 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
} }
ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra); ret = regmap_write(dev->regmap, MCHP_I2SMCC_MRA, mra);
if (ret < 0) if (ret < 0) {
if (dev->gclk_use) {
clk_unprepare(dev->gclk);
dev->gclk_use = 0;
}
return ret; return ret;
}
return regmap_write(dev->regmap, MCHP_I2SMCC_MRB, mrb); return regmap_write(dev->regmap, MCHP_I2SMCC_MRB, mrb);
} }
@ -686,31 +691,37 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
err = wait_event_interruptible_timeout(dev->wq_txrdy, err = wait_event_interruptible_timeout(dev->wq_txrdy,
dev->tx_rdy, dev->tx_rdy,
msecs_to_jiffies(500)); msecs_to_jiffies(500));
if (err == 0) {
dev_warn_once(dev->dev,
"Timeout waiting for Tx ready\n");
regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
dev->tx_rdy = 1;
}
} else { } else {
err = wait_event_interruptible_timeout(dev->wq_rxrdy, err = wait_event_interruptible_timeout(dev->wq_rxrdy,
dev->rx_rdy, dev->rx_rdy,
msecs_to_jiffies(500)); msecs_to_jiffies(500));
} if (err == 0) {
dev_warn_once(dev->dev,
if (err == 0) { "Timeout waiting for Rx ready\n");
u32 idra; regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
dev_warn_once(dev->dev, "Timeout waiting for %s\n", dev->rx_rdy = 1;
is_playback ? "Tx ready" : "Rx ready"); }
if (is_playback)
idra = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
else
idra = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
} }
if (!mchp_i2s_mcc_is_running(dev)) { if (!mchp_i2s_mcc_is_running(dev)) {
regmap_write(dev->regmap, MCHP_I2SMCC_CR, MCHP_I2SMCC_CR_CKDIS); regmap_write(dev->regmap, MCHP_I2SMCC_CR, MCHP_I2SMCC_CR_CKDIS);
if (dev->gclk_running) { if (dev->gclk_running) {
clk_disable_unprepare(dev->gclk); clk_disable(dev->gclk);
dev->gclk_running = 0; dev->gclk_running = 0;
} }
if (dev->gclk_use) {
clk_unprepare(dev->gclk);
dev->gclk_use = 0;
}
} }
return 0; return 0;
@ -809,6 +820,8 @@ static int mchp_i2s_mcc_dai_probe(struct snd_soc_dai *dai)
init_waitqueue_head(&dev->wq_txrdy); init_waitqueue_head(&dev->wq_txrdy);
init_waitqueue_head(&dev->wq_rxrdy); init_waitqueue_head(&dev->wq_rxrdy);
dev->tx_rdy = 1;
dev->rx_rdy = 1;
snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture); snd_soc_dai_init_dma_data(dai, &dev->playback, &dev->capture);

View File

@ -378,6 +378,7 @@ static struct i2c_driver cs4349_i2c_driver = {
.driver = { .driver = {
.name = "cs4349", .name = "cs4349",
.of_match_table = cs4349_of_match, .of_match_table = cs4349_of_match,
.pm = &cs4349_runtime_pm,
}, },
.id_table = cs4349_i2c_id, .id_table = cs4349_i2c_id,
.probe = cs4349_i2c_probe, .probe = cs4349_i2c_probe,

View File

@ -51,7 +51,10 @@ static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0);
static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(hpmixer_gain_tlv, -1200, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(hpmixer_gain_tlv,
0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
);
static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv, static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(adc_pga_gain_tlv,
0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0), 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
@ -89,7 +92,7 @@ static const struct snd_kcontrol_new es8316_snd_controls[] = {
SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL, SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL,
4, 0, 3, 1, hpout_vol_tlv), 4, 0, 3, 1, hpout_vol_tlv),
SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL, SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL,
0, 4, 7, 0, hpmixer_gain_tlv), 4, 0, 11, 0, hpmixer_gain_tlv),
SOC_ENUM("Playback Polarity", dacpol), SOC_ENUM("Playback Polarity", dacpol),
SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL, SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL,

View File

@ -228,7 +228,7 @@ static const struct soc_enum es8328_rline_enum =
ARRAY_SIZE(es8328_line_texts), ARRAY_SIZE(es8328_line_texts),
es8328_line_texts); es8328_line_texts);
static const struct snd_kcontrol_new es8328_right_line_controls = static const struct snd_kcontrol_new es8328_right_line_controls =
SOC_DAPM_ENUM("Route", es8328_lline_enum); SOC_DAPM_ENUM("Route", es8328_rline_enum);
/* Left Mixer */ /* Left Mixer */
static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {

View File

@ -495,6 +495,10 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
static int hdac_hda_dev_remove(struct hdac_device *hdev) static int hdac_hda_dev_remove(struct hdac_device *hdev)
{ {
struct hdac_hda_priv *hda_pvt;
hda_pvt = dev_get_drvdata(&hdev->dev);
cancel_delayed_work_sync(&hda_pvt->codec.jackpoll_work);
return 0; return 0;
} }

View File

@ -88,8 +88,10 @@ struct hdac_hdmi_port {
hda_nid_t mux_nids[HDA_MAX_CONNECTIONS]; hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
struct hdac_hdmi_eld eld; struct hdac_hdmi_eld eld;
const char *jack_pin; const char *jack_pin;
bool is_connect;
struct snd_soc_dapm_context *dapm; struct snd_soc_dapm_context *dapm;
const char *output_pin; const char *output_pin;
struct work_struct dapm_work;
}; };
struct hdac_hdmi_pcm { struct hdac_hdmi_pcm {
@ -163,11 +165,7 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
{ {
struct hdac_device *hdev = port->pin->hdev; struct hdac_device *hdev = port->pin->hdev;
if (is_connect) port->is_connect = is_connect;
snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
else
snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
if (is_connect) { if (is_connect) {
/* /*
* Report Jack connect event when a device is connected * Report Jack connect event when a device is connected
@ -193,10 +191,32 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
if (pcm->jack_event > 0) if (pcm->jack_event > 0)
pcm->jack_event--; pcm->jack_event--;
} }
}
static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)
{
if (port->is_connect)
snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
else
snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
snd_soc_dapm_sync(port->dapm); snd_soc_dapm_sync(port->dapm);
} }
static void hdac_hdmi_jack_dapm_work(struct work_struct *work)
{
struct hdac_hdmi_port *port;
port = container_of(work, struct hdac_hdmi_port, dapm_work);
hdac_hdmi_port_dapm_update(port);
}
static void hdac_hdmi_jack_report_sync(struct hdac_hdmi_pcm *pcm,
struct hdac_hdmi_port *port, bool is_connect)
{
hdac_hdmi_jack_report(pcm, port, is_connect);
hdac_hdmi_port_dapm_update(port);
}
/* MST supported verbs */ /* MST supported verbs */
/* /*
* Get the no devices that can be connected to a port on the Pin widget. * Get the no devices that can be connected to a port on the Pin widget.
@ -904,7 +924,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
list_for_each_entry_safe(p, p_next, &pcm->port_list, head) { list_for_each_entry_safe(p, p_next, &pcm->port_list, head) {
if (p == port && p->id == port->id && if (p == port && p->id == port->id &&
p->pin == port->pin) { p->pin == port->pin) {
hdac_hdmi_jack_report(pcm, port, false); hdac_hdmi_jack_report_sync(pcm, port, false);
list_del(&p->head); list_del(&p->head);
} }
} }
@ -918,7 +938,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
if (!strcmp(cvt_name, pcm->cvt->name)) { if (!strcmp(cvt_name, pcm->cvt->name)) {
list_add_tail(&port->head, &pcm->port_list); list_add_tail(&port->head, &pcm->port_list);
if (port->eld.monitor_present && port->eld.eld_valid) { if (port->eld.monitor_present && port->eld.eld_valid) {
hdac_hdmi_jack_report(pcm, port, true); hdac_hdmi_jack_report_sync(pcm, port, true);
mutex_unlock(&hdmi->pin_mutex); mutex_unlock(&hdmi->pin_mutex);
return ret; return ret;
} }
@ -1281,16 +1301,20 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
* report jack here. It will be done in usermode mux * report jack here. It will be done in usermode mux
* control select. * control select.
*/ */
if (pcm) if (pcm) {
hdac_hdmi_jack_report(pcm, port, false); hdac_hdmi_jack_report(pcm, port, false);
schedule_work(&port->dapm_work);
}
mutex_unlock(&hdmi->pin_mutex); mutex_unlock(&hdmi->pin_mutex);
return; return;
} }
if (port->eld.monitor_present && port->eld.eld_valid) { if (port->eld.monitor_present && port->eld.eld_valid) {
if (pcm) if (pcm) {
hdac_hdmi_jack_report(pcm, port, true); hdac_hdmi_jack_report(pcm, port, true);
schedule_work(&port->dapm_work);
}
print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1, print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
port->eld.eld_buffer, port->eld.eld_size, false); port->eld.eld_buffer, port->eld.eld_size, false);
@ -1319,6 +1343,7 @@ static int hdac_hdmi_add_ports(struct hdac_device *hdev,
for (i = 0; i < max_ports; i++) { for (i = 0; i < max_ports; i++) {
ports[i].id = i; ports[i].id = i;
ports[i].pin = pin; ports[i].pin = pin;
INIT_WORK(&ports[i].dapm_work, hdac_hdmi_jack_dapm_work);
} }
pin->ports = ports; pin->ports = ports;
pin->num_ports = max_ports; pin->num_ports = max_ports;
@ -2083,8 +2108,20 @@ static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
return ret; return ret;
} }
static void clear_dapm_works(struct hdac_device *hdev)
{
struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
struct hdac_hdmi_pin *pin;
int i;
list_for_each_entry(pin, &hdmi->pin_list, head)
for (i = 0; i < pin->num_ports; i++)
cancel_work_sync(&pin->ports[i].dapm_work);
}
static int hdac_hdmi_dev_remove(struct hdac_device *hdev) static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
{ {
clear_dapm_works(hdev);
snd_hdac_display_power(hdev->bus, hdev->addr, false); snd_hdac_display_power(hdev->bus, hdev->addr, false);
return 0; return 0;
@ -2103,6 +2140,8 @@ static int hdac_hdmi_runtime_suspend(struct device *dev)
if (!bus) if (!bus)
return 0; return 0;
clear_dapm_works(hdev);
/* /*
* Power down afg. * Power down afg.
* codec_read is preferred over codec_write to set the power state. * codec_read is preferred over codec_write to set the power state.

View File

@ -1619,14 +1619,18 @@ static int rt1011_hw_params(struct snd_pcm_substream *substream,
static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
unsigned int reg_val = 0, reg_bclk_inv = 0; unsigned int reg_val = 0, reg_bclk_inv = 0;
int ret = 0;
snd_soc_dapm_mutex_lock(dapm);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS: case SND_SOC_DAIFMT_CBS_CFS:
reg_val |= RT1011_I2S_TDM_MS_S; reg_val |= RT1011_I2S_TDM_MS_S;
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
@ -1636,7 +1640,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
reg_bclk_inv |= RT1011_TDM_INV_BCLK; reg_bclk_inv |= RT1011_TDM_INV_BCLK;
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@ -1652,7 +1656,7 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
reg_val |= RT1011_I2S_TDM_DF_PCM_B; reg_val |= RT1011_I2S_TDM_DF_PCM_B;
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
switch (dai->id) { switch (dai->id) {
@ -1667,9 +1671,11 @@ static int rt1011_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
break; break;
default: default:
dev_err(component->dev, "Invalid dai->id: %d\n", dai->id); dev_err(component->dev, "Invalid dai->id: %d\n", dai->id);
return -EINVAL; ret = -EINVAL;
} }
return 0;
snd_soc_dapm_mutex_unlock(dapm);
return ret;
} }
static int rt1011_set_component_sysclk(struct snd_soc_component *component, static int rt1011_set_component_sysclk(struct snd_soc_component *component,
@ -1788,8 +1794,12 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width) unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
{ {
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct snd_soc_dapm_context *dapm =
snd_soc_component_get_dapm(component);
unsigned int val = 0, tdm_en = 0; unsigned int val = 0, tdm_en = 0;
int ret = 0;
snd_soc_dapm_mutex_lock(dapm);
if (rx_mask || tx_mask) if (rx_mask || tx_mask)
tdm_en = RT1011_TDM_I2S_DOCK_EN_1; tdm_en = RT1011_TDM_I2S_DOCK_EN_1;
@ -1809,7 +1819,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
case 2: case 2:
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
switch (slot_width) { switch (slot_width) {
@ -1828,7 +1838,7 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
case 16: case 16:
break; break;
default: default:
return -EINVAL; ret = -EINVAL;
} }
snd_soc_component_update_bits(component, RT1011_TDM1_SET_1, snd_soc_component_update_bits(component, RT1011_TDM1_SET_1,
@ -1845,7 +1855,8 @@ static int rt1011_set_tdm_slot(struct snd_soc_dai *dai,
RT1011_ADCDAT1_PIN_CONFIG | RT1011_ADCDAT2_PIN_CONFIG, RT1011_ADCDAT1_PIN_CONFIG | RT1011_ADCDAT2_PIN_CONFIG,
RT1011_ADCDAT1_OUTPUT | RT1011_ADCDAT2_OUTPUT); RT1011_ADCDAT1_OUTPUT | RT1011_ADCDAT2_OUTPUT);
return 0; snd_soc_dapm_mutex_unlock(dapm);
return ret;
} }
static int rt1011_probe(struct snd_soc_component *component) static int rt1011_probe(struct snd_soc_component *component)

View File

@ -167,7 +167,7 @@ SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0), SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0), SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
SOC_ENUM("3D Low Cut-off", low_3d), SOC_ENUM("3D Low Cut-off", low_3d),
SOC_ENUM("3D High Cut-off", low_3d), SOC_ENUM("3D High Cut-off", high_3d),
SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv), SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0), SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),

View File

@ -545,18 +545,6 @@ static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0); static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
static const char *input_mode_text[] = {
"Single-Ended", "Differential Line", "Differential Mic"
};
static SOC_ENUM_SINGLE_DECL(lin_mode,
WM8904_ANALOGUE_LEFT_INPUT_1, 0,
input_mode_text);
static SOC_ENUM_SINGLE_DECL(rin_mode,
WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
input_mode_text);
static const char *hpf_mode_text[] = { static const char *hpf_mode_text[] = {
"Hi-fi", "Voice 1", "Voice 2", "Voice 3" "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
}; };
@ -591,9 +579,6 @@ static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
SOC_ENUM("Left Capture Mode", lin_mode),
SOC_ENUM("Right Capture Mode", rin_mode),
/* No TLV since it depends on mode */ /* No TLV since it depends on mode */
SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0, SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0), WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
@ -852,6 +837,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
return 0; return 0;
} }
static const char *input_mode_text[] = {
"Single-Ended", "Differential Line", "Differential Mic"
};
static const char *lin_text[] = { static const char *lin_text[] = {
"IN1L", "IN2L", "IN3L" "IN1L", "IN2L", "IN3L"
}; };
@ -866,7 +855,14 @@ static SOC_ENUM_SINGLE_DECL(lin_inv_enum, WM8904_ANALOGUE_LEFT_INPUT_1, 4,
lin_text); lin_text);
static const struct snd_kcontrol_new lin_inv_mux = static const struct snd_kcontrol_new lin_inv_mux =
SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum); SOC_DAPM_ENUM("Left Capture Inverting Mux", lin_inv_enum);
static SOC_ENUM_SINGLE_DECL(lin_mode_enum,
WM8904_ANALOGUE_LEFT_INPUT_1, 0,
input_mode_text);
static const struct snd_kcontrol_new lin_mode =
SOC_DAPM_ENUM("Left Capture Mode", lin_mode_enum);
static const char *rin_text[] = { static const char *rin_text[] = {
"IN1R", "IN2R", "IN3R" "IN1R", "IN2R", "IN3R"
@ -882,7 +878,14 @@ static SOC_ENUM_SINGLE_DECL(rin_inv_enum, WM8904_ANALOGUE_RIGHT_INPUT_1, 4,
rin_text); rin_text);
static const struct snd_kcontrol_new rin_inv_mux = static const struct snd_kcontrol_new rin_inv_mux =
SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum); SOC_DAPM_ENUM("Right Capture Inverting Mux", rin_inv_enum);
static SOC_ENUM_SINGLE_DECL(rin_mode_enum,
WM8904_ANALOGUE_RIGHT_INPUT_1, 0,
input_mode_text);
static const struct snd_kcontrol_new rin_mode =
SOC_DAPM_ENUM("Right Capture Mode", rin_mode_enum);
static const char *aif_text[] = { static const char *aif_text[] = {
"Left", "Right" "Left", "Right"
@ -932,9 +935,11 @@ SND_SOC_DAPM_SUPPLY("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux), SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
&lin_inv_mux), &lin_inv_mux),
SND_SOC_DAPM_MUX("Left Capture Mode", SND_SOC_NOPM, 0, 0, &lin_mode),
SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux), SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0, SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
&rin_inv_mux), &rin_inv_mux),
SND_SOC_DAPM_MUX("Right Capture Mode", SND_SOC_NOPM, 0, 0, &rin_mode),
SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0, SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
NULL, 0), NULL, 0),
@ -1057,6 +1062,12 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
{ "Left Capture Inverting Mux", "IN2L", "IN2L" }, { "Left Capture Inverting Mux", "IN2L", "IN2L" },
{ "Left Capture Inverting Mux", "IN3L", "IN3L" }, { "Left Capture Inverting Mux", "IN3L", "IN3L" },
{ "Left Capture Mode", "Single-Ended", "Left Capture Inverting Mux" },
{ "Left Capture Mode", "Differential Line", "Left Capture Mux" },
{ "Left Capture Mode", "Differential Line", "Left Capture Inverting Mux" },
{ "Left Capture Mode", "Differential Mic", "Left Capture Mux" },
{ "Left Capture Mode", "Differential Mic", "Left Capture Inverting Mux" },
{ "Right Capture Mux", "IN1R", "IN1R" }, { "Right Capture Mux", "IN1R", "IN1R" },
{ "Right Capture Mux", "IN2R", "IN2R" }, { "Right Capture Mux", "IN2R", "IN2R" },
{ "Right Capture Mux", "IN3R", "IN3R" }, { "Right Capture Mux", "IN3R", "IN3R" },
@ -1065,11 +1076,14 @@ static const struct snd_soc_dapm_route adc_intercon[] = {
{ "Right Capture Inverting Mux", "IN2R", "IN2R" }, { "Right Capture Inverting Mux", "IN2R", "IN2R" },
{ "Right Capture Inverting Mux", "IN3R", "IN3R" }, { "Right Capture Inverting Mux", "IN3R", "IN3R" },
{ "Left Capture PGA", NULL, "Left Capture Mux" }, { "Right Capture Mode", "Single-Ended", "Right Capture Inverting Mux" },
{ "Left Capture PGA", NULL, "Left Capture Inverting Mux" }, { "Right Capture Mode", "Differential Line", "Right Capture Mux" },
{ "Right Capture Mode", "Differential Line", "Right Capture Inverting Mux" },
{ "Right Capture Mode", "Differential Mic", "Right Capture Mux" },
{ "Right Capture Mode", "Differential Mic", "Right Capture Inverting Mux" },
{ "Right Capture PGA", NULL, "Right Capture Mux" }, { "Left Capture PGA", NULL, "Left Capture Mode" },
{ "Right Capture PGA", NULL, "Right Capture Inverting Mux" }, { "Right Capture PGA", NULL, "Right Capture Mode" },
{ "AIFOUTL Mux", "Left", "ADCL" }, { "AIFOUTL Mux", "Left", "ADCL" },
{ "AIFOUTL Mux", "Right", "ADCR" }, { "AIFOUTL Mux", "Right", "ADCR" },

View File

@ -799,15 +799,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
u32 wl = SSI_SxCCR_WL(sample_size); u32 wl = SSI_SxCCR_WL(sample_size);
int ret; int ret;
/*
* SSI is properly configured if it is enabled and running in
* the synchronous mode; Note that AC97 mode is an exception
* that should set separate configurations for STCCR and SRCCR
* despite running in the synchronous mode.
*/
if (ssi->streams && ssi->synchronous)
return 0;
if (fsl_ssi_is_i2s_master(ssi)) { if (fsl_ssi_is_i2s_master(ssi)) {
ret = fsl_ssi_set_bclk(substream, dai, hw_params); ret = fsl_ssi_set_bclk(substream, dai, hw_params);
if (ret) if (ret)
@ -823,6 +814,15 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
} }
} }
/*
* SSI is properly configured if it is enabled and running in
* the synchronous mode; Note that AC97 mode is an exception
* that should set separate configurations for STCCR and SRCCR
* despite running in the synchronous mode.
*/
if (ssi->streams && ssi->synchronous)
return 0;
if (!fsl_ssi_is_ac97(ssi)) { if (!fsl_ssi_is_ac97(ssi)) {
/* /*
* Keep the ssi->i2s_net intact while having a local variable * Keep the ssi->i2s_net intact while having a local variable

View File

@ -23,6 +23,8 @@
static struct clk *audmux_clk; static struct clk *audmux_clk;
static void __iomem *audmux_base; static void __iomem *audmux_base;
static u32 *regcache;
static u32 reg_max;
#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8) #define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) #define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
@ -317,8 +319,23 @@ static int imx_audmux_probe(struct platform_device *pdev)
if (of_id) if (of_id)
pdev->id_entry = of_id->data; pdev->id_entry = of_id->data;
audmux_type = pdev->id_entry->driver_data; audmux_type = pdev->id_entry->driver_data;
if (audmux_type == IMX31_AUDMUX)
switch (audmux_type) {
case IMX31_AUDMUX:
audmux_debugfs_init(); audmux_debugfs_init();
reg_max = 14;
break;
case IMX21_AUDMUX:
reg_max = 6;
break;
default:
dev_err(&pdev->dev, "unsupported version!\n");
return -EINVAL;
}
regcache = devm_kzalloc(&pdev->dev, sizeof(u32) * reg_max, GFP_KERNEL);
if (!regcache)
return -ENOMEM;
if (of_id) if (of_id)
imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node); imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
@ -334,12 +351,47 @@ static int imx_audmux_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM_SLEEP
static int imx_audmux_suspend(struct device *dev)
{
int i;
clk_prepare_enable(audmux_clk);
for (i = 0; i < reg_max; i++)
regcache[i] = readl(audmux_base + i * 4);
clk_disable_unprepare(audmux_clk);
return 0;
}
static int imx_audmux_resume(struct device *dev)
{
int i;
clk_prepare_enable(audmux_clk);
for (i = 0; i < reg_max; i++)
writel(regcache[i], audmux_base + i * 4);
clk_disable_unprepare(audmux_clk);
return 0;
}
#endif /* CONFIG_PM_SLEEP */
static const struct dev_pm_ops imx_audmux_pm = {
SET_SYSTEM_SLEEP_PM_OPS(imx_audmux_suspend, imx_audmux_resume)
};
static struct platform_driver imx_audmux_driver = { static struct platform_driver imx_audmux_driver = {
.probe = imx_audmux_probe, .probe = imx_audmux_probe,
.remove = imx_audmux_remove, .remove = imx_audmux_remove,
.id_table = imx_audmux_ids, .id_table = imx_audmux_ids,
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = &imx_audmux_pm,
.of_match_table = imx_audmux_dt_ids, .of_match_table = imx_audmux_dt_ids,
} }
}; };

View File

@ -193,6 +193,7 @@ static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
break; break;
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
pdata->restore_stream = false; pdata->restore_stream = false;
/* fallthrough */
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
sst_byt_stream_pause(byt, pcm_data->stream); sst_byt_stream_pause(byt, pcm_data->stream);
break; break;

View File

@ -399,6 +399,20 @@ static struct snd_soc_card snd_soc_card_cht = {
}; };
static const struct dmi_system_id cht_max98090_quirk_table[] = { static const struct dmi_system_id cht_max98090_quirk_table[] = {
{
/* Banjo model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Banjo"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Candy model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Candy"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{ {
/* Clapper model Chromebook */ /* Clapper model Chromebook */
.matches = { .matches = {
@ -406,6 +420,27 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = {
}, },
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
}, },
{
/* Cyan model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Enguarde model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Enguarde"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Glimmer model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Glimmer"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{ {
/* Gnawty model Chromebook (Acer Chromebook CB3-111) */ /* Gnawty model Chromebook (Acer Chromebook CB3-111) */
.matches = { .matches = {
@ -413,6 +448,62 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = {
}, },
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
}, },
{
/* Heli model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Heli"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Kip model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Kip"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Ninja model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Ninja"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Orco model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Orco"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Quawks model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Quawks"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Rambi model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Rambi"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Squawks model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Squawks"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{
/* Sumo model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Sumo"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{ {
/* Swanky model Chromebook (Toshiba Chromebook 2) */ /* Swanky model Chromebook (Toshiba Chromebook 2) */
.matches = { .matches = {
@ -420,6 +511,13 @@ static const struct dmi_system_id cht_max98090_quirk_table[] = {
}, },
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0, .driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
}, },
{
/* Winky model Chromebook */
.matches = {
DMI_MATCH(DMI_PRODUCT_NAME, "Winky"),
},
.driver_data = (void *)QUIRK_PMC_PLT_CLK_0,
},
{} {}
}; };

View File

@ -309,6 +309,7 @@ static const struct snd_soc_dapm_widget sof_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_SPK("Spk", NULL),
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
}; };
static const struct snd_soc_dapm_route sof_map[] = { static const struct snd_soc_dapm_route sof_map[] = {
@ -319,6 +320,9 @@ static const struct snd_soc_dapm_route sof_map[] = {
/* other jacks */ /* other jacks */
{ "IN1P", NULL, "Headset Mic" }, { "IN1P", NULL, "Headset Mic" },
/* digital mics */
{"DMic", NULL, "SoC DMIC"},
}; };
static const struct snd_soc_dapm_route speaker_map[] = { static const struct snd_soc_dapm_route speaker_map[] = {

View File

@ -222,6 +222,8 @@ struct ipc_message *sst_ipc_reply_find_msg(struct sst_generic_ipc *ipc,
if (ipc->ops.reply_msg_match != NULL) if (ipc->ops.reply_msg_match != NULL)
header = ipc->ops.reply_msg_match(header, &mask); header = ipc->ops.reply_msg_match(header, &mask);
else
mask = (u64)-1;
if (list_empty(&ipc->rx_list)) { if (list_empty(&ipc->rx_list)) {
dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n", dev_err(ipc->dev, "error: rx list empty but received 0x%llx\n",

View File

@ -188,7 +188,7 @@ static ssize_t fw_softreg_read(struct file *file, char __user *user_buf,
memset(d->fw_read_buff, 0, FW_REG_BUF); memset(d->fw_read_buff, 0, FW_REG_BUF);
if (w0_stat_sz > 0) if (w0_stat_sz > 0)
__iowrite32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2); __ioread32_copy(d->fw_read_buff, fw_reg_addr, w0_stat_sz >> 2);
for (offset = 0; offset < FW_REG_SIZE; offset += 16) { for (offset = 0; offset < FW_REG_SIZE; offset += 16) {
ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset); ret += snprintf(tmp + ret, FW_REG_BUF - ret, "%#.4x: ", offset);

View File

@ -225,7 +225,7 @@ int skl_nhlt_update_topology_bin(struct skl *skl)
struct hdac_bus *bus = skl_to_bus(skl); struct hdac_bus *bus = skl_to_bus(skl);
struct device *dev = bus->dev; struct device *dev = bus->dev;
dev_dbg(dev, "oem_id %.6s, oem_table_id %8s oem_revision %d\n", dev_dbg(dev, "oem_id %.6s, oem_table_id %.8s oem_revision %d\n",
nhlt->header.oem_id, nhlt->header.oem_table_id, nhlt->header.oem_id, nhlt->header.oem_table_id,
nhlt->header.oem_revision); nhlt->header.oem_revision);

View File

@ -241,7 +241,7 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id]; struct mtk_base_afe_memif *memif = &afe->memif[rtd->cpu_dai->id];
int hd_audio = 0; int hd_audio = 0;
int hd_align = 1; int hd_align = 0;
/* set hd mode */ /* set hd mode */
switch (substream->runtime->format) { switch (substream->runtime->format) {
@ -254,7 +254,6 @@ int mtk_afe_fe_prepare(struct snd_pcm_substream *substream,
break; break;
case SNDRV_PCM_FORMAT_S24_LE: case SNDRV_PCM_FORMAT_S24_LE:
hd_audio = 1; hd_audio = 1;
hd_align = 0;
break; break;
default: default:
dev_err(afe->dev, "%s() error: unsupported format %d\n", dev_err(afe->dev, "%s() error: unsupported format %d\n",

View File

@ -87,6 +87,7 @@ config SND_MESON_AXG_PDM
config SND_MESON_G12A_TOHDMITX config SND_MESON_G12A_TOHDMITX
tristate "Amlogic G12A To HDMI TX Control Support" tristate "Amlogic G12A To HDMI TX Control Support"
select REGMAP_MMIO
imply SND_SOC_HDMI_CODEC imply SND_SOC_HDMI_CODEC
help help
Select Y or M to add support for HDMI audio on the g12a SoC Select Y or M to add support for HDMI audio on the g12a SoC

View File

@ -327,7 +327,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev)
} }
/* Formatter dedicated reset line */ /* Formatter dedicated reset line */
formatter->reset = reset_control_get_optional_exclusive(dev, NULL); formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
if (IS_ERR(formatter->reset)) { if (IS_ERR(formatter->reset)) {
ret = PTR_ERR(formatter->reset); ret = PTR_ERR(formatter->reset);
if (ret != -EPROBE_DEFER) if (ret != -EPROBE_DEFER)

View File

@ -138,8 +138,19 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
static int rk_aif1_startup(struct snd_pcm_substream *substream)
{
/*
* Set period size to 240 because pl330 has issue
* dealing with larger period in stress testing.
*/
return snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 240, 240);
}
static const struct snd_soc_ops rk_aif1_ops = { static const struct snd_soc_ops rk_aif1_ops = {
.hw_params = rk_aif1_hw_params, .hw_params = rk_aif1_hw_params,
.startup = rk_aif1_startup,
}; };
SND_SOC_DAILINK_DEFS(hifi, SND_SOC_DAILINK_DEFS(hifi,

View File

@ -30,6 +30,7 @@ struct rsnd_adg {
struct clk *clkout[CLKOUTMAX]; struct clk *clkout[CLKOUTMAX];
struct clk_onecell_data onecell; struct clk_onecell_data onecell;
struct rsnd_mod mod; struct rsnd_mod mod;
int clk_rate[CLKMAX];
u32 flags; u32 flags;
u32 ckr; u32 ckr;
u32 rbga; u32 rbga;
@ -114,9 +115,9 @@ static void __rsnd_adg_get_timesel_ratio(struct rsnd_priv *priv,
unsigned int val, en; unsigned int val, en;
unsigned int min, diff; unsigned int min, diff;
unsigned int sel_rate[] = { unsigned int sel_rate[] = {
clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */ adg->clk_rate[CLKA], /* 0000: CLKA */
clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */ adg->clk_rate[CLKB], /* 0001: CLKB */
clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */ adg->clk_rate[CLKC], /* 0010: CLKC */
adg->rbga_rate_for_441khz, /* 0011: RBGA */ adg->rbga_rate_for_441khz, /* 0011: RBGA */
adg->rbgb_rate_for_48khz, /* 0100: RBGB */ adg->rbgb_rate_for_48khz, /* 0100: RBGB */
}; };
@ -302,7 +303,7 @@ int rsnd_adg_clk_query(struct rsnd_priv *priv, unsigned int rate)
* AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI. * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI.
*/ */
for_each_rsnd_clk(clk, adg, i) { for_each_rsnd_clk(clk, adg, i) {
if (rate == clk_get_rate(clk)) if (rate == adg->clk_rate[i])
return sel_table[i]; return sel_table[i];
} }
@ -369,10 +370,18 @@ void rsnd_adg_clk_control(struct rsnd_priv *priv, int enable)
for_each_rsnd_clk(clk, adg, i) { for_each_rsnd_clk(clk, adg, i) {
ret = 0; ret = 0;
if (enable) if (enable) {
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
else
/*
* We shouldn't use clk_get_rate() under
* atomic context. Let's keep it when
* rsnd_adg_clk_enable() was called
*/
adg->clk_rate[i] = clk_get_rate(adg->clk[i]);
} else {
clk_disable_unprepare(clk); clk_disable_unprepare(clk);
}
if (ret < 0) if (ret < 0)
dev_warn(dev, "can't use clk %d\n", i); dev_warn(dev, "can't use clk %d\n", i);

View File

@ -306,6 +306,12 @@ static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
if (!dmaengine_pcm_can_report_residue(dev, pcm->chan[i])) if (!dmaengine_pcm_can_report_residue(dev, pcm->chan[i]))
pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE; pcm->flags |= SND_DMAENGINE_PCM_FLAG_NO_RESIDUE;
if (rtd->pcm->streams[i].pcm->name[0] == '\0') {
strncpy(rtd->pcm->streams[i].pcm->name,
rtd->pcm->streams[i].pcm->id,
sizeof(rtd->pcm->streams[i].pcm->name));
}
} }
return 0; return 0;

View File

@ -80,12 +80,6 @@ struct soc_tplg {
static int soc_tplg_process_headers(struct soc_tplg *tplg); static int soc_tplg_process_headers(struct soc_tplg *tplg);
static void soc_tplg_complete(struct soc_tplg *tplg); static void soc_tplg_complete(struct soc_tplg *tplg);
struct snd_soc_dapm_widget *
snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
struct snd_soc_dapm_widget *
snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
const struct snd_soc_dapm_widget *widget);
static void soc_tplg_denum_remove_texts(struct soc_enum *se); static void soc_tplg_denum_remove_texts(struct soc_enum *se);
static void soc_tplg_denum_remove_values(struct soc_enum *se); static void soc_tplg_denum_remove_values(struct soc_enum *se);

View File

@ -329,10 +329,23 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
if (bus->ppcap) if (bus->ppcap)
dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n"); 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); ret = hda_dsp_ctrl_init_chip(sdev, true);
if (ret < 0) { if (ret < 0) {
dev_err(bus->dev, "error: init chip failed with ret: %d\n", dev_err(bus->dev, "error: init chip failed with ret: %d\n",
ret); ret);
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
hda_codec_i915_exit(sdev);
#endif
return ret; return ret;
} }
@ -340,13 +353,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
if (bus->mlcap) if (bus->mlcap)
snd_hdac_ext_bus_get_ml_capabilities(bus); snd_hdac_ext_bus_get_ml_capabilities(bus);
/* init i915 and HDMI codecs */
ret = hda_codec_i915_init(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: no HDMI audio devices found\n");
return ret;
}
/* codec detection */ /* codec detection */
if (!bus->codec_mask) { if (!bus->codec_mask) {
dev_info(bus->dev, "no hda codecs found!\n"); dev_info(bus->dev, "no hda codecs found!\n");

View File

@ -1148,11 +1148,9 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
goto err_pm_disable; goto err_pm_disable;
} }
ret = devm_snd_soc_register_component(&pdev->dev, ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s);
&sun4i_i2s_component,
&sun4i_i2s_dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not register DAI\n"); dev_err(&pdev->dev, "Could not initialise regmap fields\n");
goto err_suspend; goto err_suspend;
} }
@ -1162,9 +1160,11 @@ static int sun4i_i2s_probe(struct platform_device *pdev)
goto err_suspend; goto err_suspend;
} }
ret = sun4i_i2s_init_regmap_fields(&pdev->dev, i2s); ret = devm_snd_soc_register_component(&pdev->dev,
&sun4i_i2s_component,
&sun4i_i2s_dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not initialise regmap fields\n"); dev_err(&pdev->dev, "Could not register DAI\n");
goto err_suspend; goto err_suspend;
} }

View File

@ -23,14 +23,31 @@
#include "omap-mcbsp.h" #include "omap-mcbsp.h"
#include "../codecs/cx20442.h" #include "../codecs/cx20442.h"
static struct gpio_desc *handset_mute;
static struct gpio_desc *handsfree_mute;
static int ams_delta_event_handset(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
gpiod_set_value_cansleep(handset_mute, !SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
static int ams_delta_event_handsfree(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
gpiod_set_value_cansleep(handsfree_mute, !SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
/* Board specific DAPM widgets */ /* Board specific DAPM widgets */
static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
/* Handset */ /* Handset */
SND_SOC_DAPM_MIC("Mouthpiece", NULL), SND_SOC_DAPM_MIC("Mouthpiece", NULL),
SND_SOC_DAPM_HP("Earpiece", NULL), SND_SOC_DAPM_HP("Earpiece", ams_delta_event_handset),
/* Handsfree/Speakerphone */ /* Handsfree/Speakerphone */
SND_SOC_DAPM_MIC("Microphone", NULL), SND_SOC_DAPM_MIC("Microphone", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL), SND_SOC_DAPM_SPK("Speaker", ams_delta_event_handsfree),
}; };
/* How they are connected to codec pins */ /* How they are connected to codec pins */
@ -542,6 +559,16 @@ static int ams_delta_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
handset_mute = devm_gpiod_get(card->dev, "handset_mute",
GPIOD_OUT_HIGH);
if (IS_ERR(handset_mute))
return PTR_ERR(handset_mute);
handsfree_mute = devm_gpiod_get(card->dev, "handsfree_mute",
GPIOD_OUT_HIGH);
if (IS_ERR(handsfree_mute))
return PTR_ERR(handsfree_mute);
ret = snd_soc_register_card(card); ret = snd_soc_register_card(card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);

View File

@ -187,57 +187,9 @@ static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev, static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
u32 spcr; u32 spcr;
u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST; u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
if (spcr & mask) {
/* start off disabled */
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
spcr & ~mask);
toggle_clock(dev, playback);
}
if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
/* Start the sample generator */
spcr |= DAVINCI_MCBSP_SPCR_GRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
}
if (playback) {
/* Stop the DMA to avoid data loss */
/* while the transmitter is out of reset to handle XSYNCERR */
if (component->driver->ops->trigger) {
int ret = component->driver->ops->trigger(substream,
SNDRV_PCM_TRIGGER_STOP);
if (ret < 0)
printk(KERN_DEBUG "Playback DMA stop failed\n");
}
/* Enable the transmitter */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr |= DAVINCI_MCBSP_SPCR_XRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
/* wait for any unexpected frame sync error to occur */
udelay(100);
/* Disable the transmitter to clear any outstanding XSYNCERR */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
toggle_clock(dev, playback);
/* Restart the DMA */
if (component->driver->ops->trigger) {
int ret = component->driver->ops->trigger(substream,
SNDRV_PCM_TRIGGER_START);
if (ret < 0)
printk(KERN_DEBUG "Playback DMA start failed\n");
}
}
/* Enable transmitter or receiver */ /* Enable transmitter or receiver */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@ -575,7 +527,41 @@ static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
{ {
struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai); struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
u32 spcr;
u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
davinci_mcbsp_stop(dev, playback); davinci_mcbsp_stop(dev, playback);
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
if (spcr & mask) {
/* start off disabled */
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
spcr & ~mask);
toggle_clock(dev, playback);
}
if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
/* Start the sample generator */
spcr |= DAVINCI_MCBSP_SPCR_GRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
}
if (playback) {
/* Enable the transmitter */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr |= DAVINCI_MCBSP_SPCR_XRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
/* wait for any unexpected frame sync error to occur */
udelay(100);
/* Disable the transmitter to clear any outstanding XSYNCERR */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
toggle_clock(dev, playback);
}
return 0; return 0;
} }

View File

@ -424,8 +424,11 @@ int uniphier_aio_dai_suspend(struct snd_soc_dai *dai)
{ {
struct uniphier_aio *aio = uniphier_priv(dai); struct uniphier_aio *aio = uniphier_priv(dai);
reset_control_assert(aio->chip->rst); aio->chip->num_wup_aios--;
clk_disable_unprepare(aio->chip->clk); if (!aio->chip->num_wup_aios) {
reset_control_assert(aio->chip->rst);
clk_disable_unprepare(aio->chip->clk);
}
return 0; return 0;
} }
@ -439,13 +442,15 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
if (!aio->chip->active) if (!aio->chip->active)
return 0; return 0;
ret = clk_prepare_enable(aio->chip->clk); if (!aio->chip->num_wup_aios) {
if (ret) ret = clk_prepare_enable(aio->chip->clk);
return ret; if (ret)
return ret;
ret = reset_control_deassert(aio->chip->rst); ret = reset_control_deassert(aio->chip->rst);
if (ret) if (ret)
goto err_out_clock; goto err_out_clock;
}
aio_iecout_set_enable(aio->chip, true); aio_iecout_set_enable(aio->chip, true);
aio_chip_init(aio->chip); aio_chip_init(aio->chip);
@ -458,7 +463,7 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
ret = aio_init(sub); ret = aio_init(sub);
if (ret) if (ret)
goto err_out_clock; goto err_out_reset;
if (!sub->setting) if (!sub->setting)
continue; continue;
@ -466,11 +471,16 @@ int uniphier_aio_dai_resume(struct snd_soc_dai *dai)
aio_port_reset(sub); aio_port_reset(sub);
aio_src_reset(sub); aio_src_reset(sub);
} }
aio->chip->num_wup_aios++;
return 0; return 0;
err_out_reset:
if (!aio->chip->num_wup_aios)
reset_control_assert(aio->chip->rst);
err_out_clock: err_out_clock:
clk_disable_unprepare(aio->chip->clk); if (!aio->chip->num_wup_aios)
clk_disable_unprepare(aio->chip->clk);
return ret; return ret;
} }
@ -619,6 +629,7 @@ int uniphier_aio_probe(struct platform_device *pdev)
return PTR_ERR(chip->rst); return PTR_ERR(chip->rst);
chip->num_aios = chip->chip_spec->num_dais; chip->num_aios = chip->chip_spec->num_dais;
chip->num_wup_aios = chip->num_aios;
chip->aios = devm_kcalloc(dev, chip->aios = devm_kcalloc(dev,
chip->num_aios, sizeof(struct uniphier_aio), chip->num_aios, sizeof(struct uniphier_aio),
GFP_KERNEL); GFP_KERNEL);

View File

@ -285,6 +285,7 @@ struct uniphier_aio_chip {
struct uniphier_aio *aios; struct uniphier_aio *aios;
int num_aios; int num_aios;
int num_wup_aios;
struct uniphier_aio_pll *plls; struct uniphier_aio_pll *plls;
int num_plls; int num_plls;