Merge branch 'asoc-5.4' into asoc-next

This commit is contained in:
Mark Brown
2019-09-15 10:31:44 +01:00
273 changed files with 12154 additions and 6887 deletions

View File

@@ -529,10 +529,6 @@ static const struct snd_kcontrol_new pm860x_snd_controls[] = {
* DAPM Controls
*/
/* PCM Switch / PCM Interface */
static const struct snd_kcontrol_new pcm_switch_controls =
SOC_DAPM_SINGLE("Switch", PM860X_ADC_EN_2, 0, 1, 0);
/* AUX1 Switch */
static const struct snd_kcontrol_new aux1_switch_controls =
SOC_DAPM_SINGLE("Switch", PM860X_ANA_TO_ANA, 4, 1, 0);
@@ -549,17 +545,6 @@ static const struct snd_kcontrol_new lepa_switch_controls =
static const struct snd_kcontrol_new repa_switch_controls =
SOC_DAPM_SINGLE("Switch", PM860X_DAC_EN_2, 1, 1, 0);
/* PCM Mux / Mux7 */
static const char *aif1_text[] = {
"PCM L", "PCM R",
};
static SOC_ENUM_SINGLE_DECL(aif1_enum,
PM860X_PCM_IFACE_3, 6, aif1_text);
static const struct snd_kcontrol_new aif1_mux =
SOC_DAPM_ENUM("PCM Mux", aif1_enum);
/* I2S Mux / Mux9 */
static const char *i2s_din_text[] = {
"DIN", "DIN1",

View File

@@ -70,10 +70,12 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS43130 if I2C
select SND_SOC_CS4341 if SND_SOC_I2C_AND_SPI
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L15 if MFD_CS47L15
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS47L35 if MFD_CS47L35
select SND_SOC_CS47L85 if MFD_CS47L85
select SND_SOC_CS47L90 if MFD_CS47L90
select SND_SOC_CS47L92 if MFD_CS47L92
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_CX2072X if I2C
@@ -197,6 +199,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_TS3A227E if I2C
select SND_SOC_TWL4030 if TWL4030_CORE
select SND_SOC_TWL6040 if TWL6040_CORE
select SND_SOC_UDA1334 if GPIOLIB
select SND_SOC_UDA134X
select SND_SOC_UDA1380 if I2C
select SND_SOC_WCD9335 if SLIMBUS
@@ -581,6 +584,9 @@ config SND_SOC_CS4349
tristate "Cirrus Logic CS4349 CODEC"
depends on I2C
config SND_SOC_CS47L15
tristate
config SND_SOC_CS47L24
tristate
@@ -593,6 +599,9 @@ config SND_SOC_CS47L85
config SND_SOC_CS47L90
tristate
config SND_SOC_CS47L92
tristate
# Cirrus Logic Quad-Channel ADC
config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
@@ -722,12 +731,16 @@ config SND_SOC_LOCHNAGAR_SC
config SND_SOC_MADERA
tristate
default y if SND_SOC_CS47L15=y
default y if SND_SOC_CS47L35=y
default y if SND_SOC_CS47L85=y
default y if SND_SOC_CS47L90=y
default y if SND_SOC_CS47L92=y
default m if SND_SOC_CS47L15=m
default m if SND_SOC_CS47L35=m
default m if SND_SOC_CS47L85=m
default m if SND_SOC_CS47L90=m
default m if SND_SOC_CS47L92=m
config SND_SOC_MAX98088
tristate "Maxim MAX98088/9 Low-Power, Stereo Audio Codec"
@@ -1195,6 +1208,14 @@ config SND_SOC_TWL4030
config SND_SOC_TWL6040
tristate
config SND_SOC_UDA1334
tristate "NXP UDA1334 DAC"
depends on GPIOLIB
help
The UDA1334 is an NXP audio codec, supports the I2S-bus data format
and has basic features such as de-emphasis (at 44.1 kHz sampling
rate) and mute.
config SND_SOC_UDA134X
tristate

View File

@@ -64,10 +64,12 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
snd-soc-cs43130-objs := cs43130.o
snd-soc-cs4341-objs := cs4341.o
snd-soc-cs4349-objs := cs4349.o
snd-soc-cs47l15-objs := cs47l15.o
snd-soc-cs47l24-objs := cs47l24.o
snd-soc-cs47l35-objs := cs47l35.o
snd-soc-cs47l85-objs := cs47l85.o
snd-soc-cs47l90-objs := cs47l90.o
snd-soc-cs47l92-objs := cs47l92.o
snd-soc-cs53l30-objs := cs53l30.o
snd-soc-cx20442-objs := cx20442.o
snd-soc-cx2072x-objs := cx2072x.o
@@ -210,6 +212,7 @@ snd-soc-tscs454-objs := tscs454.o
snd-soc-ts3a227e-objs := ts3a227e.o
snd-soc-twl4030-objs := twl4030.o
snd-soc-twl6040-objs := twl6040.o
snd-soc-uda1334-objs := uda1334.o
snd-soc-uda134x-objs := uda134x.o
snd-soc-uda1380-objs := uda1380.o
snd-soc-wcd9335-objs := wcd-clsh-v2.o wcd9335.o
@@ -346,9 +349,11 @@ obj-$(CONFIG_SND_SOC_CS43130) += snd-soc-cs43130.o
obj-$(CONFIG_SND_SOC_CS4341) += snd-soc-cs4341.o
obj-$(CONFIG_SND_SOC_CS4349) += snd-soc-cs4349.o
obj-$(CONFIG_SND_SOC_CS47L24) += snd-soc-cs47l24.o
obj-$(CONFIG_SND_SOC_CS47L15) += snd-soc-cs47l15.o
obj-$(CONFIG_SND_SOC_CS47L35) += snd-soc-cs47l35.o
obj-$(CONFIG_SND_SOC_CS47L85) += snd-soc-cs47l85.o
obj-$(CONFIG_SND_SOC_CS47L90) += snd-soc-cs47l90.o
obj-$(CONFIG_SND_SOC_CS47L92) += snd-soc-cs47l92.o
obj-$(CONFIG_SND_SOC_CS53L30) += snd-soc-cs53l30.o
obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
obj-$(CONFIG_SND_SOC_CX2072X) += snd-soc-cx2072x.o
@@ -490,6 +495,7 @@ obj-$(CONFIG_SND_SOC_TSCS454) += snd-soc-tscs454.o
obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o
obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_UDA1334) += snd-soc-uda1334.o
obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
obj-$(CONFIG_SND_SOC_WCD9335) += snd-soc-wcd9335.o

View File

@@ -413,15 +413,10 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = {
.ops = &ad193x_dai_ops,
};
struct ad193x_reg_default {
unsigned int reg;
unsigned int val;
};
/* codec register values to set after reset */
static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
{
const struct ad193x_reg_default reg_init[] = {
static const struct reg_sequence reg_init[] = {
{ 0, 0x99 }, /* PLL_CLK_CTRL0: pll input: mclki/xi 12.288Mhz */
{ 1, 0x04 }, /* PLL_CLK_CTRL1: no on-chip Vref */
{ 2, 0x40 }, /* DAC_CTRL0: TDM mode */
@@ -437,21 +432,17 @@ static void ad193x_reg_default_init(struct ad193x_priv *ad193x)
{ 12, 0x00 }, /* DAC_L4_VOL: no attenuation */
{ 13, 0x00 }, /* DAC_R4_VOL: no attenuation */
};
const struct ad193x_reg_default reg_adc_init[] = {
static const struct reg_sequence reg_adc_init[] = {
{ 14, 0x03 }, /* ADC_CTRL0: high-pass filter enable */
{ 15, 0x43 }, /* ADC_CTRL1: sata delay=1, adc aux mode */
{ 16, 0x00 }, /* ADC_CTRL2: reset */
};
int i;
for (i = 0; i < ARRAY_SIZE(reg_init); i++)
regmap_write(ad193x->regmap, reg_init[i].reg, reg_init[i].val);
regmap_multi_reg_write(ad193x->regmap, reg_init, ARRAY_SIZE(reg_init));
if (ad193x_has_adc(ad193x)) {
for (i = 0; i < ARRAY_SIZE(reg_adc_init); i++) {
regmap_write(ad193x->regmap, reg_adc_init[i].reg,
reg_adc_init[i].val);
}
regmap_multi_reg_write(ad193x->regmap, reg_adc_init,
ARRAY_SIZE(reg_adc_init));
}
}

View File

@@ -334,7 +334,7 @@ static struct cs4271_clk_cfg cs4271_clk_tab[] = {
{0, CS4271_MODE1_MODE_4X, 256, CS4271_MODE1_DIV_2},
};
#define CS4171_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
#define CS4271_NR_RATIOS ARRAY_SIZE(cs4271_clk_tab)
static int cs4271_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
@@ -383,13 +383,13 @@ static int cs4271_hw_params(struct snd_pcm_substream *substream,
val = CS4271_MODE1_MODE_4X;
ratio = cs4271->mclk / cs4271->rate;
for (i = 0; i < CS4171_NR_RATIOS; i++)
for (i = 0; i < CS4271_NR_RATIOS; i++)
if ((cs4271_clk_tab[i].master == cs4271->master) &&
(cs4271_clk_tab[i].speed_mode == val) &&
(cs4271_clk_tab[i].ratio == ratio))
break;
if (i == CS4171_NR_RATIOS) {
if (i == CS4271_NR_RATIOS) {
dev_err(component->dev, "Invalid sample rate\n");
return -EINVAL;
}

View File

@@ -199,14 +199,6 @@ static const struct soc_enum beep_bass_enum =
SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1,
ARRAY_SIZE(beep_bass_text), beep_bass_text);
static const char * const adc_swap_text[] = {
"None", "A+B/2", "A-B/2", "Swap"
};
static const struct soc_enum adc_swap_enum =
SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3,
ARRAY_SIZE(adc_swap_text), adc_swap_text);
static const char * const pgaa_mux_text[] = {
"AIN1A", "AIN2A", "AIN3A"};

View File

@@ -273,12 +273,6 @@ static SOC_ENUM_SINGLE_DECL(xsp_output_mux_enum,
CS42L73_MIXERCTL, 4,
cs42l73_spo_mixer_text);
static const struct snd_kcontrol_new vsp_output_mux =
SOC_DAPM_ENUM("Route", vsp_output_mux_enum);
static const struct snd_kcontrol_new xsp_output_mux =
SOC_DAPM_ENUM("Route", xsp_output_mux_enum);
static const struct snd_kcontrol_new hp_amp_ctl =
SOC_DAPM_SINGLE("Switch", CS42L73_PWRCTL3, 0, 1, 1);

View File

@@ -684,6 +684,8 @@ static int cs42xx8_runtime_suspend(struct device *dev)
#endif
const struct dev_pm_ops cs42xx8_pm = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(cs42xx8_runtime_suspend, cs42xx8_runtime_resume, NULL)
};
EXPORT_SYMBOL_GPL(cs42xx8_pm);

1490
sound/soc/codecs/cs47l15.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -524,7 +524,7 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", MADERA_SYSTEM_CLOCK_1, MADERA_SYSCLK_ENA_SHIFT,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("OPCLK", MADERA_OUTPUT_SYSTEM_CLOCK,
MADERA_OPCLK_ENA_SHIFT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, 6,
SND_SOC_DAPM_SUPPLY("DSPCLK", MADERA_DSP_CLOCK_1, MADERA_DSP_CLK_ENA_SHIFT,
0, NULL, 0),
SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),

View File

@@ -2402,13 +2402,6 @@ static irqreturn_t cs47l90_adsp2_irq(int irq, void *data)
return IRQ_HANDLED;
}
static irqreturn_t cs47l90_dsp_bus_error(int irq, void *data)
{
struct wm_adsp *dsp = (struct wm_adsp *)data;
return wm_adsp2_bus_error(dsp);
}
static int cs47l90_component_probe(struct snd_soc_component *component)
{
struct cs47l90 *cs47l90 = snd_soc_component_get_drvdata(component);
@@ -2558,7 +2551,7 @@ static int cs47l90_probe(struct platform_device *pdev)
if (ret == 0) {
ret = madera_init_bus_error_irq(&cs47l90->core, i,
cs47l90_dsp_bus_error);
wm_adsp2_bus_error);
if (ret != 0)
wm_adsp2_remove(&cs47l90->core.adsp[i]);
}

2039
sound/soc/codecs/cs47l92.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
@@ -33,6 +34,7 @@ static const unsigned int supported_mclk_lrck_ratios[] = {
struct es8316_priv {
struct mutex lock;
struct clk *mclk;
struct regmap *regmap;
struct snd_soc_component *component;
struct snd_soc_jack *jack;
@@ -363,13 +365,21 @@ static int es8316_set_dai_sysclk(struct snd_soc_dai *codec_dai,
{
struct snd_soc_component *component = codec_dai->component;
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
int i;
int i, ret;
int count = 0;
es8316->sysclk = freq;
if (freq == 0)
if (freq == 0) {
es8316->sysclk_constraints.list = NULL;
es8316->sysclk_constraints.count = 0;
return 0;
}
ret = clk_set_rate(es8316->mclk, freq);
if (ret)
return ret;
/* Limit supported sample rates to ones that can be autodetected
* by the codec running in slave mode.
@@ -444,17 +454,10 @@ static int es8316_pcm_startup(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
if (es8316->sysclk == 0) {
dev_err(component->dev, "No sysclk provided\n");
return -EINVAL;
}
/* The set of sample rates that can be supported depends on the
* MCLK supplied to the CODEC.
*/
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&es8316->sysclk_constraints);
if (es8316->sysclk_constraints.list)
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&es8316->sysclk_constraints);
return 0;
}
@@ -466,11 +469,19 @@ static int es8316_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
u8 wordlen = 0;
int i;
if (!es8316->sysclk) {
dev_err(component->dev, "No MCLK configured\n");
return -EINVAL;
/* Validate supported sample rates that are autodetected from MCLK */
for (i = 0; i < NR_SUPPORTED_MCLK_LRCK_RATIOS; i++) {
const unsigned int ratio = supported_mclk_lrck_ratios[i];
if (es8316->sysclk % ratio != 0)
continue;
if (es8316->sysclk / ratio == params_rate(params))
break;
}
if (i == NR_SUPPORTED_MCLK_LRCK_RATIOS)
return -EINVAL;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
@@ -700,9 +711,24 @@ static int es8316_set_jack(struct snd_soc_component *component,
static int es8316_probe(struct snd_soc_component *component)
{
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
int ret;
es8316->component = component;
es8316->mclk = devm_clk_get_optional(component->dev, "mclk");
if (IS_ERR(es8316->mclk)) {
dev_err(component->dev, "unable to get mclk\n");
return PTR_ERR(es8316->mclk);
}
if (!es8316->mclk)
dev_warn(component->dev, "assuming static mclk\n");
ret = clk_prepare_enable(es8316->mclk);
if (ret) {
dev_err(component->dev, "unable to enable mclk\n");
return ret;
}
/* Reset codec and enable current state machine */
snd_soc_component_write(component, ES8316_RESET, 0x3f);
usleep_range(5000, 5500);
@@ -725,8 +751,16 @@ static int es8316_probe(struct snd_soc_component *component)
return 0;
}
static void es8316_remove(struct snd_soc_component *component)
{
struct es8316_priv *es8316 = snd_soc_component_get_drvdata(component);
clk_disable_unprepare(es8316->mclk);
}
static const struct snd_soc_component_driver soc_component_dev_es8316 = {
.probe = es8316_probe,
.remove = es8316_remove,
.set_jack = es8316_set_jack,
.controls = es8316_snd_controls,
.num_controls = ARRAY_SIZE(es8316_snd_controls),

View File

@@ -99,7 +99,6 @@ static SOC_ENUM_SINGLE_DECL(adcpol,
static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0);
static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0);
static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0);
static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0);

View File

@@ -7,6 +7,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
@@ -274,6 +275,8 @@ struct hdmi_codec_priv {
struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx;
struct mutex lock;
struct snd_soc_jack *jack;
unsigned int jack_status;
};
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
@@ -663,6 +666,49 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai)
return 0;
}
static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
unsigned int jack_status)
{
if (hcp->jack && jack_status != hcp->jack_status) {
snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
hcp->jack_status = jack_status;
}
}
static void plugged_cb(struct device *dev, bool plugged)
{
struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
if (plugged)
hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
else
hdmi_codec_jack_report(hcp, 0);
}
/**
* hdmi_codec_set_jack_detect - register HDMI plugged callback
* @component: the hdmi-codec instance
* @jack: ASoC jack to report (dis)connection events on
*/
int hdmi_codec_set_jack_detect(struct snd_soc_component *component,
struct snd_soc_jack *jack)
{
struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
int ret = -EOPNOTSUPP;
if (hcp->hcd.ops->hook_plugged_cb) {
hcp->jack = jack;
ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
hcp->hcd.data,
plugged_cb,
component->dev);
if (ret)
hcp->jack = NULL;
}
return ret;
}
EXPORT_SYMBOL_GPL(hdmi_codec_set_jack_detect);
static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
{
struct hdmi_codec_daifmt *cf = dai->playback_dma_data;

View File

@@ -405,7 +405,6 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
{
struct rk3036_codec_priv *priv;
struct device_node *of_node = pdev->dev.of_node;
struct resource *res;
void __iomem *base;
struct regmap *grf;
int ret;
@@ -414,8 +413,7 @@ static int rk3036_codec_platform_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@@ -545,15 +545,13 @@ static int jz4725b_codec_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct jz_icdc *icdc;
struct resource *mem;
int ret;
icdc = devm_kzalloc(dev, sizeof(*icdc), GFP_KERNEL);
if (!icdc)
return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
icdc->base = devm_ioremap_resource(dev, mem);
icdc->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(icdc->base))
return PTR_ERR(icdc->base);

View File

@@ -318,7 +318,6 @@ static int jz4740_codec_probe(struct platform_device *pdev)
{
int ret;
struct jz4740_codec *jz4740_codec;
struct resource *mem;
void __iomem *base;
jz4740_codec = devm_kzalloc(&pdev->dev, sizeof(*jz4740_codec),
@@ -326,8 +325,7 @@ static int jz4740_codec_probe(struct platform_device *pdev)
if (!jz4740_codec)
return -ENOMEM;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, mem);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@@ -87,6 +87,16 @@
#define MADERA_FLLAO_MIN_N 4
#define MADERA_FLLAO_MAX_N 1023
#define MADERA_FLLAO_MAX_FBDIV 254
#define MADERA_FLLHJ_INT_MAX_N 1023
#define MADERA_FLLHJ_INT_MIN_N 1
#define MADERA_FLLHJ_FRAC_MAX_N 255
#define MADERA_FLLHJ_FRAC_MIN_N 4
#define MADERA_FLLHJ_LOW_THRESH 192000
#define MADERA_FLLHJ_MID_THRESH 1152000
#define MADERA_FLLHJ_MAX_THRESH 13000000
#define MADERA_FLLHJ_LOW_GAINS 0x23f0
#define MADERA_FLLHJ_MID_GAINS 0x22f2
#define MADERA_FLLHJ_HIGH_GAINS 0x21f0
#define MADERA_FLL_SYNCHRONISER_OFFS 0x10
#define CS47L35_FLL_SYNCHRONISER_OFFS 0xE
@@ -96,6 +106,7 @@
#define MADERA_FLL_CONTROL_4_OFFS 0x4
#define MADERA_FLL_CONTROL_5_OFFS 0x5
#define MADERA_FLL_CONTROL_6_OFFS 0x6
#define MADERA_FLL_GAIN_OFFS 0x8
#define MADERA_FLL_CONTROL_7_OFFS 0x9
#define MADERA_FLL_EFS_2_OFFS 0xA
#define MADERA_FLL_SYNCHRONISER_1_OFFS 0x1
@@ -107,6 +118,9 @@
#define MADERA_FLL_SYNCHRONISER_7_OFFS 0x7
#define MADERA_FLL_SPREAD_SPECTRUM_OFFS 0x9
#define MADERA_FLL_GPIO_CLOCK_OFFS 0xA
#define MADERA_FLL_CONTROL_10_OFFS 0xA
#define MADERA_FLL_CONTROL_11_OFFS 0xB
#define MADERA_FLL1_DIGITAL_TEST_1_OFFS 0xD
#define MADERA_FLLAO_CONTROL_1_OFFS 0x1
#define MADERA_FLLAO_CONTROL_2_OFFS 0x2
@@ -300,6 +314,100 @@ int madera_free_overheat(struct madera_priv *priv)
}
EXPORT_SYMBOL_GPL(madera_free_overheat);
static int madera_get_variable_u32_array(struct device *dev,
const char *propname,
u32 *dest, int n_max,
int multiple)
{
int n, ret;
n = device_property_count_u32(dev, propname);
if (n < 0) {
if (n == -EINVAL)
return 0; /* missing, ignore */
dev_warn(dev, "%s malformed (%d)\n", propname, n);
return n;
} else if ((n % multiple) != 0) {
dev_warn(dev, "%s not a multiple of %d entries\n",
propname, multiple);
return -EINVAL;
}
if (n > n_max)
n = n_max;
ret = device_property_read_u32_array(dev, propname, dest, n);
if (ret < 0)
return ret;
return n;
}
static void madera_prop_get_inmode(struct madera_priv *priv)
{
struct madera *madera = priv->madera;
struct madera_codec_pdata *pdata = &madera->pdata.codec;
u32 tmp[MADERA_MAX_INPUT * MADERA_MAX_MUXED_CHANNELS];
int n, i, in_idx, ch_idx;
BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode) != MADERA_MAX_INPUT);
BUILD_BUG_ON(ARRAY_SIZE(pdata->inmode[0]) != MADERA_MAX_MUXED_CHANNELS);
n = madera_get_variable_u32_array(madera->dev, "cirrus,inmode",
tmp, ARRAY_SIZE(tmp),
MADERA_MAX_MUXED_CHANNELS);
if (n < 0)
return;
in_idx = 0;
ch_idx = 0;
for (i = 0; i < n; ++i) {
pdata->inmode[in_idx][ch_idx] = tmp[i];
if (++ch_idx == MADERA_MAX_MUXED_CHANNELS) {
ch_idx = 0;
++in_idx;
}
}
}
static void madera_prop_get_pdata(struct madera_priv *priv)
{
struct madera *madera = priv->madera;
struct madera_codec_pdata *pdata = &madera->pdata.codec;
u32 out_mono[ARRAY_SIZE(pdata->out_mono)];
int i, n;
madera_prop_get_inmode(priv);
n = madera_get_variable_u32_array(madera->dev, "cirrus,out-mono",
out_mono, ARRAY_SIZE(out_mono), 1);
if (n > 0)
for (i = 0; i < n; ++i)
pdata->out_mono[i] = !!out_mono[i];
madera_get_variable_u32_array(madera->dev,
"cirrus,max-channels-clocked",
pdata->max_channels_clocked,
ARRAY_SIZE(pdata->max_channels_clocked),
1);
madera_get_variable_u32_array(madera->dev, "cirrus,pdm-fmt",
pdata->pdm_fmt,
ARRAY_SIZE(pdata->pdm_fmt), 1);
madera_get_variable_u32_array(madera->dev, "cirrus,pdm-mute",
pdata->pdm_mute,
ARRAY_SIZE(pdata->pdm_mute), 1);
madera_get_variable_u32_array(madera->dev, "cirrus,dmic-ref",
pdata->dmic_ref,
ARRAY_SIZE(pdata->dmic_ref), 1);
}
int madera_core_init(struct madera_priv *priv)
{
int i;
@@ -308,6 +416,9 @@ int madera_core_init(struct madera_priv *priv)
BUILD_BUG_ON(!madera_mixer_texts[MADERA_NUM_MIXER_INPUTS - 1]);
BUILD_BUG_ON(!madera_mixer_values[MADERA_NUM_MIXER_INPUTS - 1]);
if (!dev_get_platdata(priv->madera->dev))
madera_prop_get_pdata(priv);
mutex_init(&priv->rate_lock);
for (i = 0; i < MADERA_MAX_HP_OUTPUT; i++)
@@ -944,6 +1055,10 @@ static void madera_configure_input_mode(struct madera *madera)
int max_analogue_inputs, max_dmic_sup, i;
switch (madera->type) {
case CS47L15:
max_analogue_inputs = 1;
max_dmic_sup = 2;
break;
case CS47L35:
max_analogue_inputs = 2;
max_dmic_sup = 2;
@@ -1770,6 +1885,18 @@ const struct soc_enum madera_asrc1_rate[] = {
};
EXPORT_SYMBOL_GPL(madera_asrc1_rate);
const struct soc_enum madera_asrc1_bidir_rate[] = {
SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE1,
MADERA_ASRC1_RATE1_SHIFT, 0xf,
MADERA_RATE_ENUM_SIZE,
madera_rate_text, madera_rate_val),
SOC_VALUE_ENUM_SINGLE(MADERA_ASRC1_RATE2,
MADERA_ASRC1_RATE2_SHIFT, 0xf,
MADERA_RATE_ENUM_SIZE,
madera_rate_text, madera_rate_val),
};
EXPORT_SYMBOL_GPL(madera_asrc1_bidir_rate);
const struct soc_enum madera_asrc2_rate[] = {
SOC_VALUE_ENUM_SINGLE(MADERA_ASRC2_RATE1,
MADERA_ASRC2_RATE1_SHIFT, 0xf,
@@ -2149,6 +2276,9 @@ int madera_out_ev(struct snd_soc_dapm_widget *w,
switch (madera->type) {
case CS47L90:
case CS47L91:
case CS42L92:
case CS47L92:
case CS47L93:
out_up_delay = 6;
break;
default:
@@ -2264,9 +2394,17 @@ int madera_hp_ev(struct snd_soc_dapm_widget *w,
madera->hp_ena &= ~mask;
madera->hp_ena |= val;
/* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
ep_sel &= MADERA_EP_SEL_MASK;
switch (madera->type) {
case CS42L92:
case CS47L92:
case CS47L93:
break;
default:
/* if OUT1 is routed to EPOUT, ignore HP clamp and impedance */
regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
ep_sel &= MADERA_EP_SEL_MASK;
break;
}
/* Force off if HPDET has disabled the clamp for this output */
if (!ep_sel &&
@@ -2442,6 +2580,58 @@ static int madera_get_dspclk_setting(struct madera *madera,
}
}
static int madera_set_outclk(struct snd_soc_component *component,
unsigned int source, unsigned int freq)
{
int div, div_inc, rate;
switch (source) {
case MADERA_OUTCLK_SYSCLK:
dev_dbg(component->dev, "Configured OUTCLK to SYSCLK\n");
snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
MADERA_OUT_CLK_SRC_MASK, source);
return 0;
case MADERA_OUTCLK_ASYNCCLK:
dev_dbg(component->dev, "Configured OUTCLK to ASYNCCLK\n");
snd_soc_component_update_bits(component, MADERA_OUTPUT_RATE_1,
MADERA_OUT_CLK_SRC_MASK, source);
return 0;
case MADERA_OUTCLK_MCLK1:
case MADERA_OUTCLK_MCLK2:
case MADERA_OUTCLK_MCLK3:
break;
default:
return -EINVAL;
}
if (freq % 4000)
rate = 5644800;
else
rate = 6144000;
div = 1;
div_inc = 0;
while (div <= 8) {
if (freq / div == rate && !(freq % div)) {
dev_dbg(component->dev, "Configured %dHz OUTCLK\n", rate);
snd_soc_component_update_bits(component,
MADERA_OUTPUT_RATE_1,
MADERA_OUT_EXT_CLK_DIV_MASK |
MADERA_OUT_CLK_SRC_MASK,
(div_inc << MADERA_OUT_EXT_CLK_DIV_SHIFT) |
source);
return 0;
}
div_inc++;
div *= 2;
}
dev_err(component->dev,
"Unable to generate %dHz OUTCLK from %dHz MCLK\n",
rate, freq);
return -EINVAL;
}
int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
int source, unsigned int freq, int dir)
{
@@ -2478,6 +2668,8 @@ int madera_set_sysclk(struct snd_soc_component *component, int clk_id,
case MADERA_CLK_OPCLK:
case MADERA_CLK_ASYNC_OPCLK:
return madera_set_opclk(component, clk_id, freq);
case MADERA_CLK_OUTCLK:
return madera_set_outclk(component, source, freq);
default:
return -EINVAL;
}
@@ -2691,6 +2883,10 @@ static const unsigned int madera_sr_vals[] = {
#define MADERA_192K_44K1_RATE_MASK 0x003E00
#define MADERA_192K_RATE_MASK (MADERA_192K_48K_RATE_MASK | \
MADERA_192K_44K1_RATE_MASK)
#define MADERA_384K_48K_RATE_MASK 0x0F007E
#define MADERA_384K_44K1_RATE_MASK 0x007E00
#define MADERA_384K_RATE_MASK (MADERA_384K_48K_RATE_MASK | \
MADERA_384K_44K1_RATE_MASK)
static const struct snd_pcm_hw_constraint_list madera_constraint = {
.count = ARRAY_SIZE(madera_sr_vals),
@@ -2703,6 +2899,7 @@ static int madera_startup(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component;
struct madera_priv *priv = snd_soc_component_get_drvdata(component);
struct madera_dai_priv *dai_priv = &priv->dai[dai->id - 1];
struct madera *madera = priv->madera;
unsigned int base_rate;
if (!substream->runtime)
@@ -2722,12 +2919,26 @@ static int madera_startup(struct snd_pcm_substream *substream,
return 0;
}
if (base_rate == 0)
dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
else if (base_rate % 4000)
dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
else
dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
switch (madera->type) {
case CS42L92:
case CS47L92:
case CS47L93:
if (base_rate == 0)
dai_priv->constraint.mask = MADERA_384K_RATE_MASK;
else if (base_rate % 4000)
dai_priv->constraint.mask = MADERA_384K_44K1_RATE_MASK;
else
dai_priv->constraint.mask = MADERA_384K_48K_RATE_MASK;
break;
default:
if (base_rate == 0)
dai_priv->constraint.mask = MADERA_192K_RATE_MASK;
else if (base_rate % 4000)
dai_priv->constraint.mask = MADERA_192K_44K1_RATE_MASK;
else
dai_priv->constraint.mask = MADERA_192K_48K_RATE_MASK;
break;
}
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
@@ -4048,6 +4259,308 @@ int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
}
EXPORT_SYMBOL_GPL(madera_set_fll_ao_refclk);
static int madera_fllhj_disable(struct madera_fll *fll)
{
struct madera *madera = fll->madera;
bool change;
madera_fll_dbg(fll, "Disabling FLL\n");
/* Disable lockdet, but don't set ctrl_upd update but. This allows the
* lock status bit to clear as normal, but should the FLL be enabled
* again due to a control clock being required, the lock won't re-assert
* as the FLL config registers are automatically applied when the FLL
* enables.
*/
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_11_OFFS,
MADERA_FLL1_LOCKDET_MASK, 0);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
MADERA_FLL1_HOLD_MASK, MADERA_FLL1_HOLD_MASK);
regmap_update_bits_check(madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
MADERA_FLL1_ENA_MASK, 0, &change);
madera_wait_for_fll(fll, false);
/* ctrl_up gates the writes to all the fll's registers, setting it to 0
* here ensures that after a runtime suspend/resume cycle when one
* enables the fll then ctrl_up is the last bit that is configured
* by the fll enable code rather than the cache sync operation which
* would have updated it much earlier before writing out all fll
* registers
*/
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_2_OFFS,
MADERA_FLL1_CTRL_UPD_MASK, 0);
if (change)
pm_runtime_put_autosuspend(madera->dev);
return 0;
}
static int madera_fllhj_apply(struct madera_fll *fll, int fin)
{
struct madera *madera = fll->madera;
int refdiv, fref, fout, lockdet_thr, fbdiv, hp, fast_clk, fllgcd;
bool frac = false;
unsigned int fll_n, min_n, max_n, ratio, theta, lambda;
unsigned int gains, val, num;
madera_fll_dbg(fll, "fin=%d, fout=%d\n", fin, fll->fout);
for (refdiv = 0; refdiv < 4; refdiv++)
if ((fin / (1 << refdiv)) <= MADERA_FLLHJ_MAX_THRESH)
break;
fref = fin / (1 << refdiv);
/* Use simple heuristic approach to find a configuration that
* should work for most input clocks.
*/
fast_clk = 0;
fout = fll->fout;
frac = fout % fref;
if (fref < MADERA_FLLHJ_LOW_THRESH) {
lockdet_thr = 2;
gains = MADERA_FLLHJ_LOW_GAINS;
if (frac)
fbdiv = 256;
else
fbdiv = 4;
} else if (fref < MADERA_FLLHJ_MID_THRESH) {
lockdet_thr = 8;
gains = MADERA_FLLHJ_MID_GAINS;
fbdiv = 1;
} else {
lockdet_thr = 8;
gains = MADERA_FLLHJ_HIGH_GAINS;
fbdiv = 1;
/* For high speed input clocks, enable 300MHz fast oscillator
* when we're in fractional divider mode.
*/
if (frac) {
fast_clk = 0x3;
fout = fll->fout * 6;
}
}
/* Use high performance mode for fractional configurations. */
if (frac) {
hp = 0x3;
min_n = MADERA_FLLHJ_FRAC_MIN_N;
max_n = MADERA_FLLHJ_FRAC_MAX_N;
} else {
hp = 0x0;
min_n = MADERA_FLLHJ_INT_MIN_N;
max_n = MADERA_FLLHJ_INT_MAX_N;
}
ratio = fout / fref;
madera_fll_dbg(fll, "refdiv=%d, fref=%d, frac:%d\n",
refdiv, fref, frac);
while (ratio / fbdiv < min_n) {
fbdiv /= 2;
if (fbdiv < 1) {
madera_fll_err(fll, "FBDIV (%d) must be >= 1\n", fbdiv);
return -EINVAL;
}
}
while (frac && (ratio / fbdiv > max_n)) {
fbdiv *= 2;
if (fbdiv >= 1024) {
madera_fll_err(fll, "FBDIV (%u) >= 1024\n", fbdiv);
return -EINVAL;
}
}
madera_fll_dbg(fll, "lockdet=%d, hp=0x%x, fbdiv:%d\n",
lockdet_thr, hp, fbdiv);
/* Calculate N.K values */
fllgcd = gcd(fout, fbdiv * fref);
num = fout / fllgcd;
lambda = (fref * fbdiv) / fllgcd;
fll_n = num / lambda;
theta = num % lambda;
madera_fll_dbg(fll, "fll_n=%d, gcd=%d, theta=%d, lambda=%d\n",
fll_n, fllgcd, theta, lambda);
/* Some sanity checks before any registers are written. */
if (fll_n < min_n || fll_n > max_n) {
madera_fll_err(fll, "N not in valid %s mode range %d-%d: %d\n",
frac ? "fractional" : "integer", min_n, max_n,
fll_n);
return -EINVAL;
}
if (fbdiv < 1 || (frac && fbdiv >= 1024) || (!frac && fbdiv >= 256)) {
madera_fll_err(fll, "Invalid fbdiv for %s mode (%u)\n",
frac ? "fractional" : "integer", fbdiv);
return -EINVAL;
}
/* clear the ctrl_upd bit to guarantee we write to it later. */
regmap_write(madera->regmap,
fll->base + MADERA_FLL_CONTROL_2_OFFS,
fll_n << MADERA_FLL1_N_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_3_OFFS,
MADERA_FLL1_THETA_MASK,
theta << MADERA_FLL1_THETA_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_4_OFFS,
MADERA_FLL1_LAMBDA_MASK,
lambda << MADERA_FLL1_LAMBDA_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_5_OFFS,
MADERA_FLL1_FB_DIV_MASK,
fbdiv << MADERA_FLL1_FB_DIV_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_6_OFFS,
MADERA_FLL1_REFCLK_DIV_MASK,
refdiv << MADERA_FLL1_REFCLK_DIV_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_GAIN_OFFS,
0xffff,
gains);
val = hp << MADERA_FLL1_HP_SHIFT;
val |= 1 << MADERA_FLL1_PHASEDET_ENA_SHIFT;
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_10_OFFS,
MADERA_FLL1_HP_MASK | MADERA_FLL1_PHASEDET_ENA_MASK,
val);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_11_OFFS,
MADERA_FLL1_LOCKDET_THR_MASK,
lockdet_thr << MADERA_FLL1_LOCKDET_THR_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL1_DIGITAL_TEST_1_OFFS,
MADERA_FLL1_SYNC_EFS_ENA_MASK |
MADERA_FLL1_CLK_VCO_FAST_SRC_MASK,
fast_clk);
return 0;
}
static int madera_fllhj_enable(struct madera_fll *fll)
{
struct madera *madera = fll->madera;
int already_enabled = madera_is_enabled_fll(fll, fll->base);
int ret;
if (already_enabled < 0)
return already_enabled;
if (!already_enabled)
pm_runtime_get_sync(madera->dev);
madera_fll_dbg(fll, "Enabling FLL, initially %s\n",
already_enabled ? "enabled" : "disabled");
/* FLLn_HOLD must be set before configuring any registers */
regmap_update_bits(fll->madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
MADERA_FLL1_HOLD_MASK,
MADERA_FLL1_HOLD_MASK);
/* Apply refclk */
ret = madera_fllhj_apply(fll, fll->ref_freq);
if (ret) {
madera_fll_err(fll, "Failed to set FLL: %d\n", ret);
goto out;
}
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
CS47L92_FLL1_REFCLK_SRC_MASK,
fll->ref_src << CS47L92_FLL1_REFCLK_SRC_SHIFT);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
MADERA_FLL1_ENA_MASK,
MADERA_FLL1_ENA_MASK);
out:
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_11_OFFS,
MADERA_FLL1_LOCKDET_MASK,
MADERA_FLL1_LOCKDET_MASK);
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_2_OFFS,
MADERA_FLL1_CTRL_UPD_MASK,
MADERA_FLL1_CTRL_UPD_MASK);
/* Release the hold so that flln locks to external frequency */
regmap_update_bits(madera->regmap,
fll->base + MADERA_FLL_CONTROL_1_OFFS,
MADERA_FLL1_HOLD_MASK,
0);
if (!already_enabled)
madera_wait_for_fll(fll, true);
return 0;
}
static int madera_fllhj_validate(struct madera_fll *fll,
unsigned int ref_in,
unsigned int fout)
{
if (fout && !ref_in) {
madera_fll_err(fll, "fllout set without valid input clk\n");
return -EINVAL;
}
if (fll->fout && fout != fll->fout) {
madera_fll_err(fll, "Can't change output on active FLL\n");
return -EINVAL;
}
if (ref_in / MADERA_FLL_MAX_REFDIV > MADERA_FLLHJ_MAX_THRESH) {
madera_fll_err(fll, "Can't scale %dMHz to <=13MHz\n", ref_in);
return -EINVAL;
}
return 0;
}
int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
unsigned int fin, unsigned int fout)
{
int ret = 0;
/* To remain consistent with previous FLLs, we expect fout to be
* provided in the form of the required sysclk rate, which is
* 2x the calculated fll out.
*/
if (fout)
fout /= 2;
if (fll->ref_src == source && fll->ref_freq == fin &&
fll->fout == fout)
return 0;
if (fin && fout && madera_fllhj_validate(fll, fin, fout))
return -EINVAL;
fll->ref_src = source;
fll->ref_freq = fin;
fll->fout = fout;
if (fout)
ret = madera_fllhj_enable(fll);
else
madera_fllhj_disable(fll);
return ret;
}
EXPORT_SYMBOL_GPL(madera_fllhj_set_refclk);
/**
* madera_set_output_mode - Set the mode of the specified output
*

View File

@@ -47,6 +47,7 @@
#define MADERA_CLK_SYSCLK_3 6
#define MADERA_CLK_ASYNCCLK_2 7
#define MADERA_CLK_DSPCLK 8
#define MADERA_CLK_OUTCLK 9
#define MADERA_CLK_SRC_MCLK1 0x0
#define MADERA_CLK_SRC_MCLK2 0x1
@@ -61,6 +62,12 @@
#define MADERA_CLK_SRC_AIF4BCLK 0xB
#define MADERA_CLK_SRC_FLLAO 0xF
#define MADERA_OUTCLK_SYSCLK 0
#define MADERA_OUTCLK_ASYNCCLK 1
#define MADERA_OUTCLK_MCLK1 4
#define MADERA_OUTCLK_MCLK2 5
#define MADERA_OUTCLK_MCLK3 6
#define MADERA_MIXER_VOL_MASK 0x00FE
#define MADERA_MIXER_VOL_SHIFT 1
#define MADERA_MIXER_VOL_WIDTH 7
@@ -326,6 +333,7 @@ extern const struct soc_enum madera_sample_rate[];
extern const struct soc_enum madera_isrc_fsl[];
extern const struct soc_enum madera_isrc_fsh[];
extern const struct soc_enum madera_asrc1_rate[];
extern const struct soc_enum madera_asrc1_bidir_rate[];
extern const struct soc_enum madera_asrc2_rate[];
extern const struct soc_enum madera_dfc_width[];
extern const struct soc_enum madera_dfc_type[];
@@ -403,6 +411,8 @@ int madera_set_fll_syncclk(struct madera_fll *fll, int source,
unsigned int fref, unsigned int fout);
int madera_set_fll_ao_refclk(struct madera_fll *fll, int source,
unsigned int fin, unsigned int fout);
int madera_fllhj_set_refclk(struct madera_fll *fll, int source,
unsigned int fin, unsigned int fout);
int madera_core_init(struct madera_priv *priv);
int madera_core_free(struct madera_priv *priv);

View File

@@ -154,10 +154,6 @@ static const DECLARE_TLV_DB_RANGE(max98371_gain_tlv,
8, 10, TLV_DB_SCALE_ITEM(400, 100, 0)
);
static const DECLARE_TLV_DB_RANGE(max98371_noload_gain_tlv,
0, 11, TLV_DB_SCALE_ITEM(950, 100, 0),
);
static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1);
static const struct snd_kcontrol_new max98371_snd_controls[] = {

View File

@@ -12,6 +12,7 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <sound/tlv.h>
#include "max98373.h"
@@ -901,6 +902,17 @@ static void max98373_slot_config(struct i2c_client *i2c,
else
max98373->i_slot = 1;
max98373->reset_gpio = of_get_named_gpio(dev->of_node,
"maxim,reset-gpio", 0);
if (!gpio_is_valid(max98373->reset_gpio)) {
dev_err(dev, "Looking up %s property in node %s failed %d\n",
"maxim,reset-gpio", dev->of_node->full_name,
max98373->reset_gpio);
} else {
dev_dbg(dev, "maxim,reset-gpio=%d",
max98373->reset_gpio);
}
if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value))
max98373->spkfb_slot = value & 0xF;
else
@@ -929,7 +941,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
else
max98373->interleave_mode = false;
/* regmap initialization */
max98373->regmap
= devm_regmap_init_i2c(i2c, &max98373_regmap);
@@ -940,6 +951,24 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
return ret;
}
/* voltage/current slot & gpio configuration */
max98373_slot_config(i2c, max98373);
/* Power on device */
if (gpio_is_valid(max98373->reset_gpio)) {
ret = gpio_request(max98373->reset_gpio, "MAX98373_RESET");
if (ret) {
dev_err(&i2c->dev, "%s: Failed to request gpio %d\n",
__func__, max98373->reset_gpio);
gpio_free(max98373->reset_gpio);
return -EINVAL;
}
gpio_direction_output(max98373->reset_gpio, 0);
msleep(50);
gpio_direction_output(max98373->reset_gpio, 1);
msleep(20);
}
/* Check Revision ID */
ret = regmap_read(max98373->regmap,
MAX98373_R21FF_REV_ID, &reg);
@@ -950,9 +979,6 @@ static int max98373_i2c_probe(struct i2c_client *i2c,
}
dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg);
/* voltage/current slot configuration */
max98373_slot_config(i2c, max98373);
/* codec registeration */
ret = devm_snd_soc_register_component(&i2c->dev, &soc_codec_dev_max98373,
max98373_dai, ARRAY_SIZE(max98373_dai));

View File

@@ -205,6 +205,7 @@
struct max98373_priv {
struct regmap *regmap;
int reset_gpio;
unsigned int v_slot;
unsigned int i_slot;
unsigned int spkfb_slot;

View File

@@ -27,19 +27,6 @@ struct max9850_priv {
unsigned int sysclk;
};
/* max9850 register cache */
static const struct reg_default max9850_reg[] = {
{ 2, 0x0c },
{ 3, 0x00 },
{ 4, 0x00 },
{ 5, 0x00 },
{ 6, 0x00 },
{ 7, 0x00 },
{ 8, 0x00 },
{ 9, 0x00 },
{ 10, 0x00 },
};
/* these registers are not used at the moment but provided for the sake of
* completeness */
static bool max9850_volatile_register(struct device *dev, unsigned int reg)

View File

@@ -20,15 +20,6 @@ static const char * const max98926_boost_voltage_txt[] = {
"6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V", "6.5V"
};
static const char * const max98926_boost_current_txt[] = {
"0.6", "0.8", "1.0", "1.2", "1.4", "1.6", "1.8", "2.0",
"2.2", "2.4", "2.6", "2.8", "3.2", "3.6", "4.0", "4.4"
};
static const char *const max98926_dai_txt[] = {
"Left", "Right", "LeftRight", "LeftRightDiv2",
};
static const char *const max98926_pdm_ch_text[] = {
"Current", "Voltage",
};

View File

@@ -56,7 +56,6 @@ static const DECLARE_TLV_DB_SCALE(alclvl, -2250, 150, 0);
static const DECLARE_TLV_DB_SCALE(mingain, -1200, 600, 0);
static const DECLARE_TLV_DB_SCALE(maxgain, -675, 600, 0);
static const DECLARE_TLV_DB_SCALE(boost_vol, -1200, 75, 0);
static const DECLARE_TLV_DB_SCALE(ngth, -7650, 150, 0);
static const char * const ml26124_companding[] = {"16bit PCM", "u-law",
"A-law"};

View File

@@ -1185,10 +1185,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "mbhc_switch_int");
if (irq < 0) {
dev_err(dev, "failed to get mbhc switch irq\n");
if (irq < 0)
return irq;
}
ret = devm_request_threaded_irq(dev, irq, NULL,
pm8916_mbhc_switch_irq_handler,
@@ -1200,10 +1198,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
if (priv->mbhc_btn_enabled) {
irq = platform_get_irq_byname(pdev, "mbhc_but_press_det");
if (irq < 0) {
dev_err(dev, "failed to get button press irq\n");
if (irq < 0)
return irq;
}
ret = devm_request_threaded_irq(dev, irq, NULL,
mbhc_btn_press_irq_handler,
@@ -1214,10 +1210,8 @@ static int pm8916_wcd_analog_spmi_probe(struct platform_device *pdev)
dev_err(dev, "cannot request mbhc button press irq\n");
irq = platform_get_irq_byname(pdev, "mbhc_but_rel_det");
if (irq < 0) {
dev_err(dev, "failed to get button release irq\n");
if (irq < 0)
return irq;
}
ret = devm_request_threaded_irq(dev, irq, NULL,
mbhc_btn_release_irq_handler,

View File

@@ -1143,7 +1143,6 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
struct msm8916_wcd_digital_priv *priv;
struct device *dev = &pdev->dev;
void __iomem *base;
struct resource *mem_res;
struct regmap *digital_map;
int ret;
@@ -1151,8 +1150,7 @@ static int msm8916_wcd_digital_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, mem_res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@@ -1066,11 +1066,6 @@ static int mt_mic_bias_2_event(struct snd_soc_dapm_widget *w,
return 0;
}
/* DAPM Kcontrols */
static const struct snd_kcontrol_new mt_lineout_control =
SOC_DAPM_SINGLE("Switch", MT6351_AUDDEC_ANA_CON3,
RG_AUDLOLPWRUP_VAUDP32_BIT, 1, 0);
/* DAPM Widgets */
static const struct snd_soc_dapm_widget mt6351_dapm_widgets[] = {
/* Digital Clock */

View File

@@ -1730,6 +1730,10 @@ static int mt6358_dmic_enable(struct mt6358_priv *priv)
/* UL turn on */
regmap_write(priv->regmap, MT6358_AFE_UL_SRC_CON0_L, 0x0003);
/* Prevent pop noise form dmic hw */
msleep(100);
return 0;
}
@@ -2255,10 +2259,8 @@ static struct snd_soc_dai_driver mt6358_dai_driver[] = {
},
};
static int mt6358_codec_init_reg(struct mt6358_priv *priv)
static void mt6358_codec_init_reg(struct mt6358_priv *priv)
{
int ret = 0;
/* Disable HeadphoneL/HeadphoneR short circuit protection */
regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON0,
RG_AUDHPLSCDISABLE_VAUDP15_MASK_SFT,
@@ -2285,8 +2287,6 @@ static int mt6358_codec_init_reg(struct mt6358_priv *priv)
/* set gpio */
playback_gpio_reset(priv);
capture_gpio_reset(priv);
return ret;
}
static int mt6358_codec_probe(struct snd_soc_component *cmpnt)

View File

@@ -44,18 +44,25 @@ static const char *const pcm3168a_supply_names[PCM3168A_NUM_SUPPLIES] = {
"VCCDA2"
};
#define PCM3168A_DAI_DAC 0
#define PCM3168A_DAI_ADC 1
/* ADC/DAC side parameters */
struct pcm3168a_io_params {
bool master_mode;
unsigned int fmt;
int tdm_slots;
u32 tdm_mask;
int slot_width;
};
struct pcm3168a_priv {
struct regulator_bulk_data supplies[PCM3168A_NUM_SUPPLIES];
struct regmap *regmap;
struct clk *scki;
bool adc_master_mode;
bool dac_master_mode;
unsigned long sysclk;
unsigned int adc_fmt;
unsigned int dac_fmt;
int tdm_slots;
u32 tdm_mask[2];
int slot_width;
struct pcm3168a_io_params io_params[2];
};
static const char *const pcm3168a_roll_off[] = { "Sharp", "Slow" };
@@ -263,7 +270,7 @@ static unsigned int pcm3168a_scki_ratios[] = {
#define PCM3168A_NUM_SCKI_RATIOS_DAC ARRAY_SIZE(pcm3168a_scki_ratios)
#define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
#define PCM1368A_MAX_SYSCLK 36864000
#define PCM3168A_MAX_SYSCLK 36864000
static int pcm3168a_reset(struct pcm3168a_priv *pcm3168a)
{
@@ -296,7 +303,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component);
int ret;
if (freq > PCM1368A_MAX_SYSCLK)
if (freq > PCM3168A_MAX_SYSCLK)
return -EINVAL;
ret = clk_set_rate(pcm3168a->scki, freq);
@@ -308,8 +315,7 @@ static int pcm3168a_set_dai_sysclk(struct snd_soc_dai *dai,
return 0;
}
static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
unsigned int format, bool dac)
static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai, unsigned int format)
{
struct snd_soc_component *component = dai->component;
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
@@ -356,43 +362,31 @@ static int pcm3168a_set_dai_fmt(struct snd_soc_dai *dai,
return -EINVAL;
}
if (dac) {
if (dai->id == PCM3168A_DAI_DAC) {
reg = PCM3168A_DAC_PWR_MST_FMT;
mask = PCM3168A_DAC_FMT_MASK;
shift = PCM3168A_DAC_FMT_SHIFT;
pcm3168a->dac_master_mode = master_mode;
pcm3168a->dac_fmt = fmt;
} else {
reg = PCM3168A_ADC_MST_FMT;
mask = PCM3168A_ADC_FMTAD_MASK;
shift = PCM3168A_ADC_FMTAD_SHIFT;
pcm3168a->adc_master_mode = master_mode;
pcm3168a->adc_fmt = fmt;
}
pcm3168a->io_params[dai->id].master_mode = master_mode;
pcm3168a->io_params[dai->id].fmt = fmt;
regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift);
return 0;
}
static int pcm3168a_set_dai_fmt_dac(struct snd_soc_dai *dai,
unsigned int format)
{
return pcm3168a_set_dai_fmt(dai, format, true);
}
static int pcm3168a_set_dai_fmt_adc(struct snd_soc_dai *dai,
unsigned int format)
{
return pcm3168a_set_dai_fmt(dai, format, false);
}
static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
unsigned int rx_mask, int slots,
int slot_width)
{
struct snd_soc_component *component = dai->component;
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
if (tx_mask >= (1<<slots) || rx_mask >= (1<<slots)) {
dev_err(component->dev,
@@ -408,22 +402,13 @@ static int pcm3168a_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
return -EINVAL;
}
if (pcm3168a->tdm_slots && pcm3168a->tdm_slots != slots) {
dev_err(component->dev, "Not matching slots %d vs %d\n",
pcm3168a->tdm_slots, slots);
return -EINVAL;
}
if (pcm3168a->slot_width && pcm3168a->slot_width != slot_width) {
dev_err(component->dev, "Not matching slot_width %d vs %d\n",
pcm3168a->slot_width, slot_width);
return -EINVAL;
}
pcm3168a->tdm_slots = slots;
pcm3168a->slot_width = slot_width;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_PLAYBACK] = tx_mask;
pcm3168a->tdm_mask[SNDRV_PCM_STREAM_CAPTURE] = rx_mask;
io_params->tdm_slots = slots;
io_params->slot_width = slot_width;
/* Ignore the not relevant mask for the DAI/direction */
if (dai->id == PCM3168A_DAI_DAC)
io_params->tdm_mask = tx_mask;
else
io_params->tdm_mask = rx_mask;
return 0;
}
@@ -434,7 +419,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
bool tx, master_mode;
struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id];
bool master_mode;
u32 val, mask, shift, reg;
unsigned int rate, fmt, ratio, max_ratio;
unsigned int tdm_slots;
@@ -444,23 +430,21 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
ratio = pcm3168a->sysclk / rate;
tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
if (tx) {
if (dai->id == PCM3168A_DAI_DAC) {
max_ratio = PCM3168A_NUM_SCKI_RATIOS_DAC;
reg = PCM3168A_DAC_PWR_MST_FMT;
mask = PCM3168A_DAC_MSDA_MASK;
shift = PCM3168A_DAC_MSDA_SHIFT;
master_mode = pcm3168a->dac_master_mode;
fmt = pcm3168a->dac_fmt;
} else {
max_ratio = PCM3168A_NUM_SCKI_RATIOS_ADC;
reg = PCM3168A_ADC_MST_FMT;
mask = PCM3168A_ADC_MSAD_MASK;
shift = PCM3168A_ADC_MSAD_SHIFT;
master_mode = pcm3168a->adc_master_mode;
fmt = pcm3168a->adc_fmt;
}
master_mode = io_params->master_mode;
fmt = io_params->fmt;
for (i = 0; i < max_ratio; i++) {
if (pcm3168a_scki_ratios[i] == ratio)
break;
@@ -471,8 +455,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
if (pcm3168a->slot_width)
slot_width = pcm3168a->slot_width;
if (io_params->slot_width)
slot_width = io_params->slot_width;
else
slot_width = params_width(params);
@@ -497,8 +481,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
if (pcm3168a->tdm_slots)
tdm_slots = pcm3168a->tdm_slots;
if (io_params->tdm_slots)
tdm_slots = io_params->tdm_slots;
else
tdm_slots = params_channels(params);
@@ -534,7 +518,7 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(pcm3168a->regmap, reg, mask, val);
if (tx) {
if (dai->id == PCM3168A_DAI_DAC) {
mask = PCM3168A_DAC_FMT_MASK;
shift = PCM3168A_DAC_FMT_SHIFT;
} else {
@@ -552,20 +536,13 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
{
struct snd_soc_component *component = dai->component;
struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(component);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
unsigned int fmt;
unsigned int sample_min;
unsigned int channel_max;
unsigned int channel_maxs[] = {
6, /* rx */
8 /* tx */
8, /* DAC */
6 /* ADC */
};
if (tx)
fmt = pcm3168a->dac_fmt;
else
fmt = pcm3168a->adc_fmt;
/*
* Available Data Bits
*
@@ -578,7 +555,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
* I2S
* LEFT_J
*/
switch (fmt) {
switch (pcm3168a->io_params[dai->id].fmt) {
case PCM3168A_FMT_RIGHT_J:
sample_min = 16;
channel_max = 2;
@@ -588,7 +565,7 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
case PCM3168A_FMT_DSP_A:
case PCM3168A_FMT_DSP_B:
sample_min = 24;
channel_max = channel_maxs[tx];
channel_max = channel_maxs[dai->id];
break;
default:
sample_min = 24;
@@ -599,32 +576,29 @@ static int pcm3168a_startup(struct snd_pcm_substream *substream,
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
sample_min, 32);
/* Allow all channels in multi DIN/DOUT mode */
if (pcm3168a->io_params[dai->id].tdm_slots == 2)
channel_max = channel_maxs[dai->id];
snd_pcm_hw_constraint_minmax(substream->runtime,
SNDRV_PCM_HW_PARAM_CHANNELS,
2, channel_max);
return 0;
}
static const struct snd_soc_dai_ops pcm3168a_dac_dai_ops = {
static const struct snd_soc_dai_ops pcm3168a_dai_ops = {
.startup = pcm3168a_startup,
.set_fmt = pcm3168a_set_dai_fmt_dac,
.set_fmt = pcm3168a_set_dai_fmt,
.set_sysclk = pcm3168a_set_dai_sysclk,
.hw_params = pcm3168a_hw_params,
.digital_mute = pcm3168a_digital_mute,
.set_tdm_slot = pcm3168a_set_tdm_slot,
};
static const struct snd_soc_dai_ops pcm3168a_adc_dai_ops = {
.startup = pcm3168a_startup,
.set_fmt = pcm3168a_set_dai_fmt_adc,
.set_sysclk = pcm3168a_set_dai_sysclk,
.hw_params = pcm3168a_hw_params,
.set_tdm_slot = pcm3168a_set_tdm_slot,
};
static struct snd_soc_dai_driver pcm3168a_dais[] = {
{
.name = "pcm3168a-dac",
.id = PCM3168A_DAI_DAC,
.playback = {
.stream_name = "Playback",
.channels_min = 1,
@@ -632,10 +606,11 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = {
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = PCM3168A_FORMATS
},
.ops = &pcm3168a_dac_dai_ops
.ops = &pcm3168a_dai_ops
},
{
.name = "pcm3168a-adc",
.id = PCM3168A_DAI_ADC,
.capture = {
.stream_name = "Capture",
.channels_min = 1,
@@ -643,7 +618,7 @@ static struct snd_soc_dai_driver pcm3168a_dais[] = {
.rates = SNDRV_PCM_RATE_8000_96000,
.formats = PCM3168A_FORMATS
},
.ops = &pcm3168a_adc_dai_ops
.ops = &pcm3168a_dai_ops
},
};

View File

@@ -432,7 +432,6 @@ static int rk3328_platform_probe(struct platform_device *pdev)
{
struct device_node *rk3328_np = pdev->dev.of_node;
struct rk3328_codec_priv *rk3328;
struct resource *res;
struct regmap *grf;
void __iomem *base;
int ret = 0;
@@ -482,8 +481,7 @@ static int rk3328_platform_probe(struct platform_device *pdev)
return ret;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@@ -978,9 +978,6 @@ static bool rt1011_readable_register(struct device *dev, unsigned int reg)
}
}
static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9435, 37, 0);
static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1739, 37, 0);
static const char * const rt1011_din_source_select[] = {
"Left",
"Right",
@@ -1029,6 +1026,8 @@ static const char * const rt1011_tdm_adc_swap_select[] = {
static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc1_1_enum, RT1011_TDM1_SET_3, 6,
rt1011_tdm_adc_swap_select);
static SOC_ENUM_SINGLE_DECL(rt1011_tdm_adc2_1_enum, RT1011_TDM1_SET_3, 4,
rt1011_tdm_adc_swap_select);
static void rt1011_reset(struct regmap *regmap)
{
@@ -1223,7 +1222,10 @@ static int rt1011_bq_drc_info(struct snd_kcontrol *kcontrol,
static int rt1011_r0_cali_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = 0;
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component);
ucontrol->value.integer.value[0] = rt1011->cali_done;
return 0;
}
@@ -1237,6 +1239,7 @@ static int rt1011_r0_cali_put(struct snd_kcontrol *kcontrol,
if (!component->card->instantiated)
return 0;
rt1011->cali_done = 0;
if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF &&
ucontrol->value.integer.value[0])
rt1011_calibrate(rt1011, 1);
@@ -1333,7 +1336,8 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
/* TDM1 Data Out Selection */
SOC_ENUM("TDM1 DOUT Source", rt1011_tdm1_adc1_dat_enum),
SOC_ENUM("TDM1 DOUT Location", rt1011_tdm1_adc1_loc_enum),
SOC_ENUM("TDM1 ADCDAT Swap Select", rt1011_tdm_adc1_1_enum),
SOC_ENUM("TDM1 ADC1DAT Swap Select", rt1011_tdm_adc1_1_enum),
SOC_ENUM("TDM1 ADC2DAT Swap Select", rt1011_tdm_adc2_1_enum),
/* Data Out Mode */
SOC_ENUM("I2S ADC DOUT Mode", rt1011_adc_dout_mode_enum),
@@ -1355,6 +1359,10 @@ static const struct snd_kcontrol_new rt1011_snd_controls[] = {
SOC_SINGLE_EXT("R0 Calibration", SND_SOC_NOPM, 0, 1, 0,
rt1011_r0_cali_get, rt1011_r0_cali_put),
RT1011_R0_LOAD("R0 Load Mode"),
/* R0 temperature */
SOC_SINGLE("R0 Temperature", RT1011_STP_INITIAL_RESISTANCE_TEMP,
2, 255, 0),
};
static int rt1011_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source,
@@ -1511,7 +1519,8 @@ static const struct snd_soc_dapm_route rt1011_dapm_routes[] = {
static int rt1011_get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
int i;
static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;
@@ -2139,6 +2148,7 @@ static int rt1011_calibrate(struct rt1011_priv *rt1011, unsigned char cali_flag)
r0_factor = ((format / r0[0] * 100) / 128)
- (r0_integer * 100);
rt1011->r0_reg = r0[0];
rt1011->cali_done = 1;
dev_info(dev, "r0 resistance about %d.%02d ohm, reg=0x%X\n",
r0_integer, r0_factor, r0[0]);
}
@@ -2189,6 +2199,13 @@ static void rt1011_calibration_work(struct work_struct *work)
rt1011_calibrate(rt1011, 1);
/*
* This flag should reset after booting.
* The factory test will do calibration again and use this flag to check
* whether the calibration completed
*/
rt1011->cali_done = 0;
/* initial */
rt1011_reg_init(component);
}

View File

@@ -227,6 +227,7 @@
#define RT1011_STP_CALIB_RS_TEMP 0x152a
#define RT1011_INIT_RECIPROCAL_REG_24_16 0x1538
#define RT1011_INIT_RECIPROCAL_REG_15_0 0x1539
#define RT1011_STP_INITIAL_RESISTANCE_TEMP 0x153c
#define RT1011_STP_ALPHA_RECIPROCAL_MSB 0x153e
#define RT1011_SPK_RESISTANCE_1 0x1544
#define RT1011_SPK_RESISTANCE_2 0x1546
@@ -665,7 +666,7 @@ struct rt1011_priv {
int pll_out;
int bq_drc_set;
unsigned int r0_reg;
unsigned int r0_reg, cali_done;
int recv_spk_mode;
};

View File

@@ -608,7 +608,8 @@ static const struct snd_soc_dapm_route rt1305_dapm_routes[] = {
static int rt1305_get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
int i;
static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;

View File

@@ -1,13 +1,10 @@
/*
* rt1308.c -- RT1308 ALSA SoC amplifier component driver
*
* Copyright 2019 Realtek Semiconductor Corp.
* Author: Derek Fang <derek.fang@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
// SPDX-License-Identifier: GPL-2.0
//
// rt1308.c -- RT1308 ALSA SoC amplifier component driver
//
// Copyright 2019 Realtek Semiconductor Corp.
// Author: Derek Fang <derek.fang@realtek.com>
//
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -40,10 +37,10 @@ static const struct reg_sequence init_list[] = {
{ RT1308_VREF, 0x18100000 },
{ RT1308_IV_SENSE, 0x87010000 },
{ RT1308_DUMMY_REG, 0x00000200 },
{ RT1308_SIL_DET, 0x61c30000 },
{ RT1308_SIL_DET, 0xe1c30000 },
{ RT1308_DC_CAL_2, 0x00ffff00 },
{ RT1308_CLK_DET, 0x01000000 },
{ RT1308_POWER_STATUS, 0x00800000 },
{ RT1308_POWER_STATUS, 0x08800000 },
{ RT1308_DAC_SET, 0xafaf0700 },
};
@@ -308,12 +305,13 @@ static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
msleep(30);
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
RT1308_POW_PDB_REG_BIT, RT1308_POW_PDB_REG_BIT);
RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT,
RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT);
msleep(40);
break;
case SND_SOC_DAPM_PRE_PMD:
snd_soc_component_update_bits(component, RT1308_POWER_STATUS,
RT1308_POW_PDB_REG_BIT, 0);
RT1308_POW_PDB_REG_BIT | RT1308_POW_PDB_MN_BIT, 0);
usleep_range(150000, 200000);
break;
@@ -438,7 +436,8 @@ static const struct snd_soc_dapm_route rt1308_dapm_routes[] = {
static int rt1308_get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
int i;
static const int pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;
@@ -808,33 +807,11 @@ static void rt1308_efuse(struct rt1308_priv *rt1308)
{
regmap_write(rt1308->regmap, RT1308_RESET, 0);
regmap_write(rt1308->regmap, RT1308_POWER, 0xff371600);
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52100000);
regmap_write(rt1308->regmap, RT1308_I2C_I2S_SDW_SET, 0x01014005);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
regmap_write(rt1308->regmap, RT1308_PADS_1, 0x50150505);
regmap_write(rt1308->regmap, RT1308_VREF, 0x18100000);
regmap_write(rt1308->regmap, RT1308_IV_SENSE, 0x87010000);
regmap_write(rt1308->regmap, RT1308_DUMMY_REG, 0x00000200);
regmap_write(rt1308->regmap, RT1308_SIL_DET, 0x61c30000);
regmap_write(rt1308->regmap, RT1308_CLK_DET, 0x03700000);
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x50022f00);
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x01800000);
regmap_write(rt1308->regmap, RT1308_DC_CAL_2, 0x00ffff00);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x607e5501);
regmap_write(rt1308->regmap, RT1308_CLK_2, 0x0060e000);
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x04fe0f00);
msleep(100);
regmap_write(rt1308->regmap, RT1308_EFUSE_1, 0x44fe0f00);
msleep(20);
regmap_write(rt1308->regmap, RT1308_PVDD_OFFSET_CTL, 0x10000000);
regmap_write(rt1308->regmap, RT1308_POWER_STATUS, 0x00800000);
regmap_write(rt1308->regmap, RT1308_POWER, 0x0);
regmap_write(rt1308->regmap, RT1308_CLK_1, 0x52000000);
regmap_write(rt1308->regmap, RT1308_CLASS_D_SET_2, 0x227f5501);
regmap_write(rt1308->regmap, RT1308_SINE_TONE_GEN_1, 0x10022f00);
}
static int rt1308_i2c_probe(struct i2c_client *i2c,

View File

@@ -1,12 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* RT1308.h -- RT1308 ALSA SoC amplifier component driver
* rt1308.h -- RT1308 ALSA SoC amplifier component driver
*
* Copyright 2019 Realtek Semiconductor Corp.
* Author: Derek Fang <derek.fang@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _RT1308_H_

View File

@@ -2566,7 +2566,7 @@ static int set_dmic_power(struct snd_soc_dapm_widget *w,
return 0;
}
static int rt5655_set_verf(struct snd_soc_dapm_widget *w,
static int rt5665_set_verf(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
@@ -2686,11 +2686,11 @@ static const struct snd_soc_dapm_widget rt5665_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5665_PWR_VOL,
RT5665_PWR_MIC_DET_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("Vref1", RT5665_PWR_ANLG_1, RT5665_PWR_VREF1_BIT, 0,
rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("Vref2", RT5665_PWR_ANLG_1, RT5665_PWR_VREF2_BIT, 0,
rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
SND_SOC_DAPM_SUPPLY("Vref3", RT5665_PWR_ANLG_1, RT5665_PWR_VREF3_BIT, 0,
rt5655_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
rt5665_set_verf, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),
/* ASRC */
SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5665_ASRC_1,

View File

@@ -691,10 +691,12 @@ static void rt5677_set_dsp_mode(struct snd_soc_component *component, bool on)
struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
if (on) {
regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x2);
regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1,
RT5677_PWR_DSP, RT5677_PWR_DSP);
rt5677->is_dsp_mode = true;
} else {
regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1, 0x2, 0x0);
regmap_update_bits(rt5677->regmap, RT5677_PWR_DSP1,
RT5677_PWR_DSP, 0x0);
rt5677->is_dsp_mode = false;
}
}
@@ -4466,7 +4468,8 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK,
0x0055);
5 << RT5677_LDO1_SEL_SFT |
5 << RT5677_LDO2_SEL_SFT);
regmap_update_bits(rt5677->regmap,
RT5677_PR_BASE + RT5677_BIAS_CUR4,
0x0f00, 0x0f00);
@@ -4490,9 +4493,11 @@ static int rt5677_set_bias_level(struct snd_soc_component *component,
case SND_SOC_BIAS_OFF:
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0);
regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000);
regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000);
regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022);
regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000);
regmap_write(rt5677->regmap, RT5677_PWR_ANLG1,
2 << RT5677_LDO1_SEL_SFT |
2 << RT5677_LDO2_SEL_SFT);
regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2,
RT5677_PWR_CORE, 0);
regmap_update_bits(rt5677->regmap,
RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
@@ -4719,7 +4724,8 @@ static int rt5677_probe(struct snd_soc_component *component)
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC,
~RT5677_IRQ_DEBOUNCE_SEL_MASK, 0x0020);
regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x0c00);
regmap_write(rt5677->regmap, RT5677_PWR_DSP2,
RT5677_PWR_SLIM_ISO | RT5677_PWR_CORE_ISO);
for (i = 0; i < RT5677_GPIO_NUM; i++)
rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);

View File

@@ -31,6 +31,13 @@
#define SGTL5000_DAP_REG_OFFSET 0x0100
#define SGTL5000_MAX_REG_OFFSET 0x013A
/* Delay for the VAG ramp up */
#define SGTL5000_VAG_POWERUP_DELAY 500 /* ms */
/* Delay for the VAG ramp down */
#define SGTL5000_VAG_POWERDOWN_DELAY 500 /* ms */
#define SGTL5000_OUTPUTS_MUTE (SGTL5000_HP_MUTE | SGTL5000_LINE_OUT_MUTE)
/* default value of sgtl5000 registers */
static const struct reg_default sgtl5000_reg_defaults[] = {
{ SGTL5000_CHIP_DIG_POWER, 0x0000 },
@@ -123,6 +130,13 @@ enum {
I2S_SCLK_STRENGTH_HIGH,
};
enum {
HP_POWER_EVENT,
DAC_POWER_EVENT,
ADC_POWER_EVENT,
LAST_POWER_EVENT = ADC_POWER_EVENT
};
/* sgtl5000 private structure in codec */
struct sgtl5000_priv {
int sysclk; /* sysclk rate */
@@ -137,8 +151,109 @@ struct sgtl5000_priv {
u8 micbias_voltage;
u8 lrclk_strength;
u8 sclk_strength;
u16 mute_state[LAST_POWER_EVENT + 1];
};
static inline int hp_sel_input(struct snd_soc_component *component)
{
return (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_CTRL) &
SGTL5000_HP_SEL_MASK) >> SGTL5000_HP_SEL_SHIFT;
}
static inline u16 mute_output(struct snd_soc_component *component,
u16 mute_mask)
{
u16 mute_reg = snd_soc_component_read32(component,
SGTL5000_CHIP_ANA_CTRL);
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
mute_mask, mute_mask);
return mute_reg;
}
static inline void restore_output(struct snd_soc_component *component,
u16 mute_mask, u16 mute_reg)
{
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
mute_mask, mute_reg);
}
static void vag_power_on(struct snd_soc_component *component, u32 source)
{
if (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) &
SGTL5000_VAG_POWERUP)
return;
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
/* When VAG powering on to get local loop from Line-In, the sleep
* is required to avoid loud pop.
*/
if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN &&
source == HP_POWER_EVENT)
msleep(SGTL5000_VAG_POWERUP_DELAY);
}
static int vag_power_consumers(struct snd_soc_component *component,
u16 ana_pwr_reg, u32 source)
{
int consumers = 0;
/* count dac/adc consumers unconditional */
if (ana_pwr_reg & SGTL5000_DAC_POWERUP)
consumers++;
if (ana_pwr_reg & SGTL5000_ADC_POWERUP)
consumers++;
/*
* If the event comes from HP and Line-In is selected,
* current action is 'DAC to be powered down'.
* As HP_POWERUP is not set when HP muxed to line-in,
* we need to keep VAG power ON.
*/
if (source == HP_POWER_EVENT) {
if (hp_sel_input(component) == SGTL5000_HP_SEL_LINE_IN)
consumers++;
} else {
if (ana_pwr_reg & SGTL5000_HP_POWERUP)
consumers++;
}
return consumers;
}
static void vag_power_off(struct snd_soc_component *component, u32 source)
{
u16 ana_pwr = snd_soc_component_read32(component,
SGTL5000_CHIP_ANA_POWER);
if (!(ana_pwr & SGTL5000_VAG_POWERUP))
return;
/*
* This function calls when any of VAG power consumers is disappearing.
* Thus, if there is more than one consumer at the moment, as minimum
* one consumer will definitely stay after the end of the current
* event.
* Don't clear VAG_POWERUP if 2 or more consumers of VAG present:
* - LINE_IN (for HP events) / HP (for DAC/ADC events)
* - DAC
* - ADC
* (the current consumer is disappearing right now)
*/
if (vag_power_consumers(component, ana_pwr, source) >= 2)
return;
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, 0);
/* In power down case, we need wait 400-1000 ms
* when VAG fully ramped down.
* As longer we wait, as smaller pop we've got.
*/
msleep(SGTL5000_VAG_POWERDOWN_DELAY);
}
/*
* mic_bias power on/off share the same register bits with
* output impedance of mic bias, when power on mic bias, we
@@ -170,36 +285,46 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w,
return 0;
}
/*
* As manual described, ADC/DAC only works when VAG powerup,
* So enabled VAG before ADC/DAC up.
* In power down case, we need wait 400ms when vag fully ramped down.
*/
static int power_vag_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
static int vag_and_mute_control(struct snd_soc_component *component,
int event, int event_source)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
const u32 mask = SGTL5000_DAC_POWERUP | SGTL5000_ADC_POWERUP;
static const u16 mute_mask[] = {
/*
* Mask for HP_POWER_EVENT.
* Muxing Headphones have to be wrapped with mute/unmute
* headphones only.
*/
SGTL5000_HP_MUTE,
/*
* Masks for DAC_POWER_EVENT/ADC_POWER_EVENT.
* Muxing DAC or ADC block have to wrapped with mute/unmute
* both headphones and line-out.
*/
SGTL5000_OUTPUTS_MUTE,
SGTL5000_OUTPUTS_MUTE
};
struct sgtl5000_priv *sgtl5000 =
snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, SGTL5000_VAG_POWERUP);
msleep(400);
case SND_SOC_DAPM_PRE_PMU:
sgtl5000->mute_state[event_source] =
mute_output(component, mute_mask[event_source]);
break;
case SND_SOC_DAPM_POST_PMU:
vag_power_on(component, event_source);
restore_output(component, mute_mask[event_source],
sgtl5000->mute_state[event_source]);
break;
case SND_SOC_DAPM_PRE_PMD:
/*
* Don't clear VAG_POWERUP, when both DAC and ADC are
* operational to prevent inadvertently starving the
* other one of them.
*/
if ((snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) &
mask) != mask) {
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_POWER,
SGTL5000_VAG_POWERUP, 0);
msleep(400);
}
sgtl5000->mute_state[event_source] =
mute_output(component, mute_mask[event_source]);
vag_power_off(component, event_source);
break;
case SND_SOC_DAPM_POST_PMD:
restore_output(component, mute_mask[event_source],
sgtl5000->mute_state[event_source]);
break;
default:
break;
@@ -208,6 +333,41 @@ static int power_vag_event(struct snd_soc_dapm_widget *w,
return 0;
}
/*
* Mute Headphone when power it up/down.
* Control VAG power on HP power path.
*/
static int headphone_pga_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);
return vag_and_mute_control(component, event, HP_POWER_EVENT);
}
/* As manual describes, ADC/DAC powering up/down requires
* to mute outputs to avoid pops.
* Control VAG power on ADC/DAC power path.
*/
static int adc_updown_depop(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
return vag_and_mute_control(component, event, ADC_POWER_EVENT);
}
static int dac_updown_depop(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
return vag_and_mute_control(component, event, DAC_POWER_EVENT);
}
/* input sources for ADC */
static const char *adc_mux_text[] = {
"MIC_IN", "LINE_IN"
@@ -280,7 +440,10 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
mic_bias_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_PGA("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0),
SND_SOC_DAPM_PGA_E("HP", SGTL5000_CHIP_ANA_POWER, 4, 0, NULL, 0,
headphone_pga_event,
SND_SOC_DAPM_PRE_POST_PMU |
SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_PGA("LO", SGTL5000_CHIP_ANA_POWER, 0, 0, NULL, 0),
SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0, &adc_mux),
@@ -301,11 +464,12 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = {
0, SGTL5000_CHIP_DIG_POWER,
1, 0),
SND_SOC_DAPM_ADC("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0),
SND_SOC_DAPM_DAC("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0),
SND_SOC_DAPM_PRE("VAG_POWER_PRE", power_vag_event),
SND_SOC_DAPM_POST("VAG_POWER_POST", power_vag_event),
SND_SOC_DAPM_ADC_E("ADC", "Capture", SGTL5000_CHIP_ANA_POWER, 1, 0,
adc_updown_depop, SND_SOC_DAPM_PRE_POST_PMU |
SND_SOC_DAPM_PRE_POST_PMD),
SND_SOC_DAPM_DAC_E("DAC", "Playback", SGTL5000_CHIP_ANA_POWER, 3, 0,
dac_updown_depop, SND_SOC_DAPM_PRE_POST_PMU |
SND_SOC_DAPM_PRE_POST_PMD),
};
/* routes for sgtl5000 */
@@ -556,6 +720,7 @@ static const struct snd_kcontrol_new sgtl5000_snd_controls[] = {
SGTL5000_CHIP_ANA_ADC_CTRL,
8, 1, 0, capture_6db_attenuate),
SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0),
SOC_SINGLE("Capture Switch", SGTL5000_CHIP_ANA_CTRL, 0, 1, 1),
SOC_DOUBLE_TLV("Headphone Playback Volume",
SGTL5000_CHIP_ANA_HP_CTRL,
@@ -1173,12 +1338,17 @@ static int sgtl5000_set_power_regs(struct snd_soc_component *component)
SGTL5000_INT_OSC_EN);
/* Enable VDDC charge pump */
ana_pwr |= SGTL5000_VDDC_CHRGPMP_POWERUP;
} else if (vddio >= 3100 && vdda >= 3100) {
} else {
ana_pwr &= ~SGTL5000_VDDC_CHRGPMP_POWERUP;
/* VDDC use VDDIO rail */
lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
SGTL5000_VDDC_MAN_ASSN_SHIFT;
/*
* if vddio == vdda the source of charge pump should be
* assigned manually to VDDIO
*/
if (vddio == vdda) {
lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD;
lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO <<
SGTL5000_VDDC_MAN_ASSN_SHIFT;
}
}
snd_soc_component_write(component, SGTL5000_CHIP_LINREG_CTRL, lreg_ctrl);
@@ -1288,6 +1458,7 @@ static int sgtl5000_probe(struct snd_soc_component *component)
int ret;
u16 reg;
struct sgtl5000_priv *sgtl5000 = snd_soc_component_get_drvdata(component);
unsigned int zcd_mask = SGTL5000_HP_ZCD_EN | SGTL5000_ADC_ZCD_EN;
/* power up sgtl5000 */
ret = sgtl5000_set_power_regs(component);
@@ -1296,7 +1467,7 @@ static int sgtl5000_probe(struct snd_soc_component *component)
/* enable small pop, introduce 400ms delay in turning off */
snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL,
SGTL5000_SMALL_POP, 1);
SGTL5000_SMALL_POP, SGTL5000_SMALL_POP);
/* disable short cut detector */
snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0);
@@ -1315,9 +1486,8 @@ static int sgtl5000_probe(struct snd_soc_component *component)
0x1f);
snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg);
snd_soc_component_write(component, SGTL5000_CHIP_ANA_CTRL,
SGTL5000_HP_ZCD_EN |
SGTL5000_ADC_ZCD_EN);
snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL,
zcd_mask, zcd_mask);
snd_soc_component_update_bits(component, SGTL5000_CHIP_MIC_CTRL,
SGTL5000_BIAS_R_MASK,

View File

@@ -273,7 +273,7 @@
#define SGTL5000_BIAS_CTRL_MASK 0x000e
#define SGTL5000_BIAS_CTRL_SHIFT 1
#define SGTL5000_BIAS_CTRL_WIDTH 3
#define SGTL5000_SMALL_POP 1
#define SGTL5000_SMALL_POP 0x0001
/*
* SGTL5000_CHIP_MIC_CTRL

View File

@@ -459,7 +459,6 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
int ret;
struct sirf_audio_codec *sirf_audio_codec;
void __iomem *base;
struct resource *mem_res;
sirf_audio_codec = devm_kzalloc(&pdev->dev,
sizeof(struct sirf_audio_codec), GFP_KERNEL);
@@ -468,8 +467,7 @@ static int sirf_audio_codec_driver_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sirf_audio_codec);
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, mem_res);
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@@ -67,8 +67,6 @@ static SOC_ENUM_SINGLE_DECL(rec_src_enum,
static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
SOC_DAPM_ENUM("Input Select", rec_src_enum);
static SOC_ENUM_SINGLE_DECL(tlv320aic23_rec_src,
TLV320AIC23_ANLG, 2, rec_src_text);
static SOC_ENUM_SINGLE_DECL(tlv320aic23_deemph,
TLV320AIC23_DIGT, 1, deemph_text);

View File

@@ -258,7 +258,6 @@ static SOC_ENUM_SINGLE_DECL(mic1rp_p_enum, AIC31XX_MICPGAPI, 4,
static SOC_ENUM_SINGLE_DECL(mic1lm_p_enum, AIC31XX_MICPGAPI, 2,
mic_select_text);
static SOC_ENUM_SINGLE_DECL(cm_m_enum, AIC31XX_MICPGAMI, 6, mic_select_text);
static SOC_ENUM_SINGLE_DECL(mic1lm_m_enum, AIC31XX_MICPGAMI, 4,
mic_select_text);
@@ -1553,7 +1552,8 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset",
GPIOD_OUT_LOW);
if (IS_ERR(aic31xx->gpio_reset)) {
dev_err(aic31xx->dev, "not able to acquire gpio\n");
if (PTR_ERR(aic31xx->gpio_reset) != -EPROBE_DEFER)
dev_err(aic31xx->dev, "not able to acquire gpio\n");
return PTR_ERR(aic31xx->gpio_reset);
}
@@ -1564,7 +1564,9 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
ARRAY_SIZE(aic31xx->supplies),
aic31xx->supplies);
if (ret) {
dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret);
if (ret != -EPROBE_DEFER)
dev_err(aic31xx->dev,
"Failed to request supplies: %d\n", ret);
return ret;
}

View File

@@ -22,7 +22,6 @@
#include "tscs454.h"
static const unsigned int PLL_48K_RATE = (48000 * 256);
static const unsigned int PLL_44_1K_RATE = (44100 * 256);
#define COEFF_SIZE 3

View File

@@ -1108,10 +1108,8 @@ static int twl6040_probe(struct snd_soc_component *component)
priv->component = component;
priv->plug_irq = platform_get_irq(pdev, 0);
if (priv->plug_irq < 0) {
dev_err(component->dev, "invalid irq: %d\n", priv->plug_irq);
if (priv->plug_irq < 0)
return priv->plug_irq;
}
INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work);

295
sound/soc/codecs/uda1334.c Normal file
View File

@@ -0,0 +1,295 @@
// SPDX-License-Identifier: GPL-2.0-only
//
// uda1334.c -- UDA1334 ALSA SoC Audio driver
//
// Based on WM8523 ALSA SoC Audio driver written by Mark Brown
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/initval.h>
#define UDA1334_NUM_RATES 6
/* codec private data */
struct uda1334_priv {
struct gpio_desc *mute;
struct gpio_desc *deemph;
unsigned int sysclk;
unsigned int rate_constraint_list[UDA1334_NUM_RATES];
struct snd_pcm_hw_constraint_list rate_constraint;
};
static const struct snd_soc_dapm_widget uda1334_dapm_widgets[] = {
SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
};
static const struct snd_soc_dapm_route uda1334_dapm_routes[] = {
{ "LINEVOUTL", NULL, "DAC" },
{ "LINEVOUTR", NULL, "DAC" },
};
static int uda1334_put_deemph(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
int deemph = ucontrol->value.integer.value[0];
if (deemph > 1)
return -EINVAL;
gpiod_set_value_cansleep(uda1334->deemph, deemph);
return 0;
};
static int uda1334_get_deemph(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
int ret;
ret = gpiod_get_value_cansleep(uda1334->deemph);
if (ret < 0)
return -EINVAL;
ucontrol->value.integer.value[0] = ret;
return 0;
};
static const struct snd_kcontrol_new uda1334_snd_controls[] = {
SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
uda1334_get_deemph, uda1334_put_deemph),
};
static const struct {
int value;
int ratio;
} lrclk_ratios[UDA1334_NUM_RATES] = {
{ 1, 128 },
{ 2, 192 },
{ 3, 256 },
{ 4, 384 },
{ 5, 512 },
{ 6, 768 },
};
static int uda1334_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
/*
* The set of sample rates that can be supported depends on the
* MCLK supplied to the CODEC - enforce this.
*/
if (!uda1334->sysclk) {
dev_err(component->dev,
"No MCLK configured, call set_sysclk() on init\n");
return -EINVAL;
}
snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
&uda1334->rate_constraint);
gpiod_set_value_cansleep(uda1334->mute, 1);
return 0;
}
static void uda1334_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
gpiod_set_value_cansleep(uda1334->mute, 0);
}
static int uda1334_set_dai_sysclk(struct snd_soc_dai *codec_dai,
int clk_id, unsigned int freq, int dir)
{
struct snd_soc_component *component = codec_dai->component;
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
unsigned int val;
int i, j = 0;
uda1334->sysclk = freq;
uda1334->rate_constraint.count = 0;
for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
val = freq / lrclk_ratios[i].ratio;
/*
* Check that it's a standard rate since core can't
* cope with others and having the odd rates confuses
* constraint matching.
*/
switch (val) {
case 8000:
case 32000:
case 44100:
case 48000:
case 64000:
case 88200:
case 96000:
dev_dbg(component->dev, "Supported sample rate: %dHz\n",
val);
uda1334->rate_constraint_list[j++] = val;
uda1334->rate_constraint.count++;
break;
default:
dev_dbg(component->dev, "Skipping sample rate: %dHz\n",
val);
}
}
/* Need at least one supported rate... */
if (uda1334->rate_constraint.count == 0)
return -EINVAL;
return 0;
}
static int uda1334_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
{
fmt &= (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK |
SND_SOC_DAIFMT_MASTER_MASK);
if (fmt != (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS)) {
dev_err(codec_dai->dev, "Invalid DAI format\n");
return -EINVAL;
}
return 0;
}
static int uda1334_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
{
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(dai->component);
if (uda1334->mute)
gpiod_set_value_cansleep(uda1334->mute, mute);
return 0;
}
#define UDA1334_RATES SNDRV_PCM_RATE_8000_96000
#define UDA1334_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
static const struct snd_soc_dai_ops uda1334_dai_ops = {
.startup = uda1334_startup,
.shutdown = uda1334_shutdown,
.set_sysclk = uda1334_set_dai_sysclk,
.set_fmt = uda1334_set_fmt,
.mute_stream = uda1334_mute_stream,
};
static struct snd_soc_dai_driver uda1334_dai = {
.name = "uda1334-hifi",
.playback = {
.stream_name = "Playback",
.channels_min = 2,
.channels_max = 2,
.rates = UDA1334_RATES,
.formats = UDA1334_FORMATS,
},
.ops = &uda1334_dai_ops,
};
static int uda1334_probe(struct snd_soc_component *component)
{
struct uda1334_priv *uda1334 = snd_soc_component_get_drvdata(component);
uda1334->rate_constraint.list = &uda1334->rate_constraint_list[0];
uda1334->rate_constraint.count =
ARRAY_SIZE(uda1334->rate_constraint_list);
return 0;
}
static const struct snd_soc_component_driver soc_component_dev_uda1334 = {
.probe = uda1334_probe,
.controls = uda1334_snd_controls,
.num_controls = ARRAY_SIZE(uda1334_snd_controls),
.dapm_widgets = uda1334_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(uda1334_dapm_widgets),
.dapm_routes = uda1334_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(uda1334_dapm_routes),
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
.non_legacy_dai_naming = 1,
};
static const struct of_device_id uda1334_of_match[] = {
{ .compatible = "nxp,uda1334" },
{ /* sentinel*/ }
};
MODULE_DEVICE_TABLE(of, uda1334_of_match);
static int uda1334_codec_probe(struct platform_device *pdev)
{
struct uda1334_priv *uda1334;
int ret;
uda1334 = devm_kzalloc(&pdev->dev, sizeof(struct uda1334_priv),
GFP_KERNEL);
if (!uda1334)
return -ENOMEM;
platform_set_drvdata(pdev, uda1334);
uda1334->mute = devm_gpiod_get(&pdev->dev, "nxp,mute", GPIOD_OUT_LOW);
if (IS_ERR(uda1334->mute)) {
ret = PTR_ERR(uda1334->mute);
dev_err(&pdev->dev, "Failed to get mute line: %d\n", ret);
return ret;
}
uda1334->deemph = devm_gpiod_get(&pdev->dev, "nxp,deemph", GPIOD_OUT_LOW);
if (IS_ERR(uda1334->deemph)) {
ret = PTR_ERR(uda1334->deemph);
dev_err(&pdev->dev, "Failed to get deemph line: %d\n", ret);
return ret;
}
ret = devm_snd_soc_register_component(&pdev->dev,
&soc_component_dev_uda1334,
&uda1334_dai, 1);
if (ret < 0)
dev_err(&pdev->dev, "Failed to register component: %d\n", ret);
return ret;
}
static struct platform_driver uda1334_codec_driver = {
.probe = uda1334_codec_probe,
.driver = {
.name = "uda1334-codec",
.of_match_table = uda1334_of_match,
},
};
module_platform_driver(uda1334_codec_driver);
MODULE_DESCRIPTION("ASoC UDA1334 driver");
MODULE_AUTHOR("Andra Danciu <andradanciu1997@gmail.com>");
MODULE_ALIAS("platform:uda1334-codec");
MODULE_LICENSE("GPL v2");

View File

@@ -65,7 +65,7 @@ struct wcd_clsh_ctrl {
#define WCD9XXX_FLYBACK_EN_PWDN_WITH_DELAY 0
#define WCD9XXX_RX_BIAS_FLYB_BUFF WCD9335_REG(0x6, 0xC7)
#define WCD9XXX_RX_BIAS_FLYB_VNEG_5_UA_MASK GENMASK(7, 4)
#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(0, 3)
#define WCD9XXX_RX_BIAS_FLYB_VPOS_5_UA_MASK GENMASK(3, 0)
#define WCD9XXX_HPH_L_EN WCD9335_REG(0x6, 0xD3)
#define WCD9XXX_HPH_CONST_SEL_L_MASK GENMASK(7, 3)
#define WCD9XXX_HPH_CONST_SEL_BYPASS 0

View File

@@ -2071,9 +2071,10 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
.id = AIF1_PB,
.playback = {
.stream_name = "AIF1 Playback",
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
SNDRV_PCM_RATE_384000,
.formats = WCD9335_FORMATS_S16_S24_LE,
.rate_max = 192000,
.rate_max = 384000,
.rate_min = 8000,
.channels_min = 1,
.channels_max = 2,
@@ -2099,10 +2100,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
.id = AIF2_PB,
.playback = {
.stream_name = "AIF2 Playback",
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
SNDRV_PCM_RATE_384000,
.formats = WCD9335_FORMATS_S16_S24_LE,
.rate_min = 8000,
.rate_max = 192000,
.rate_max = 384000,
.channels_min = 1,
.channels_max = 2,
},
@@ -2127,10 +2129,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
.id = AIF3_PB,
.playback = {
.stream_name = "AIF3 Playback",
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
SNDRV_PCM_RATE_384000,
.formats = WCD9335_FORMATS_S16_S24_LE,
.rate_min = 8000,
.rate_max = 192000,
.rate_max = 384000,
.channels_min = 1,
.channels_max = 2,
},
@@ -2155,10 +2158,11 @@ static struct snd_soc_dai_driver wcd9335_slim_dais[] = {
.id = AIF4_PB,
.playback = {
.stream_name = "AIF4 Playback",
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK |
SNDRV_PCM_RATE_384000,
.formats = WCD9335_FORMATS_S16_S24_LE,
.rate_min = 8000,
.rate_max = 192000,
.rate_max = 384000,
.channels_min = 1,
.channels_max = 2,
},
@@ -3018,7 +3022,6 @@ static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w,
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
struct wcd9335_codec *wcd = snd_soc_component_get_drvdata(comp);
struct wcd_slim_codec_dai_data *dai = &wcd->dai[w->shift];
int ret = 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -3030,7 +3033,7 @@ static int wcd9335_codec_enable_slim(struct snd_soc_dapm_widget *w,
break;
}
return ret;
return 0;
}
static int wcd9335_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
@@ -3535,7 +3538,6 @@ static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
int hph_mode = wcd->hph_mode;
u8 dem_inp;
int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -3575,7 +3577,7 @@ static int wcd9335_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static int wcd9335_codec_lineout_dac_event(struct snd_soc_dapm_widget *w,
@@ -3603,7 +3605,6 @@ static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -3617,7 +3618,7 @@ static int wcd9335_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static void wcd9335_codec_hph_post_pa_config(struct wcd9335_codec *wcd,
@@ -3688,7 +3689,6 @@ static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
int hph_mode = wcd->hph_mode;
u8 dem_inp;
int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -3727,7 +3727,7 @@ static int wcd9335_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
@@ -3737,7 +3737,6 @@ static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
int hph_mode = wcd->hph_mode;
int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -3776,7 +3775,7 @@ static int wcd9335_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
@@ -3785,7 +3784,6 @@ static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
int vol_reg = 0, mix_vol_reg = 0;
int ret = 0;
if (w->reg == WCD9335_ANA_LO_1_2) {
if (w->shift == 7) {
@@ -3833,7 +3831,7 @@ static int wcd9335_codec_enable_lineout_pa(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static void wcd9335_codec_init_flyback(struct snd_soc_component *component)
@@ -3888,7 +3886,6 @@ static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
struct wcd9335_codec *wcd = dev_get_drvdata(comp->dev);
int hph_mode = wcd->hph_mode;
int ret = 0;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
@@ -3926,14 +3923,13 @@ static int wcd9335_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kc, int event)
{
struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
int ret = 0;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
@@ -3963,7 +3959,7 @@ static int wcd9335_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
break;
};
return ret;
return 0;
}
static irqreturn_t wcd9335_slimbus_irq(int irq, void *data)
@@ -4062,7 +4058,8 @@ static int wcd9335_setup_irqs(struct wcd9335_codec *wcd)
ret = devm_request_threaded_irq(wcd->dev, irq, NULL,
wcd9335_irqs[i].handler,
IRQF_TRIGGER_RISING,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
wcd9335_irqs[i].name, wcd);
if (ret) {
dev_err(wcd->dev, "Failed to request %s\n",

View File

@@ -140,7 +140,7 @@ struct pll_factors {
* to allow rounding later */
#define FIXED_FLL_SIZE ((1 << 22) * 10)
static int wm8995_pll_factors(struct device *dev,
static int wm8955_pll_factors(struct device *dev,
int Fref, int Fout, struct pll_factors *pll)
{
u64 Kpart;
@@ -279,7 +279,7 @@ static int wm8955_configure_clocking(struct snd_soc_component *component)
/* Use the last divider configuration we saw for the
* sample rate. */
ret = wm8995_pll_factors(component->dev, wm8955->mclk_rate,
ret = wm8955_pll_factors(component->dev, wm8955->mclk_rate,
clock_cfgs[sr].mclk, &pll);
if (ret != 0) {
dev_err(component->dev,

View File

@@ -273,7 +273,7 @@ static const struct soc_enum wm8988_rline_enum =
wm8988_line_texts,
wm8988_line_values);
static const struct snd_kcontrol_new wm8988_right_line_controls =
SOC_DAPM_ENUM("Route", wm8988_lline_enum);
SOC_DAPM_ENUM("Route", wm8988_rline_enum);
/* Left Mixer */
static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = {

View File

@@ -4242,8 +4242,9 @@ static void wm_adsp_fatal_error(struct wm_adsp *dsp)
}
}
irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp)
irqreturn_t wm_adsp2_bus_error(int irq, void *data)
{
struct wm_adsp *dsp = (struct wm_adsp *)data;
unsigned int val;
struct regmap *regmap = dsp->regmap;
int ret = 0;
@@ -4307,8 +4308,9 @@ error:
}
EXPORT_SYMBOL_GPL(wm_adsp2_bus_error);
irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp)
irqreturn_t wm_halo_bus_error(int irq, void *data)
{
struct wm_adsp *dsp = (struct wm_adsp *)data;
struct regmap *regmap = dsp->regmap;
unsigned int fault[6];
struct reg_sequence clear[] = {

View File

@@ -171,8 +171,8 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
int wm_adsp_early_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
irqreturn_t wm_adsp2_bus_error(struct wm_adsp *adsp);
irqreturn_t wm_halo_bus_error(struct wm_adsp *dsp);
irqreturn_t wm_adsp2_bus_error(int irq, void *data);
irqreturn_t wm_halo_bus_error(int irq, void *data);
irqreturn_t wm_halo_wdt_expire(int irq, void *data);
int wm_adsp_event(struct snd_soc_dapm_widget *w,