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