瀏覽代碼

touch: Add panel event notifier support

Add panel event notifier support for parade
tech driver.

Change-Id: I347f9805b19bcd03b23a8ad34130dc1f5b05b3e8
Signed-off-by: Surya Teja Kudiri <[email protected]>
Surya Teja Kudiri 2 年之前
父節點
當前提交
e74f386766
共有 2 個文件被更改,包括 202 次插入35 次删除
  1. 196 33
      pt/pt_core.c
  2. 6 2
      pt/pt_regs.h

+ 196 - 33
pt/pt_core.c

@@ -32,7 +32,9 @@
 #include <linux/kthread.h>
 #include <linux/suspend.h>
 #include "pt_regs.h"
+#if defined(CONFIG_PANEL_NOTIFIER)
 #include <linux/soc/qcom/panel_event_notifier.h>
+#endif
 
 #define PINCTRL_STATE_ACTIVE    "pmx_ts_active"
 #define PINCTRL_STATE_SUSPEND   "pmx_ts_suspend"
@@ -52,7 +54,7 @@
 
 #define PT_STATUS_STR_LEN (50)
 
-#if defined(CONFIG_DRM)
+#if defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
 static struct drm_panel *active_panel;
 #endif
 
@@ -12791,21 +12793,19 @@ static void pt_suspend_work(struct work_struct *work)
 	return;
 }
 
+#if defined(CONFIG_PANEL_NOTIFIER)
 /*******************************************************************************
- * FUNCTION: drm_notifier_callback
+ * FUNCTION: panel_event_notifier_callback
  *
- * SUMMARY: Call back function for DRM notifier to allow to call
+ * SUMMARY: Call back function for Panel Event notifier to allow to call
  * resume/suspend attention list.
  *
- * RETURN:
- *   0 = success
- *
  * PARAMETERS:
- *  *self   - pointer to notifier_block structure
- *   event  - event type of fb notifier
- *  *data   - pointer to fb_event structure
+ *   tag           - type of input panel.
+ *  *notification  - pointer to notification details.
+ *  *client_data   - pointer to core data
  ******************************************************************************/
-static void drm_notifier_callback(enum panel_event_notifier_tag tag,
+static void panel_event_notifier_callback(enum panel_event_notifier_tag tag,
 		struct panel_event_notification *notification, void *client_data)
 {
 	struct pt_core_data *cd = client_data;
@@ -12817,14 +12817,6 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
 	}
 
 	pt_debug(cd->dev, DL_INFO, "%s: DRM notifier called!\n", __func__);
-
-	if (!(notification->notif_type == DRM_PANEL_EVENT_BLANK ||
-		notification->notif_type == DRM_PANEL_EVENT_BLANK)) {
-		pt_debug(cd->dev, DL_INFO, "%s: Event(%d) do not need process\n",
-			__func__, notification->notif_type);
-		goto exit;
-	}
-
 	if (cd->quick_boot || cd->drv_debug_suspend)
 		goto exit;
 
@@ -12835,10 +12827,167 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
 
 	if (notification->notif_type == DRM_PANEL_EVENT_UNBLANK) {
 		pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__);
-		if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
+		if (notification->notif_data.early_trigger) {
+			pr_err("%s: resume: event = %d, not care\n", __func__, notification->notif_type);
 			pt_debug(cd->dev, DL_INFO, "%s: resume: event = %d, not care\n",
 				__func__, notification->notif_type);
-		} else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
+		} else {
+				pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
+					__func__);
+				cancel_work_sync(&cd->resume_offload_work);
+				cancel_work_sync(&cd->suspend_offload_work);
+				cancel_work_sync(&cd->resume_work);
+				cancel_work_sync(&cd->suspend_work);
+
+				queue_work(cd->pt_workqueue, &cd->resume_work);
+#if defined(CONFIG_PM_SLEEP)
+				pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
+					__func__);
+				if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
+					pt_core_resume_(cd->dev);
+#endif
+				cd->fb_state = FB_ON;
+				pt_debug(cd->dev, DL_INFO, "%s: Resume notified!\n", __func__);
+		}
+	} else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
+		pt_debug(cd->dev, DL_INFO, "%s: BLANK!\n", __func__);
+		if (notification->notif_data.early_trigger) {
+#if defined(CONFIG_PM_SLEEP)
+			pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n",
+				__func__);
+			if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
+				pt_core_suspend_(cd->dev);
+#endif
+			cancel_work_sync(&cd->resume_offload_work);
+			cancel_work_sync(&cd->suspend_offload_work);
+			cancel_work_sync(&cd->resume_work);
+			cancel_work_sync(&cd->suspend_work);
+
+			queue_work(cd->pt_workqueue, &cd->suspend_work);
+			cd->fb_state = FB_OFF;
+			pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
+		} else {
+			pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
+				__func__, notification->notif_type);
+		}
+	} else if (notification->notif_type == DRM_PANEL_EVENT_BLANK_LP) {
+		pt_debug(cd->dev, DL_INFO, "%s: LOWPOWER!\n", __func__);
+                if (notification->notif_data.early_trigger) {
+#if defined(CONFIG_PM_SLEEP)
+			pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n", __func__);
+			if (cd->cpdata->flags & PT_CORE_FLAG_SKIP_RUNTIME)
+				pt_core_suspend_(cd->dev);
+#endif
+			cancel_work_sync(&cd->resume_offload_work);
+			cancel_work_sync(&cd->suspend_offload_work);
+			cancel_work_sync(&cd->resume_work);
+			cancel_work_sync(&cd->suspend_work);
+
+			queue_work(cd->pt_workqueue, &cd->suspend_work);
+			cd->fb_state = FB_OFF;
+			pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
+		} else {
+			pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
+                                __func__, notification->notif_type);
+		}
+
+	} else {
+		pt_debug(cd->dev, DL_INFO, "%s: DRM BLANK(%d) do not need process\n",
+			__func__, notification->notif_type);
+	}
+exit:
+	return;
+}
+
+/*******************************************************************************
+ * FUNCTION: pt_setup_panel_event_notifier
+ *
+ * SUMMARY: Set up call back function into drm notifier.
+ *
+ * PARAMETERS:
+ *  *cd   - pointer to core data
+ ******************************************************************************/
+static void pt_setup_panel_event_notifier(struct pt_core_data *cd)
+{
+	void *cookie = NULL;
+
+	if (!active_panel)
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: Active panel not registered!\n", __func__);
+
+	cd->pt_workqueue = create_singlethread_workqueue("ts_wq");
+	if (!cd->pt_workqueue) {
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: worker thread creation failed !\n", __func__);
+	}
+
+	if (cd->pt_workqueue) {
+		INIT_WORK(&cd->resume_work, pt_resume_work);
+		INIT_WORK(&cd->suspend_work, pt_suspend_work);
+	}
+
+
+	cookie = panel_event_notifier_register(PANEL_EVENT_NOTIFICATION_PRIMARY,
+			PANEL_EVENT_NOTIFIER_CLIENT_PRIMARY_TOUCH,
+			active_panel,&panel_event_notifier_callback, cd);
+
+	if (active_panel && !cookie)
+	{
+		pt_debug(cd->dev, DL_ERROR,
+				"%s: Register notifier failed!\n", __func__);
+	}
+}
+#else
+
+/*******************************************************************************
+ * FUNCTION: drm_notifier_callback
+ *
+ * SUMMARY: Call back function for DRM notifier to allow to call
+ * resume/suspend attention list.
+ *
+ * RETURN:
+ *   0 = success
+ *
+ * PARAMETERS:
+ *  *self   - pointer to notifier_block structure
+ *   event  - event type of fb notifier
+ *  *data   - pointer to fb_event structure
+ ******************************************************************************/
+static int drm_notifier_callback(struct notifier_block *self,
+		unsigned long event, void *data)
+{
+	struct pt_core_data *cd =
+		container_of(self, struct pt_core_data, fb_notifier);
+	struct drm_panel_notifier *evdata = data;
+	int *blank;
+
+	pt_debug(cd->dev, DL_INFO, "%s: DRM notifier called!\n", __func__);
+
+	if (!evdata)
+		goto exit;
+
+	if (!(event == DRM_PANEL_EARLY_EVENT_BLANK ||
+		event == DRM_PANEL_EVENT_BLANK)) {
+		pt_debug(cd->dev, DL_INFO, "%s: Event(%lu) do not need process\n",
+			__func__, event);
+		goto exit;
+	}
+
+	if (cd->quick_boot || cd->drv_debug_suspend)
+		goto exit;
+
+	blank = evdata->data;
+	pt_debug(cd->dev, DL_INFO, "%s: DRM event:%lu,blank:%d fb_state %d sleep state %d ",
+		__func__, event, *blank, cd->fb_state, cd->sleep_state);
+	pt_debug(cd->dev, DL_INFO, "%s: DRM Power - %s - FB state %d ",
+		__func__, (*blank == DRM_PANEL_BLANK_UNBLANK)?"UP":"DOWN", cd->fb_state);
+
+	if (*blank == DRM_PANEL_BLANK_UNBLANK) {
+		pt_debug(cd->dev, DL_INFO, "%s: UNBLANK!\n", __func__);
+		if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
+			pt_debug(cd->dev, DL_INFO, "%s: resume: event = %lu, not care\n",
+				__func__, event);
+		} else if (event == DRM_PANEL_EVENT_BLANK) {
 			if (cd->fb_state != FB_ON) {
 				pt_debug(cd->dev, DL_INFO, "%s: Resume notifier called!\n",
 					__func__);
@@ -12858,9 +13007,9 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
 				pt_debug(cd->dev, DL_INFO, "%s: Resume notified!\n", __func__);
 			}
 		}
-	} else if (notification->notif_type == DRM_PANEL_EVENT_BLANK_LP) {
+	} else if (*blank == DRM_PANEL_BLANK_LP || *blank == DRM_PANEL_BLANK_POWERDOWN) {
 		pt_debug(cd->dev, DL_INFO, "%s: LOWPOWER!\n", __func__);
-		if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
+		if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
 			if (cd->fb_state != FB_OFF) {
 #if defined(CONFIG_PM_SLEEP)
 				pt_debug(cd->dev, DL_INFO, "%s: Suspend notifier called!\n",
@@ -12877,16 +13026,17 @@ static void drm_notifier_callback(enum panel_event_notifier_tag tag,
 				cd->fb_state = FB_OFF;
 				pt_debug(cd->dev, DL_INFO, "%s: Suspend notified!\n", __func__);
 			}
-		} else if (notification->notif_type == DRM_PANEL_EVENT_BLANK) {
-			pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %d, not care\n",
-				__func__, notification->notif_type);
+
+		} else if (event == DRM_PANEL_EVENT_BLANK) {
+			pt_debug(cd->dev, DL_INFO, "%s: suspend: event = %lu, not care\n",
+				__func__, event);
 		}
 	} else {
 		pt_debug(cd->dev, DL_INFO, "%s: DRM BLANK(%d) do not need process\n",
-			__func__, notification->notif_type);
+			__func__, *blank);
 	}
 exit:
-	return;
+	return 0;
 }
 
 /*******************************************************************************
@@ -12899,7 +13049,9 @@ exit:
  ******************************************************************************/
 static void pt_setup_drm_notifier(struct pt_core_data *cd)
 {
-	void *cookie = NULL;
+	cd->fb_state = FB_NONE;
+	cd->fb_notifier.notifier_call = drm_notifier_callback;
+	pt_debug(cd->dev, DL_INFO, "%s: Setting up drm notifier\n", __func__);
 
 	if (!active_panel)
 		pt_debug(cd->dev, DL_ERROR,
@@ -12916,10 +13068,13 @@ static void pt_setup_drm_notifier(struct pt_core_data *cd)
 		INIT_WORK(&cd->suspend_work, pt_suspend_work);
 	}
 
-	cookie = panel_event_notifier_register(PANEL_EVENT_NOTIFICATION_PRIMARY,
-			PANEL_EVENT_NOTIFIER_CLIENT_PRIMARY_TOUCH,
-			active_panel,&drm_notifier_callback, cd);
+	if (active_panel &&
+		drm_panel_notifier_register(active_panel,
+			&cd->fb_notifier) < 0)
+		pt_debug(cd->dev, DL_ERROR,
+			"%s: Register notifier failed!\n", __func__);
 }
+#endif
 #elif defined(CONFIG_FB)
 /*******************************************************************************
  * FUNCTION: fb_notifier_callback
@@ -17600,7 +17755,7 @@ int pt_probe(const struct pt_bus_ops *ops, struct device *dev,
 	/* Set platform easywake value */
 	cd->easy_wakeup_gesture = cd->cpdata->easy_wakeup_gesture;
 
-#ifdef CONFIG_DRM
+#if defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
 	/* Setup active dsi panel */
 	active_panel = cd->cpdata->active_panel;
 #endif
@@ -17846,6 +18001,11 @@ skip_enum:
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	pt_setup_early_suspend(cd);
+#elif defined(CONFIG_PANEL_NOTIFIER)
+	pt_debug(dev, DL_ERROR, "%s: Probe: Setup Panel Event notifier\n", __func__);
+	pt_setup_panel_event_notifier(cd);
+	INIT_WORK(&cd->resume_offload_work, pt_resume_offload_work);
+	INIT_WORK(&cd->suspend_offload_work, pt_suspend_offload_work);
 #elif defined(CONFIG_DRM)
 	pt_debug(dev, DL_ERROR, "%s: Probe: Setup drm notifier\n", __func__);
 	pt_setup_drm_notifier(cd);
@@ -17967,9 +18127,12 @@ int pt_release(struct pt_core_data *cd)
 
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	unregister_early_suspend(&cd->es);
-#elif defined(CONFIG_DRM)
+#elif defined(CONFIG_PANEL_NOTIFIER)
 	if (active_panel)
 		panel_event_notifier_unregister(&cd->fb_notifier);
+#elif defined(CONFIG_DRM)
+	if (active_panel)
+		drm_panel_notifier_unregister(active_panel, &cd->fb_notifier);
 #elif defined(CONFIG_FB)
 	fb_unregister_client(&cd->fb_notifier);
 #endif

+ 6 - 2
pt/pt_regs.h

@@ -45,12 +45,16 @@
 #define CONFIG_DRM
 #endif
 
+#if IS_ENABLED(CONFIG_QCOM_PANEL_EVENT_NOTIFIER)
+#define CONFIG_PANEL_NOTIFIER
+#endif
+
 #include <linux/device.h>
 #include <linux/fb.h>
 #include <linux/notifier.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
 #include <linux/earlysuspend.h>
-#elif defined(CONFIG_DRM)
+#elif defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
 #include <drm/drm_panel.h>
 #endif
 
@@ -1521,7 +1525,7 @@ struct pt_core_data {
 	int raw_cmd_status;
 #ifdef CONFIG_HAS_EARLYSUSPEND
 	struct early_suspend es;
-#elif defined(CONFIG_FB) || defined(CONFIG_DRM)
+#elif defined(CONFIG_FB) || defined(CONFIG_DRM) || defined(CONFIG_PANEL_NOTIFIER)
 	struct notifier_block fb_notifier;
 	enum pt_fb_state fb_state;
 #endif