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

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

Merge "btfm: Close 3990 FM tx ports first and keep overflow bit always set"

parents 01e6ff9f 795ac6ea
Loading
Loading
Loading
Loading
+62 −12
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ static int btfm_slim_dai_startup(struct snd_pcm_substream *substream,
	int ret;
	struct btfmslim *btfmslim = dai->dev->platform_data;

	BTFMSLIM_DBG("substream = %s  stream = %d dai name = %s",
	BTFMSLIM_DBG("substream = %s  stream = %d dai->name = %s",
		 substream->name, substream->stream, dai->name);
	ret = btfm_slim_hw_init(btfmslim);
	return ret;
@@ -63,10 +63,52 @@ static int btfm_slim_dai_startup(struct snd_pcm_substream *substream,
static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
	int i;
	struct btfmslim *btfmslim = dai->dev->platform_data;
	struct btfmslim_ch *ch;
	uint8_t rxport, grp = false, nchan = 1;

	BTFMSLIM_DBG("substream = %s  stream = %d dai name = %s",
		 substream->name, substream->stream, dai->name);
	BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
		dai->id, dai->rate);

	switch (dai->id) {
	case BTFM_FM_SLIM_TX:
		grp = true; nchan = 2;
		ch = btfmslim->tx_chs;
		rxport = 0;
		break;
	case BTFM_BT_SCO_SLIM_TX:
		ch = btfmslim->tx_chs;
		rxport = 0;
		break;
	case BTFM_BT_SCO_A2DP_SLIM_RX:
	case BTFM_BT_SPLIT_A2DP_SLIM_RX:
		ch = btfmslim->rx_chs;
		rxport = 1;
		break;
	case BTFM_SLIM_NUM_CODEC_DAIS:
	default:
		BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
		return;
	}

	if (dai->id == BTFM_FM_SLIM_TX)
		goto out;

	/* Search for dai->id matched port handler */
	for (i = 0; (i < BTFM_SLIM_NUM_CODEC_DAIS) &&
		(ch->id != BTFM_SLIM_NUM_CODEC_DAIS) &&
		(ch->id != dai->id); ch++, i++)
		;

	if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
		(ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
		BTFMSLIM_ERR("ch is invalid!!");
		return;
	}

	btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);
out:
	btfm_slim_hw_deinit(btfmslim);
}

@@ -74,14 +116,14 @@ static int btfm_slim_dai_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{
	BTFMSLIM_DBG("dai name = %s DAI-ID %x rate %d num_ch %d",
	BTFMSLIM_DBG("dai->name = %s DAI-ID %x rate %d num_ch %d",
		dai->name, dai->id, params_rate(params),
		params_channels(params));

	return 0;
}

int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
static int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
	struct snd_soc_dai *dai)
{
	int i, ret = -EINVAL;
@@ -89,7 +131,7 @@ int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
	struct btfmslim_ch *ch;
	uint8_t rxport, grp = false, nchan = 1;

	BTFMSLIM_DBG("dai name: %s, dai->id: %d, dai->rate: %d", dai->name,
	BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
		dai->id, dai->rate);

	switch (dai->id) {
@@ -129,15 +171,15 @@ int btfm_slim_dai_prepare(struct snd_pcm_substream *substream,
	return ret;
}

int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
static int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
	struct snd_soc_dai *dai)
{
	int i, ret = -EINVAL;
	int ret = -EINVAL, i;
	struct btfmslim *btfmslim = dai->dev->platform_data;
	struct btfmslim_ch *ch;
	uint8_t rxport, grp = false, nchan = 1;

	BTFMSLIM_DBG("dai name: %s, dai->id: %d, dai->rate: %d", dai->name,
	BTFMSLIM_DBG("dai->name: %s, dai->id: %d, dai->rate: %d", dai->name,
		dai->id, dai->rate);

	switch (dai->id) {
@@ -158,7 +200,12 @@ int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
	case BTFM_SLIM_NUM_CODEC_DAIS:
	default:
		BTFMSLIM_ERR("dai->id is invalid:%d", dai->id);
		return ret;
		goto out;
	}

	if (dai->id != BTFM_FM_SLIM_TX) {
		ret = 0;
		goto out;
	}

	/* Search for dai->id matched port handler */
@@ -170,9 +217,12 @@ int btfm_slim_dai_hw_free(struct snd_pcm_substream *substream,
	if ((ch->port == BTFM_SLIM_PGD_PORT_LAST) ||
		(ch->id == BTFM_SLIM_NUM_CODEC_DAIS)) {
		BTFMSLIM_ERR("ch is invalid!!");
		return ret;
		goto out;
	}
	ret = btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);

	btfm_slim_disable_ch(btfmslim, ch, rxport, grp, nchan);

out:
	return ret;
}

+35 −34
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim)
{
	int ret = 0;
	uint8_t reg_val;
	uint16_t reg;

	BTFMSLIM_DBG("");

@@ -46,20 +47,20 @@ int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim)
		return -EINVAL;

	/* Get SB_SLAVE_HW_REV_MSB value*/
	ret = btfm_slim_read(btfmslim, CHRK_SB_SLAVE_HW_REV_MSB,  1,
		&reg_val, IFD);
	reg = CHRK_SB_SLAVE_HW_REV_MSB;
	ret = btfm_slim_read(btfmslim, reg,  1, &reg_val, IFD);
	if (ret) {
		BTFMSLIM_ERR("failed to read (%d)", ret);
		BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
		goto error;
	}
	BTFMSLIM_DBG("Major Rev: 0x%x, Minor Rev: 0x%x",
		(reg_val & 0xF0) >> 4, (reg_val & 0x0F));

	/* Get SB_SLAVE_HW_REV_LSB value*/
	ret = btfm_slim_read(btfmslim, CHRK_SB_SLAVE_HW_REV_LSB,  1,
		&reg_val, IFD);
	reg = CHRK_SB_SLAVE_HW_REV_LSB;
	ret = btfm_slim_read(btfmslim, reg,  1, &reg_val, IFD);
	if (ret) {
		BTFMSLIM_ERR("failed to read (%d)", ret);
		BTFMSLIM_ERR("failed to read (%d) reg 0x%x", ret, reg);
		goto error;
	}
	BTFMSLIM_DBG("Step Rev: 0x%x", reg_val);
@@ -80,41 +81,41 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,
	if (rxport) {
		/* Port enable */
		reg = CHRK_SB_PGD_PORT_RX_CFGN(port_num - 0x10);
	} else { /* txport */
		/* Multiple Channel Setting - only FM Tx will be multiple
		 * channel
		 */
		if (enable && (port_num == CHRK_SB_PGD_PORT_TX1_FM ||
			port_num == CHRK_SB_PGD_PORT_TX2_FM)) {
		goto enable_disable_rxport;
	}
	/* txport */
	if (!enable)
		goto enable_disable_txport;

	/* Multiple Channel Setting - only for FM Tx */
	if (port_num == CHRK_SB_PGD_PORT_TX1_FM ||
		port_num == CHRK_SB_PGD_PORT_TX2_FM) {

		reg_val = (0x1 << CHRK_SB_PGD_PORT_TX1_FM) |
				(0x1 << CHRK_SB_PGD_PORT_TX2_FM);
		reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num);
		ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
		if (ret) {
				BTFMSLIM_ERR("failed to write (%d)", ret);
			BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
			goto error;
		}
	}

		/* Enable Tx port hw auto recovery for underrun or
		 * overrun error
		 */
		reg_val = (enable) ? (CHRK_ENABLE_OVERRUN_AUTO_RECOVERY |
				CHRK_ENABLE_UNDERRUN_AUTO_RECOVERY) : 0x0;

		ret = btfm_slim_write(btfmslim,
			CHRK_SB_PGD_PORT_TX_OR_UR_CFGN(port_num), 1,
			&reg_val, IFD);
	/* Enable Tx port hw auto recovery for underrun or overrun error */
	reg_val = (CHRK_ENABLE_OVERRUN_AUTO_RECOVERY |
				CHRK_ENABLE_UNDERRUN_AUTO_RECOVERY);
	reg = CHRK_SB_PGD_PORT_TX_OR_UR_CFGN(port_num);
	ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
	if (ret) {
			BTFMSLIM_ERR("failed to write (%d)", ret);
		BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);
		goto error;
	}

enable_disable_txport:
	/* Port enable */
	reg = CHRK_SB_PGD_PORT_TX_CFGN(port_num);
	}

enable_disable_rxport:
	if (enable)
		/* Set water mark to 1 and enable the port */
		reg_val = CHRK_SB_PGD_PORT_ENABLE | CHRK_SB_PGD_PORT_WM_LB;
@@ -123,7 +124,7 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num,

	ret = btfm_slim_write(btfmslim, reg, 1, &reg_val, IFD);
	if (ret)
		BTFMSLIM_ERR("failed to write (%d)", ret);
		BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg);

error:
	return ret;