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: Rohit kumar <rohitkr@codeaurora.org>
Signed-off-by: Laxminath Kasam <lkasam@codeaurora.org>
This commit is contained in:
Laxminath Kasam
2018-09-22 01:58:18 +05:30
parent fb0d683b37
commit 1aab2c064a
5 changed files with 96 additions and 3 deletions

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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 = {

View File

@@ -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;

View File

@@ -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)