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

Commit 1aab2c06 authored by Laxminath Kasam's avatar Laxminath Kasam
Browse files

asoc: wcd937x: add SSR changes for wcd937x codec driver



Add changes to recover audio after SSR on wcd937x driver.

Change-Id: I661605e9b1bd71f08f331d14ae52f89ba8423d4f
Signed-off-by: default avatarRohit kumar <rohitkr@codeaurora.org>
Signed-off-by: default avatarLaxminath Kasam <lkasam@codeaurora.org>
parent fb0d683b
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -123,6 +123,8 @@ enum {


enum {
enum {
	BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
	BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
	BOLERO_WCD_EVT_SSR_DOWN,
	BOLERO_WCD_EVT_SSR_UP,
};
};


enum {
enum {
+1 −0
Original line number Original line Diff line number Diff line
@@ -974,6 +974,7 @@ int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc,
		return -EINVAL;
		return -EINVAL;
	}
	}


	wcd937x_mbhc_hs_detect_exit(codec);
	wcd_mbhc_deinit(wcd_mbhc);
	wcd_mbhc_deinit(wcd_mbhc);
	ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
	ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
			    wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED);
			    wcd_mbhc_registers, WCD937X_ZDET_SUPPORTED);
+4 −2
Original line number Original line Diff line number Diff line
@@ -450,8 +450,10 @@ static bool wcd937x_volatile_register(struct device *dev, unsigned int reg)
{
{
	if(reg <= WCD937X_BASE_ADDRESS)
	if(reg <= WCD937X_BASE_ADDRESS)
		return 0;
		return 0;
	return (wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
	if ((wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
		& ~(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG);
		&& !(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG))
		return true;
	return false;
}
}


struct regmap_config wcd937x_regmap_config = {
struct regmap_config wcd937x_regmap_config = {
+71 −1
Original line number Original line Diff line number Diff line
@@ -48,6 +48,8 @@ static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);


static int wcd937x_handle_post_irq(void *data);
static int wcd937x_handle_post_irq(void *data);
static int wcd937x_reset(struct device *dev);
static int wcd937x_reset_low(struct device *dev);


static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
static const struct regmap_irq wcd937x_irqs[WCD937X_NUM_IRQS] = {
	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
	REGMAP_IRQ_REG(WCD937X_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x01),
@@ -1216,6 +1218,23 @@ int wcd937x_micbias_control(struct snd_soc_codec *codec,
}
}
EXPORT_SYMBOL(wcd937x_micbias_control);
EXPORT_SYMBOL(wcd937x_micbias_control);


static int wcd937x_get_logical_addr(struct swr_device *swr_dev)
{
	int ret = 0;
	uint8_t devnum = 0;

	ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
	if (ret) {
		dev_err(&swr_dev->dev,
			"%s get devnum %d for dev addr %lx failed\n",
			__func__, devnum, swr_dev->addr);
		swr_remove_device(swr_dev);
		return ret;
	}
	swr_dev->dev_num = devnum;
	return 0;
}

static int wcd937x_event_notify(struct notifier_block *block,
static int wcd937x_event_notify(struct notifier_block *block,
				unsigned long val,
				unsigned long val,
				void *data)
				void *data)
@@ -1223,8 +1242,10 @@ static int wcd937x_event_notify(struct notifier_block *block,
	u16 event = (val & 0xffff);
	u16 event = (val & 0xffff);
	u16 amic = (val >> 0x10);
	u16 amic = (val >> 0x10);
	u16 mask = 0x40, reg = 0x0;
	u16 mask = 0x40, reg = 0x0;
	int ret = 0;
	struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data);
	struct wcd937x_priv *wcd937x = dev_get_drvdata((struct device *)data);
	struct snd_soc_codec *codec = wcd937x->codec;
	struct snd_soc_codec *codec = wcd937x->codec;
	struct wcd_mbhc *mbhc;


	switch (event) {
	switch (event) {
	case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
	case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
@@ -1238,6 +1259,25 @@ static int wcd937x_event_notify(struct notifier_block *block,
			mask = 0x20;
			mask = 0x20;
		snd_soc_update_bits(codec, reg, mask, 0x00);
		snd_soc_update_bits(codec, reg, mask, 0x00);
		break;
		break;
	case BOLERO_WCD_EVT_SSR_DOWN:
		wcd937x_reset_low(wcd937x->dev);
		break;
	case BOLERO_WCD_EVT_SSR_UP:
		wcd937x_reset(wcd937x->dev);
		wcd937x_get_logical_addr(wcd937x->tx_swr_dev);
		wcd937x_get_logical_addr(wcd937x->rx_swr_dev);
		regcache_mark_dirty(wcd937x->regmap);
		regcache_sync(wcd937x->regmap);
		/* Initialize MBHC module */
		mbhc = &wcd937x->mbhc->wcd_mbhc;
		ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, codec);
		if (ret) {
			dev_err(codec->dev, "%s: mbhc initialization failed\n",
				__func__);
		} else {
			wcd937x_mbhc_hs_detect(codec, mbhc->mbhc_cfg);
		}
		break;
	default:
	default:
		dev_err(codec->dev, "%s: invalid event %d\n", __func__, event);
		dev_err(codec->dev, "%s: invalid event %d\n", __func__, event);
		break;
		break;
@@ -1923,7 +1963,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wcd937x = {
	},
	},
};
};


int wcd937x_reset(struct device *dev)
static int wcd937x_reset(struct device *dev)
{
{
	struct wcd937x_priv *wcd937x = NULL;
	struct wcd937x_priv *wcd937x = NULL;
	int rc = 0;
	int rc = 0;
@@ -2026,6 +2066,36 @@ static void wcd937x_dt_parse_micbias_info(struct device *dev,
	}
	}
}
}


static int wcd937x_reset_low(struct device *dev)
{
	struct wcd937x_priv *wcd937x = NULL;
	int rc = 0;

	if (!dev)
		return -ENODEV;

	wcd937x = dev_get_drvdata(dev);
	if (!wcd937x)
		return -EINVAL;

	if (!wcd937x->rst_np) {
		dev_err(dev, "%s: reset gpio device node not specified\n",
				__func__);
		return -EINVAL;
	}

	rc = msm_cdc_pinctrl_select_sleep_state(wcd937x->rst_np);
	if (rc) {
		dev_err(dev, "%s: wcd sleep state request fail!\n",
				__func__);
		return rc;
	}
	/* 20ms sleep required after pulling the reset gpio to LOW */
	usleep_range(20, 30);

	return rc;
}

struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev)
struct wcd937x_pdata *wcd937x_populate_dt_data(struct device *dev)
{
{
	struct wcd937x_pdata *pdata = NULL;
	struct wcd937x_pdata *pdata = NULL;
+18 −0
Original line number Original line Diff line number Diff line
@@ -85,6 +85,21 @@ static const struct component_ops wcd937x_slave_comp_ops = {
	.unbind = wcd937x_slave_unbind,
	.unbind = wcd937x_slave_unbind,
};
};


static int wcd937x_swr_up(struct swr_device *pdev)
{
	return 0;
}

static int wcd937x_swr_down(struct swr_device *pdev)
{
	return 0;
}

static int wcd937x_swr_reset(struct swr_device *pdev)
{
	return 0;
}

static int wcd937x_swr_probe(struct swr_device *pdev)
static int wcd937x_swr_probe(struct swr_device *pdev)
{
{
	return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
	return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
@@ -105,6 +120,9 @@ static struct swr_driver wcd937x_slave_driver = {
	.probe = wcd937x_swr_probe,
	.probe = wcd937x_swr_probe,
	.remove = wcd937x_swr_remove,
	.remove = wcd937x_swr_remove,
	.id_table = wcd937x_swr_id,
	.id_table = wcd937x_swr_id,
	.device_up = wcd937x_swr_up,
	.device_down = wcd937x_swr_down,
	.reset_device = wcd937x_swr_reset,
};
};


static int __init wcd937x_slave_init(void)
static int __init wcd937x_slave_init(void)