mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Linux 4.20
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAlwgIJYeHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiG0F4H/jwv83AI9qxd4Zsj geztCq0w1Vc48Gz/yDvl5MxZ74//q7Wz01qRTKisMNJla+Z0VuUReL12w0BGT0ko ZwPqrvPtM04pA7A6J+vLM8t6k7Ck0q7xC3z/Y9eN5qxtC7yOX/X8RziiXBmyMzM5 nVpFYQwlk9/hSUHjPwMgf2dV32vNYl3FEph3g6nrqQLLdtsHiii9N8rC+cAU2jKg sZ8Cp6REYYxt9LWEilsGof+oLnH+oUkXecB7WKKvSaAVHqR20xdpZ3ZvRcVyLfQ4 XCXBu8PIYYBWsa/iwuu0h4NuosGzEYbWOjnXKozOaV2KoqCT/Rk1egKIgb55EpyA kFH4wfc= =WAE7 -----END PGP SIGNATURE----- Merge tag 'v4.20' into for-linus Sync with mainline to get linux/overflow.h among other things.
This commit is contained in:
commit
3eb66e91a2
24798 changed files with 1696439 additions and 1122469 deletions
|
|
@ -16,7 +16,7 @@ config INPUT
|
|||
|
||||
Say N here if you have a headless (no monitor, no keyboard) system.
|
||||
|
||||
More information is available: <file:Documentation/input/input.txt>
|
||||
More information is available: <file:Documentation/input/input.rst>
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ config INPUT_JOYDEV
|
|||
|
||||
If unsure, say Y.
|
||||
|
||||
More information is available: <file:Documentation/input/joystick.txt>
|
||||
More information is available: <file:Documentation/input/joydev/joystick.rst>
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called joydev.
|
||||
|
|
|
|||
|
|
@ -98,8 +98,7 @@ static int input_leds_connect(struct input_handler *handler,
|
|||
if (!num_leds)
|
||||
return -ENXIO;
|
||||
|
||||
leds = kzalloc(sizeof(*leds) + num_leds * sizeof(*leds->leds),
|
||||
GFP_KERNEL);
|
||||
leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL);
|
||||
if (!leds)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots,
|
|||
if (mt)
|
||||
return mt->num_slots != num_slots ? -EINVAL : 0;
|
||||
|
||||
mt = kzalloc(sizeof(*mt) + num_slots * sizeof(*mt->slots), GFP_KERNEL);
|
||||
mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL);
|
||||
if (!mt)
|
||||
goto err_mem;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ menuconfig INPUT_JOYSTICK
|
|||
and the list of supported devices will be displayed. This option
|
||||
doesn't affect the kernel.
|
||||
|
||||
Please read the file <file:Documentation/input/joystick.txt> which
|
||||
Please read the file <file:Documentation/input/joydev/joystick.rst> which
|
||||
contains more information.
|
||||
|
||||
if INPUT_JOYSTICK
|
||||
|
|
@ -25,7 +25,7 @@ config JOYSTICK_ANALOG
|
|||
Flightstick Pro, ThrustMaster FCS, 6 and 8 button gamepads, or
|
||||
Saitek Cyborg joysticks.
|
||||
|
||||
Please read the file <file:Documentation/input/joystick.txt> which
|
||||
Please read the file <file:Documentation/input/joydev/joystick.rst> which
|
||||
contains more information.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
|
|
@ -214,7 +214,7 @@ config JOYSTICK_DB9
|
|||
gamepad, Sega Saturn gamepad, or a Multisystem -- Atari, Amiga,
|
||||
Commodore, Amstrad CPC joystick connected to your parallel port.
|
||||
For more information on how to use the driver please read
|
||||
<file:Documentation/input/joystick-parport.txt>.
|
||||
<file:Documentation/input/devices/joystick-parport.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called db9.
|
||||
|
|
@ -229,7 +229,7 @@ config JOYSTICK_GAMECON
|
|||
Sony PlayStation gamepad or a Multisystem -- Atari, Amiga,
|
||||
Commodore, Amstrad CPC joystick connected to your parallel port.
|
||||
For more information on how to use the driver please read
|
||||
<file:Documentation/input/joystick-parport.txt>.
|
||||
<file:Documentation/input/devices/joystick-parport.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called gamecon.
|
||||
|
|
@ -241,7 +241,7 @@ config JOYSTICK_TURBOGRAFX
|
|||
Say Y here if you have the TurboGraFX interface by Steffen Schwenke,
|
||||
and want to use it with Multisystem -- Atari, Amiga, Commodore,
|
||||
Amstrad CPC joystick. For more information on how to use the driver
|
||||
please read <file:Documentation/input/joystick-parport.txt>.
|
||||
please read <file:Documentation/input/devices/joystick-parport.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called turbografx.
|
||||
|
|
@ -287,7 +287,7 @@ config JOYSTICK_XPAD
|
|||
and/or "Event interface support" (CONFIG_INPUT_EVDEV) as well.
|
||||
|
||||
For information about how to connect the X-Box pad to USB, see
|
||||
<file:Documentation/input/xpad.txt>.
|
||||
<file:Documentation/input/devices/xpad.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called xpad.
|
||||
|
|
@ -313,7 +313,7 @@ config JOYSTICK_WALKERA0701
|
|||
Say Y or M here if you have a Walkera WK-0701 transmitter which is
|
||||
supplied with a ready to fly Walkera helicopters such as HM36,
|
||||
HM37, HM60 and want to use it via parport as a joystick. More
|
||||
information is available: <file:Documentation/input/walkera0701.txt>
|
||||
information is available: <file:Documentation/input/devices/walkera0701.rst>
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called walkera0701.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,6 @@ config JOYSTICK_IFORCE_232
|
|||
connected to your serial (COM) port.
|
||||
|
||||
You will need an additional utility called inputattach, see
|
||||
<file:Documentation/input/joystick.txt>
|
||||
and <file:Documentation/input/ff.txt>.
|
||||
<file:Documentation/input/joydev/joystick.rst>
|
||||
and <file:Documentation/input/ff.rst>.
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr
|
|||
|
||||
timeout = gameport_time(gameport, 10000); /* 10 ms */
|
||||
|
||||
buf = kmalloc(BUF_SIZE * sizeof(struct joydump), GFP_KERNEL);
|
||||
buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk(KERN_INFO "joydump: no memory for testing\n");
|
||||
goto jd_end;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (c) 2008 Peter Popovec
|
||||
*
|
||||
* More about driver: <file:Documentation/input/walkera0701.txt>
|
||||
* More about driver: <file:Documentation/input/devices/walkera0701.rst>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ config KEYBOARD_CROS_EC
|
|||
help
|
||||
Say Y here to enable the matrix keyboard used by ChromeOS devices
|
||||
and implemented on the ChromeOS EC. You must enable one bus option
|
||||
(MFD_CROS_EC_I2C or MFD_CROS_EC_SPI) to use this.
|
||||
(CROS_EC_I2C or CROS_EC_SPI) to use this.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called cros_ec_keyb.
|
||||
|
|
@ -747,4 +747,13 @@ config KEYBOARD_BCM
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called bcm-keypad.
|
||||
|
||||
config KEYBOARD_MTK_PMIC
|
||||
tristate "MediaTek PMIC keys support"
|
||||
depends on MFD_MT6397
|
||||
help
|
||||
Say Y here if you want to use the pmic keys (powerkey/homekey).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pmic-keys.
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
|
|||
obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
|
||||
obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o
|
||||
obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o
|
||||
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o
|
||||
|
|
|
|||
|
|
@ -357,8 +357,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
|
|||
}
|
||||
|
||||
priv = devm_kzalloc(dev,
|
||||
sizeof(*priv) +
|
||||
cap->num_channels * sizeof(priv->keycodes[0]),
|
||||
struct_size(priv, keycodes, cap->num_channels),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ static int clps711x_keypad_probe(struct platform_device *pdev)
|
|||
if (priv->row_count < 1)
|
||||
return -EINVAL;
|
||||
|
||||
priv->gpio_data = devm_kzalloc(dev,
|
||||
sizeof(*priv->gpio_data) * priv->row_count,
|
||||
priv->gpio_data = devm_kcalloc(dev,
|
||||
priv->row_count, sizeof(*priv->gpio_data),
|
||||
GFP_KERNEL);
|
||||
if (!priv->gpio_data)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* linux/drivers/hil/hilkbd.c
|
||||
*
|
||||
* Copyright (C) 1998 Philip Blundell <philb@gnu.org>
|
||||
* Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai>
|
||||
* Copyright (C) 1999 Matthew Wilcox <willy@infradead.org>
|
||||
* Copyright (C) 1999-2007 Helge Deller <deller@gmx.de>
|
||||
*
|
||||
* Very basic HP Human Interface Loop (HIL) driver.
|
||||
|
|
@ -57,8 +57,8 @@ MODULE_LICENSE("GPL v2");
|
|||
#define HIL_DATA 0x1
|
||||
#define HIL_CMD 0x3
|
||||
#define HIL_IRQ 2
|
||||
#define hil_readb(p) readb(p)
|
||||
#define hil_writeb(v,p) writeb((v),(p))
|
||||
#define hil_readb(p) readb((const volatile void __iomem *)(p))
|
||||
#define hil_writeb(v, p) writeb((v), (volatile void __iomem *)(p))
|
||||
|
||||
#else
|
||||
#error "HIL is not supported on this platform"
|
||||
|
|
|
|||
|
|
@ -443,9 +443,9 @@ matrix_keypad_parse_dt(struct device *dev)
|
|||
of_property_read_u32(np, "col-scan-delay-us",
|
||||
&pdata->col_scan_delay_us);
|
||||
|
||||
gpios = devm_kzalloc(dev,
|
||||
sizeof(unsigned int) *
|
||||
(pdata->num_row_gpios + pdata->num_col_gpios),
|
||||
gpios = devm_kcalloc(dev,
|
||||
pdata->num_row_gpios + pdata->num_col_gpios,
|
||||
sizeof(unsigned int),
|
||||
GFP_KERNEL);
|
||||
if (!gpios) {
|
||||
dev_err(dev, "could not allocate memory for gpios\n");
|
||||
|
|
|
|||
339
drivers/input/keyboard/mtk-pmic-keys.c
Normal file
339
drivers/input/keyboard/mtk-pmic-keys.c
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* Copyright (C) 2017 MediaTek, Inc.
|
||||
*
|
||||
* Author: Chen Zhong <chen.zhong@mediatek.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/mt6323/registers.h>
|
||||
#include <linux/mfd/mt6397/registers.h>
|
||||
#include <linux/mfd/mt6397/core.h>
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5
|
||||
#define MTK_PMIC_RST_DU_MASK 0x3
|
||||
#define MTK_PMIC_RST_DU_SHIFT 8
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST \
|
||||
(MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
|
||||
#define MTK_PMIC_HOMEKEY_RST \
|
||||
(MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
|
||||
|
||||
#define MTK_PMIC_PWRKEY_INDEX 0
|
||||
#define MTK_PMIC_HOMEKEY_INDEX 1
|
||||
#define MTK_PMIC_MAX_KEY_COUNT 2
|
||||
|
||||
struct mtk_pmic_keys_regs {
|
||||
u32 deb_reg;
|
||||
u32 deb_mask;
|
||||
u32 intsel_reg;
|
||||
u32 intsel_mask;
|
||||
};
|
||||
|
||||
#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \
|
||||
_intsel_reg, _intsel_mask) \
|
||||
{ \
|
||||
.deb_reg = _deb_reg, \
|
||||
.deb_mask = _deb_mask, \
|
||||
.intsel_reg = _intsel_reg, \
|
||||
.intsel_mask = _intsel_mask, \
|
||||
}
|
||||
|
||||
struct mtk_pmic_regs {
|
||||
const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
|
||||
u32 pmic_rst_reg;
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6397_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
|
||||
0x8, MT6397_INT_RSV, 0x10),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
|
||||
0x10, MT6397_INT_RSV, 0x8),
|
||||
.pmic_rst_reg = MT6397_TOP_RST_MISC,
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6323_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x2, MT6323_INT_MISC_CON, 0x10),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x4, MT6323_INT_MISC_CON, 0x8),
|
||||
.pmic_rst_reg = MT6323_TOP_RST_MISC,
|
||||
};
|
||||
|
||||
struct mtk_pmic_keys_info {
|
||||
struct mtk_pmic_keys *keys;
|
||||
const struct mtk_pmic_keys_regs *regs;
|
||||
unsigned int keycode;
|
||||
int irq;
|
||||
bool wakeup:1;
|
||||
};
|
||||
|
||||
struct mtk_pmic_keys {
|
||||
struct input_dev *input_dev;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT];
|
||||
};
|
||||
|
||||
enum mtk_pmic_keys_lp_mode {
|
||||
LP_DISABLE,
|
||||
LP_ONEKEY,
|
||||
LP_TWOKEY,
|
||||
};
|
||||
|
||||
static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
|
||||
u32 pmic_rst_reg)
|
||||
{
|
||||
int ret;
|
||||
u32 long_press_mode, long_press_debounce;
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"power-off-time-sec", &long_press_debounce);
|
||||
if (ret)
|
||||
long_press_debounce = 0;
|
||||
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
|
||||
long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"mediatek,long-press-mode", &long_press_mode);
|
||||
if (ret)
|
||||
long_press_mode = LP_DISABLE;
|
||||
|
||||
switch (long_press_mode) {
|
||||
case LP_ONEKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
break;
|
||||
case LP_TWOKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
MTK_PMIC_HOMEKEY_RST);
|
||||
break;
|
||||
case LP_DISABLE:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
0);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
|
||||
{
|
||||
struct mtk_pmic_keys_info *info = data;
|
||||
u32 key_deb, pressed;
|
||||
|
||||
regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb);
|
||||
|
||||
key_deb &= info->regs->deb_mask;
|
||||
|
||||
pressed = !key_deb;
|
||||
|
||||
input_report_key(info->keys->input_dev, info->keycode, pressed);
|
||||
input_sync(info->keys->input_dev);
|
||||
|
||||
dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n",
|
||||
pressed ? "pressed" : "released", info->keycode);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
|
||||
struct mtk_pmic_keys_info *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
info->keys = keys;
|
||||
|
||||
ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg,
|
||||
info->regs->intsel_mask,
|
||||
info->regs->intsel_mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_threaded_irq(keys->dev, info->irq, NULL,
|
||||
mtk_pmic_keys_irq_handler_thread,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
|
||||
"mtk-pmic-keys", info);
|
||||
if (ret) {
|
||||
dev_err(keys->dev, "Failed to request IRQ: %d: %d\n",
|
||||
info->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_set_capability(keys->input_dev, EV_KEY, info->keycode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
|
||||
{
|
||||
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
|
||||
if (keys->keys[index].wakeup)
|
||||
enable_irq_wake(keys->keys[index].irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
|
||||
{
|
||||
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
|
||||
if (keys->keys[index].wakeup)
|
||||
disable_irq_wake(keys->keys[index].irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
|
||||
mtk_pmic_keys_resume);
|
||||
|
||||
static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt6397-keys",
|
||||
.data = &mt6397_regs,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6323-keys",
|
||||
.data = &mt6323_regs,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl);
|
||||
|
||||
static int mtk_pmic_keys_probe(struct platform_device *pdev)
|
||||
{
|
||||
int error, index = 0;
|
||||
unsigned int keycount;
|
||||
struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device_node *node = pdev->dev.of_node, *child;
|
||||
struct mtk_pmic_keys *keys;
|
||||
const struct mtk_pmic_regs *mtk_pmic_regs;
|
||||
struct input_dev *input_dev;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
|
||||
|
||||
keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
|
||||
if (!keys)
|
||||
return -ENOMEM;
|
||||
|
||||
keys->dev = &pdev->dev;
|
||||
keys->regmap = pmic_chip->regmap;
|
||||
mtk_pmic_regs = of_id->data;
|
||||
|
||||
keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
|
||||
if (!input_dev) {
|
||||
dev_err(keys->dev, "input allocate device fail.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input_dev->name = "mtk-pmic-keys";
|
||||
input_dev->id.bustype = BUS_HOST;
|
||||
input_dev->id.vendor = 0x0001;
|
||||
input_dev->id.product = 0x0001;
|
||||
input_dev->id.version = 0x0001;
|
||||
|
||||
keycount = of_get_available_child_count(node);
|
||||
if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
|
||||
dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
|
||||
|
||||
keys->keys[index].irq = platform_get_irq(pdev, index);
|
||||
if (keys->keys[index].irq < 0)
|
||||
return keys->keys[index].irq;
|
||||
|
||||
error = of_property_read_u32(child,
|
||||
"linux,keycodes", &keys->keys[index].keycode);
|
||||
if (error) {
|
||||
dev_err(keys->dev,
|
||||
"failed to read key:%d linux,keycode property: %d\n",
|
||||
index, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(child, "wakeup-source"))
|
||||
keys->keys[index].wakeup = true;
|
||||
|
||||
error = mtk_pmic_key_setup(keys, &keys->keys[index]);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"register input device failed (%d)\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
|
||||
|
||||
platform_set_drvdata(pdev, keys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pmic_keys_pdrv = {
|
||||
.probe = mtk_pmic_keys_probe,
|
||||
.driver = {
|
||||
.name = "mtk-pmic-keys",
|
||||
.of_match_table = of_mtk_pmic_keys_match_tbl,
|
||||
.pm = &mtk_pmic_keys_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(pmic_keys_pdrv);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Chen Zhong <[email protected]>");
|
||||
MODULE_DESCRIPTION("MTK pmic-keys driver v0.1");
|
||||
|
|
@ -339,7 +339,8 @@ static int omap4_keypad_probe(struct platform_device *pdev)
|
|||
|
||||
keypad_data->row_shift = get_count_order(keypad_data->cols);
|
||||
max_keys = keypad_data->rows << keypad_data->row_shift;
|
||||
keypad_data->keymap = kzalloc(max_keys * sizeof(keypad_data->keymap[0]),
|
||||
keypad_data->keymap = kcalloc(max_keys,
|
||||
sizeof(keypad_data->keymap[0]),
|
||||
GFP_KERNEL);
|
||||
if (!keypad_data->keymap) {
|
||||
dev_err(&pdev->dev, "Not enough memory for keymap\n");
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ samsung_keypad_parse_dt(struct device *dev)
|
|||
|
||||
key_count = of_get_child_count(np);
|
||||
keymap_data->keymap_size = key_count;
|
||||
keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
|
||||
keymap = devm_kcalloc(dev, key_count, sizeof(uint32_t), GFP_KERNEL);
|
||||
if (!keymap) {
|
||||
dev_err(dev, "could not allocate memory for keymap\n");
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
|
|
|||
|
|
@ -170,8 +170,8 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
|
|||
return -EINVAL;
|
||||
|
||||
if (!keymap) {
|
||||
keymap = devm_kzalloc(input_dev->dev.parent,
|
||||
max_keys * sizeof(*keymap),
|
||||
keymap = devm_kcalloc(input_dev->dev.parent,
|
||||
max_keys, sizeof(*keymap),
|
||||
GFP_KERNEL);
|
||||
if (!keymap) {
|
||||
dev_err(input_dev->dev.parent,
|
||||
|
|
|
|||
|
|
@ -411,7 +411,7 @@ config INPUT_YEALINK
|
|||
usb sound driver, so you might want to enable that as well.
|
||||
|
||||
For information about how to use these additional functions, see
|
||||
<file:Documentation/input/yealink.txt>.
|
||||
<file:Documentation/input/devices/yealink.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called yealink.
|
||||
|
|
@ -595,7 +595,7 @@ config INPUT_GPIO_ROTARY_ENCODER
|
|||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
Say Y here to add support for rotary encoders connected to GPIO lines.
|
||||
Check file:Documentation/input/rotary-encoder.txt for more
|
||||
Check file:Documentation/input/devices/rotary-encoder.rst for more
|
||||
information.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
|
|
|
|||
|
|
@ -509,18 +509,6 @@ static int hp_sdc_rtc_proc_show(struct seq_file *m, void *v)
|
|||
#undef NY
|
||||
}
|
||||
|
||||
static int hp_sdc_rtc_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, hp_sdc_rtc_proc_show, NULL);
|
||||
}
|
||||
|
||||
static const struct file_operations hp_sdc_rtc_proc_fops = {
|
||||
.open = hp_sdc_rtc_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int hp_sdc_rtc_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
|
@ -713,7 +701,7 @@ static int __init hp_sdc_rtc_init(void)
|
|||
if (misc_register(&hp_sdc_rtc_dev) != 0)
|
||||
printk(KERN_INFO "Could not register misc. dev for i8042 rtc\n");
|
||||
|
||||
proc_create("driver/rtc", 0, NULL, &hp_sdc_rtc_proc_fops);
|
||||
proc_create_single("driver/rtc", 0, NULL, hp_sdc_rtc_proc_show);
|
||||
|
||||
printk(KERN_INFO "HP i8042 SDC + MSM-58321 RTC support loaded "
|
||||
"(RTC v " RTC_VERSION ")\n");
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* state machine code inspired by code from Tim Ruetz
|
||||
*
|
||||
* A generic driver for rotary encoders connected to GPIO lines.
|
||||
* See file:Documentation/input/rotary-encoder.txt for more information
|
||||
* See file:Documentation/input/devices/rotary-encoder.rst for more information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
|
@ -285,8 +285,8 @@ static int rotary_encoder_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
encoder->irq =
|
||||
devm_kzalloc(dev,
|
||||
sizeof(*encoder->irq) * encoder->gpios->ndescs,
|
||||
devm_kcalloc(dev,
|
||||
encoder->gpios->ndescs, sizeof(*encoder->irq),
|
||||
GFP_KERNEL);
|
||||
if (!encoder->irq)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ config MOUSE_PS2_ELANTECH
|
|||
|
||||
This driver exposes some configuration registers via sysfs
|
||||
entries. For further information,
|
||||
see <file:Documentation/input/elantech.txt>.
|
||||
see <file:Documentation/input/devices/elantech.rst>.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ config MOUSE_APPLETOUCH
|
|||
scrolling in X11.
|
||||
|
||||
For further information, see
|
||||
<file:Documentation/input/appletouch.txt>.
|
||||
<file:Documentation/input/devices/appletouch.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called appletouch.
|
||||
|
|
@ -251,7 +251,7 @@ config MOUSE_BCM5974
|
|||
|
||||
The interface is currently identical to the appletouch interface,
|
||||
for further information, see
|
||||
<file:Documentation/input/appletouch.txt>.
|
||||
<file:Documentation/input/devices/appletouch.rst>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called bcm5974.
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ static void alps_set_abs_params_v7(struct alps_data *priv,
|
|||
static void alps_set_abs_params_ss4_v2(struct alps_data *priv,
|
||||
struct input_dev *dev1);
|
||||
|
||||
/* Packet formats are described in Documentation/input/alps.txt */
|
||||
/* Packet formats are described in Documentation/input/devices/alps.rst */
|
||||
|
||||
static bool alps_is_valid_first_byte(struct alps_data *priv,
|
||||
unsigned char data)
|
||||
|
|
|
|||
|
|
@ -612,9 +612,10 @@ int rmi_read_register_desc(struct rmi_device *d, u16 addr,
|
|||
rdesc->num_registers = bitmap_weight(rdesc->presense_map,
|
||||
RMI_REG_DESC_PRESENSE_BITS);
|
||||
|
||||
rdesc->registers = devm_kzalloc(&d->dev, rdesc->num_registers *
|
||||
sizeof(struct rmi_register_desc_item),
|
||||
GFP_KERNEL);
|
||||
rdesc->registers = devm_kcalloc(&d->dev,
|
||||
rdesc->num_registers,
|
||||
sizeof(struct rmi_register_desc_item),
|
||||
GFP_KERNEL);
|
||||
if (!rdesc->registers)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -1050,7 +1051,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
|
|||
data->num_of_irq_regs = (data->irq_count + 7) / 8;
|
||||
|
||||
size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long);
|
||||
data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL);
|
||||
data->irq_memory = devm_kcalloc(dev, size, 4, GFP_KERNEL);
|
||||
if (!data->irq_memory) {
|
||||
dev_err(dev, "Failed to allocate memory for irq masks.\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -1180,14 +1180,15 @@ static int rmi_f11_initialize(struct rmi_function *fn)
|
|||
f11->sensor.attn_size += f11->sensor.nbr_fingers * 2;
|
||||
|
||||
/* allocate the in-kernel tracking buffers */
|
||||
sensor->tracking_pos = devm_kzalloc(&fn->dev,
|
||||
sizeof(struct input_mt_pos) * sensor->nbr_fingers,
|
||||
sensor->tracking_pos = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers, sizeof(struct input_mt_pos),
|
||||
GFP_KERNEL);
|
||||
sensor->tracking_slots = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers, sizeof(int), GFP_KERNEL);
|
||||
sensor->objs = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers,
|
||||
sizeof(struct rmi_2d_sensor_abs_object),
|
||||
GFP_KERNEL);
|
||||
sensor->tracking_slots = devm_kzalloc(&fn->dev,
|
||||
sizeof(int) * sensor->nbr_fingers, GFP_KERNEL);
|
||||
sensor->objs = devm_kzalloc(&fn->dev,
|
||||
sizeof(struct rmi_2d_sensor_abs_object)
|
||||
* sensor->nbr_fingers, GFP_KERNEL);
|
||||
if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -502,14 +502,15 @@ static int rmi_f12_probe(struct rmi_function *fn)
|
|||
}
|
||||
|
||||
/* allocate the in-kernel tracking buffers */
|
||||
sensor->tracking_pos = devm_kzalloc(&fn->dev,
|
||||
sizeof(struct input_mt_pos) * sensor->nbr_fingers,
|
||||
sensor->tracking_pos = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers, sizeof(struct input_mt_pos),
|
||||
GFP_KERNEL);
|
||||
sensor->tracking_slots = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers, sizeof(int), GFP_KERNEL);
|
||||
sensor->objs = devm_kcalloc(&fn->dev,
|
||||
sensor->nbr_fingers,
|
||||
sizeof(struct rmi_2d_sensor_abs_object),
|
||||
GFP_KERNEL);
|
||||
sensor->tracking_slots = devm_kzalloc(&fn->dev,
|
||||
sizeof(int) * sensor->nbr_fingers, GFP_KERNEL);
|
||||
sensor->objs = devm_kzalloc(&fn->dev,
|
||||
sizeof(struct rmi_2d_sensor_abs_object)
|
||||
* sensor->nbr_fingers, GFP_KERNEL);
|
||||
if (!sensor->tracking_pos || !sensor->tracking_slots || !sensor->objs)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ static int rmi_f54_probe(struct rmi_function *fn)
|
|||
rx = f54->num_rx_electrodes;
|
||||
tx = f54->num_tx_electrodes;
|
||||
f54->report_data = devm_kzalloc(&fn->dev,
|
||||
sizeof(u16) * tx * rx,
|
||||
array3_size(tx, rx, sizeof(u16)),
|
||||
GFP_KERNEL);
|
||||
if (f54->report_data == NULL)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len)
|
|||
buf_size = RMI_SPI_XFER_SIZE_LIMIT;
|
||||
|
||||
tmp = rmi_spi->rx_buf;
|
||||
buf = devm_kzalloc(&spi->dev, buf_size * 2,
|
||||
buf = devm_kcalloc(&spi->dev, buf_size, 2,
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
|
@ -96,9 +96,10 @@ static int rmi_spi_manage_pools(struct rmi_spi_xport *rmi_spi, int len)
|
|||
* per byte delays.
|
||||
*/
|
||||
tmp = rmi_spi->rx_xfers;
|
||||
xfer_buf = devm_kzalloc(&spi->dev,
|
||||
(rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count)
|
||||
* sizeof(struct spi_transfer), GFP_KERNEL);
|
||||
xfer_buf = devm_kcalloc(&spi->dev,
|
||||
rmi_spi->rx_xfer_count + rmi_spi->tx_xfer_count,
|
||||
sizeof(struct spi_transfer),
|
||||
GFP_KERNEL);
|
||||
if (!xfer_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ config SERIO_SERPORT
|
|||
Say Y here if you plan to use an input device (mouse, joystick,
|
||||
tablet, 6dof) that communicates over the RS232 serial (COM) port.
|
||||
|
||||
More information is available: <file:Documentation/input/input.txt>
|
||||
More information is available: <file:Documentation/input/input.rst>
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ config SERIO_PARKBD
|
|||
Say Y here if you built a simple parallel port adapter to attach
|
||||
an additional AT keyboard, XT keyboard or PS/2 mouse.
|
||||
|
||||
More information is available: <file:Documentation/input/input.txt>
|
||||
More information is available: <file:Documentation/input/input.rst>
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
|
|
|
|||
|
|
@ -20,32 +20,33 @@
|
|||
* However, when used with the E3 mailboard that producecs non-standard
|
||||
* scancodes, a custom key table must be prepared and loaded from userspace.
|
||||
*/
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_data/ams-delta-fiq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <mach/board-ams-delta.h>
|
||||
|
||||
#include <mach/ams-delta-fiq.h>
|
||||
#define DRIVER_NAME "ams-delta-serio"
|
||||
|
||||
MODULE_AUTHOR("Matt Callow");
|
||||
MODULE_DESCRIPTION("AMS Delta (E3) keyboard port driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct serio *ams_delta_serio;
|
||||
struct ams_delta_serio {
|
||||
struct serio *serio;
|
||||
struct regulator *vcc;
|
||||
unsigned int *fiq_buffer;
|
||||
};
|
||||
|
||||
static int check_data(int data)
|
||||
static int check_data(struct serio *serio, int data)
|
||||
{
|
||||
int i, parity = 0;
|
||||
|
||||
/* check valid stop bit */
|
||||
if (!(data & 0x400)) {
|
||||
dev_warn(&ams_delta_serio->dev,
|
||||
"invalid stop bit, data=0x%X\n",
|
||||
data);
|
||||
dev_warn(&serio->dev, "invalid stop bit, data=0x%X\n", data);
|
||||
return SERIO_FRAME;
|
||||
}
|
||||
/* calculate the parity */
|
||||
|
|
@ -55,9 +56,9 @@ static int check_data(int data)
|
|||
}
|
||||
/* it should be odd */
|
||||
if (!(parity & 0x01)) {
|
||||
dev_warn(&ams_delta_serio->dev,
|
||||
"parity check failed, data=0x%X parity=0x%X\n",
|
||||
data, parity);
|
||||
dev_warn(&serio->dev,
|
||||
"parity check failed, data=0x%X parity=0x%X\n", data,
|
||||
parity);
|
||||
return SERIO_PARITY;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -65,127 +66,130 @@ static int check_data(int data)
|
|||
|
||||
static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
int *circ_buff = &fiq_buffer[FIQ_CIRC_BUFF];
|
||||
struct ams_delta_serio *priv = dev_id;
|
||||
int *circ_buff = &priv->fiq_buffer[FIQ_CIRC_BUFF];
|
||||
int data, dfl;
|
||||
u8 scancode;
|
||||
|
||||
fiq_buffer[FIQ_IRQ_PEND] = 0;
|
||||
priv->fiq_buffer[FIQ_IRQ_PEND] = 0;
|
||||
|
||||
/*
|
||||
* Read data from the circular buffer, check it
|
||||
* and then pass it on the serio
|
||||
*/
|
||||
while (fiq_buffer[FIQ_KEYS_CNT] > 0) {
|
||||
while (priv->fiq_buffer[FIQ_KEYS_CNT] > 0) {
|
||||
|
||||
data = circ_buff[fiq_buffer[FIQ_HEAD_OFFSET]++];
|
||||
fiq_buffer[FIQ_KEYS_CNT]--;
|
||||
if (fiq_buffer[FIQ_HEAD_OFFSET] == fiq_buffer[FIQ_BUF_LEN])
|
||||
fiq_buffer[FIQ_HEAD_OFFSET] = 0;
|
||||
data = circ_buff[priv->fiq_buffer[FIQ_HEAD_OFFSET]++];
|
||||
priv->fiq_buffer[FIQ_KEYS_CNT]--;
|
||||
if (priv->fiq_buffer[FIQ_HEAD_OFFSET] ==
|
||||
priv->fiq_buffer[FIQ_BUF_LEN])
|
||||
priv->fiq_buffer[FIQ_HEAD_OFFSET] = 0;
|
||||
|
||||
dfl = check_data(data);
|
||||
dfl = check_data(priv->serio, data);
|
||||
scancode = (u8) (data >> 1) & 0xFF;
|
||||
serio_interrupt(ams_delta_serio, scancode, dfl);
|
||||
serio_interrupt(priv->serio, scancode, dfl);
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ams_delta_serio_open(struct serio *serio)
|
||||
{
|
||||
/* enable keyboard */
|
||||
gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 1);
|
||||
struct ams_delta_serio *priv = serio->port_data;
|
||||
|
||||
return 0;
|
||||
/* enable keyboard */
|
||||
return regulator_enable(priv->vcc);
|
||||
}
|
||||
|
||||
static void ams_delta_serio_close(struct serio *serio)
|
||||
{
|
||||
struct ams_delta_serio *priv = serio->port_data;
|
||||
|
||||
/* disable keyboard */
|
||||
gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0);
|
||||
regulator_disable(priv->vcc);
|
||||
}
|
||||
|
||||
static const struct gpio ams_delta_gpios[] __initconst_or_module = {
|
||||
{
|
||||
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
|
||||
.flags = GPIOF_DIR_IN,
|
||||
.label = "serio-data",
|
||||
},
|
||||
{
|
||||
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
|
||||
.flags = GPIOF_DIR_IN,
|
||||
.label = "serio-clock",
|
||||
},
|
||||
{
|
||||
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR,
|
||||
.flags = GPIOF_OUT_INIT_LOW,
|
||||
.label = "serio-power",
|
||||
},
|
||||
{
|
||||
.gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT,
|
||||
.flags = GPIOF_OUT_INIT_LOW,
|
||||
.label = "serio-dataout",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init ams_delta_serio_init(void)
|
||||
static int ams_delta_serio_init(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
struct ams_delta_serio *priv;
|
||||
struct serio *serio;
|
||||
int irq, err;
|
||||
|
||||
if (!machine_is_ams_delta())
|
||||
return -ENODEV;
|
||||
|
||||
ams_delta_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
|
||||
if (!ams_delta_serio)
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
ams_delta_serio->id.type = SERIO_8042;
|
||||
ams_delta_serio->open = ams_delta_serio_open;
|
||||
ams_delta_serio->close = ams_delta_serio_close;
|
||||
strlcpy(ams_delta_serio->name, "AMS DELTA keyboard adapter",
|
||||
sizeof(ams_delta_serio->name));
|
||||
strlcpy(ams_delta_serio->phys, "GPIO/serio0",
|
||||
sizeof(ams_delta_serio->phys));
|
||||
priv->fiq_buffer = pdev->dev.platform_data;
|
||||
if (!priv->fiq_buffer)
|
||||
return -EINVAL;
|
||||
|
||||
err = gpio_request_array(ams_delta_gpios,
|
||||
ARRAY_SIZE(ams_delta_gpios));
|
||||
if (err) {
|
||||
pr_err("ams_delta_serio: Couldn't request gpio pins\n");
|
||||
goto serio;
|
||||
priv->vcc = devm_regulator_get(&pdev->dev, "vcc");
|
||||
if (IS_ERR(priv->vcc)) {
|
||||
err = PTR_ERR(priv->vcc);
|
||||
dev_err(&pdev->dev, "regulator request failed (%d)\n", err);
|
||||
/*
|
||||
* When running on a non-dt platform and requested regulator
|
||||
* is not available, devm_regulator_get() never returns
|
||||
* -EPROBE_DEFER as it is not able to justify if the regulator
|
||||
* may still appear later. On the other hand, the board can
|
||||
* still set full constriants flag at late_initcall in order
|
||||
* to instruct devm_regulator_get() to returnn a dummy one
|
||||
* if sufficient. Hence, if we get -ENODEV here, let's convert
|
||||
* it to -EPROBE_DEFER and wait for the board to decide or
|
||||
* let Deferred Probe infrastructure handle this error.
|
||||
*/
|
||||
if (err == -ENODEV)
|
||||
err = -EPROBE_DEFER;
|
||||
return err;
|
||||
}
|
||||
|
||||
err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
|
||||
ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING,
|
||||
"ams-delta-serio", 0);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return -ENXIO;
|
||||
|
||||
err = devm_request_irq(&pdev->dev, irq, ams_delta_serio_interrupt,
|
||||
IRQ_TYPE_EDGE_RISING, DRIVER_NAME, priv);
|
||||
if (err < 0) {
|
||||
pr_err("ams_delta_serio: couldn't request gpio interrupt %d\n",
|
||||
gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK));
|
||||
goto gpio;
|
||||
dev_err(&pdev->dev, "IRQ request failed (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
/*
|
||||
* Since GPIO register handling for keyboard clock pin is performed
|
||||
* at FIQ level, switch back from edge to simple interrupt handler
|
||||
* to avoid bad interaction.
|
||||
*/
|
||||
irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
|
||||
handle_simple_irq);
|
||||
|
||||
serio_register_port(ams_delta_serio);
|
||||
dev_info(&ams_delta_serio->dev, "%s\n", ams_delta_serio->name);
|
||||
serio = kzalloc(sizeof(*serio), GFP_KERNEL);
|
||||
if (!serio)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->serio = serio;
|
||||
|
||||
serio->id.type = SERIO_8042;
|
||||
serio->open = ams_delta_serio_open;
|
||||
serio->close = ams_delta_serio_close;
|
||||
strlcpy(serio->name, "AMS DELTA keyboard adapter", sizeof(serio->name));
|
||||
strlcpy(serio->phys, dev_name(&pdev->dev), sizeof(serio->phys));
|
||||
serio->dev.parent = &pdev->dev;
|
||||
serio->port_data = priv;
|
||||
|
||||
serio_register_port(serio);
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
dev_info(&serio->dev, "%s\n", serio->name);
|
||||
|
||||
return 0;
|
||||
gpio:
|
||||
gpio_free_array(ams_delta_gpios,
|
||||
ARRAY_SIZE(ams_delta_gpios));
|
||||
serio:
|
||||
kfree(ams_delta_serio);
|
||||
return err;
|
||||
}
|
||||
module_init(ams_delta_serio_init);
|
||||
|
||||
static void __exit ams_delta_serio_exit(void)
|
||||
static int ams_delta_serio_exit(struct platform_device *pdev)
|
||||
{
|
||||
serio_unregister_port(ams_delta_serio);
|
||||
free_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0);
|
||||
gpio_free_array(ams_delta_gpios,
|
||||
ARRAY_SIZE(ams_delta_gpios));
|
||||
struct ams_delta_serio *priv = platform_get_drvdata(pdev);
|
||||
|
||||
serio_unregister_port(priv->serio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
module_exit(ams_delta_serio_exit);
|
||||
|
||||
static struct platform_driver ams_delta_serio_driver = {
|
||||
.probe = ams_delta_serio_init,
|
||||
.remove = ams_delta_serio_exit,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME
|
||||
},
|
||||
};
|
||||
module_platform_driver(ams_delta_serio_driver);
|
||||
|
|
|
|||
|
|
@ -424,6 +424,9 @@ static struct hv_driver hv_kbd_drv = {
|
|||
.id_table = id_table,
|
||||
.probe = hv_kbd_probe,
|
||||
.remove = hv_kbd_remove,
|
||||
.driver = {
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init hv_kbd_init(void)
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file,
|
|||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define COMPAT_SPIOCSTYPE _IOW('q', 0x01, compat_ulong_t)
|
||||
static long serport_ldisc_compat_ioctl(struct tty_struct *tty,
|
||||
static int serport_ldisc_compat_ioctl(struct tty_struct *tty,
|
||||
struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -92,6 +92,19 @@ config TOUCHSCREEN_AD7879_SPI
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called ad7879-spi.
|
||||
|
||||
config TOUCHSCREEN_ADC
|
||||
tristate "Generic ADC based resistive touchscreen"
|
||||
depends on IIO
|
||||
select IIO_BUFFER_CB
|
||||
help
|
||||
Say Y here if you want to use the generic ADC
|
||||
resistive touchscreen driver.
|
||||
|
||||
If unsure, say N (but it's safe to say "Y").
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called resistive-adc-touch.ko.
|
||||
|
||||
config TOUCHSCREEN_AR1021_I2C
|
||||
tristate "Microchip AR1020/1021 i2c touchscreen"
|
||||
depends on I2C && OF
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
|
|||
obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ADC) += resistive-adc-touch.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
|
||||
|
|
|
|||
204
drivers/input/touchscreen/resistive-adc-touch.c
Normal file
204
drivers/input/touchscreen/resistive-adc-touch.c
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* ADC generic resistive touchscreen (GRTS)
|
||||
* This is a generic input driver that connects to an ADC
|
||||
* given the channels in device tree, and reports events to the input
|
||||
* subsystem.
|
||||
*
|
||||
* Copyright (C) 2017,2018 Microchip Technology,
|
||||
* Author: Eugen Hristev <eugen.hristev@microchip.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/iio/consumer.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define DRIVER_NAME "resistive-adc-touch"
|
||||
#define GRTS_DEFAULT_PRESSURE_MIN 50000
|
||||
#define GRTS_MAX_POS_MASK GENMASK(11, 0)
|
||||
|
||||
/**
|
||||
* grts_state - generic resistive touch screen information struct
|
||||
* @pressure_min: number representing the minimum for the pressure
|
||||
* @pressure: are we getting pressure info or not
|
||||
* @iio_chans: list of channels acquired
|
||||
* @iio_cb: iio_callback buffer for the data
|
||||
* @input: the input device structure that we register
|
||||
* @prop: touchscreen properties struct
|
||||
*/
|
||||
struct grts_state {
|
||||
u32 pressure_min;
|
||||
bool pressure;
|
||||
struct iio_channel *iio_chans;
|
||||
struct iio_cb_buffer *iio_cb;
|
||||
struct input_dev *input;
|
||||
struct touchscreen_properties prop;
|
||||
};
|
||||
|
||||
static int grts_cb(const void *data, void *private)
|
||||
{
|
||||
const u16 *touch_info = data;
|
||||
struct grts_state *st = private;
|
||||
unsigned int x, y, press = 0x0;
|
||||
|
||||
/* channel data coming in buffer in the order below */
|
||||
x = touch_info[0];
|
||||
y = touch_info[1];
|
||||
if (st->pressure)
|
||||
press = touch_info[2];
|
||||
|
||||
if ((!x && !y) || (st->pressure && (press < st->pressure_min))) {
|
||||
/* report end of touch */
|
||||
input_report_key(st->input, BTN_TOUCH, 0);
|
||||
input_sync(st->input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* report proper touch to subsystem*/
|
||||
touchscreen_report_pos(st->input, &st->prop, x, y, false);
|
||||
if (st->pressure)
|
||||
input_report_abs(st->input, ABS_PRESSURE, press);
|
||||
input_report_key(st->input, BTN_TOUCH, 1);
|
||||
input_sync(st->input);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int grts_open(struct input_dev *dev)
|
||||
{
|
||||
int error;
|
||||
struct grts_state *st = input_get_drvdata(dev);
|
||||
|
||||
error = iio_channel_start_all_cb(st->iio_cb);
|
||||
if (error) {
|
||||
dev_err(dev->dev.parent, "failed to start callback buffer.\n");
|
||||
return error;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void grts_close(struct input_dev *dev)
|
||||
{
|
||||
struct grts_state *st = input_get_drvdata(dev);
|
||||
|
||||
iio_channel_stop_all_cb(st->iio_cb);
|
||||
}
|
||||
|
||||
static void grts_disable(void *data)
|
||||
{
|
||||
iio_channel_release_all_cb(data);
|
||||
}
|
||||
|
||||
static int grts_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct grts_state *st;
|
||||
struct input_dev *input;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct iio_channel *chan;
|
||||
int error;
|
||||
|
||||
st = devm_kzalloc(dev, sizeof(struct grts_state), GFP_KERNEL);
|
||||
if (!st)
|
||||
return -ENOMEM;
|
||||
|
||||
/* get the channels from IIO device */
|
||||
st->iio_chans = devm_iio_channel_get_all(dev);
|
||||
if (IS_ERR(st->iio_chans)) {
|
||||
error = PTR_ERR(st->iio_chans);
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev, "can't get iio channels.\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
chan = &st->iio_chans[0];
|
||||
st->pressure = false;
|
||||
while (chan && chan->indio_dev) {
|
||||
if (!strcmp(chan->channel->datasheet_name, "pressure"))
|
||||
st->pressure = true;
|
||||
chan++;
|
||||
}
|
||||
|
||||
if (st->pressure) {
|
||||
error = device_property_read_u32(dev,
|
||||
"touchscreen-min-pressure",
|
||||
&st->pressure_min);
|
||||
if (error) {
|
||||
dev_dbg(dev, "can't get touchscreen-min-pressure property.\n");
|
||||
st->pressure_min = GRTS_DEFAULT_PRESSURE_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
input = devm_input_allocate_device(dev);
|
||||
if (!input) {
|
||||
dev_err(dev, "failed to allocate input device.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input->name = DRIVER_NAME;
|
||||
input->id.bustype = BUS_HOST;
|
||||
input->open = grts_open;
|
||||
input->close = grts_close;
|
||||
|
||||
input_set_abs_params(input, ABS_X, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
|
||||
input_set_abs_params(input, ABS_Y, 0, GRTS_MAX_POS_MASK - 1, 0, 0);
|
||||
if (st->pressure)
|
||||
input_set_abs_params(input, ABS_PRESSURE, st->pressure_min,
|
||||
0xffff, 0, 0);
|
||||
|
||||
input_set_capability(input, EV_KEY, BTN_TOUCH);
|
||||
|
||||
/* parse optional device tree properties */
|
||||
touchscreen_parse_properties(input, false, &st->prop);
|
||||
|
||||
st->input = input;
|
||||
input_set_drvdata(input, st);
|
||||
|
||||
error = input_register_device(input);
|
||||
if (error) {
|
||||
dev_err(dev, "failed to register input device.");
|
||||
return error;
|
||||
}
|
||||
|
||||
st->iio_cb = iio_channel_get_all_cb(dev, grts_cb, st);
|
||||
if (IS_ERR(st->iio_cb)) {
|
||||
dev_err(dev, "failed to allocate callback buffer.\n");
|
||||
return PTR_ERR(st->iio_cb);
|
||||
}
|
||||
|
||||
error = devm_add_action_or_reset(dev, grts_disable, st->iio_cb);
|
||||
if (error) {
|
||||
dev_err(dev, "failed to add disable action.\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id grts_of_match[] = {
|
||||
{
|
||||
.compatible = "resistive-adc-touch",
|
||||
}, {
|
||||
/* sentinel */
|
||||
},
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, grts_of_match);
|
||||
|
||||
static struct platform_driver grts_driver = {
|
||||
.probe = grts_probe,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = of_match_ptr(grts_of_match),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(grts_driver);
|
||||
|
||||
MODULE_AUTHOR("Eugen Hristev <[email protected]>");
|
||||
MODULE_DESCRIPTION("Generic ADC Resistive Touch Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
@ -304,7 +304,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
|
|||
msg[1].len = len;
|
||||
msg[1].buf = buf;
|
||||
|
||||
i2c_lock_adapter(adap);
|
||||
i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (__i2c_transfer(adap, &msg[i], 1) < 0) {
|
||||
|
|
@ -313,7 +313,7 @@ static int rohm_i2c_burst_read(struct i2c_client *client, u8 start, void *buf,
|
|||
}
|
||||
}
|
||||
|
||||
i2c_unlock_adapter(adap);
|
||||
i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/sort.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
|
||||
#include <linux/mfd/ti_am335x_tscadc.h>
|
||||
|
||||
|
|
@ -46,6 +47,7 @@ static const int config_pins[] = {
|
|||
struct titsc {
|
||||
struct input_dev *input;
|
||||
struct ti_tscadc_dev *mfd_tscadc;
|
||||
struct device *dev;
|
||||
unsigned int irq;
|
||||
unsigned int wires;
|
||||
unsigned int x_plate_resistance;
|
||||
|
|
@ -276,7 +278,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
|
|||
if (status & IRQENB_HW_PEN) {
|
||||
ts_dev->pen_down = true;
|
||||
irqclr |= IRQENB_HW_PEN;
|
||||
pm_stay_awake(ts_dev->mfd_tscadc->dev);
|
||||
pm_stay_awake(ts_dev->dev);
|
||||
}
|
||||
|
||||
if (status & IRQENB_PENUP) {
|
||||
|
|
@ -286,7 +288,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
|
|||
input_report_key(input_dev, BTN_TOUCH, 0);
|
||||
input_report_abs(input_dev, ABS_PRESSURE, 0);
|
||||
input_sync(input_dev);
|
||||
pm_relax(ts_dev->mfd_tscadc->dev);
|
||||
pm_relax(ts_dev->dev);
|
||||
} else {
|
||||
ts_dev->pen_down = true;
|
||||
}
|
||||
|
|
@ -422,6 +424,7 @@ static int titsc_probe(struct platform_device *pdev)
|
|||
ts_dev->mfd_tscadc = tscadc_dev;
|
||||
ts_dev->input = input_dev;
|
||||
ts_dev->irq = tscadc_dev->irq;
|
||||
ts_dev->dev = &pdev->dev;
|
||||
|
||||
err = titsc_parse_dt(pdev, ts_dev);
|
||||
if (err) {
|
||||
|
|
@ -436,6 +439,11 @@ static int titsc_probe(struct platform_device *pdev)
|
|||
goto err_free_mem;
|
||||
}
|
||||
|
||||
device_init_wakeup(&pdev->dev, true);
|
||||
err = dev_pm_set_wake_irq(&pdev->dev, ts_dev->irq);
|
||||
if (err)
|
||||
dev_err(&pdev->dev, "irq wake enable failed.\n");
|
||||
|
||||
titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK);
|
||||
titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
|
||||
titsc_writel(ts_dev, REG_IRQENABLE, IRQENB_EOS);
|
||||
|
|
@ -467,6 +475,8 @@ static int titsc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
free_irq(ts_dev->irq, ts_dev);
|
||||
err_free_mem:
|
||||
input_free_device(input_dev);
|
||||
|
|
@ -479,6 +489,8 @@ static int titsc_remove(struct platform_device *pdev)
|
|||
struct titsc *ts_dev = platform_get_drvdata(pdev);
|
||||
u32 steps;
|
||||
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
free_irq(ts_dev->irq, ts_dev);
|
||||
|
||||
/* total steps followed by the enable mask */
|
||||
|
|
@ -499,7 +511,7 @@ static int __maybe_unused titsc_suspend(struct device *dev)
|
|||
unsigned int idle;
|
||||
|
||||
tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
|
||||
if (device_may_wakeup(tscadc_dev->dev)) {
|
||||
if (device_may_wakeup(dev)) {
|
||||
titsc_writel(ts_dev, REG_IRQSTATUS, TSC_IRQENB_MASK);
|
||||
idle = titsc_readl(ts_dev, REG_IRQENABLE);
|
||||
titsc_writel(ts_dev, REG_IRQENABLE,
|
||||
|
|
@ -515,11 +527,11 @@ static int __maybe_unused titsc_resume(struct device *dev)
|
|||
struct ti_tscadc_dev *tscadc_dev;
|
||||
|
||||
tscadc_dev = ti_tscadc_dev_get(to_platform_device(dev));
|
||||
if (device_may_wakeup(tscadc_dev->dev)) {
|
||||
if (device_may_wakeup(dev)) {
|
||||
titsc_writel(ts_dev, REG_IRQWAKEUP,
|
||||
0x00);
|
||||
titsc_writel(ts_dev, REG_IRQCLR, IRQENB_HW_PEN);
|
||||
pm_relax(ts_dev->mfd_tscadc->dev);
|
||||
pm_relax(dev);
|
||||
}
|
||||
titsc_step_config(ts_dev);
|
||||
titsc_writel(ts_dev, REG_FIFO0THR,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@ const struct regmap_config tsc200x_regmap_config = {
|
|||
.read_flag_mask = TSC200X_REG_READ,
|
||||
.write_flag_mask = TSC200X_REG_PND0,
|
||||
.wr_table = &tsc200x_writable_table,
|
||||
.use_single_rw = true,
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(tsc200x_regmap_config);
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
* The default values correspond to Mainstone II in QVGA mode
|
||||
*
|
||||
* Please read
|
||||
* Documentation/input/input-programming.txt for more details.
|
||||
* Documentation/input/input-programming.rst for more details.
|
||||
*/
|
||||
|
||||
static int abs_x[3] = {150, 4000, 5};
|
||||
|
|
|
|||
Loading…
Reference in a new issue