Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88cb5111 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/twl4030' into asoc-next

parents 86408059 052901f4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -286,6 +286,8 @@ struct device;
	.info = snd_soc_info_volsw, \
	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 1) }
#define SOC_DAPM_SINGLE_VIRT(xname, max) \
	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0)
#define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.info = snd_soc_info_volsw, \
@@ -300,6 +302,8 @@ struct device;
	.tlv.p = (tlv_array), \
	.get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \
	.private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
#define SOC_DAPM_SINGLE_TLV_VIRT(xname, max, tlv_array) \
	SOC_DAPM_SINGLE(xname, SND_SOC_NOPM, 0, max, 0, tlv_array)
#define SOC_DAPM_ENUM(xname, xenum) \
{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
	.info = snd_soc_info_enum_double, \
+2 −1
Original line number Diff line number Diff line
@@ -1051,7 +1051,8 @@ struct snd_soc_pcm_runtime {
/* mixer control */
struct soc_mixer_control {
	int min, max, platform_max;
	unsigned int reg, rreg, shift, rshift;
	int reg, rreg;
	unsigned int shift, rshift;
	unsigned int invert:1;
	unsigned int autodisable:1;
};
+36 −44
Original line number Diff line number Diff line
@@ -46,13 +46,7 @@
/* TWL4030 PMBR1 Register GPIO6 mux bits */
#define TWL4030_GPIO6_PWM0_MUTE(value)	((value & 0x03) << 2)

/* Shadow register used by the audio driver */
#define TWL4030_REG_SW_SHADOW		0x4A
#define TWL4030_CACHEREGNUM	(TWL4030_REG_SW_SHADOW + 1)

/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
#define TWL4030_HFL_EN			0x01
#define TWL4030_HFR_EN			0x02
#define TWL4030_CACHEREGNUM	(TWL4030_REG_MISC_SET_2 + 1)

/*
 * twl4030 register cache & default register settings
@@ -132,7 +126,6 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
	0x00, /* REG_VIBRA_PWM_SET	(0x47)	*/
	0x00, /* REG_ANAMIC_GAIN	(0x48)	*/
	0x00, /* REG_MISC_SET_2		(0x49)	*/
	0x00, /* REG_SW_SHADOW		(0x4A)	- Shadow, non HW register */
};

/* codec private data */
@@ -198,7 +191,6 @@ static int twl4030_write(struct snd_soc_codec *codec,
	int write_to_reg = 0;

	twl4030_write_reg_cache(codec, reg, value);
	if (likely(reg < TWL4030_REG_SW_SHADOW)) {
	/* Decide if the given register can be written */
	switch (reg) {
	case TWL4030_REG_EAR_CTL:
@@ -233,7 +225,7 @@ static int twl4030_write(struct snd_soc_codec *codec,
	if (write_to_reg)
		return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
					    value, reg);
	}

	return 0;
}

@@ -532,7 +524,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);

/* Handsfree Left virtual mute */
static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control =
	SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0);
	SOC_DAPM_SINGLE_VIRT("Switch", 1);

/* Handsfree Right */
static const char *twl4030_handsfreer_texts[] =
@@ -548,7 +540,7 @@ SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);

/* Handsfree Right virtual mute */
static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control =
	SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0);
	SOC_DAPM_SINGLE_VIRT("Switch", 1);

/* Vibra */
/* Vibra audio path selection */
+28 −18
Original line number Diff line number Diff line
@@ -499,18 +499,22 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
		int val;
		struct soc_mixer_control *mc = (struct soc_mixer_control *)
			w->kcontrol_news[i].private_value;
		unsigned int reg = mc->reg;
		int reg = mc->reg;
		unsigned int shift = mc->shift;
		int max = mc->max;
		unsigned int mask = (1 << fls(max)) - 1;
		unsigned int invert = mc->invert;

		if (reg != SND_SOC_NOPM) {
			val = soc_widget_read(w, reg);
			val = (val >> shift) & mask;
			if (invert)
				val = max - val;

			p->connect = !!val;
		} else {
			p->connect = 0;
		}

	}
	break;
	case snd_soc_dapm_mux: {
@@ -1840,6 +1844,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
			 */
			switch (w->id) {
			case snd_soc_dapm_siggen:
			case snd_soc_dapm_vmid:
				break;
			case snd_soc_dapm_supply:
			case snd_soc_dapm_regulator_supply:
@@ -2791,7 +2796,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
	struct snd_soc_card *card = codec->card;
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	unsigned int reg = mc->reg;
	int reg = mc->reg;
	unsigned int shift = mc->shift;
	int max = mc->max;
	unsigned int mask = (1 << fls(max)) - 1;
@@ -2804,7 +2809,7 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
			 kcontrol->id.name);

	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
	if (dapm_kcontrol_is_powered(kcontrol))
	if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
		val = (snd_soc_read(codec, reg) >> shift) & mask;
	else
		val = dapm_kcontrol_get_value(kcontrol);
@@ -2835,7 +2840,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
	struct snd_soc_card *card = codec->card;
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	unsigned int reg = mc->reg;
	int reg = mc->reg;
	unsigned int shift = mc->shift;
	int max = mc->max;
	unsigned int mask = (1 << fls(max)) - 1;
@@ -2857,19 +2862,24 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,

	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);

	dapm_kcontrol_set_value(kcontrol, val);
	change = dapm_kcontrol_set_value(kcontrol, val);

	if (reg != SND_SOC_NOPM) {
		mask = mask << shift;
		val = val << shift;

		change = snd_soc_test_bits(codec, reg, mask, val);
	}

	if (change) {
		if (reg != SND_SOC_NOPM) {
			update.kcontrol = kcontrol;
			update.reg = reg;
			update.mask = mask;
			update.val = val;

			card->update = &update;
		}

		soc_dapm_mixer_update_power(card, kcontrol, connect);