b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 1 | /*******************************************************************************
|
| 2 | * Copyright (C) 2009, mbtk Corporation.
|
| 3 | *
|
| 4 | * File Name: mbtk_GpioWakeUp.c
|
| 5 | * File Mark:
|
| 6 | * Description:
|
| 7 | * Others:
|
| 8 | * Version: V1.0
|
| 9 | * Author: xxxx
|
| 10 | * Date: 2023-07-04
|
| 11 | * History 1:
|
| 12 | * Date:
|
| 13 | * Version:
|
| 14 | * Author:
|
| 15 | * Modification:
|
| 16 | * History 2:
|
| 17 | ********************************************************************************/
|
| 18 |
|
| 19 | /****************************************************************************
|
| 20 | * Include files
|
| 21 | ****************************************************************************/
|
| 22 | #include <linux/module.h>
|
| 23 | #include <linux/kernel.h>
|
| 24 | #include <linux/kthread.h>
|
| 25 | #include <linux/init.h>
|
| 26 | #include <linux/spinlock.h>
|
| 27 | #include <linux/interrupt.h>
|
| 28 | #include <linux/types.h>
|
| 29 | #include <linux/suspend.h>
|
| 30 | #include <linux/tick.h>
|
| 31 | #include <linux/slab.h>
|
| 32 | #include <linux/err.h>
|
| 33 |
|
| 34 | #include <linux/of_irq.h>
|
| 35 | #include <linux/of_address.h>
|
| 36 | #include <linux/of_platform.h>
|
| 37 | #include <linux/of_gpio.h>
|
hj.shao | bbc3514 | 2025-08-26 23:30:26 -0700 | [diff] [blame^] | 38 | #include <linux/edge_wakeup_mmp.h>
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 39 |
|
| 40 | //#include <mach/irqs.h>
|
| 41 | //#include <uapi/linux/gpio.h>
|
| 42 | //#include <linux/soc/sc/pcu.h>
|
| 43 | #include <linux/irq.h>
|
| 44 | #include <linux/delay.h>
|
| 45 | #include <linux/gpio.h>
|
| 46 | #include <linux/pm_wakeup.h>
|
| 47 | //#include <linux/soc/sc/drv_idle.h>
|
| 48 |
|
| 49 | #include <linux/sysfs.h>
|
| 50 | #include <linux/kobject.h>
|
| 51 | #include <linux/input.h>
|
| 52 | /****************************************************************************
|
| 53 | * Local Macros
|
| 54 | ****************************************************************************/
|
| 55 |
|
| 56 | #define HAS_WAKE_OUT_PIN 1 // 1: for output pin level when wakeup or sleeping; 0 is disable
|
| 57 |
|
| 58 | #define HAS_WAKE_SOURCE_LOCK 1 //1: for wakelock when wakeup and release when sleeping with the wake gpio level
|
| 59 |
|
| 60 | #define HAL_GPIO_WAKUP_PM 1 // release or lock wakelock when sleep or wakeup
|
| 61 |
|
| 62 | #define WAKEUP_STATE_VALUE 0
|
| 63 |
|
| 64 | #define WAKEUP_KEY KEY_1 //KEY_POWER ,report key code to application
|
| 65 |
|
lichengzhang | e371771 | 2025-06-19 10:43:51 +0800 | [diff] [blame] | 66 | #define CP_WAKE_STATUS 1
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 67 |
|
lichengzhang | e371771 | 2025-06-19 10:43:51 +0800 | [diff] [blame] | 68 | #define CP_SLEEP_STATUS 0
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 69 |
|
| 70 | #ifndef TRUE
|
| 71 | #define TRUE 1
|
| 72 | #endif
|
| 73 |
|
| 74 | #ifndef FALSE
|
| 75 | #define FALSE 0
|
| 76 | #endif
|
| 77 |
|
| 78 |
|
| 79 |
|
| 80 | #define GPIO_WAKUP_DEBUG
|
| 81 |
|
| 82 | #ifdef GPIO_WAKUP_DEBUG
|
| 83 | #define GPIO_WAKUP_debug(fmt, args...) printk(KERN_INFO "[SLP] " fmt, ##args)
|
| 84 | #else
|
| 85 | #define GPIO_WAKUP_debug(fmt, args...)
|
| 86 | #endif
|
| 87 |
|
| 88 | #define GPIO_WAKUP_STATE "GpioWakeUp_state"
|
| 89 | /****************************************************************************
|
| 90 | * Local Types
|
| 91 | ****************************************************************************/
|
| 92 |
|
| 93 |
|
| 94 | struct mbtkGpioWakeUp_dev
|
| 95 | {
|
| 96 | struct device *dev;
|
| 97 | struct pinctrl *pctrl_wk_int;
|
| 98 | struct pinctrl_state *st_gpio;
|
| 99 | struct pinctrl_state *st_int;
|
| 100 | int wake_state;
|
| 101 | int curr_gpio_value;
|
| 102 |
|
| 103 | struct task_struct *wake_int_thread;
|
| 104 | spinlock_t wk_lock;
|
| 105 |
|
| 106 | struct semaphore wk_sem;
|
| 107 | int wake_ap_gpio;
|
| 108 | int wake_me_gpio;
|
| 109 | struct gpio_desc *gd;
|
| 110 | struct input_dev *input;
|
| 111 | int eint_irq;
|
| 112 | int GpioWakeUp_irq_state;
|
| 113 | int wake_cnt;
|
| 114 | int sleep_cnt;
|
| 115 | struct wakeup_source *GpioWakeUp_ws;
|
| 116 |
|
| 117 | };
|
| 118 |
|
| 119 |
|
| 120 | /****************************************************************************
|
| 121 | * Global Variables
|
| 122 | ****************************************************************************/
|
| 123 |
|
| 124 | //static int wakeup_irq_occurs = 0;
|
| 125 | struct wakeup_source *GpioWakeUp_wake_lock;
|
| 126 | static int GpioWakeUp_init_flag = 0;
|
| 127 |
|
| 128 |
|
| 129 |
|
| 130 | static int currState = 1;
|
| 131 |
|
| 132 | /****************************************************************************
|
| 133 | * Local Constants
|
| 134 | ****************************************************************************/
|
| 135 |
|
| 136 |
|
| 137 | struct mbtkGpioWakeUp_dev g_GpioWakeUp = {0};
|
| 138 |
|
| 139 |
|
| 140 | /*******************************************************************************
|
| 141 | * Function: ApWakeCp int
|
| 142 | * Description: ap2cp wake up int thread
|
| 143 | * Parameters:
|
| 144 | * Input:
|
| 145 | *
|
| 146 | * Output:
|
| 147 | *
|
| 148 | * Returns:
|
| 149 | *
|
| 150 | * Others:
|
| 151 | ********************************************************************************/
|
| 152 |
|
| 153 | irqreturn_t GpioWakeUp_wkcp_thread_fn(int irq, void *priv)
|
| 154 | {
|
| 155 | unsigned long flags;
|
| 156 | int gpio_value;
|
| 157 |
|
| 158 | struct mbtkGpioWakeUp_dev *GpioWakeUp_dev = (struct mbtkGpioWakeUp_dev *)priv;
|
| 159 |
|
| 160 | disable_irq_nosync(irq);/*jb.qi add for dtr on 20240202*/
|
| 161 |
|
| 162 | gpio_value = 0 ;
|
| 163 |
|
| 164 | //pr_err("%s/L%d\n", __func__, __LINE__);
|
| 165 | if(GpioWakeUp_dev->GpioWakeUp_ws){
|
| 166 | //gpio_value = gpio_get_value_cansleep(GpioWakeUp_dev->wake_me_gpio) ;
|
| 167 | //if(gpio_value == 0)
|
| 168 | __pm_wakeup_event(GpioWakeUp_dev->GpioWakeUp_ws, 2000);
|
| 169 | }
|
| 170 |
|
| 171 | /*if (pinctrl_select_state(GpioWakeUp_dev->pctrl_wk_int, GpioWakeUp_dev->st_gpio) < 0) {
|
| 172 | printk("setting card detect gpio failed\n");
|
| 173 | }*/
|
| 174 |
|
| 175 | spin_lock_irqsave(&GpioWakeUp_dev->wk_lock, flags);
|
| 176 | gpio_value = gpio_get_value_cansleep(GpioWakeUp_dev->wake_me_gpio) ;
|
| 177 | spin_unlock_irqrestore(&GpioWakeUp_dev->wk_lock, flags);
|
| 178 |
|
| 179 | if(gpio_value < 0)
|
| 180 | {
|
| 181 | printk( "[%s-%d]: gpio get state failed\n",__func__,__LINE__);
|
| 182 | }
|
| 183 | if(gpio_value != currState)
|
| 184 | {
|
| 185 | GPIO_WAKUP_debug("interrup handler: gpio%d_value is %d \n",GpioWakeUp_dev->wake_me_gpio,gpio_value);
|
| 186 | GpioWakeUp_dev->wake_state = gpio_value;
|
| 187 | //input_report_key(GpioWakeUp_dev->input, WAKEUP_KEY, !!gpio_value);
|
| 188 |
|
| 189 | input_event(GpioWakeUp_dev->input, EV_MSC, MSC_RAW, !!gpio_value);
|
| 190 | input_sync(GpioWakeUp_dev->input);
|
| 191 |
|
| 192 | #if HAS_WAKE_SOURCE_LOCK
|
| 193 | if(WAKEUP_STATE_VALUE == gpio_value){ //wake up
|
| 194 |
|
| 195 | pm_stay_awake(g_GpioWakeUp.dev);
|
| 196 | }
|
| 197 | else{ //into sleep
|
| 198 |
|
| 199 | pm_relax(g_GpioWakeUp.dev);
|
| 200 | }
|
| 201 | #endif
|
| 202 | }
|
| 203 | currState = gpio_value;
|
| 204 |
|
| 205 | enable_irq(GpioWakeUp_dev->eint_irq);
|
| 206 |
|
| 207 | return IRQ_HANDLED;
|
| 208 | }
|
| 209 |
|
| 210 | #if HAL_GPIO_WAKUP_PM
|
| 211 |
|
| 212 | static int mbtkGpioWakeUp_pm_resume(struct device *dev)
|
| 213 | {
|
| 214 |
|
| 215 | //pm_stay_awake(g_GpioWakeUp.dev);
|
lichengzhang | d419211 | 2025-07-02 13:25:50 +0800 | [diff] [blame] | 216 | //gpio_direction_output(g_GpioWakeUp.wake_ap_gpio, CP_WAKE_STATUS);
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 217 | pr_info("mbtkGpioWakeUp_pm_resume\n");
|
| 218 | return 0;
|
| 219 | }
|
| 220 |
|
| 221 | static int mbtkGpioWakeUp_pm_suspend(struct device *dev)
|
| 222 | {
|
| 223 | //pm_relax(g_GpioWakeUp.dev);
|
| 224 | gpio_direction_output(g_GpioWakeUp.wake_ap_gpio, CP_SLEEP_STATUS);
|
| 225 | pr_info("mbtkGpioWakeUp_pm_suspend\n");
|
| 226 | return 0;
|
| 227 | }
|
| 228 |
|
| 229 | static int mbtkGpioWakeUp_pm_runtime_resume(struct device *dev)
|
| 230 | {
|
| 231 | /* enable clk and restore regs */
|
| 232 | pr_info("mbtkGpioWakeUp_pm_runtime_resume\n");
|
| 233 | return 0;
|
| 234 | }
|
| 235 |
|
| 236 | static int mbtkGpioWakeUp_pm_runtime_suspend(struct device *dev)
|
| 237 | {
|
| 238 | /* backup regs and disable clk */
|
| 239 | pr_info("mbtkGpioWakeUp_pm_runtime_suspend\n");
|
| 240 | return 0;
|
| 241 | }
|
| 242 |
|
| 243 | static int mbtkGpioWakeUp_pm_runtime_idle(struct device *dev)
|
| 244 | {
|
| 245 | pr_info("mbtkGpioWakeUp_pm_runtime_idle\n");
|
| 246 | return 0;
|
| 247 | }
|
| 248 |
|
| 249 | static const struct dev_pm_ops mbtkGpioWakeUp_pm = {
|
| 250 | .resume = mbtkGpioWakeUp_pm_resume,
|
| 251 | .suspend = mbtkGpioWakeUp_pm_suspend,
|
| 252 | .runtime_resume = mbtkGpioWakeUp_pm_runtime_resume,
|
| 253 | .runtime_suspend = mbtkGpioWakeUp_pm_runtime_suspend,
|
| 254 | .runtime_idle = mbtkGpioWakeUp_pm_runtime_idle
|
| 255 | };
|
| 256 | #endif
|
| 257 |
|
| 258 |
|
| 259 | static const struct of_device_id mbtkGpioWakeUp_match[] = {
|
| 260 | { .compatible = "mbtk,GpioWakeUp", },
|
| 261 | { }
|
| 262 | };
|
| 263 |
|
| 264 | static ssize_t mbtkGpioWakeUp_value_show(struct device *dev,
|
| 265 | struct device_attribute *attr, char *buf)
|
| 266 | {
|
| 267 | int gpio_value;
|
| 268 | unsigned long flags;
|
| 269 |
|
| 270 | struct mbtkGpioWakeUp_dev *GpioWakeUp_dev = &g_GpioWakeUp;
|
| 271 | spin_lock_irqsave(&GpioWakeUp_dev->wk_lock, flags);
|
| 272 | gpio_value = gpio_get_value_cansleep(GpioWakeUp_dev->wake_me_gpio) ;
|
| 273 | spin_unlock_irqrestore(&GpioWakeUp_dev->wk_lock, flags);
|
| 274 | currState = gpio_value;
|
| 275 | input_event(GpioWakeUp_dev->input, EV_MSC, MSC_RAW, gpio_value);
|
| 276 | input_sync(GpioWakeUp_dev->input);
|
| 277 | sprintf(buf, "%d\n", gpio_value);
|
| 278 | printk("gpio%d = %d \n",GpioWakeUp_dev->wake_me_gpio,gpio_value);
|
| 279 | return strlen(buf) + 1;
|
| 280 | }
|
| 281 |
|
| 282 | static ssize_t mbtkGpioWakeUp_value_store(struct device *dev,
|
| 283 | struct device_attribute *attr, const char *buf,
|
| 284 | size_t size)
|
| 285 | {
|
| 286 | int gpio_value=0;
|
| 287 | struct mbtkGpioWakeUp_dev *GpioWakeUp_dev = &g_GpioWakeUp;
|
| 288 | sscanf(buf, "%d", &gpio_value);
|
| 289 | if (gpio_value != 0 && gpio_value != 1) {
|
| 290 | pr_err("%s: invalid value %d, should be 0 or 1\n",
|
| 291 | __func__, gpio_value);
|
| 292 | return -EINVAL;
|
| 293 | }
|
| 294 | input_event(GpioWakeUp_dev->input, EV_MSC, MSC_RAW, gpio_value);
|
| 295 | input_sync(GpioWakeUp_dev->input);
|
| 296 |
|
| 297 | return size;
|
| 298 | }
|
| 299 |
|
| 300 | static DEVICE_ATTR(WakeUpValue, 0664, mbtkGpioWakeUp_value_show, mbtkGpioWakeUp_value_store);
|
| 301 |
|
| 302 | int mbtkGpioWakeUp_probe(struct platform_device *pdev)
|
| 303 | {
|
| 304 | int gpio;
|
hj.shao | 403e704 | 2025-08-07 21:10:27 -0700 | [diff] [blame] | 305 | int hsm_en_gpio;
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 306 | int gpio_value;
|
| 307 | unsigned long flags;
|
| 308 | int ret = 0, error;
|
| 309 |
|
| 310 | struct device_node *np = NULL;
|
| 311 | struct input_dev *input;
|
| 312 |
|
| 313 | g_GpioWakeUp.dev = &pdev->dev;
|
| 314 | np = pdev->dev.of_node;
|
| 315 |
|
| 316 | sema_init(&g_GpioWakeUp.wk_sem,0);
|
| 317 | spin_lock_init(&g_GpioWakeUp.wk_lock);
|
| 318 |
|
| 319 | device_init_wakeup(&pdev->dev, true);
|
| 320 |
|
| 321 | g_GpioWakeUp.GpioWakeUp_ws = wakeup_source_register(g_GpioWakeUp.dev ,"GpioWakeUp");
|
| 322 | if(g_GpioWakeUp.GpioWakeUp_ws == NULL){
|
| 323 | printk("adb_setup wakeup_source_create fail\n");
|
| 324 | goto wake_source_init_fail;
|
| 325 | }
|
| 326 |
|
hj.shao | 403e704 | 2025-08-07 21:10:27 -0700 | [diff] [blame] | 327 | hsm_en_gpio = of_get_named_gpio(np, "hsm-en-out-gpio", 0);
|
| 328 | if (unlikely(hsm_en_gpio < 0)) {
|
| 329 | pr_err("%s. parse hsm-en-out-gpio failed\n", __func__);
|
| 330 | ret = -EINVAL;
|
| 331 | } else {
|
| 332 | pr_err("%s. hsm-en-out-gpio=%d\n", __func__, hsm_en_gpio);
|
| 333 | if (gpio_request(hsm_en_gpio, "hsm-en-out-gpio")) {
|
| 334 | pr_err("Failed to request GPIO %d\n", hsm_en_gpio);
|
| 335 | ret = -EBUSY;
|
| 336 | }
|
| 337 | if (gpio_direction_output(hsm_en_gpio, 1)) {
|
| 338 | pr_err("Failed to set GPIO %d as output\n", hsm_en_gpio);
|
| 339 | ret = -EIO;
|
| 340 | }
|
| 341 | pr_err("hsm-gpio config sucess\n");
|
| 342 | gpio_free(hsm_en_gpio);
|
| 343 | }
|
| 344 |
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 345 |
|
| 346 | gpio = of_get_named_gpio(np, "wakeup-in-gpio", 0);
|
| 347 | if (unlikely(gpio < 0)) {
|
| 348 | pr_err("%s. parse wakeup-in-gpio failed\n", __func__);
|
| 349 | ret = -EINVAL;
|
| 350 | } else {
|
| 351 | pr_err("%s. wakeup-in-gpio=%d\n", __func__, gpio);
|
| 352 | }
|
| 353 |
|
| 354 | if(gpio >= 0)
|
| 355 | {
|
hj.shao | bbc3514 | 2025-08-26 23:30:26 -0700 | [diff] [blame^] | 356 | request_mfp_edge_wakeup(gpio, NULL, NULL, g_GpioWakeUp.dev);
|
hong.liu | f241688 | 2025-05-23 20:41:06 -0700 | [diff] [blame] | 357 | /*LYNQ_MODFIY_START
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 358 | ret = gpio_request(gpio, "wakeup-in");
|
| 359 | if(ret < 0)
|
| 360 | {
|
hong.liu | f241688 | 2025-05-23 20:41:06 -0700 | [diff] [blame] | 361 | pr_err("%s. gpio_request for wakeup-in-gpio=%d failed\n", __func__,gpio);
|
| 362 | return ret;
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 363 | }
|
hong.liu | f241688 | 2025-05-23 20:41:06 -0700 | [diff] [blame] | 364 | LYNQ_MODFIY_END*/
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 365 | g_GpioWakeUp.wake_me_gpio = gpio;
|
| 366 |
|
| 367 | gpio_direction_input(g_GpioWakeUp.wake_me_gpio);
|
| 368 |
|
| 369 | g_GpioWakeUp.eint_irq = gpio_to_irq(g_GpioWakeUp.wake_me_gpio);
|
| 370 |
|
| 371 | if (g_GpioWakeUp.eint_irq < 0)
|
| 372 | {
|
| 373 | error = g_GpioWakeUp.eint_irq ;
|
| 374 | printk("Unable to get irq number for GPIO %d, error %d\n",g_GpioWakeUp.wake_me_gpio, error);
|
| 375 | goto wake_in_pin_init_fail;
|
| 376 | }
|
| 377 | else
|
| 378 | {
|
| 379 | printk("wake in gpio request irq %d sucess\n", g_GpioWakeUp.eint_irq);
|
| 380 | }
|
| 381 | }
|
| 382 |
|
| 383 | input = input_allocate_device();;
|
| 384 | if (!input) {
|
| 385 | printk("failed to allocate state\n");
|
| 386 | error = -ENOMEM;
|
| 387 | goto input_fail;
|
| 388 | }
|
| 389 |
|
| 390 |
|
| 391 | g_GpioWakeUp.input = input;
|
| 392 | input->name = "WAKE-in-GPIO";
|
| 393 |
|
| 394 | /* 2. ?? */
|
| 395 | /* 2.1 ??????? */
|
| 396 | set_bit(EV_MSC, g_GpioWakeUp.input->evbit);
|
| 397 | set_bit(EV_SYN, g_GpioWakeUp.input->evbit);
|
| 398 | /* 2.2 ?????????????: L,S,ENTER,LEFTSHIT */
|
| 399 |
|
| 400 | set_bit(MSC_RAW, g_GpioWakeUp.input->mscbit);
|
| 401 | //set_bit(KEY_LEFTSHIFT, buttons_dev->keybit);
|
| 402 |
|
| 403 | /* 3. ?? */
|
| 404 | input_set_capability(g_GpioWakeUp.input, EV_MSC, MSC_RAW);
|
| 405 | error = input_register_device(input);
|
| 406 | if (error)
|
| 407 | {
|
| 408 | pr_err("%s. input_register_device=%d failed\n", __func__,error);
|
| 409 |
|
| 410 | goto input_fail;
|
| 411 | }
|
| 412 |
|
| 413 |
|
| 414 | spin_lock_irqsave(&g_GpioWakeUp.wk_lock, flags);
|
| 415 |
|
| 416 | gpio_value = gpio_get_value(g_GpioWakeUp.wake_me_gpio) ;
|
| 417 |
|
| 418 | spin_unlock_irqrestore(&g_GpioWakeUp.wk_lock, flags);
|
| 419 | if(gpio_value < 0)
|
| 420 | {
|
| 421 | printk( "[%s-%d]: gpio get state failed\n",__func__,__LINE__);
|
| 422 | }
|
| 423 |
|
| 424 | //input_report_key(g_GpioWakeUp.input, KEY_1, !!gpio_value);
|
| 425 |
|
| 426 | input_event(input, EV_MSC, MSC_RAW, !!gpio_value);
|
| 427 | input_sync(input);
|
| 428 |
|
| 429 | #if HAS_WAKE_SOURCE_LOCK
|
| 430 | if(WAKEUP_STATE_VALUE == gpio_value)
|
| 431 | {
|
| 432 | pm_stay_awake(g_GpioWakeUp.dev);
|
| 433 | }
|
| 434 | else
|
| 435 | {
|
| 436 |
|
| 437 | pm_relax(g_GpioWakeUp.dev);
|
| 438 | }
|
| 439 | #endif
|
| 440 |
|
| 441 | currState = gpio_value;
|
| 442 |
|
| 443 | GPIO_WAKUP_debug("%s. devm_request_threaded_irqn", __func__);
|
| 444 |
|
| 445 | ret = devm_request_threaded_irq(g_GpioWakeUp.dev, g_GpioWakeUp.eint_irq,NULL,GpioWakeUp_wkcp_thread_fn, (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT),"GpioWakeUp_wake int", &g_GpioWakeUp);
|
| 446 |
|
| 447 | if(ret<0){
|
| 448 | panic("mbtkGpioWakeUp_probe request_irq fail, %d", ret);
|
| 449 | }
|
| 450 |
|
| 451 |
|
| 452 | enable_irq_wake(g_GpioWakeUp.eint_irq);
|
| 453 |
|
| 454 | ret = device_create_file(g_GpioWakeUp.dev, &dev_attr_WakeUpValue);
|
| 455 | if(ret)
|
| 456 | {
|
| 457 | printk("ERROR: mbtkGpioWakeUp device_create_file failed\n");
|
| 458 | }
|
| 459 |
|
| 460 | #if HAS_WAKE_OUT_PIN
|
| 461 | gpio = of_get_named_gpio(np, "wakeup-out-gpio", 0);
|
| 462 | if (unlikely(gpio < 0)) {
|
| 463 | pr_err("%s. parse wakeup-out-gpio failed\n", __func__);
|
| 464 | } else
|
| 465 | {
|
| 466 | pr_err("%s. wakeup-out-gpio=%d\n", __func__, gpio);
|
| 467 | }
|
| 468 |
|
| 469 | if(gpio >= 0)
|
| 470 | {
|
hong.liu | f241688 | 2025-05-23 20:41:06 -0700 | [diff] [blame] | 471 | /*LYNQ_MODFIY_START
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 472 | ret = gpio_request(gpio, "wakeup-out");
|
| 473 | if(ret < 0)
|
| 474 | {
|
| 475 | pr_err("%s. gpio_request for wakeup-out-gpio=%d failed\n", __func__,gpio);
|
| 476 | goto wake_out_pin_init_fail;
|
| 477 | }
|
hong.liu | f241688 | 2025-05-23 20:41:06 -0700 | [diff] [blame] | 478 | LYNQ_MODFIY_END*/
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 479 | g_GpioWakeUp.wake_ap_gpio = gpio;
|
| 480 | GPIO_WAKUP_debug("%s. gpio_request for wakeup-out-gpio=%d sucess\n", __func__,g_GpioWakeUp.wake_ap_gpio);
|
| 481 | }
|
| 482 |
|
lichengzhang | e2da2ca | 2025-06-03 16:28:45 +0800 | [diff] [blame] | 483 | gpio_direction_output(g_GpioWakeUp.wake_ap_gpio, CP_WAKE_STATUS);
|
b.liu | b17525e | 2025-05-14 17:22:29 +0800 | [diff] [blame] | 484 |
|
| 485 | #endif
|
| 486 |
|
| 487 |
|
| 488 | g_GpioWakeUp.wake_cnt = 0;
|
| 489 | g_GpioWakeUp.sleep_cnt = 0;
|
| 490 |
|
| 491 | #if HAS_WAKE_OUT_PIN
|
| 492 | wake_out_pin_init_fail:
|
| 493 | if(ret){
|
| 494 | pr_err("wakeup-out gpio%d init failed\n",gpio);
|
| 495 | }
|
| 496 | #endif
|
| 497 |
|
| 498 | input_fail:
|
| 499 | input_free_device(g_GpioWakeUp.input);
|
| 500 |
|
| 501 | wake_in_pin_init_fail:
|
| 502 | if(ret){
|
| 503 | pr_err("wakeup-in gpio%d init failed\n",gpio);
|
| 504 | }
|
| 505 |
|
| 506 | //pinctrl_init_fail:
|
| 507 | // if(ret){
|
| 508 | // printk("pinctrl_init_fail\n");
|
| 509 | // }
|
| 510 |
|
| 511 | wake_source_init_fail:
|
| 512 |
|
| 513 | //pm_relax(g_GpioWakeUp.dev);
|
| 514 | return ret;
|
| 515 | }
|
| 516 |
|
| 517 | static struct platform_driver mbtkGpioWakeUp_driver = {
|
| 518 | .probe = mbtkGpioWakeUp_probe,
|
| 519 | .driver = {
|
| 520 | .name = "mbtk_GpioWakeUp",
|
| 521 | #if HAL_GPIO_WAKUP_PM
|
| 522 | .pm = &mbtkGpioWakeUp_pm,
|
| 523 | #endif
|
| 524 | .of_match_table = mbtkGpioWakeUp_match,
|
| 525 | },
|
| 526 | };
|
| 527 |
|
| 528 |
|
| 529 | /*******************************************************************************
|
| 530 | * Function: zDrvAp2cp_Initiate
|
| 531 | * Description:
|
| 532 | * Parameters:
|
| 533 | * Input:
|
| 534 | *
|
| 535 | * Output:
|
| 536 | *
|
| 537 | * Returns:
|
| 538 | *
|
| 539 | * Others:
|
| 540 | ********************************************************************************/
|
| 541 | static int __init zDrvGpioWakeUp_Initiate(void)
|
| 542 | {
|
| 543 | int ret=0;
|
| 544 | //int errCode = -1;
|
| 545 |
|
| 546 | GpioWakeUp_init_flag = 1;
|
| 547 |
|
| 548 | ret = platform_driver_register(&mbtkGpioWakeUp_driver);
|
| 549 | if (ret != 0){
|
| 550 | printk("GPIO_WAKUP: platform_driver_register fail!\n");
|
| 551 | return ret;
|
| 552 | }
|
| 553 |
|
| 554 | return 0;
|
| 555 | }
|
| 556 |
|
| 557 | int zDrvGpioWakeUp_Release(void)
|
| 558 | {
|
| 559 |
|
| 560 | gpio_free(g_GpioWakeUp.wake_me_gpio);
|
| 561 | #if HAS_WAKE_OUT_PIN
|
| 562 | gpio_free(g_GpioWakeUp.wake_ap_gpio);
|
| 563 | #endif
|
| 564 |
|
| 565 | return 0;
|
| 566 | }
|
| 567 |
|
| 568 |
|
| 569 | late_initcall(zDrvGpioWakeUp_Initiate);
|
| 570 |
|
| 571 | //module_exit(zDrvGpioWakeUp_Release);
|
| 572 |
|
| 573 |
|