diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c index f6fee2063a..e6313c13ea 100644 --- a/asoc/codecs/aqt1000/aqt1000-core.c +++ b/asoc/codecs/aqt1000/aqt1000-core.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -21,6 +23,9 @@ #include #include #include +#include +#include +#include #include #include "../msm-cdc-pinctrl.h" #include "../msm-cdc-supply.h" @@ -93,8 +98,22 @@ static int aqt1000_bringup(struct aqt1000 *aqt) regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK, + 0x04, 0x00); + + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); + regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, + 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, + 0x01, 0x01); + regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, + 0x01, 0x01); + /* Codec digital reset */ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_RST_CTL, 0x01, 0x01); + /* Add 100usec delay as per HW requirement */ + usleep_range(100, 110); return 0; } @@ -378,6 +397,13 @@ static struct aqt1000_pdata *aqt1000_populate_dt_data(struct device *dev) goto err_parse_dt_prop; } + pdata->irq_gpio = of_get_named_gpio(dev->of_node, + "qcom,gpio-connect", 0); + if (!gpio_is_valid(pdata->irq_gpio)) { + dev_err(dev, "%s: TLMM connect gpio not found\n", __func__); + goto err_parse_dt_prop; + } + return pdata; err_parse_dt_prop: @@ -457,6 +483,7 @@ static int aqt1000_i2c_probe(struct i2c_client *client, aqt1000->dev = &client->dev; aqt1000->dev_up = true; aqt1000->mclk_rate = pdata->mclk_rate; + aqt1000->irq = client->irq; aqt1000->num_of_supplies = pdata->num_supplies; ret = msm_cdc_init_supplies(aqt1000->dev, &aqt1000->supplies, @@ -496,6 +523,9 @@ static int aqt1000_i2c_probe(struct i2c_client *client, goto err_supplies; } + pm_runtime_set_active(aqt1000->dev); + pm_runtime_enable(aqt1000->dev); + ret = aqt_register_codec(&client->dev); if (ret) { dev_err(aqt1000->dev, "%s: Codec registration failed\n", @@ -506,6 +536,7 @@ static int aqt1000_i2c_probe(struct i2c_client *client, return ret; err_cdc_register: + pm_runtime_disable(aqt1000->dev); aqt1000_device_exit(aqt1000); err_supplies: msm_cdc_release_supplies(aqt1000->dev, aqt1000->supplies, @@ -527,6 +558,7 @@ static int aqt1000_i2c_remove(struct i2c_client *client) aqt = dev_get_drvdata(&client->dev); + pm_runtime_disable(aqt->dev); msm_cdc_release_supplies(aqt->dev, aqt->supplies, pdata->regulator, pdata->num_supplies); @@ -535,6 +567,22 @@ static int aqt1000_i2c_remove(struct i2c_client *client) return 0; } +#ifdef CONFIG_PM +static int aqt1000_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s system resume\n", __func__); + + return 0; +} + +static int aqt1000_runtime_suspend(struct device *dev) +{ + dev_dbg(dev, "%s system suspend\n", __func__); + + return 0; +} +#endif + #ifdef CONFIG_PM_SLEEP static int aqt1000_i2c_resume(struct device *dev) { @@ -556,8 +604,10 @@ static struct i2c_device_id aqt1000_id_table[] = { MODULE_DEVICE_TABLE(i2c, aqt1000_id_table); static const struct dev_pm_ops aqt1000_i2c_pm_ops = { - .suspend = aqt1000_i2c_suspend, - .resume = aqt1000_i2c_resume, + SET_RUNTIME_PM_OPS(aqt1000_runtime_suspend, + aqt1000_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(aqt1000_i2c_suspend, + aqt1000_i2c_resume) }; static const struct of_device_id aqt_match_table[] = { diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c index 0c13353064..321b490bef 100644 --- a/asoc/codecs/aqt1000/aqt1000-irq.c +++ b/asoc/codecs/aqt1000/aqt1000-irq.c @@ -77,7 +77,8 @@ int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name, if (irq < 0) return irq; - return request_threaded_irq(irq, NULL, handler, IRQF_ONESHOT, + return request_threaded_irq(irq, NULL, handler, + IRQF_ONESHOT | IRQF_TRIGGER_RISING, name, data); } EXPORT_SYMBOL(aqt_request_irq); @@ -160,6 +161,8 @@ static struct irq_chip aqt_irq_chip = { .irq_enable = aqt_irq_enable, }; +static struct lock_class_key aqt_irq_lock_class; + static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_hw_number_t hw) { @@ -167,6 +170,7 @@ static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq, irq_set_chip_data(virq, data); irq_set_chip_and_handler(virq, &aqt_irq_chip, handle_simple_irq); + irq_set_lockdep_class(virq, &aqt_irq_lock_class); irq_set_nested_thread(virq, 1); irq_set_noprobe(virq); @@ -196,12 +200,6 @@ int aqt_irq_init(struct aqt1000 *aqt) return -EINVAL; } - if (!aqt->irq) { - dev_dbg(aqt->dev, "%s: No interrupt specified\n", __func__); - aqt->irq_base = 0; - return 0; - } - pdata = dev_get_platdata(aqt->dev); if (!pdata) { dev_err(aqt->dev, "%s: Invalid platform data\n", __func__); @@ -214,13 +212,7 @@ int aqt_irq_init(struct aqt1000 *aqt) flags = pdata->irq_flags; if (pdata->irq_gpio) { - if (gpio_to_irq(pdata->irq_gpio) != aqt->irq) { - dev_warn(aqt->dev, "%s: IRQ %d is not GPIO %d (%d)\n", - __func__, aqt->irq, pdata->irq_gpio, - gpio_to_irq(pdata->irq_gpio)); - aqt->irq = gpio_to_irq(pdata->irq_gpio); - } - + aqt->irq = gpio_to_irq(pdata->irq_gpio); ret = devm_gpio_request_one(aqt->dev, pdata->irq_gpio, GPIOF_IN, "AQT IRQ"); if (ret) { @@ -229,10 +221,6 @@ int aqt_irq_init(struct aqt1000 *aqt) pdata->irq_gpio = 0; return ret; } - } else { - dev_dbg(aqt->dev, "%s: irq_gpio is %d\n", - __func__, pdata->irq_gpio); - return 0; } irq_data = irq_get_irq_data(aqt->irq); @@ -242,6 +230,7 @@ int aqt_irq_init(struct aqt1000 *aqt) return -EINVAL; } + aqt->num_irq_regs = aqt_regmap_irq_chip.num_regs; for (i = 0; i < aqt->num_irq_regs; i++) { regmap_write(aqt->regmap, (AQT1000_INTR_CTRL_INT_TYPE_2 + i), 0); diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h index 9dc74a425a..7ae3276ff7 100644 --- a/asoc/codecs/aqt1000/aqt1000-routing.h +++ b/asoc/codecs/aqt1000/aqt1000-routing.h @@ -85,30 +85,30 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT ANC0 FB MUX", "ANC_IN_HPHL", "AQT RX INT1 MIX2"}, {"AQT ANC1 FB MUX", "ANC_IN_HPHR", "AQT RX INT2 MIX2"}, - {"AQT I2S_L RX", "AIF1_PB", "AQT AIF1 PB"}, - {"AQT I2S_R RX", "AIF1_PB", "AQT AIF1 PB"}, + {"AQT I2S_L RX", NULL, "AQT AIF1 PB"}, + {"AQT I2S_R RX", NULL, "AQT AIF1 PB"}, - {"AQT RX INT1_1 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT1_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_1 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT1_1 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT1_1 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT1_1 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT1_1 MUX", "DEC_V", "AQT ADC2 MUX"}, - {"AQT RX INT2_1 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT2_1 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_1 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT2_1 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT2_1 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT2_1 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT2_1 MUX", "DEC_V", "AQT ADC2 MUX"}, - {"AQT RX INT1_2 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT1_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT1_2 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT1_2 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT1_2 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT1_2 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT1_2 MUX", "DEC_V", "AQT ADC2 MUX"}, {"AQT RX INT1_2 MUX", "IIR0", "AQT IIR0"}, - {"AQT RX INT2_2 MUX", "I2S_L", "AQT I2S_L RX"}, - {"AQT RX INT2_2 MUX", "I2S_R", "AQT I2S_R RX"}, + {"AQT RX INT2_2 MUX", "I2S0_L", "AQT I2S_L RX"}, + {"AQT RX INT2_2 MUX", "I2S0_R", "AQT I2S_R RX"}, {"AQT RX INT2_2 MUX", "DEC_L", "AQT ADC0 MUX"}, {"AQT RX INT2_2 MUX", "DEC_R", "AQT ADC1 MUX"}, {"AQT RX INT2_2 MUX", "DEC_V", "AQT ADC2 MUX"}, @@ -137,6 +137,8 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT RX INT1 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT1 MIX2"}, {"AQT RX INT1 DAC", NULL, "AQT RX INT1 DEM MUX"}, {"AQT RX INT1 DAC", NULL, "AQT RX_BIAS"}, + {"AQT RX_BIAS", NULL, "AQT MCLK"}, + {"AQT MIC BIAS1", NULL, "AQT MCLK"}, {"AQT HPHL PA", NULL, "AQT RX INT1 DAC"}, {"AQT HPHL", NULL, "AQT HPHL PA"}, @@ -152,10 +154,12 @@ const struct snd_soc_dapm_route aqt_audio_map[] = { {"AQT ANC HPHR PA", NULL, "AQT RX INT2 DAC"}, {"AQT ANC HPHR", NULL, "AQT ANC HPHR PA"}, - {"AQT IIR0", NULL, "AQT TX_PATH2"}, + {"AQT IIR0", NULL, "AQT ADC2 MUX"}, {"AQT SRC0", NULL, "AQT IIR0"}, - {"AQT RX INT1 MIX2", "SRC0", "AQT SRC0"}, - {"AQT RX INT2 MIX2", "SRC0", "AQT SRC0"}, + {"AQT RX ST MUX", "SRC0", "AQT SRC0"}, + + {"AQT RX INT1 MIX2", NULL, "AQT RX ST MUX"}, + {"AQT RX INT2 MIX2", NULL, "AQT RX ST MUX"}, /* Native clk main path routing */ {"AQT RX INT1_1 NATIVE MUX", "ON", "AQT RX INT1_1 MUX"}, diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c index 21baae762a..8463d82230 100644 --- a/asoc/codecs/aqt1000/aqt1000.c +++ b/asoc/codecs/aqt1000/aqt1000.c @@ -2542,6 +2542,26 @@ static const char * const native_mux_text[] = { AQT_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text); AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text); +static int aqt_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); + int ret = 0; + + dev_dbg(codec->dev, "%s: event = %d\n", __func__, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ret = aqt_cdc_mclk_enable(codec, true); + break; + case SND_SOC_DAPM_POST_PMD: + ret = aqt_cdc_mclk_enable(codec, false); + break; + } + + return ret; +} + static int aif_cap_mixer_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -2561,8 +2581,17 @@ static const struct snd_kcontrol_new aif1_cap_mixer[] = { aif_cap_mixer_get, aif_cap_mixer_put), }; +static const char * const rx_inp_st_mux_text[] = { + "ZERO", "SRC0", +}; +AQT_DAPM_ENUM(rx_inp_st, AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4, + rx_inp_st_mux_text); + static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { + SND_SOC_DAPM_SUPPLY("AQT MCLK", SND_SOC_NOPM, 0, 0, aqt_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_AIF_OUT_E("AQT AIF1 CAP", "AQT AIF1 Capture", 0, SND_SOC_NOPM, AIF1_CAP, 0, aqt_codec_enable_i2s_tx, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), @@ -2720,6 +2749,10 @@ static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = { AQT_DAPM_MUX("AQT RX INT1_1 NATIVE MUX", 0, int1_1_native), AQT_DAPM_MUX("AQT RX INT2_1 NATIVE MUX", 0, int2_1_native), + + SND_SOC_DAPM_MUX("AQT RX ST MUX", + AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 0, + &rx_inp_st_mux), }; static int aqt_startup(struct snd_pcm_substream *substream, @@ -3230,14 +3263,10 @@ int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root, EXPORT_SYMBOL(aqt_codec_info_create_codec_entry); static const struct aqt_reg_mask_val aqt_codec_reg_init[] = { - {AQT1000_CHIP_CFG0_CLK_CFG_MCLK, 0x04, 0x00}, {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01}, }; static const struct aqt_reg_mask_val aqt_codec_reg_update[] = { - {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x01, 0x01}, - {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01}, - {AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG, 0x01, 0x01}, {AQT1000_LDOH_MODE, 0x1F, 0x0B}, {AQT1000_MICB1_TEST_CTL_2, 0x07, 0x01}, {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x03, 0x02},