Browse Source

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 <[email protected]>
Aditya Bavanari 6 years ago
parent
commit
c4e96121c5
3 changed files with 66 additions and 1 deletions
  1. 37 0
      asoc/codecs/bolero/bolero-cdc.c
  2. 10 1
      asoc/codecs/bolero/bolero-cdc.h
  3. 19 0
      asoc/codecs/bolero/tx-macro.c

+ 37 - 0
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);

+ 10 - 1
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 */

+ 19 - 0
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)