Unverified Commit 7ffe09ee authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/for-5.9' into asoc-linus

parents 549738f1 ebb11d1d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4170,6 +4170,7 @@ CIRRUS LOGIC AUDIO CODEC DRIVERS
M:	James Schulman <james.schulman@cirrus.com>
M:	David Rhodes <david.rhodes@cirrus.com>
L:	alsa-devel@alsa-project.org (moderated for non-subscribers)
L:	patches@opensource.cirrus.com
S:	Maintained
F:	sound/soc/codecs/cs*
+1 −1
Original line number Diff line number Diff line
@@ -1089,6 +1089,7 @@ static const struct snd_soc_dapm_route cs47l15_dapm_routes[] = {
	{ "HPOUT1 Demux", NULL, "OUT1R" },

	{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
	{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },

	{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
	{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
@@ -1268,7 +1269,6 @@ static irqreturn_t cs47l15_adsp2_irq(int irq, void *data)

static const struct snd_soc_dapm_route cs47l15_mono_routes[] = {
	{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
	{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
};

static int cs47l15_component_probe(struct snd_soc_component *component)
+1 −1
Original line number Diff line number Diff line
@@ -1305,6 +1305,7 @@ static const struct snd_soc_dapm_route cs47l35_dapm_routes[] = {
	{ "SPKOUTP", NULL, "OUT4L" },

	{ "OUT1R", NULL, "HPOUT1 Mono Mux" },
	{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },

	{ "HPOUTL", "HPOUT", "HPOUT1 Demux" },
	{ "HPOUTR", "HPOUT", "HPOUT1 Demux" },
@@ -1550,7 +1551,6 @@ static irqreturn_t cs47l35_adsp2_irq(int irq, void *data)

static const struct snd_soc_dapm_route cs47l35_mono_routes[] = {
	{ "HPOUT1 Mono Mux", "HPOUT", "OUT1L" },
	{ "HPOUT1 Mono Mux", "EPOUT", "OUT1L" },
};

static int cs47l35_component_probe(struct snd_soc_component *component)
+90 −21
Original line number Diff line number Diff line
@@ -484,6 +484,33 @@ static int rt1015_bypass_boost_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static void rt1015_calibrate(struct rt1015_priv *rt1015)
{
	struct snd_soc_component *component = rt1015->component;
	struct regmap *regmap = rt1015->regmap;

	snd_soc_dapm_mutex_lock(&component->dapm);
	regcache_cache_bypass(regmap, true);

	regmap_write(regmap, RT1015_PWR1, 0xd7df);
	regmap_write(regmap, RT1015_PWR4, 0x00b2);
	regmap_write(regmap, RT1015_CLSD_INTERNAL8, 0x2008);
	regmap_write(regmap, RT1015_CLSD_INTERNAL9, 0x0140);
	regmap_write(regmap, RT1015_GAT_BOOST, 0x0efe);
	regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000d);
	regmap_write(regmap, RT1015_PWR_STATE_CTRL, 0x000e);
	regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a00);
	regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a01);
	regmap_write(regmap, RT1015_DC_CALIB_CLSD1, 0x5a05);
	msleep(500);
	regmap_write(regmap, RT1015_PWR1, 0x0);

	regcache_cache_bypass(regmap, false);
	regcache_mark_dirty(regmap);
	regcache_sync(regmap);
	snd_soc_dapm_mutex_unlock(&component->dapm);
}

static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
@@ -494,20 +521,12 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,

	if (!rt1015->dac_is_used) {
		rt1015->bypass_boost = ucontrol->value.integer.value[0];
		if (rt1015->bypass_boost == RT1015_Bypass_Boost) {
			snd_soc_component_write(component,
				RT1015_PWR4, 0x00b2);
			snd_soc_component_write(component,
				RT1015_CLSD_INTERNAL8, 0x2008);
			snd_soc_component_write(component,
				RT1015_CLSD_INTERNAL9, 0x0140);
			snd_soc_component_write(component,
				RT1015_GAT_BOOST, 0x0efe);
			snd_soc_component_write(component,
				RT1015_PWR_STATE_CTRL, 0x000d);
			msleep(500);
			snd_soc_component_write(component,
				RT1015_PWR_STATE_CTRL, 0x000e);
		if (rt1015->bypass_boost == RT1015_Bypass_Boost &&
			!rt1015->cali_done) {
			rt1015_calibrate(rt1015);
			rt1015->cali_done = 1;

			regmap_write(rt1015->regmap, RT1015_MONO_DYNA_CTRL, 0x0010);
		}
	} else
		dev_err(component->dev, "DAC is being used!\n");
@@ -515,6 +534,32 @@ static int rt1015_bypass_boost_put(struct snd_kcontrol *kcontrol,
	return 0;
}

static void rt1015_flush_work(struct work_struct *work)
{
	struct rt1015_priv *rt1015 = container_of(work, struct rt1015_priv,
						flush_work.work);
	struct snd_soc_component *component = rt1015->component;
	unsigned int val, i = 0, count = 20;

	while (i < count) {
		usleep_range(1000, 1500);
		dev_dbg(component->dev, "Flush DAC (retry:%u)\n", i);
		regmap_read(rt1015->regmap, RT1015_CLK_DET, &val);
		if (val & 0x800)
			break;
		i++;
	}

	regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
	regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
	regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);

	if (val & 0x800)
		dev_dbg(component->dev, "Flush DAC completed.\n");
	else
		dev_warn(component->dev, "Fail to flush DAC data.\n");
}

static const struct snd_kcontrol_new rt1015_snd_controls[] = {
	SOC_SINGLE_TLV("DAC Playback Volume", RT1015_DAC1, RT1015_DAC_VOL_SFT,
		127, 0, dac_vol_tlv),
@@ -568,12 +613,7 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
		break;

	case SND_SOC_DAPM_POST_PMU:
		if (rt1015->bypass_boost == RT1015_Bypass_Boost) {
		regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x00a8);
			regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x0597);
			regmap_write(rt1015->regmap, RT1015_SYS_RST1, 0x05f7);
			regmap_write(rt1015->regmap, RT1015_MAN_I2C, 0x0028);
		}
		break;

	case SND_SOC_DAPM_POST_PMD:
@@ -589,6 +629,8 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
				RT1015_SYS_RST1, 0x05f5);
		}
		rt1015->dac_is_used = 0;

		cancel_delayed_work_sync(&rt1015->flush_work);
		break;

	default:
@@ -597,6 +639,24 @@ static int r1015_dac_event(struct snd_soc_dapm_widget *w,
	return 0;
}

static int rt1015_amp_drv_event(struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	struct snd_soc_component *component =
		snd_soc_dapm_to_component(w->dapm);
	struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		if (rt1015->hw_config == RT1015_HW_28)
			schedule_delayed_work(&rt1015->flush_work, msecs_to_jiffies(10));
		break;
	default:
		break;
	}
	return 0;
}

static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
	SND_SOC_DAPM_SUPPLY("LDO2", RT1015_PWR1, RT1015_PWR_LDO2_BIT, 0,
		NULL, 0),
@@ -630,6 +690,8 @@ static const struct snd_soc_dapm_widget rt1015_dapm_widgets[] = {
		r1015_dac_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
		SND_SOC_DAPM_POST_PMD),

	SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0,
			rt1015_amp_drv_event, SND_SOC_DAPM_POST_PMU),
	SND_SOC_DAPM_OUTPUT("SPO"),
};

@@ -648,7 +710,8 @@ static const struct snd_soc_dapm_route rt1015_dapm_routes[] = {
	{ "DAC", NULL, "MIXERV" },
	{ "DAC", NULL, "SUMV" },
	{ "DAC", NULL, "VREFLV" },
	{ "SPO", NULL, "DAC" },
	{ "Amp Drv", NULL, "DAC" },
	{ "SPO", NULL, "Amp Drv" },
};

static int rt1015_hw_params(struct snd_pcm_substream *substream,
@@ -888,8 +951,11 @@ static int rt1015_probe(struct snd_soc_component *component)

	rt1015->component = component;
	rt1015->bclk_ratio = 0;
	rt1015->cali_done = 0;
	snd_soc_component_write(component, RT1015_BAT_RPO_STEP1, 0x061c);

	INIT_DELAYED_WORK(&rt1015->flush_work, rt1015_flush_work);

	return 0;
}

@@ -897,6 +963,7 @@ static void rt1015_remove(struct snd_soc_component *component)
{
	struct rt1015_priv *rt1015 = snd_soc_component_get_drvdata(component);

	cancel_delayed_work_sync(&rt1015->flush_work);
	regmap_write(rt1015->regmap, RT1015_RESET, 0);
}

@@ -1022,6 +1089,8 @@ static int rt1015_i2c_probe(struct i2c_client *i2c,
		return ret;
	}

	rt1015->hw_config = (i2c->addr == 0x29) ? RT1015_HW_29 : RT1015_HW_28;

	regmap_read(rt1015->regmap, RT1015_DEVICE_ID, &val);
	if ((val != RT1015_DEVICE_ID_VAL) && (val != RT1015_DEVICE_ID_VAL2)) {
		dev_err(&i2c->dev,
+8 −0
Original line number Diff line number Diff line
@@ -373,6 +373,11 @@ enum {
	RT1015_Bypass_Boost,
};

enum {
	RT1015_HW_28 = 0,
	RT1015_HW_29,
};

struct rt1015_priv {
	struct snd_soc_component *component;
	struct regmap *regmap;
@@ -389,6 +394,9 @@ struct rt1015_priv {
	int bypass_boost;
	int amp_ver;
	int dac_is_used;
	int cali_done;
	int hw_config;
	struct delayed_work flush_work;
};

#endif /* __RT1015_H__ */
Loading