^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * gpio detection driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2015 Rockchip Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This software is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * License version 2, as published by the Free Software Foundation, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * may be copied, distributed, and modified under those terms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/fb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/gpio_detection.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/wakelock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/rk_keys.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define WAKE_LOCK_TIMEOUT_MS (5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct gpio_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct gpio_detection *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct device dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct gpio_desc *gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct delayed_work work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned int debounce_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct gpio_detection {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct class_attribute cls_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct gpio_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct pinctrl *pinctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct pinctrl_state *pins_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct notifier_block fb_notifier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct wake_lock wake_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int mirror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static struct class *gpio_detection_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static BLOCKING_NOTIFIER_HEAD(gpio_det_notifier_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static int system_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #if IS_ENABLED(CONFIG_GPIO_DET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * gpio_det_notifier_call_chain - notify clients of gpio_det_events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int gpio_det_notifier_call_chain(unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return blocking_notifier_call_chain(&gpio_det_notifier_list, val, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) EXPORT_SYMBOL_GPL(gpio_det_notifier_call_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * gpio_det_register_notifier - register a client notifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @nb: notifier block to callback on events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int gpio_det_register_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) int ret = blocking_notifier_chain_register(&gpio_det_notifier_list, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) EXPORT_SYMBOL(gpio_det_register_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * gpio_det_unregister_client - unregister a client notifier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * @nb: notifier block to callback on events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int gpio_det_unregister_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return blocking_notifier_chain_unregister(&gpio_det_notifier_list, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) EXPORT_SYMBOL(gpio_det_unregister_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static void gpio_det_report_event(struct gpio_data *gpiod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct gpio_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct gpio_detection *gpio_det = gpiod->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) char *status = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) char *envp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) event.val = gpiod->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) event.name = gpiod->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) status = kasprintf(GFP_KERNEL, "GPIO_NAME=%s GPIO_STATE=%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) gpiod->name, event.val ? "over" : "on");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) envp[0] = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) envp[1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) wake_lock_timeout(&gpio_det->wake_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) msecs_to_jiffies(WAKE_LOCK_TIMEOUT_MS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) kobject_uevent_env(&gpiod->dev.kobj, KOBJ_CHANGE, envp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (gpiod->notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) gpio_det_notifier_call_chain(GPIO_EVENT, &event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) kfree(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void gpio_det_work_func(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct gpio_data *gpiod = container_of(work, struct gpio_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int val = gpiod_get_value(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (gpiod->val != val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) gpiod->val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) gpio_det_report_event(gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (system_suspend && gpiod->wakeup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) rk_send_power_key(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) rk_send_power_key(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static irqreturn_t gpio_det_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct gpio_data *gpiod = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int val = gpiod_get_raw_value(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) unsigned int irqflags = IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) irqflags |= IRQ_TYPE_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) irqflags |= IRQ_TYPE_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) irq_set_irq_type(gpiod->irq, irqflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mod_delayed_work(system_wq, &gpiod->work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) msecs_to_jiffies(gpiod->debounce_ms));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int gpio_det_init_status_check(struct gpio_detection *gpio_det)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct gpio_data *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) for (i = 0; i < gpio_det->num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) gpiod = &gpio_det->data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) gpiod->val = gpiod_get_value(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (gpiod->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) gpio_det_report_event(gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int gpio_det_fb_notifier_callback(struct notifier_block *self,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct gpio_detection *gpio_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct fb_event *evdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) int fb_blank;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) gpio_det = container_of(self, struct gpio_detection, fb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) fb_blank = *(int *)evdata->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (fb_blank == FB_BLANK_UNBLANK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) system_suspend = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) system_suspend = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int gpio_det_fb_notifier_register(struct gpio_detection *gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) gpio->fb_notifier.notifier_call = gpio_det_fb_notifier_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return fb_register_client(&gpio->fb_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static ssize_t gpio_detection_info_show(struct class *class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct class_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct gpio_detection *gpio_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) gpio_det = container_of(attr, struct gpio_detection, cls_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return sprintf(buf, "%d\n", gpio_det->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static ssize_t status_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct gpio_data *gpiod = container_of(dev, struct gpio_data, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) unsigned int val = gpiod_get_value(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return sprintf(buf, "%d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static ssize_t status_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct gpio_data *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct gpio_event event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) gpiod = container_of(dev, struct gpio_data, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ret = kstrtoint(buf, 0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (val >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) event.val = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) event.name = gpiod->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) gpio_det_notifier_call_chain(GPIO_EVENT, &event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) gpiod->notify = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static DEVICE_ATTR_RW(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static struct attribute *gpio_detection_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) &dev_attr_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ATTRIBUTE_GROUPS(gpio_detection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int __init gpio_deteciton_class_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) gpio_detection_class = class_create(THIS_MODULE, "gpio-detection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (IS_ERR(gpio_detection_class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) pr_err("create gpio_detection class failed (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) PTR_ERR(gpio_detection_class));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return PTR_ERR(gpio_detection_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int gpio_detection_class_register(struct gpio_detection *gpio_det,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct gpio_data *gpiod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) gpiod->dev.class = gpio_detection_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_set_name(&gpiod->dev, "%s", gpiod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) dev_set_drvdata(&gpiod->dev, gpio_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = device_register(&gpiod->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ret = sysfs_create_groups(&gpiod->dev.kobj, gpio_detection_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) static int gpio_det_parse_dt(struct gpio_detection *gpio_det,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct gpio_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct gpio_data *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct fwnode_handle *child;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) num = of_get_child_count(gpio_det->dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) count = device_get_child_node_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!count || !num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) data = devm_kzalloc(gpio_det->dev, num * sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) of_property_read_u32(gpio_det->dev->of_node, "rockchip,camcap-type",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) &gpio_det->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) of_property_read_u32(gpio_det->dev->of_node, "rockchip,camcap-mirror",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) &gpio_det->mirror);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) gpio_det->info = (gpio_det->mirror << 4) | gpio_det->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) device_for_each_child_node(dev, child) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) node = to_of_node(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) gpiod = &data[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) gpiod->parent = gpio_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) gpiod->notify = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) gpiod->name = of_get_property(node, "label", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) gpiod->wakeup = !!of_get_property(node, "gpio,wakeup", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) of_property_read_u32(node, "linux,debounce-ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) &gpiod->debounce_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (!strcmp(gpiod->name, "car-reverse"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) gpiod->gpio = devm_get_gpiod_from_child(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) "car-reverse", child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) gpiod->gpio = devm_get_gpiod_from_child(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) "car-acc", child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) gpio_det->num = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) gpio_det->data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int gpio_det_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct gpio_detection *gpio_det;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) struct gpio_data *gpiod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) unsigned long irqflags = IRQF_ONESHOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) gpio_det = devm_kzalloc(&pdev->dev, sizeof(*gpio_det), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!gpio_det)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) gpio_det->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) gpio_det->cls_attr.attr.name = "info";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) gpio_det->cls_attr.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) gpio_det->cls_attr.show = gpio_detection_info_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_set_name(gpio_det->dev, "gpio_detection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!pdev->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) gpio_det->pinctrl = devm_pinctrl_get(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (IS_ERR(gpio_det->pinctrl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) dev_err(&pdev->dev, "pinctrl get failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return PTR_ERR(gpio_det->pinctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) gpio_det->pins_default = pinctrl_lookup_state(gpio_det->pinctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) PINCTRL_STATE_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (IS_ERR(gpio_det->pins_default))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) dev_err(gpio_det->dev, "get default pinstate failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pinctrl_select_state(gpio_det->pinctrl, gpio_det->pins_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (gpio_det_parse_dt(gpio_det, pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) wake_lock_init(&gpio_det->wake_lock, WAKE_LOCK_SUSPEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) "gpio_detection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) for (i = 0; i < gpio_det->num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) gpiod = &gpio_det->data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) gpiod_direction_input(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) gpiod->irq = gpiod_to_irq(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (gpiod->irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(gpio_det->dev, "failed to get irq number for GPIO %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) gpiod->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ret = gpio_detection_class_register(gpio_det, gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) INIT_DELAYED_WORK(&gpiod->work, gpio_det_work_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) gpiod->val = gpiod_get_raw_value(gpiod->gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) if (gpiod->val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) irqflags |= IRQ_TYPE_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) irqflags |= IRQ_TYPE_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = devm_request_threaded_irq(gpio_det->dev, gpiod->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) NULL, gpio_det_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) irqflags | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) gpiod->name, gpiod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dev_err(gpio_det->dev, "request irq(%s) failed:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) gpiod->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (gpiod->wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) enable_irq_wake(gpiod->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (gpio_det->info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ret = class_create_file(gpio_detection_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) &gpio_det->cls_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev_warn(gpio_det->dev, "create class file failed:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) gpio_det_fb_notifier_register(gpio_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) gpio_det_init_status_check(gpio_det);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) dev_info(gpio_det->dev, "gpio detection driver probe success\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) #if defined(CONFIG_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static const struct of_device_id gpio_det_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) .compatible = "gpio-detection"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static struct platform_driver gpio_det_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) .name = "gpio-detection",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) .of_match_table = of_match_ptr(gpio_det_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .probe = gpio_det_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #ifdef CONFIG_VIDEO_REVERSE_IMAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) int gpio_det_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static int __init gpio_det_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!gpio_deteciton_class_init())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return platform_driver_register(&gpio_det_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #ifndef CONFIG_VIDEO_REVERSE_IMAGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) fs_initcall_sync(gpio_det_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static void __exit gpio_det_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) platform_driver_unregister(&gpio_det_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) module_exit(gpio_det_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) MODULE_ALIAS("platform:gpio-detection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) MODULE_AUTHOR("ROCKCHIP");