From 071106ecf68c401173c58808b1cf5f68cc50d390 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 05 Jan 2024 08:39:27 +0000
Subject: [PATCH] change wifi driver to cypress
---
kernel/drivers/input/keyboard/snvs_pwrkey.c | 111 ++++++++++++++++++++++++++++++++++---------------------
1 files changed, 69 insertions(+), 42 deletions(-)
diff --git a/kernel/drivers/input/keyboard/snvs_pwrkey.c b/kernel/drivers/input/keyboard/snvs_pwrkey.c
index 4c67cf3..ad8660b 100644
--- a/kernel/drivers/input/keyboard/snvs_pwrkey.c
+++ b/kernel/drivers/input/keyboard/snvs_pwrkey.c
@@ -3,6 +3,7 @@
// Driver for the IMX SNVS ON/OFF Power Key
// Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
+#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -15,18 +16,20 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
-#define SNVS_LPSR_REG 0x4C /* LP Status Register */
-#define SNVS_LPCR_REG 0x38 /* LP Control Register */
-#define SNVS_HPSR_REG 0x14
-#define SNVS_HPSR_BTN BIT(6)
-#define SNVS_LPSR_SPO BIT(18)
-#define SNVS_LPCR_DEP_EN BIT(5)
+#define SNVS_HPVIDR1_REG 0xBF8
+#define SNVS_LPSR_REG 0x4C /* LP Status Register */
+#define SNVS_LPCR_REG 0x38 /* LP Control Register */
+#define SNVS_HPSR_REG 0x14
+#define SNVS_HPSR_BTN BIT(6)
+#define SNVS_LPSR_SPO BIT(18)
+#define SNVS_LPCR_DEP_EN BIT(5)
-#define DEBOUNCE_TIME 30
-#define REPEAT_INTERVAL 60
+#define DEBOUNCE_TIME 30
+#define REPEAT_INTERVAL 60
struct pwrkey_drv_data {
struct regmap *snvs;
@@ -36,6 +39,7 @@
int wakeup;
struct timer_list check_timer;
struct input_dev *input;
+ u8 minor_rev;
};
static void imx_imx_snvs_check_for_events(struct timer_list *t)
@@ -66,18 +70,39 @@
{
struct platform_device *pdev = dev_id;
struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
+ struct input_dev *input = pdata->input;
u32 lp_status;
- pm_wakeup_event(pdata->input->dev.parent, 0);
+ pm_wakeup_event(input->dev.parent, 0);
regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status);
- if (lp_status & SNVS_LPSR_SPO)
- mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+ if (lp_status & SNVS_LPSR_SPO) {
+ if (pdata->minor_rev == 0) {
+ /*
+ * The first generation i.MX6 SoCs only sends an
+ * interrupt on button release. To mimic power-key
+ * usage, we'll prepend a press event.
+ */
+ input_report_key(input, pdata->keycode, 1);
+ input_sync(input);
+ input_report_key(input, pdata->keycode, 0);
+ input_sync(input);
+ pm_relax(input->dev.parent);
+ } else {
+ mod_timer(&pdata->check_timer,
+ jiffies + msecs_to_jiffies(DEBOUNCE_TIME));
+ }
+ }
/* clear SPO status */
regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
return IRQ_HANDLED;
+}
+
+static void imx_snvs_pwrkey_disable_clk(void *data)
+{
+ clk_disable_unprepare(data);
}
static void imx_snvs_pwrkey_act(void *pdata)
@@ -89,10 +114,12 @@
static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
{
- struct pwrkey_drv_data *pdata = NULL;
- struct input_dev *input = NULL;
+ struct pwrkey_drv_data *pdata;
+ struct input_dev *input;
struct device_node *np;
+ struct clk *clk;
int error;
+ u32 vid;
/* Get SNVS register Page */
np = pdev->dev.of_node;
@@ -114,13 +141,36 @@
dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n");
}
+ clk = devm_clk_get_optional(&pdev->dev, NULL);
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "Failed to get snvs clock (%pe)\n", clk);
+ return PTR_ERR(clk);
+ }
+
+ error = clk_prepare_enable(clk);
+ if (error) {
+ dev_err(&pdev->dev, "Failed to enable snvs clock (%pe)\n",
+ ERR_PTR(error));
+ return error;
+ }
+
+ error = devm_add_action_or_reset(&pdev->dev,
+ imx_snvs_pwrkey_disable_clk, clk);
+ if (error) {
+ dev_err(&pdev->dev,
+ "Failed to register clock cleanup handler (%pe)\n",
+ ERR_PTR(error));
+ return error;
+ }
+
pdata->wakeup = of_property_read_bool(np, "wakeup-source");
pdata->irq = platform_get_irq(pdev, 0);
- if (pdata->irq < 0) {
- dev_err(&pdev->dev, "no irq defined in platform data\n");
+ if (pdata->irq < 0)
return -EINVAL;
- }
+
+ regmap_read(pdata->snvs, SNVS_HPVIDR1_REG, &vid);
+ pdata->minor_rev = vid & 0xff;
regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN);
@@ -167,28 +217,9 @@
}
device_init_wakeup(&pdev->dev, pdata->wakeup);
-
- return 0;
-}
-
-static int __maybe_unused imx_snvs_pwrkey_suspend(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
-
- if (device_may_wakeup(&pdev->dev))
- enable_irq_wake(pdata->irq);
-
- return 0;
-}
-
-static int __maybe_unused imx_snvs_pwrkey_resume(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev);
-
- if (device_may_wakeup(&pdev->dev))
- disable_irq_wake(pdata->irq);
+ error = dev_pm_set_wake_irq(&pdev->dev, pdata->irq);
+ if (error)
+ dev_err(&pdev->dev, "irq wake enable failed.\n");
return 0;
}
@@ -199,13 +230,9 @@
};
MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids);
-static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend,
- imx_snvs_pwrkey_resume);
-
static struct platform_driver imx_snvs_pwrkey_driver = {
.driver = {
.name = "snvs_pwrkey",
- .pm = &imx_snvs_pwrkey_pm_ops,
.of_match_table = imx_snvs_pwrkey_ids,
},
.probe = imx_snvs_pwrkey_probe,
--
Gitblit v1.6.2