diff options
author | Amit Bhanagay <amitbhanagay@google.com> | 2022-10-31 06:59:28 +0000 |
---|---|---|
committer | Amit Bhanagay <amitbhanagay@google.com> | 2022-11-13 06:09:43 +0000 |
commit | 976ddbbda2f7c3d9409788c7a13300a4959291d5 (patch) | |
tree | 333e51fb33cde0015ed4ea098b52317e5af24a60 /ots_pat9126 | |
parent | bc1c07d307aada992290ddcf0b974dfd433b3df2 (diff) | |
download | rotary-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.c | 123 |
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; } |