From c4e96121c5c917b8d44c037f46ce597208853369 Mon Sep 17 00:00:00 2001 From: Aditya Bavanari Date: Wed, 14 Nov 2018 14:46:38 +0530 Subject: [PATCH] asoc: bolero: Add support to register wake irq Add reg_wake_irq macro callback and issue an event from Tx macro to Tx sound wire master instance in order to register for wake irq and to handle the ipc wake up interrupt. Change-Id: Iefddc1f85173ce267c0b00c9d06be3a4a2fe29fe Signed-off-by: Aditya Bavanari --- asoc/codecs/bolero/bolero-cdc.c | 37 +++++++++++++++++++++++++++++++++ asoc/codecs/bolero/bolero-cdc.h | 11 +++++++++- asoc/codecs/bolero/tx-macro.c | 19 +++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c index d6a196b6c830..a0822ebdec0c 100644 --- a/asoc/codecs/bolero/bolero-cdc.c +++ b/asoc/codecs/bolero/bolero-cdc.c @@ -344,6 +344,9 @@ int bolero_register_macro(struct device *dev, u16 macro_id, priv->macro_params[macro_id].dev = dev; priv->current_mclk_mux_macro[macro_id] = bolero_mclk_mux_tbl[macro_id][MCLK_MUX0]; + if (macro_id == TX_MACRO) + priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq; + priv->num_dais += ops->num_dais; priv->num_macros_registered++; priv->macros_supported[macro_id] = true; @@ -403,6 +406,9 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id) priv->macro_params[macro_id].mclk_fn = NULL; priv->macro_params[macro_id].event_handler = NULL; priv->macro_params[macro_id].dev = NULL; + if (macro_id == TX_MACRO) + priv->macro_params[macro_id].reg_wake_irq = NULL; + priv->num_dais -= priv->macro_params[macro_id].num_dais; priv->num_macros_registered--; @@ -663,6 +669,37 @@ int bolero_info_create_codec_entry(struct snd_info_entry *codec_root, } EXPORT_SYMBOL(bolero_info_create_codec_entry); +/** + * bolero_register_wake_irq - Register wake irq of Tx macro + * + * @codec: codec ptr. + * @ipc_wakeup: bool to identify ipc_wakeup to be used or HW interrupt line. + * + * Return: 0 on success or negative error code on failure. + */ +int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 ipc_wakeup) +{ + struct bolero_priv *priv = NULL; + + if (!codec) + return -EINVAL; + + priv = snd_soc_codec_get_drvdata(codec); + if (!priv) + return -EINVAL; + + if (!bolero_is_valid_codec_dev(priv->dev)) { + dev_err(codec->dev, "%s: invalid codec\n", __func__); + return -EINVAL; + } + + if (priv->macro_params[TX_MACRO].reg_wake_irq) + priv->macro_params[TX_MACRO].reg_wake_irq(codec, ipc_wakeup); + + return 0; +} +EXPORT_SYMBOL(bolero_register_wake_irq); + static int bolero_soc_codec_probe(struct snd_soc_codec *codec) { struct bolero_priv *priv = dev_get_drvdata(codec->dev); diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h index aa524918e64f..36d17f5ab521 100644 --- a/asoc/codecs/bolero/bolero-cdc.h +++ b/asoc/codecs/bolero/bolero-cdc.h @@ -45,7 +45,8 @@ enum { BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */ BOLERO_MACRO_EVT_SSR_DOWN, BOLERO_MACRO_EVT_SSR_UP, - BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET + BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET, + BOLERO_MACRO_EVT_REG_WAKE_IRQ }; struct macro_ops { @@ -57,6 +58,7 @@ struct macro_ops { int (*mclk_fn)(struct device *dev, bool enable); int (*event_handler)(struct snd_soc_codec *codec, u16 event, u32 data); + int (*reg_wake_irq)(struct snd_soc_codec *codec, u32 data); char __iomem *io_base; }; @@ -71,6 +73,7 @@ int bolero_request_clock(struct device *dev, u16 macro_id, int bolero_info_create_codec_entry( struct snd_info_entry *codec_root, struct snd_soc_codec *codec); +int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data); void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n); #else static inline int bolero_register_macro(struct device *dev, @@ -107,5 +110,11 @@ static int bolero_info_create_codec_entry( static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n) { } + +static inline int bolero_register_wake_irq(struct snd_soc_codec *codec, + u32 data) +{ + return 0; +} #endif /* CONFIG_SND_SOC_BOLERO */ #endif /* BOLERO_CDC_H */ diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index a16f778de4d3..e58cbd5c989e 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -331,6 +331,24 @@ static int tx_macro_event_handler(struct snd_soc_codec *codec, u16 event, return 0; } +static int tx_macro_reg_wake_irq(struct snd_soc_codec *codec, + u32 data) +{ + struct device *tx_dev = NULL; + struct tx_macro_priv *tx_priv = NULL; + u32 ipc_wakeup = data; + int ret = 0; + + if (!tx_macro_get_data(codec, &tx_dev, &tx_priv, __func__)) + return -EINVAL; + + ret = swrm_wcd_notify( + tx_priv->swr_ctrl_data[0].tx_swr_pdev, + SWR_REGISTER_WAKE_IRQ, &ipc_wakeup); + + return ret; +} + static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) { struct delayed_work *hpf_delayed_work = NULL; @@ -1683,6 +1701,7 @@ static void tx_macro_init_ops(struct macro_ops *ops, ops->num_dais = ARRAY_SIZE(tx_macro_dai); ops->mclk_fn = tx_macro_mclk_ctrl; ops->event_handler = tx_macro_event_handler; + ops->reg_wake_irq = tx_macro_reg_wake_irq; } static int tx_macro_probe(struct platform_device *pdev)