summaryrefslogtreecommitdiff
path: root/ots_pat9126
diff options
context:
space:
mode:
authorAmit Bhanagay <amitbhanagay@google.com>2022-10-31 06:59:28 +0000
committerAmit Bhanagay <amitbhanagay@google.com>2022-11-13 06:09:43 +0000
commit976ddbbda2f7c3d9409788c7a13300a4959291d5 (patch)
tree333e51fb33cde0015ed4ea098b52317e5af24a60 /ots_pat9126
parentbc1c07d307aada992290ddcf0b974dfd433b3df2 (diff)
downloadrotary-encoders-976ddbbda2f7c3d9409788c7a13300a4959291d5.tar.gz
pat9126: Use DRM suspend/resume notifiers
Integrate DRM suspend/resume with crown low power/normal modes. These replace the framebuffer hooks that no longer exist in 5.4. Bug: 254115794 Signed-off-by: Amit Bhanagay <amitbhanagay@google.com> Change-Id: I48355ac8d40274e88938b81ab6dd4edf03ccfd37
Diffstat (limited to 'ots_pat9126')
-rw-r--r--ots_pat9126/pat9126.c123
1 files changed, 91 insertions, 32 deletions
diff --git a/ots_pat9126/pat9126.c b/ots_pat9126/pat9126.c
index ba78f58..288e8f0 100644
--- a/ots_pat9126/pat9126.c
+++ b/ots_pat9126/pat9126.c
@@ -14,17 +14,16 @@
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
#include "pat9126.h"
-#include <linux/fb.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
-
#include <linux/notifier.h>
#include <linux/reboot.h>
-#include<linux/time.h>
+#include <linux/time.h>
#include <linux/rtc.h>
#include <linux/string.h>
+#include <drm/drm_panel.h>
struct pixart_pat9126_data {
struct i2c_client *client;
@@ -46,7 +45,7 @@ struct pixart_pat9126_data {
struct workqueue_struct *workqueue;
struct delayed_work polling_work;
struct delayed_work resume_work;
- struct notifier_block fb_notif;
+ struct notifier_block drm_panel_notif;
struct mutex mtx;
struct regulator *vdd_supply;
struct regulator *vld_supply;
@@ -66,7 +65,11 @@ struct rw_reg_info {
struct rw_reg_info pat9126_reg_info;
/* Declaration of suspend and resume functions */
-static int pat9126_fb_callback(struct notifier_block *nb, unsigned long type, void *arg);
+static struct drm_panel *active_panel;
+static int pat9126_drm_panel_notifier_callback(struct notifier_block *self,
+ unsigned long event,
+ void *data);
+
static int pat9126_display_suspend(struct device *dev);
static int pat9126_display_resume(struct device *dev);
@@ -822,6 +825,31 @@ static int pat9126_parse_dt(struct device *dev,
return 0;
}
+static int pat9126_check_dt(struct device_node *np)
+{
+ int i;
+ int count;
+ struct device_node *node;
+ struct drm_panel *panel;
+
+ count = of_count_phandle_with_args(np, "panel", NULL);
+ if (count <= 0) {
+ return 0;
+ }
+
+ for (i = 0; i < count; i++) {
+ node = of_parse_phandle(np, "panel", i);
+ panel = of_drm_find_panel(node);
+ of_node_put(node);
+ if (!IS_ERR(panel)) {
+ active_panel = panel;
+ return 0;
+ }
+ }
+
+ return PTR_ERR(panel);
+}
+
static int pat9126_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -830,6 +858,17 @@ static int pat9126_i2c_probe(struct i2c_client *client,
struct input_dev *input;
struct device *dev = &client->dev;
+ struct device_node *dp = NULL;
+ dp = client->dev.of_node;
+
+ ret = pat9126_check_dt(dp);
+ if (ret) {
+ if (ret == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ }
+ return -ENODEV;
+ }
+
ret = i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE);
if (ret < 0) {
dev_err(dev, "I2C not supported\n");
@@ -896,13 +935,15 @@ static int pat9126_i2c_probe(struct i2c_client *client,
mutex_init(&data->mtx);
data->state = PAT9126_STATE_ON;
- data->display_mode = FB_BLANK_UNBLANK;
-
- data->fb_notif.notifier_call = pat9126_fb_callback;
- ret = fb_register_client(&data->fb_notif);
-
- if (ret) {
- pr_err("[PAT9126]: Failed to register FB callback\n");
+ data->display_mode = DRM_PANEL_BLANK_UNBLANK;
+ data->drm_panel_notif.notifier_call = pat9126_drm_panel_notifier_callback;
+
+ if (active_panel) {
+ ret = drm_panel_notifier_register(active_panel, &data->drm_panel_notif);
+ if (ret) {
+ dev_err(dev, "register drm_panel_notifier failed, errno:%d\n", ret);
+ goto err_regulators;
+ }
}
INIT_DELAYED_WORK(&data->polling_work, pat9126_work_handler);
@@ -938,41 +979,59 @@ err_regulators:
static int pat9126_i2c_remove(struct i2c_client *client)
{
+ int ret = 0;
+ struct device *dev = &client->dev;
struct pixart_pat9126_data *data = i2c_get_clientdata(client);
+ dev_dbg(dev, "%s\n", __func__);
+ if (data) {
+ if (active_panel) {
+ ret = drm_panel_notifier_unregister(active_panel,
+ &data->drm_panel_notif);
+ if (ret) {
+ dev_dbg(dev, "[PAT9126]: unregister "
+ "drm_panel_notifier failed, "
+ "errno:%d\n", ret);
+ }
+ }
+ }
pat9126_disable_regulators(data);
- return 0;
+ return ret;
}
-static int pat9126_fb_callback(struct notifier_block *nb, unsigned long type, void *arg) {
- struct fb_event *event_data = arg;
+static int pat9126_drm_panel_notifier_callback(struct notifier_block *nb,
+ unsigned long event,
+ void *arg)
+{
+ struct drm_panel_notifier *evdata = arg;
+ int *blank;
struct pixart_pat9126_data *data =
- container_of(nb, struct pixart_pat9126_data, fb_notif);
- struct device *dev = &data->client->dev;
- int *blank_ptr = event_data->data;
- int new_mode;
+ container_of(nb, struct pixart_pat9126_data, drm_panel_notif);
- if (type != FB_EVENT_BLANK) {
+ if (!evdata) {
return 0;
}
- if (!blank_ptr) {
- pr_warn("[PAT9126] 'blank' is NULL\n");
+ if (!(event == DRM_PANEL_EARLY_EVENT_BLANK ||
+ event == DRM_PANEL_EVENT_BLANK)) {
return 0;
}
- new_mode = *blank_ptr;
-
- if (new_mode == FB_BLANK_UNBLANK &&
- data->display_mode != FB_BLANK_UNBLANK) {
- pat9126_display_resume(dev);
- } else if (new_mode != FB_BLANK_UNBLANK &&
- data->display_mode == FB_BLANK_UNBLANK) {
- pat9126_display_suspend(dev);
- }
+ if (evdata->data && data) {
+ blank = evdata->data;
+ if (event == DRM_PANEL_EARLY_EVENT_BLANK) {
+ if ((*blank == DRM_PANEL_BLANK_POWERDOWN) ||
+ (*blank == DRM_PANEL_BLANK_LP)) {
+ pat9126_display_suspend(&data->client->dev);
+ }
+ } else if (event == DRM_PANEL_EVENT_BLANK) {
+ if (*blank == DRM_PANEL_BLANK_UNBLANK) {
+ pat9126_display_resume(&data->client->dev);
+ }
+ }
+ }
- data->display_mode = new_mode;
return 0;
}