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:
@@ -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 {
|
||||||
|
@@ -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);
|
||||||
|
@@ -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 = {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user