|
@@ -36,6 +36,8 @@
|
|
|
#include <asm/traps.h>
|
|
|
#include <linux/firmware.h>
|
|
|
#include <linux/of_gpio.h>
|
|
|
+#include <linux/err.h>
|
|
|
+#include <linux/of_device.h>
|
|
|
|
|
|
#if defined(CONFIG_FB)
|
|
|
#include <linux/notifier.h>
|
|
@@ -60,6 +62,10 @@ static int raydium_enable_regulator(struct raydium_ts_data *cd, bool en);
|
|
|
const struct attribute_group raydium_attr_group;
|
|
|
#endif /*end of CONFIG_RM_SYSFS_DEBUG*/
|
|
|
|
|
|
+#if defined(CONFIG_DRM)
|
|
|
+ static struct drm_panel *active_panel;
|
|
|
+#endif
|
|
|
+
|
|
|
unsigned char g_u8_addr;
|
|
|
unsigned char g_u8_raydium_flag;
|
|
|
unsigned char g_u8_i2c_mode;
|
|
@@ -156,7 +162,7 @@ static int raydium_gpio_configure(bool on)
|
|
|
msleep(RAYDIUM_RESET_INTERVAL_10MSEC);
|
|
|
if (i32_err) {
|
|
|
LOGD(LOG_ERR,
|
|
|
- "[touch]set_direction for irq gpio failed\n");
|
|
|
+ "[touch]set_direction for rst gpio failed\n");
|
|
|
goto err_rst_gpio_dir;
|
|
|
}
|
|
|
|
|
@@ -687,14 +693,13 @@ void raydium_irq_control(bool enable)
|
|
|
}
|
|
|
|
|
|
/* Clear interrupts first */
|
|
|
- if (g_raydium_ts->blank != FB_BLANK_POWERDOWN) {
|
|
|
+ if (g_raydium_ts->blank != DRM_PANEL_BLANK_POWERDOWN) {
|
|
|
if (g_u8_i2c_mode == PDA2_MODE) {
|
|
|
mutex_lock(&g_raydium_ts->lock);
|
|
|
if (raydium_i2c_pda2_set_page(g_raydium_ts->client,
|
|
|
- g_raydium_ts->is_suspend,
|
|
|
- RAYDIUM_PDA2_PAGE_0) < 0)
|
|
|
- LOGD(LOG_ERR, "[touch]set page fail%s\n",
|
|
|
- __func__);
|
|
|
+ g_raydium_ts->is_suspend,
|
|
|
+ RAYDIUM_PDA2_PAGE_0) < 0)
|
|
|
+ LOGD(LOG_ERR, "[touch]set page fail%s\n", __func__);
|
|
|
mutex_unlock(&g_raydium_ts->lock);
|
|
|
usleep_range(500, 1500);
|
|
|
}
|
|
@@ -1072,7 +1077,7 @@ int raydium_read_touchdata(unsigned char *p_u8_tp_status, unsigned char *p_u8_b
|
|
|
unsigned char u8_retry;
|
|
|
unsigned char u8_read_size;
|
|
|
unsigned char u8_read_buf[MAX_REPORT_PACKET_SIZE];
|
|
|
-
|
|
|
+// int i = 0;
|
|
|
u8_retry = 3;
|
|
|
|
|
|
mutex_lock(&g_raydium_ts->lock);
|
|
@@ -1182,6 +1187,10 @@ static void raydium_work_handler(struct work_struct *work)
|
|
|
|
|
|
#ifdef GESTURE_EN
|
|
|
unsigned char u8_i;
|
|
|
+ LOGD(LOG_DEBUG, "[touch]ts->blank:%x, g_u8_i2c_mode:%x\n",
|
|
|
+ g_raydium_ts->blank, g_u8_i2c_mode);
|
|
|
+ LOGD(LOG_DEBUG, "[touch]u8_tp_status:%x, g_raydium_ts->is_palm:%x\n",
|
|
|
+ u8_tp_status[POS_GES_STATUS], g_raydium_ts->is_palm);
|
|
|
|
|
|
if (g_u8_i2c_mode == PDA2_MODE) {
|
|
|
i32_ret = raydium_read_touchdata(u8_tp_status, u8_buf);
|
|
@@ -1192,7 +1201,7 @@ static void raydium_work_handler(struct work_struct *work)
|
|
|
}
|
|
|
}
|
|
|
/*when display on can use palm to suspend*/
|
|
|
- if (g_raydium_ts->blank == FB_BLANK_UNBLANK) {
|
|
|
+ if (g_raydium_ts->blank == DRM_PANEL_BLANK_UNBLANK) {
|
|
|
if (u8_tp_status[POS_GES_STATUS] == RAD_PALM_ENABLE) {
|
|
|
if (g_raydium_ts->is_palm == 0) {
|
|
|
/* release all touches*/
|
|
@@ -1230,11 +1239,15 @@ static void raydium_work_handler(struct work_struct *work)
|
|
|
g_raydium_ts->is_palm = 0;
|
|
|
/*goto exit;*/
|
|
|
}
|
|
|
- } else if (g_raydium_ts->blank == FB_BLANK_VSYNC_SUSPEND ||
|
|
|
- g_raydium_ts->blank == FB_BLANK_POWERDOWN) {
|
|
|
+ }
|
|
|
+ //else if (g_raydium_ts->blank == DRM_PANEL_BLANK_LP ||
|
|
|
+ // g_raydium_ts->blank == DRM_PANEL_BLANK_POWERDOWN)
|
|
|
+ {
|
|
|
+ LOGD(LOG_INFO, "[touch] elseif u8_tp_status:%x\n", u8_tp_status[POS_GES_STATUS]);
|
|
|
/*need check small area*/
|
|
|
- if (u8_tp_status[POS_GES_STATUS] == RAD_WAKE_UP
|
|
|
- && g_u8_wakeup_flag == false) {
|
|
|
+ //if (u8_tp_status[POS_GES_STATUS] == RAD_WAKE_UP
|
|
|
+ // && g_u8_wakeup_flag == false) {
|
|
|
+ if (u8_tp_status[POS_GES_STATUS] == 0) {
|
|
|
input_report_key(g_raydium_ts->input_dev, KEY_POWER, true);
|
|
|
usleep_range(9500, 10500);
|
|
|
input_sync(g_raydium_ts->input_dev);
|
|
@@ -1341,7 +1354,7 @@ exit_error:
|
|
|
static void raydium_ts_do_suspend(void)
|
|
|
{
|
|
|
unsigned char u8_i = 0;
|
|
|
- int rc;
|
|
|
+ int rc = 0;
|
|
|
|
|
|
if (g_u8_raw_data_type == 0)
|
|
|
g_u8_resetflag = false;
|
|
@@ -1353,11 +1366,10 @@ static void raydium_ts_do_suspend(void)
|
|
|
rc = raydium_enable_regulator(g_raydium_ts, false);
|
|
|
if (rc < 0) {
|
|
|
LOGD(LOG_ERR, "[touch]%s:Failed to disable regulators:rc=%d\n",
|
|
|
- __func__, rc);
|
|
|
+ __func__, rc);
|
|
|
}
|
|
|
LOGD(LOG_INFO, "[touch]%s:voltage regulators disabled:rc=%d\n",
|
|
|
- __func__, rc);
|
|
|
-
|
|
|
+ __func__, rc);
|
|
|
/*#ifndef GESTURE_EN*/
|
|
|
raydium_irq_control(DISABLE);
|
|
|
/*#endif*/
|
|
@@ -1399,6 +1411,7 @@ static void raydium_ts_do_resume(void)
|
|
|
int i32_ret = 0;
|
|
|
unsigned char u8_retry = 0;
|
|
|
#endif
|
|
|
+ int rc = 0;
|
|
|
|
|
|
|
|
|
LOGD(LOG_INFO, "[touch]%s, %d.\n", __func__, g_raydium_ts->is_suspend);
|
|
@@ -1438,13 +1451,14 @@ static void raydium_ts_do_resume(void)
|
|
|
g_u8_checkflag = false;
|
|
|
}
|
|
|
#endif
|
|
|
+
|
|
|
rc = raydium_enable_regulator(g_raydium_ts, true);
|
|
|
if (rc < 0) {
|
|
|
- LOGD(LOG_ERR, "[touch]%s:Failed to disable regulators:rc=%d\n",
|
|
|
- __func__, rc);
|
|
|
- }
|
|
|
- LOGD(LOG_INFO, "[touch]%s:voltage regulators disabled:rc=%d\n",
|
|
|
+ LOGD(LOG_ERR, "[touch]%s: failed to enable regulators: rc=%d\n",
|
|
|
__func__, rc);
|
|
|
+ }
|
|
|
+ LOGD(LOG_INFO, "[touch]%s: voltage regulators enabled: rc=%d\n",
|
|
|
+ __func__, rc);
|
|
|
raydium_irq_control(ENABLE);
|
|
|
#ifdef GESTURE_EN
|
|
|
if (device_may_wakeup(&g_raydium_ts->client->dev)) {
|
|
@@ -1571,6 +1585,121 @@ static int raydium_ts_resume(struct device *dev)
|
|
|
}
|
|
|
#endif /*end of CONFIG_FB*/
|
|
|
|
|
|
+
|
|
|
+#if defined(CONFIG_DRM)
|
|
|
+/*******************************************************************************
|
|
|
+ * 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 raydium_ts_data *g_raydium_ts =
|
|
|
+ container_of(self, struct raydium_ts_data, fb_notif);
|
|
|
+ struct drm_panel_notifier *evdata = data;
|
|
|
+ int *blank;
|
|
|
+
|
|
|
+ LOGD(LOG_INFO, "%s: DRM notifier called!\n", __func__);
|
|
|
+
|
|
|
+ if (!evdata)
|
|
|
+ goto exit;
|
|
|
+
|
|
|
+ if (!(event == DRM_PANEL_EARLY_EVENT_BLANK ||
|
|
|
+ event == DRM_PANEL_EVENT_BLANK)) {
|
|
|
+ LOGD(LOG_INFO, "%s: Event(%lu) do not need process\n",
|
|
|
+ __func__, event);
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ blank = evdata->data;
|
|
|
+ LOGD(LOG_INFO, "%s: DRM event:%lu,blank:%d fb_state %d ",
|
|
|
+ __func__, event, *blank, g_raydium_ts->fb_state);
|
|
|
+ LOGD(LOG_INFO, "%s: DRM Power - %s - FB state %d ",
|
|
|
+ __func__, (*blank == DRM_PANEL_BLANK_UNBLANK)?"UP":"DOWN", g_raydium_ts->fb_state);
|
|
|
+
|
|
|
+ if (*blank == DRM_PANEL_BLANK_UNBLANK) {
|
|
|
+ LOGD(LOG_INFO, "%s: UNBLANK!\n", __func__);
|
|
|
+
|
|
|
+ if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
|
|
|
+ LOGD(LOG_INFO, "%s: resume: event = %lu, not care\n",
|
|
|
+ __func__, event);
|
|
|
+ } else if (event == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ if (g_raydium_ts->fb_state != FB_ON) {
|
|
|
+ LOGD(LOG_INFO, "%s: Resume notifier called!\n",
|
|
|
+ __func__);
|
|
|
+
|
|
|
+#if defined(CONFIG_PM)
|
|
|
+ raydium_ts_resume(&g_raydium_ts->client->dev);
|
|
|
+#endif
|
|
|
+ g_raydium_ts->fb_state = FB_ON;
|
|
|
+ LOGD(LOG_INFO, "%s: Resume notified!\n", __func__);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (*blank == DRM_PANEL_BLANK_LP || *blank == DRM_PANEL_BLANK_POWERDOWN) {
|
|
|
+ LOGD(LOG_INFO, "%s: LOWPOWER!\n", __func__);
|
|
|
+ if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
|
|
|
+ if (g_raydium_ts->fb_state != FB_OFF) {
|
|
|
+ LOGD(LOG_INFO, "%s: Suspend notifier called!\n",
|
|
|
+ __func__);
|
|
|
+#if defined(CONFIG_PM)
|
|
|
+ raydium_ts_suspend(&g_raydium_ts->client->dev);
|
|
|
+#endif
|
|
|
+ g_raydium_ts->fb_state = FB_OFF;
|
|
|
+ LOGD(LOG_INFO, "%s: Suspend notified!\n", __func__);
|
|
|
+ }
|
|
|
+ } else if (event == DRM_PANEL_EVENT_BLANK) {
|
|
|
+ LOGD(LOG_INFO, "%s: suspend: event = %lu, not care\n",
|
|
|
+ __func__, event);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ LOGD(LOG_INFO, "%s: DRM BLANK(%d) do not need process\n",
|
|
|
+ __func__, *blank);
|
|
|
+ }
|
|
|
+exit:
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ * FUNCTION: raydium_setup_drm_notifier
|
|
|
+ *
|
|
|
+ * SUMMARY: Set up call back function into drm notifier.
|
|
|
+ *
|
|
|
+ * PARAMETERS:
|
|
|
+ * g_raydium_ts - pointer to core data
|
|
|
+ *******************************************************************************/
|
|
|
+static void raydium_setup_drm_notifier(struct raydium_ts_data *g_raydium_ts)
|
|
|
+{
|
|
|
+ g_raydium_ts->fb_state = FB_ON;
|
|
|
+ g_raydium_ts->fb_notif.notifier_call = drm_notifier_callback;
|
|
|
+ LOGD(LOG_INFO, "%s: Setting up drm notifier\n", __func__);
|
|
|
+
|
|
|
+ if (!active_panel)
|
|
|
+ LOGD(LOG_ERR, "%s: Active panel not registered!\n", __func__);
|
|
|
+
|
|
|
+ if (active_panel && drm_panel_notifier_register(active_panel,
|
|
|
+ &g_raydium_ts->fb_notif) < 0)
|
|
|
+ LOGD(LOG_ERR, "%s: Register notifier failed!\n", __func__);
|
|
|
+}
|
|
|
+#endif /*end of CONFIG_DRM*/
|
|
|
+
|
|
|
+/*******************************************************************************
|
|
|
+ * FUNCTION: raydium_setup_drm_notifier
|
|
|
+ *
|
|
|
+ * SUMMARY: Set up call back function into fb notifier.
|
|
|
+ *
|
|
|
+ * PARAMETERS:
|
|
|
+ * g_raydium_ts - pointer to core data
|
|
|
+ *******************************************************************************/
|
|
|
#if defined(CONFIG_FB)
|
|
|
static int fb_notifier_callback(struct notifier_block *self,
|
|
|
unsigned long event,
|
|
@@ -1699,10 +1828,55 @@ static int raydium_get_dt_coords(struct device *dev, char *name,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*******************************************************************************
|
|
|
+ * FUNCTION: raydium_check_dsi_panel_dt
|
|
|
+ *
|
|
|
+ * SUMMARY: Get the DSI active panel information from dtsi
|
|
|
+ *
|
|
|
+ * RETURN:
|
|
|
+ * 0 = success
|
|
|
+ * !0 = fail
|
|
|
+ *
|
|
|
+ * PARAMETERS:
|
|
|
+ * np - pointer to device_node structure
|
|
|
+ * active_panel - name of active DSI panel
|
|
|
+ ******************************************************************************/
|
|
|
+
|
|
|
+static int raydium_check_dsi_panel_dt(struct device_node *np, struct drm_panel **active_panel)
|
|
|
+{
|
|
|
+ int i = 0;
|
|
|
+ int count = 0;
|
|
|
+ struct device_node *node = NULL;
|
|
|
+ struct drm_panel *panel = NULL;
|
|
|
+
|
|
|
+ count = of_count_phandle_with_args(np, "panel", NULL);
|
|
|
+ pr_info("%s: Active panel count: %d\n", __func__, count);
|
|
|
+ if (count <= 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ for (i = 0; i < count; i++) {
|
|
|
+ node = of_parse_phandle(np, "panel", i);
|
|
|
+
|
|
|
+ if (node != NULL)
|
|
|
+ pr_info("%s: Node handle successfully parsed !\n", __func__);
|
|
|
+ panel = of_drm_find_panel(node);
|
|
|
+ of_node_put(node);
|
|
|
+
|
|
|
+ if (!IS_ERR(panel)) {
|
|
|
+ pr_info("%s: Active panel selected !\n", __func__);
|
|
|
+ *active_panel = panel;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pr_err("%s: Active panel NOT selected !\n", __func__);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int raydium_parse_dt(struct device *dev,
|
|
|
struct raydium_ts_platform_data *pdata)
|
|
|
{
|
|
|
struct device_node *np = dev->of_node;
|
|
|
+ struct drm_panel *active_panel = NULL;
|
|
|
int rc = 0;
|
|
|
u32 temp_val = 0;
|
|
|
|
|
@@ -1731,6 +1905,17 @@ static int raydium_parse_dt(struct device *dev,
|
|
|
if ((s32)(pdata->irq_gpio) < 0)
|
|
|
return pdata->irq_gpio;
|
|
|
|
|
|
+ rc = raydium_check_dsi_panel_dt(np, &active_panel);
|
|
|
+ pr_info("%s: Panel not selected, rc=%d\n", __func__, rc);
|
|
|
+ if (rc) {
|
|
|
+ pr_err("%s: Panel not selected, rc=%d\n", __func__, rc);
|
|
|
+ if (rc == -EPROBE_DEFER) {
|
|
|
+ pr_err("%s: Probe defer selected, rc=%d\n", __func__, rc);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pdata->active_panel = active_panel;
|
|
|
+ pr_info("%s: Successful insert of active panel in core data\n", __func__);
|
|
|
|
|
|
rc = of_property_read_u32(np,
|
|
|
"raydium,hard-reset-delay-ms", &temp_val);
|
|
@@ -1844,7 +2029,6 @@ exit_error:
|
|
|
mutex_unlock(&g_raydium_ts->lock);
|
|
|
return i32_ret;
|
|
|
}
|
|
|
-
|
|
|
static int raydium_get_regulator(struct raydium_ts_data *cd, bool get)
|
|
|
{
|
|
|
int rc;
|
|
@@ -1966,9 +2150,8 @@ exit:
|
|
|
#endif
|
|
|
return rc;
|
|
|
}
|
|
|
-
|
|
|
static int raydium_ts_probe(struct i2c_client *client,
|
|
|
- const struct i2c_device_id *id)
|
|
|
+ const struct i2c_device_id *id)
|
|
|
{
|
|
|
struct raydium_ts_platform_data *pdata =
|
|
|
(struct raydium_ts_platform_data *)client->dev.platform_data;
|
|
@@ -2078,7 +2261,10 @@ static int raydium_ts_probe(struct i2c_client *client,
|
|
|
ret = -EPROBE_DEFER;
|
|
|
goto exit_check_i2c;
|
|
|
}
|
|
|
-
|
|
|
+#ifdef CONFIG_DRM
|
|
|
+ /* Setup active dsi panel */
|
|
|
+ active_panel = pdata->active_panel;
|
|
|
+#endif
|
|
|
/*input device initialization*/
|
|
|
input_dev = input_allocate_device();
|
|
|
if (!input_dev) {
|
|
@@ -2127,6 +2313,11 @@ static int raydium_ts_probe(struct i2c_client *client,
|
|
|
LOGD(LOG_DEBUG, "[touch]client irq : %d, pdata flags : %d\n",
|
|
|
client->irq, pdata->irqflags);
|
|
|
|
|
|
+#if defined(CONFIG_DRM)
|
|
|
+ LOGD(LOG_DEBUG, "%s: Probe: Setup drm notifier\n", __func__);
|
|
|
+ raydium_setup_drm_notifier(g_raydium_ts);
|
|
|
+#endif/*end of CONFIG_DRM*/
|
|
|
+
|
|
|
g_raydium_ts->irq = gpio_to_irq(pdata->irq_gpio);
|
|
|
ret = request_threaded_irq(g_raydium_ts->irq, NULL, raydium_ts_interrupt,
|
|
|
IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_SUSPEND,
|
|
@@ -2191,11 +2382,11 @@ exit_check_i2c:
|
|
|
gpio_free(pdata->irq_gpio);
|
|
|
|
|
|
err_gpio_req:
|
|
|
- raydium_get_regulator(g_raydium_ts, false);
|
|
|
+ raydium_enable_regulator(g_raydium_ts, false);
|
|
|
+
|
|
|
error_get_regulator:
|
|
|
raydium_get_regulator(g_raydium_ts, false);
|
|
|
error_alloc_data:
|
|
|
-
|
|
|
parse_dt_failed:
|
|
|
exit_check_functionality_failed:
|
|
|
return ret;
|
|
@@ -2209,6 +2400,9 @@ static int raydium_ts_remove(struct i2c_client *client)
|
|
|
raydium_unregister_notifier();
|
|
|
#elif defined(CONFIG_HAS_EARLYSUSPEND)
|
|
|
unregister_early_suspend(&g_raydium_ts->early_suspend);
|
|
|
+#elif defined(CONFIG_DRM)
|
|
|
+ if (active_panel)
|
|
|
+ drm_panel_notifier_unregister(active_panel, &g_raydium_ts->fb_notifier);
|
|
|
#endif/*end of CONFIG_FB*/
|
|
|
input_unregister_device(g_raydium_ts->input_dev);
|
|
|
input_free_device(g_raydium_ts->input_dev);
|
|
@@ -2231,7 +2425,6 @@ static int raydium_ts_remove(struct i2c_client *client)
|
|
|
|
|
|
raydium_enable_regulator(g_raydium_ts, false);
|
|
|
raydium_get_regulator(g_raydium_ts, false);
|
|
|
- kfree(g_raydium_ts);
|
|
|
|
|
|
i2c_set_clientdata(client, NULL);
|
|
|
return 0;
|