Nokia N900 >> Native Debian >> Kernel 5.3.0

實做Lock Key功能(Kernel)


雖然可以使用xbindkeys方式實現,但是,缺點就是關閉屏幕的速度太慢,因此,司徒只好使用修改驅動程式,藉此實現Lock Key的功能,關閉屏幕就不會因CPU Usage而變慢,程式如下:

diff -Naur old/gpio_keys.c new/gpio_keys.c
--- old/gpio_keys.c	2019-11-20 14:08:09.002930484 +0800
+++ new/gpio_keys.c	2019-11-20 14:17:09.421705901 +0800
@@ -1,13 +1,13 @@
-// SPDX-License-Identifier: GPL-2.0-only
 /*
+ * SPDX-License-Identifier: GPL-2.0-only
  * Driver for keys on GPIO lines capable of generating interrupts.
  *
  * Copyright 2005 Phil Blundell
  * Copyright 2010, 2011 David Jander <david@protonic.nl>
+ * Copyright 2019 Steward Fu <steward.fu@gmail.com>
  */
 
 #include <linux/module.h>
-
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
@@ -29,6 +29,12 @@
 #include <linux/spinlock.h>
 #include <dt-bindings/input/gpio-keys.h>
 
+#define LOCK_KEY 152
+int gpio_keys_lock=0;
+extern int twl4030_pwrbutton_lock;
+EXPORT_SYMBOL(gpio_keys_lock);
+int set_mylcd(int level);
+
 struct gpio_button_data {
 	const struct gpio_keys_button *button;
 	struct input_dev *input;
@@ -361,7 +367,8 @@
 	const struct gpio_keys_button *button = bdata->button;
 	struct input_dev *input = bdata->input;
 	unsigned int type = button->type ?: EV_KEY;
-	int state;
+	int state, code, value;
+  static int pre_value=0, lcd=0;
 
 	state = gpiod_get_value_cansleep(bdata->gpiod);
 	if (state < 0) {
@@ -371,12 +378,29 @@
 	}
 
 	if (type == EV_ABS) {
-		if (state)
-			input_event(input, type, button->code, button->value);
-	} else {
-		input_event(input, type, *bdata->code, state);
-	}
-	input_sync(input);
+		if (state) {
+      code = button->code;
+      value = button->value;
+    }
+	} 
+  else {
+    code = *bdata->code;
+    value = state;
+	}
+
+  if ((code == LOCK_KEY) && (pre_value == 1) && (value == 0)) {
+    gpio_keys_lock = !gpio_keys_lock;
+    if (gpio_keys_lock) {
+      lcd = set_mylcd(0);
+    }
+    else {
+      set_mylcd(lcd);
+    }
+  }
+  pre_value = value;
+
+  input_event(input, type, code, value);
+  input_sync(input);
 }
 
 static void gpio_keys_gpio_work_func(struct work_struct *work)
@@ -386,16 +410,26 @@
 
 	gpio_keys_gpio_report_event(bdata);
 
-	if (bdata->button->wakeup)
-		pm_relax(bdata->input->dev.parent);
+  if (bdata->button->wakeup) {
+    pm_relax(bdata->input->dev.parent);
+  }
 }
 
 static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
 {
 	struct gpio_button_data *bdata = dev_id;
+  const struct gpio_keys_button *button = bdata->button;
 
 	BUG_ON(irq != bdata->irq);
 
+  if (twl4030_pwrbutton_lock) {
+	  return IRQ_HANDLED;
+  }
+
+  if ((gpio_keys_lock) && (button->code != LOCK_KEY)) {
+	  return IRQ_HANDLED;
+  }
+
 	if (bdata->button->wakeup) {
 		const struct gpio_keys_button *button = bdata->button;
 
@@ -647,15 +681,16 @@
 
 static void gpio_keys_report_state(struct gpio_keys_drvdata *ddata)
 {
+  int i;
 	struct input_dev *input = ddata->input;
-	int i;
 
 	for (i = 0; i < ddata->pdata->nbuttons; i++) {
 		struct gpio_button_data *bdata = &ddata->data[i];
-		if (bdata->gpiod)
-			gpio_keys_gpio_report_event(bdata);
+		if (bdata->gpiod) {
+  	  gpio_keys_gpio_report_event(bdata);
+    }
 	}
-	input_sync(input);
+  input_sync(input);
 }
 
 static int gpio_keys_open(struct input_dev *input)
diff -Naur old/panel-sony-acx565akm.c new/panel-sony-acx565akm.c
--- old/panel-sony-acx565akm.c	2019-11-20 14:08:38.214850327 +0800
+++ new/panel-sony-acx565akm.c	2019-11-20 14:17:31.341664421 +0800
@@ -52,6 +52,9 @@
 #define MIPID_VER_LS041Y3		4
 #define MIPID_VER_L4F00311		8
 #define MIPID_VER_ACX565AKM		9
+	
+static struct panel_drv_data *mylcd;
+int set_mylcd(int level);
 
 struct panel_drv_data {
 	struct omap_dss_device	dssdev;
@@ -333,6 +336,13 @@
 	return bv;
 }
 
+int set_mylcd(int level)
+{
+  int ret = acx565akm_get_actual_brightness(mylcd);
+  acx565akm_set_brightness(mylcd, level);
+  return ret;
+}
+EXPORT_SYMBOL(set_mylcd);
 
 static int acx565akm_bl_update_status(struct backlight_device *dev)
 {
@@ -849,6 +859,7 @@
 		goto err_reg;
 	}
 
+  mylcd = ddata;
 	return 0;
 
 err_reg:
diff -Naur old/twl4030_keypad.c new/twl4030_keypad.c
--- old/twl4030_keypad.c	2019-11-20 14:08:13.906916875 +0800
+++ new/twl4030_keypad.c	2019-11-20 14:17:18.817688068 +0800
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2007 Texas Instruments, Inc.
  * Copyright (C) 2008 Nokia Corporation
+ * Copyright (C) 2019 Steward Fu <steward.fu@gmail.com>
  *
  * Code re-written for 2430SDP by:
  * Syed Mohammed Khasim <x0khasim@ti.com>
@@ -44,6 +45,9 @@
 #define TWL4030_ROW_SHIFT	4
 #define TWL4030_KEYMAP_SIZE	(TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT)
 
+extern int gpio_keys_lock;
+extern int twl4030_pwrbutton_lock;
+
 struct twl4030_keypad {
 	unsigned short	keymap[TWL4030_KEYMAP_SIZE];
 	u16		kp_state[TWL4030_MAX_ROWS];
@@ -231,7 +235,7 @@
 			code = MATRIX_SCAN_CODE(row, col, TWL4030_ROW_SHIFT);
 			input_event(input, EV_MSC, MSC_SCAN, code);
 			input_report_key(input, kp->keymap[code],
-					 new_state[row] & (1 << col));
+				new_state[row] & (1 << col));
 		}
 		kp->kp_state[row] = new_state[row];
 	}
@@ -246,9 +250,17 @@
 	struct twl4030_keypad *kp = _kp;
 	u8 reg;
 	int ret;
+  
+  if (twl4030_pwrbutton_lock) {
+	  return IRQ_HANDLED;
+  }
 
 	/* Read & Clear TWL4030 pending interrupt */
 	ret = twl4030_kpread(kp, &reg, KEYP_ISR1, 1);
+  
+  if (gpio_keys_lock) {
+	  return IRQ_HANDLED;
+  }
 
 	/*
 	 * Release all keys if I2C has gone bad or
diff -Naur old/twl4030-pwrbutton.c new/twl4030-pwrbutton.c
--- old/twl4030-pwrbutton.c	2019-11-20 14:08:02.750947929 +0800
+++ new/twl4030-pwrbutton.c	2019-11-20 14:16:58.997725780 +0800
@@ -2,6 +2,7 @@
  * twl4030-pwrbutton.c - TWL4030 Power Button Input Driver
  *
  * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2019 Steward Fu <steward.fu@gmail.com>
  *
  * Written by Peter De Schrijver <peter.de-schrijver@nokia.com>
  * Several fixes by Felipe Balbi <felipe.balbi@nokia.com>
@@ -30,18 +31,27 @@
 #include <linux/mfd/twl.h>
 
 #define PWR_PWRON_IRQ (1 << 0)
-
 #define STS_HW_CONDITIONS 0xf
 
+int twl4030_pwrbutton_lock=0;
+EXPORT_SYMBOL(twl4030_pwrbutton_lock);
+
 static irqreturn_t powerbutton_irq(int irq, void *_pwr)
 {
 	struct input_dev *pwr = _pwr;
 	int err;
 	u8 value;
+  static int pre_value=0;
 
 	err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &value, STS_HW_CONDITIONS);
 	if (!err)  {
 		pm_wakeup_event(pwr->dev.parent, 0);
+    value&= PWR_PWRON_IRQ;
+    if ((pre_value == 1) && (value == 0)) {
+      twl4030_pwrbutton_lock = !twl4030_pwrbutton_lock;
+    }
+    pre_value = value;
+
 		input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ);
 		input_sync(pwr);
 	} else {

P.S. 或者將LOCK_KEY改成10就可以在關上屏幕時,關閉背光亮度。


返回上一頁