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

Commit 5691f7af authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd9320: Handle overflow/underflow slimbus interrupts"

parents ace85c70 10ea438f
Loading
Loading
Loading
Loading
+67 −5
Original line number Diff line number Diff line
@@ -260,6 +260,8 @@ MODULE_PARM_DESC(spkr_drv_wrnd,

#define TAIKO_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)

#define TAIKO_SLIM_PGD_PORT_INT_TX_EN0 (TAIKO_SLIM_PGD_PORT_INT_EN0 + 2)

enum {
	AIF1_PB = 0,
	AIF1_CAP,
@@ -4931,6 +4933,46 @@ static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
	return ret;
}

static void taiko_codec_enable_int_port(struct wcd9xxx_codec_dai_data *dai,
					  struct snd_soc_codec *codec)
{
	struct wcd9xxx_ch *ch;
	int port_num = 0;
	unsigned short reg = 0;
	u8 val = 0;
	if (!dai || !codec) {
		pr_err("%s: Invalid params\n", __func__);
		return;
	}
	list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
		if (ch->port >= TAIKO_RX_PORT_START_NUMBER) {
			port_num = ch->port - TAIKO_RX_PORT_START_NUMBER;
			reg = TAIKO_SLIM_PGD_PORT_INT_EN0 + (port_num / 8);
			val = wcd9xxx_interface_reg_read(codec->control_data,
				reg);
			if (!(val & (1 << (port_num % 8)))) {
				val |= (1 << (port_num % 8));
				wcd9xxx_interface_reg_write(
					codec->control_data, reg, val);
				val = wcd9xxx_interface_reg_read(
					codec->control_data, reg);
			}
		} else {
			port_num = ch->port;
			reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
			val = wcd9xxx_interface_reg_read(codec->control_data,
				reg);
			if (!(val & (1 << (port_num % 8)))) {
				val |= (1 << (port_num % 8));
				wcd9xxx_interface_reg_write(codec->control_data,
					reg, val);
				val = wcd9xxx_interface_reg_read(
					codec->control_data, reg);
			}
		}
	}
}

static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
				     struct snd_kcontrol *kcontrol,
				     int event)
@@ -4957,6 +4999,7 @@ static int taiko_codec_enable_slimrx(struct snd_soc_dapm_widget *w,

	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		taiko_codec_enable_int_port(dai, codec);
		(void) taiko_codec_enable_slim_chmask(dai, true);
		ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
					      dai->rate, dai->bit_width,
@@ -5021,6 +5064,7 @@ static int taiko_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
		/*Enable spkr VI clocks*/
		snd_soc_update_bits(codec,
		TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL, 0xC, 0xC);
		taiko_codec_enable_int_port(dai, codec);
		(void) taiko_codec_enable_slim_chmask(dai, true);
		ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
					dai->rate, dai->bit_width,
@@ -5068,6 +5112,7 @@ static int taiko_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
	dai = &taiko_p->dai[w->shift];
	switch (event) {
	case SND_SOC_DAPM_POST_PMU:
		taiko_codec_enable_int_port(dai, codec);
		(void) taiko_codec_enable_slim_chmask(dai, true);
		ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
					      dai->rate, dai->bit_width,
@@ -5676,8 +5721,9 @@ static irqreturn_t taiko_slimbus_irq(int irq, void *data)
	unsigned long status = 0;
	int i, j, port_id, k;
	u32 bit;
	u8 val;
	u8 val, int_val = 0;
	bool tx, cleared;
	unsigned short reg = 0;

	for (i = TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
	     i <= TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
@@ -5698,6 +5744,22 @@ static irqreturn_t taiko_slimbus_irq(int irq, void *data)
			pr_err_ratelimited(
			   "%s: underflow error on %s port %d, value %x\n",
			   __func__, (tx ? "TX" : "RX"), port_id, val);
		if ((val & TAIKO_SLIM_IRQ_OVERFLOW) ||
			(val & TAIKO_SLIM_IRQ_UNDERFLOW)) {
			if (!tx)
				reg = TAIKO_SLIM_PGD_PORT_INT_EN0 +
					(port_id / 8);
			else
				reg = TAIKO_SLIM_PGD_PORT_INT_TX_EN0 +
					(port_id / 8);
			int_val = wcd9xxx_interface_reg_read(
				codec->control_data, reg);
			if (int_val & (1 << (port_id % 8))) {
				int_val = int_val ^ (1 << (port_id % 8));
				wcd9xxx_interface_reg_write(codec->control_data,
					reg, int_val);
			}
		}
		if (val & TAIKO_SLIM_IRQ_PORT_CLOSED) {
			/*
			 * INT SOURCE register starts from RX to TX