Merge branch 'next' into for-linus
Second round of input updates for 3.19.
This commit is contained in:
commit
6d32af019a
|
@ -10,12 +10,13 @@ Optional properties:
|
|||
Each button (key) is represented as a sub-node of "gpio-keys":
|
||||
Subnode properties:
|
||||
|
||||
- gpios: OF device-tree gpio specification.
|
||||
- interrupts: the interrupt line for that input.
|
||||
- label: Descriptive name of the key.
|
||||
- linux,code: Keycode to emit.
|
||||
|
||||
Required mutual exclusive subnode-properties:
|
||||
- gpios: OF device-tree gpio specification.
|
||||
- interrupts: the interrupt line for that input
|
||||
Note that either "interrupts" or "gpios" properties can be omitted, but not
|
||||
both at the same time. Specifying both properties is allowed.
|
||||
|
||||
Optional subnode-properties:
|
||||
- linux,input-type: Specify event type this button/key generates.
|
||||
|
@ -23,6 +24,9 @@ Optional subnode-properties:
|
|||
- debounce-interval: Debouncing interval time in milliseconds.
|
||||
If not specified defaults to 5.
|
||||
- gpio-key,wakeup: Boolean, button can wake-up the system.
|
||||
- linux,can-disable: Boolean, indicates that button is connected
|
||||
to dedicated (not shared) interrupt which can be disabled to
|
||||
suppress events from the button.
|
||||
|
||||
Example nodes:
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ Optional properties:
|
|||
- debounce-interval : Debouncing interval time in milliseconds
|
||||
- st,scan-count : Scanning cycles elapsed before key data is updated
|
||||
- st,no-autorepeat : If specified device will not autorepeat
|
||||
- keypad,num-rows : See ./matrix-keymap.txt
|
||||
- keypad,num-columns : See ./matrix-keymap.txt
|
||||
|
||||
Example:
|
||||
|
||||
|
|
|
@ -28,6 +28,13 @@
|
|||
#include <linux/cdev.h>
|
||||
#include "input-compat.h"
|
||||
|
||||
enum evdev_clock_type {
|
||||
EV_CLK_REAL = 0,
|
||||
EV_CLK_MONO,
|
||||
EV_CLK_BOOT,
|
||||
EV_CLK_MAX
|
||||
};
|
||||
|
||||
struct evdev {
|
||||
int open;
|
||||
struct input_handle handle;
|
||||
|
@ -49,12 +56,32 @@ struct evdev_client {
|
|||
struct fasync_struct *fasync;
|
||||
struct evdev *evdev;
|
||||
struct list_head node;
|
||||
int clkid;
|
||||
int clk_type;
|
||||
bool revoked;
|
||||
unsigned int bufsize;
|
||||
struct input_event buffer[];
|
||||
};
|
||||
|
||||
static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
|
||||
{
|
||||
switch (clkid) {
|
||||
|
||||
case CLOCK_REALTIME:
|
||||
client->clk_type = EV_CLK_REAL;
|
||||
break;
|
||||
case CLOCK_MONOTONIC:
|
||||
client->clk_type = EV_CLK_MONO;
|
||||
break;
|
||||
case CLOCK_BOOTTIME:
|
||||
client->clk_type = EV_CLK_BOOT;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* flush queued events of type @type, caller must hold client->buffer_lock */
|
||||
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
|
||||
{
|
||||
|
@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
|
|||
struct input_event ev;
|
||||
ktime_t time;
|
||||
|
||||
time = (client->clkid == CLOCK_MONOTONIC) ?
|
||||
ktime_get() : ktime_get_real();
|
||||
time = client->clk_type == EV_CLK_REAL ?
|
||||
ktime_get_real() :
|
||||
client->clk_type == EV_CLK_MONO ?
|
||||
ktime_get() :
|
||||
ktime_get_boottime();
|
||||
|
||||
ev.time = ktime_to_timeval(time);
|
||||
ev.type = EV_SYN;
|
||||
|
@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client,
|
|||
|
||||
static void evdev_pass_values(struct evdev_client *client,
|
||||
const struct input_value *vals, unsigned int count,
|
||||
ktime_t mono, ktime_t real)
|
||||
ktime_t *ev_time)
|
||||
{
|
||||
struct evdev *evdev = client->evdev;
|
||||
const struct input_value *v;
|
||||
|
@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client,
|
|||
if (client->revoked)
|
||||
return;
|
||||
|
||||
event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ?
|
||||
mono : real);
|
||||
event.time = ktime_to_timeval(ev_time[client->clk_type]);
|
||||
|
||||
/* Interrupts are disabled, just acquire the lock. */
|
||||
spin_lock(&client->buffer_lock);
|
||||
|
@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle,
|
|||
{
|
||||
struct evdev *evdev = handle->private;
|
||||
struct evdev_client *client;
|
||||
ktime_t time_mono, time_real;
|
||||
ktime_t ev_time[EV_CLK_MAX];
|
||||
|
||||
time_mono = ktime_get();
|
||||
time_real = ktime_mono_to_real(time_mono);
|
||||
ev_time[EV_CLK_MONO] = ktime_get();
|
||||
ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
|
||||
ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
|
||||
TK_OFFS_BOOT);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
client = rcu_dereference(evdev->grab);
|
||||
|
||||
if (client)
|
||||
evdev_pass_values(client, vals, count, time_mono, time_real);
|
||||
evdev_pass_values(client, vals, count, ev_time);
|
||||
else
|
||||
list_for_each_entry_rcu(client, &evdev->client_list, node)
|
||||
evdev_pass_values(client, vals, count,
|
||||
time_mono, time_real);
|
||||
evdev_pass_values(client, vals, count, ev_time);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
|
|||
case EVIOCSCLOCKID:
|
||||
if (copy_from_user(&i, p, sizeof(unsigned int)))
|
||||
return -EFAULT;
|
||||
if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
|
||||
return -EINVAL;
|
||||
client->clkid = i;
|
||||
return 0;
|
||||
|
||||
return evdev_set_clk_type(client, i);
|
||||
|
||||
case EVIOCGKEYCODE:
|
||||
return evdev_handle_get_keycode(dev, p);
|
||||
|
|
|
@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev)
|
|||
|
||||
events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
|
||||
|
||||
for (i = 0; i < ABS_CNT; i++) {
|
||||
if (test_bit(i, dev->absbit)) {
|
||||
if (input_is_mt_axis(i))
|
||||
events += mt_slots;
|
||||
else
|
||||
events++;
|
||||
if (test_bit(EV_ABS, dev->evbit)) {
|
||||
for (i = 0; i < ABS_CNT; i++) {
|
||||
if (test_bit(i, dev->absbit)) {
|
||||
if (input_is_mt_axis(i))
|
||||
events += mt_slots;
|
||||
else
|
||||
events++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < REL_CNT; i++)
|
||||
if (test_bit(i, dev->relbit))
|
||||
events++;
|
||||
if (test_bit(EV_REL, dev->evbit)) {
|
||||
for (i = 0; i < REL_CNT; i++)
|
||||
if (test_bit(i, dev->relbit))
|
||||
events++;
|
||||
}
|
||||
|
||||
/* Make room for KEY and MSC events */
|
||||
events += 7;
|
||||
|
|
|
@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC
|
|||
config KEYBOARD_STMPE
|
||||
tristate "STMPE keypad support"
|
||||
depends on MFD_STMPE
|
||||
depends on OF
|
||||
select INPUT_MATRIXKMAP
|
||||
help
|
||||
Say Y here if you want to use the keypad controller on STMPE I/O
|
||||
|
|
|
@ -35,9 +35,13 @@
|
|||
struct gpio_button_data {
|
||||
const struct gpio_keys_button *button;
|
||||
struct input_dev *input;
|
||||
struct timer_list timer;
|
||||
struct work_struct work;
|
||||
unsigned int timer_debounce; /* in msecs */
|
||||
|
||||
struct timer_list release_timer;
|
||||
unsigned int release_delay; /* in msecs, for IRQ-only buttons */
|
||||
|
||||
struct delayed_work work;
|
||||
unsigned int software_debounce; /* in msecs, for GPIO-driven buttons */
|
||||
|
||||
unsigned int irq;
|
||||
spinlock_t lock;
|
||||
bool disabled;
|
||||
|
@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
|
|||
{
|
||||
if (!bdata->disabled) {
|
||||
/*
|
||||
* Disable IRQ and possible debouncing timer.
|
||||
* Disable IRQ and associated timer/work structure.
|
||||
*/
|
||||
disable_irq(bdata->irq);
|
||||
if (bdata->timer_debounce)
|
||||
del_timer_sync(&bdata->timer);
|
||||
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
|
||||
bdata->disabled = true;
|
||||
}
|
||||
|
@ -343,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
|
|||
static void gpio_keys_gpio_work_func(struct work_struct *work)
|
||||
{
|
||||
struct gpio_button_data *bdata =
|
||||
container_of(work, struct gpio_button_data, work);
|
||||
container_of(work, struct gpio_button_data, work.work);
|
||||
|
||||
gpio_keys_gpio_report_event(bdata);
|
||||
|
||||
|
@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
|
|||
pm_relax(bdata->input->dev.parent);
|
||||
}
|
||||
|
||||
static void gpio_keys_gpio_timer(unsigned long _data)
|
||||
{
|
||||
struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
|
||||
|
||||
schedule_work(&bdata->work);
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
|
||||
{
|
||||
struct gpio_button_data *bdata = dev_id;
|
||||
|
@ -366,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
|
|||
|
||||
if (bdata->button->wakeup)
|
||||
pm_stay_awake(bdata->input->dev.parent);
|
||||
if (bdata->timer_debounce)
|
||||
mod_timer(&bdata->timer,
|
||||
jiffies + msecs_to_jiffies(bdata->timer_debounce));
|
||||
else
|
||||
schedule_work(&bdata->work);
|
||||
|
||||
mod_delayed_work(system_wq,
|
||||
&bdata->work,
|
||||
msecs_to_jiffies(bdata->software_debounce));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -408,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
|||
input_event(input, EV_KEY, button->code, 1);
|
||||
input_sync(input);
|
||||
|
||||
if (!bdata->timer_debounce) {
|
||||
if (!bdata->release_delay) {
|
||||
input_event(input, EV_KEY, button->code, 0);
|
||||
input_sync(input);
|
||||
goto out;
|
||||
|
@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
|
|||
bdata->key_pressed = true;
|
||||
}
|
||||
|
||||
if (bdata->timer_debounce)
|
||||
mod_timer(&bdata->timer,
|
||||
jiffies + msecs_to_jiffies(bdata->timer_debounce));
|
||||
if (bdata->release_delay)
|
||||
mod_timer(&bdata->release_timer,
|
||||
jiffies + msecs_to_jiffies(bdata->release_delay));
|
||||
out:
|
||||
spin_unlock_irqrestore(&bdata->lock, flags);
|
||||
return IRQ_HANDLED;
|
||||
|
@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data)
|
|||
{
|
||||
struct gpio_button_data *bdata = data;
|
||||
|
||||
if (bdata->timer_debounce)
|
||||
del_timer_sync(&bdata->timer);
|
||||
|
||||
cancel_work_sync(&bdata->work);
|
||||
if (gpio_is_valid(bdata->button->gpio))
|
||||
cancel_delayed_work_sync(&bdata->work);
|
||||
else
|
||||
del_timer_sync(&bdata->release_timer);
|
||||
}
|
||||
|
||||
static int gpio_keys_setup_key(struct platform_device *pdev,
|
||||
|
@ -466,23 +465,25 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
button->debounce_interval * 1000);
|
||||
/* use timer if gpiolib doesn't provide debounce */
|
||||
if (error < 0)
|
||||
bdata->timer_debounce =
|
||||
bdata->software_debounce =
|
||||
button->debounce_interval;
|
||||
}
|
||||
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
dev_err(dev,
|
||||
"Unable to get irq number for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
return error;
|
||||
if (button->irq) {
|
||||
bdata->irq = button->irq;
|
||||
} else {
|
||||
irq = gpio_to_irq(button->gpio);
|
||||
if (irq < 0) {
|
||||
error = irq;
|
||||
dev_err(dev,
|
||||
"Unable to get irq number for GPIO %d, error %d\n",
|
||||
button->gpio, error);
|
||||
return error;
|
||||
}
|
||||
bdata->irq = irq;
|
||||
}
|
||||
bdata->irq = irq;
|
||||
|
||||
INIT_WORK(&bdata->work, gpio_keys_gpio_work_func);
|
||||
setup_timer(&bdata->timer,
|
||||
gpio_keys_gpio_timer, (unsigned long)bdata);
|
||||
INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func);
|
||||
|
||||
isr = gpio_keys_gpio_isr;
|
||||
irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
|
||||
|
@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
bdata->timer_debounce = button->debounce_interval;
|
||||
setup_timer(&bdata->timer,
|
||||
bdata->release_delay = button->debounce_interval;
|
||||
setup_timer(&bdata->release_timer,
|
||||
gpio_keys_irq_timer, (unsigned long)bdata);
|
||||
|
||||
isr = gpio_keys_irq_isr;
|
||||
|
@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
|
|||
input_set_capability(input, button->type ?: EV_KEY, button->code);
|
||||
|
||||
/*
|
||||
* Install custom action to cancel debounce timer and
|
||||
* Install custom action to cancel release timer and
|
||||
* workqueue item.
|
||||
*/
|
||||
error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
|
||||
|
@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
|||
|
||||
i = 0;
|
||||
for_each_child_of_node(node, pp) {
|
||||
int gpio = -1;
|
||||
enum of_gpio_flags flags;
|
||||
|
||||
button = &pdata->buttons[i++];
|
||||
|
||||
if (!of_find_property(pp, "gpios", NULL)) {
|
||||
button->irq = irq_of_parse_and_map(pp, 0);
|
||||
if (button->irq == 0) {
|
||||
i--;
|
||||
pdata->nbuttons--;
|
||||
dev_warn(dev, "Found button without gpios or irqs\n");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
gpio = of_get_gpio_flags(pp, 0, &flags);
|
||||
if (gpio < 0) {
|
||||
error = gpio;
|
||||
button->gpio = of_get_gpio_flags(pp, 0, &flags);
|
||||
if (button->gpio < 0) {
|
||||
error = button->gpio;
|
||||
if (error != -ENOENT) {
|
||||
if (error != -EPROBE_DEFER)
|
||||
dev_err(dev,
|
||||
"Failed to get gpio flags, error: %d\n",
|
||||
error);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
} else {
|
||||
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
|
||||
button->gpio = gpio;
|
||||
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
|
||||
button->irq = irq_of_parse_and_map(pp, 0);
|
||||
|
||||
if (!gpio_is_valid(button->gpio) && !button->irq) {
|
||||
dev_err(dev, "Found button without gpios or irqs\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (of_property_read_u32(pp, "linux,code", &button->code)) {
|
||||
dev_err(dev, "Button without keycode: 0x%x\n",
|
||||
|
@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev)
|
|||
|
||||
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL);
|
||||
|
||||
button->can_disable = !!of_get_property(pp, "linux,can-disable", NULL);
|
||||
|
||||
if (of_property_read_u32(pp, "debounce-interval",
|
||||
&button->debounce_interval))
|
||||
button->debounce_interval = 5;
|
||||
|
|
|
@ -45,13 +45,14 @@
|
|||
#define STMPE_KEYPAD_MAX_ROWS 8
|
||||
#define STMPE_KEYPAD_MAX_COLS 8
|
||||
#define STMPE_KEYPAD_ROW_SHIFT 3
|
||||
#define STMPE_KEYPAD_KEYMAP_SIZE \
|
||||
#define STMPE_KEYPAD_KEYMAP_MAX_SIZE \
|
||||
(STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad_variant - model-specific attributes
|
||||
* @auto_increment: whether the KPC_DATA_BYTE register address
|
||||
* auto-increments on multiple read
|
||||
* @set_pullup: whether the pins need to have their pull-ups set
|
||||
* @num_data: number of data bytes
|
||||
* @num_normal_data: number of normal keys' data bytes
|
||||
* @max_cols: maximum number of columns supported
|
||||
|
@ -61,6 +62,7 @@
|
|||
*/
|
||||
struct stmpe_keypad_variant {
|
||||
bool auto_increment;
|
||||
bool set_pullup;
|
||||
int num_data;
|
||||
int num_normal_data;
|
||||
int max_cols;
|
||||
|
@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
[STMPE2401] = {
|
||||
.auto_increment = false,
|
||||
.set_pullup = true,
|
||||
.num_data = 3,
|
||||
.num_normal_data = 2,
|
||||
.max_cols = 8,
|
||||
|
@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
[STMPE2403] = {
|
||||
.auto_increment = true,
|
||||
.set_pullup = true,
|
||||
.num_data = 5,
|
||||
.num_normal_data = 3,
|
||||
.max_cols = 8,
|
||||
|
@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
|
|||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad - STMPE keypad state container
|
||||
* @stmpe: pointer to parent STMPE device
|
||||
* @input: spawned input device
|
||||
* @variant: STMPE variant
|
||||
* @debounce_ms: debounce interval, in ms. Maximum is
|
||||
* %STMPE_KEYPAD_MAX_DEBOUNCE.
|
||||
* @scan_count: number of key scanning cycles to confirm key data.
|
||||
* Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
|
||||
* @no_autorepeat: disable key autorepeat
|
||||
* @rows: bitmask for the rows
|
||||
* @cols: bitmask for the columns
|
||||
* @keymap: the keymap
|
||||
*/
|
||||
struct stmpe_keypad {
|
||||
struct stmpe *stmpe;
|
||||
struct input_dev *input;
|
||||
const struct stmpe_keypad_variant *variant;
|
||||
const struct stmpe_keypad_platform_data *plat;
|
||||
|
||||
unsigned int debounce_ms;
|
||||
unsigned int scan_count;
|
||||
bool no_autorepeat;
|
||||
unsigned int rows;
|
||||
unsigned int cols;
|
||||
|
||||
unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];
|
||||
unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE];
|
||||
};
|
||||
|
||||
static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data)
|
||||
|
@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
unsigned int col_gpios = variant->col_gpios;
|
||||
unsigned int row_gpios = variant->row_gpios;
|
||||
struct stmpe *stmpe = keypad->stmpe;
|
||||
u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB];
|
||||
unsigned int pins = 0;
|
||||
unsigned int pu_pins = 0;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
for (i = 0; i < variant->max_cols; i++) {
|
||||
int num = __ffs(col_gpios);
|
||||
|
||||
if (keypad->cols & (1 << i))
|
||||
if (keypad->cols & (1 << i)) {
|
||||
pins |= 1 << num;
|
||||
pu_pins |= 1 << num;
|
||||
}
|
||||
|
||||
col_gpios &= ~(1 << num);
|
||||
}
|
||||
|
@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
|
|||
row_gpios &= ~(1 << num);
|
||||
}
|
||||
|
||||
return stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
|
||||
ret = stmpe_set_altfunc(stmpe, pins, STMPE_BLOCK_KEYPAD);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* On STMPE24xx, set pin bias to pull-up on all keypad input
|
||||
* pins (columns), this incidentally happen to be maximum 8 pins
|
||||
* and placed at GPIO0-7 so only the LSB of the pull up register
|
||||
* ever needs to be written.
|
||||
*/
|
||||
if (variant->set_pullup) {
|
||||
u8 val;
|
||||
|
||||
ret = stmpe_reg_read(stmpe, pureg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Do not touch unused pins, may be used for GPIO */
|
||||
val = ret & ~pu_pins;
|
||||
val |= pu_pins;
|
||||
|
||||
ret = stmpe_reg_write(stmpe, pureg, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
||||
{
|
||||
const struct stmpe_keypad_platform_data *plat = keypad->plat;
|
||||
const struct stmpe_keypad_variant *variant = keypad->variant;
|
||||
struct stmpe *stmpe = keypad->stmpe;
|
||||
int ret;
|
||||
|
||||
if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
|
||||
if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
|
||||
return -EINVAL;
|
||||
|
||||
if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
|
||||
if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);
|
||||
|
@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
|||
|
||||
ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
|
||||
STMPE_KPC_CTRL_MSB_SCAN_COUNT,
|
||||
plat->scan_count << 4);
|
||||
keypad->scan_count << 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
|
|||
STMPE_KPC_CTRL_LSB_SCAN |
|
||||
STMPE_KPC_CTRL_LSB_DEBOUNCE,
|
||||
STMPE_KPC_CTRL_LSB_SCAN |
|
||||
(plat->debounce_ms << 1));
|
||||
(keypad->debounce_ms << 1));
|
||||
}
|
||||
|
||||
static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
|
||||
static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad,
|
||||
u32 used_rows, u32 used_cols)
|
||||
{
|
||||
int row, col;
|
||||
|
||||
for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) {
|
||||
for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) {
|
||||
for (row = 0; row < used_rows; row++) {
|
||||
for (col = 0; col < used_cols; col++) {
|
||||
int code = MATRIX_SCAN_CODE(row, col,
|
||||
STMPE_KEYPAD_ROW_SHIFT);
|
||||
STMPE_KEYPAD_ROW_SHIFT);
|
||||
if (keypad->keymap[code] != KEY_RESERVED) {
|
||||
keypad->rows |= 1 << row;
|
||||
keypad->cols |= 1 << col;
|
||||
|
@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct stmpe_keypad_platform_data *
|
||||
stmpe_keypad_of_probe(struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
struct stmpe_keypad_platform_data *plat;
|
||||
|
||||
if (!np)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
plat = devm_kzalloc(dev, sizeof(*plat), GFP_KERNEL);
|
||||
if (!plat)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
of_property_read_u32(np, "debounce-interval", &plat->debounce_ms);
|
||||
of_property_read_u32(np, "st,scan-count", &plat->scan_count);
|
||||
|
||||
plat->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
|
||||
|
||||
return plat;
|
||||
}
|
||||
#else
|
||||
static inline const struct stmpe_keypad_platform_data *
|
||||
stmpe_keypad_of_probe(struct device *dev)
|
||||
{
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int stmpe_keypad_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
|
||||
const struct stmpe_keypad_platform_data *plat;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct stmpe_keypad *keypad;
|
||||
struct input_dev *input;
|
||||
u32 rows;
|
||||
u32 cols;
|
||||
int error;
|
||||
int irq;
|
||||
|
||||
plat = stmpe->pdata->keypad;
|
||||
if (!plat) {
|
||||
plat = stmpe_keypad_of_probe(&pdev->dev);
|
||||
if (IS_ERR(plat))
|
||||
return PTR_ERR(plat);
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
|
@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
|
|||
if (!keypad)
|
||||
return -ENOMEM;
|
||||
|
||||
keypad->stmpe = stmpe;
|
||||
keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
|
||||
|
||||
of_property_read_u32(np, "debounce-interval", &keypad->debounce_ms);
|
||||
of_property_read_u32(np, "st,scan-count", &keypad->scan_count);
|
||||
keypad->no_autorepeat = of_property_read_bool(np, "st,no-autorepeat");
|
||||
|
||||
input = devm_input_allocate_device(&pdev->dev);
|
||||
if (!input)
|
||||
return -ENOMEM;
|
||||
|
@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
|
|||
input->id.bustype = BUS_I2C;
|
||||
input->dev.parent = &pdev->dev;
|
||||
|
||||
error = matrix_keypad_build_keymap(plat->keymap_data, NULL,
|
||||
STMPE_KEYPAD_MAX_ROWS,
|
||||
STMPE_KEYPAD_MAX_COLS,
|
||||
error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
|
||||
keypad->keymap, input);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
input_set_capability(input, EV_MSC, MSC_SCAN);
|
||||
if (!plat->no_autorepeat)
|
||||
if (!keypad->no_autorepeat)
|
||||
__set_bit(EV_REP, input->evbit);
|
||||
|
||||
stmpe_keypad_fill_used_pins(keypad);
|
||||
stmpe_keypad_fill_used_pins(keypad, rows, cols);
|
||||
|
||||
keypad->stmpe = stmpe;
|
||||
keypad->plat = plat;
|
||||
keypad->input = input;
|
||||
keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
|
||||
|
||||
error = stmpe_keypad_chip_init(keypad);
|
||||
if (error < 0)
|
||||
|
|
|
@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
|
|||
unsigned char *pkt,
|
||||
unsigned char pkt_id)
|
||||
{
|
||||
/*
|
||||
* packet-fmt b7 b6 b5 b4 b3 b2 b1 b0
|
||||
* Byte0 TWO & MULTI L 1 R M 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte0 NEW L 1 X1-5 1 1 Y0-2 Y0-1 Y0-0
|
||||
* Byte1 Y0-10 Y0-9 Y0-8 Y0-7 Y0-6 Y0-5 Y0-4 Y0-3
|
||||
* Byte2 X0-11 1 X0-10 X0-9 X0-8 X0-7 X0-6 X0-5
|
||||
* Byte3 X1-11 1 X0-4 X0-3 1 X0-2 X0-1 X0-0
|
||||
* Byte4 TWO X1-10 TWO X1-9 X1-8 X1-7 X1-6 X1-5 X1-4
|
||||
* Byte4 MULTI X1-10 TWO X1-9 X1-8 X1-7 X1-6 Y1-5 1
|
||||
* Byte4 NEW X1-10 TWO X1-9 X1-8 X1-7 X1-6 0 0
|
||||
* Byte5 TWO & NEW Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 Y1-5 Y1-4
|
||||
* Byte5 MULTI Y1-10 0 Y1-9 Y1-8 Y1-7 Y1-6 F-1 F-0
|
||||
* L: Left button
|
||||
* R / M: Non-clickpads: Right / Middle button
|
||||
* Clickpads: When > 2 fingers are down, and some fingers
|
||||
* are in the button area, then the 2 coordinates reported
|
||||
* are for fingers outside the button area and these report
|
||||
* extra fingers being present in the right / left button
|
||||
* area. Note these fingers are not added to the F field!
|
||||
* so if a TWO packet is received and R = 1 then there are
|
||||
* 3 fingers down, etc.
|
||||
* TWO: 1: Two touches present, byte 0/4/5 are in TWO fmt
|
||||
* 0: If byte 4 bit 0 is 1, then byte 0/4/5 are in MULTI fmt
|
||||
* otherwise byte 0 bit 4 must be set and byte 0/4/5 are
|
||||
* in NEW fmt
|
||||
* F: Number of fingers - 3, 0 means 3 fingers, 1 means 4 ...
|
||||
*/
|
||||
|
||||
mt[0].x = ((pkt[2] & 0x80) << 4);
|
||||
mt[0].x |= ((pkt[2] & 0x3F) << 5);
|
||||
mt[0].x |= ((pkt[3] & 0x30) >> 1);
|
||||
|
@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
|
|||
|
||||
static int alps_get_mt_count(struct input_mt_pos *mt)
|
||||
{
|
||||
int i;
|
||||
int i, fingers = 0;
|
||||
|
||||
for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++)
|
||||
/* empty */;
|
||||
for (i = 0; i < MAX_TOUCHES; i++) {
|
||||
if (mt[i].x != 0 || mt[i].y != 0)
|
||||
fingers++;
|
||||
}
|
||||
|
||||
return i;
|
||||
return fingers;
|
||||
}
|
||||
|
||||
static int alps_decode_packet_v7(struct alps_fields *f,
|
||||
unsigned char *p,
|
||||
struct psmouse *psmouse)
|
||||
{
|
||||
struct alps_data *priv = psmouse->private;
|
||||
unsigned char pkt_id;
|
||||
|
||||
pkt_id = alps_get_packet_id_v7(p);
|
||||
|
@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f,
|
|||
return 0;
|
||||
if (pkt_id == V7_PACKET_ID_UNKNOWN)
|
||||
return -1;
|
||||
/*
|
||||
* NEW packets are send to indicate a discontinuity in the finger
|
||||
* coordinate reporting. Specifically a finger may have moved from
|
||||
* slot 0 to 1 or vice versa. INPUT_MT_TRACK takes care of this for
|
||||
* us.
|
||||
*
|
||||
* NEW packets have 3 problems:
|
||||
* 1) They do not contain middle / right button info (on non clickpads)
|
||||
* this can be worked around by preserving the old button state
|
||||
* 2) They do not contain an accurate fingercount, and they are
|
||||
* typically send when the number of fingers changes. We cannot use
|
||||
* the old finger count as that may mismatch with the amount of
|
||||
* touch coordinates we've available in the NEW packet
|
||||
* 3) Their x data for the second touch is inaccurate leading to
|
||||
* a possible jump of the x coordinate by 16 units when the first
|
||||
* non NEW packet comes in
|
||||
* Since problems 2 & 3 cannot be worked around, just ignore them.
|
||||
*/
|
||||
if (pkt_id == V7_PACKET_ID_NEW)
|
||||
return 1;
|
||||
|
||||
alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
|
||||
|
||||
if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) {
|
||||
f->left = (p[0] & 0x80) >> 7;
|
||||
if (pkt_id == V7_PACKET_ID_TWO)
|
||||
f->fingers = alps_get_mt_count(f->mt);
|
||||
else /* pkt_id == V7_PACKET_ID_MULTI */
|
||||
f->fingers = 3 + (p[5] & 0x03);
|
||||
|
||||
f->left = (p[0] & 0x80) >> 7;
|
||||
if (priv->flags & ALPS_BUTTONPAD) {
|
||||
if (p[0] & 0x20)
|
||||
f->fingers++;
|
||||
if (p[0] & 0x10)
|
||||
f->fingers++;
|
||||
} else {
|
||||
f->right = (p[0] & 0x20) >> 5;
|
||||
f->middle = (p[0] & 0x10) >> 4;
|
||||
}
|
||||
|
||||
if (pkt_id == V7_PACKET_ID_TWO)
|
||||
f->fingers = alps_get_mt_count(f->mt);
|
||||
else if (pkt_id == V7_PACKET_ID_MULTI)
|
||||
f->fingers = 3 + (p[5] & 0x03);
|
||||
/* Sometimes a single touch is reported in mt[1] rather then mt[0] */
|
||||
if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
|
||||
f->mt[0].x = f->mt[1].x;
|
||||
f->mt[0].y = f->mt[1].y;
|
||||
f->mt[1].x = 0;
|
||||
f->mt[1].y = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH);
|
|||
TRACKPOINT_INT_ATTR(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH);
|
||||
TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME);
|
||||
TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV);
|
||||
TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME);
|
||||
|
||||
TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
|
||||
TP_DEF_PTSON);
|
||||
|
@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = {
|
|||
&psmouse_attr_upthresh.dattr.attr,
|
||||
&psmouse_attr_ztime.dattr.attr,
|
||||
&psmouse_attr_jenks.dattr.attr,
|
||||
&psmouse_attr_drift_time.dattr.attr,
|
||||
&psmouse_attr_press_to_select.dattr.attr,
|
||||
&psmouse_attr_skipback.dattr.attr,
|
||||
&psmouse_attr_ext_dev.dattr.attr,
|
||||
|
@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state)
|
|||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, upthresh);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, jenks);
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time);
|
||||
|
||||
/* toggles */
|
||||
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select);
|
||||
|
@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
|
|||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, upthresh);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time);
|
||||
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia);
|
||||
|
||||
/* toggles */
|
||||
|
|
|
@ -70,6 +70,9 @@
|
|||
#define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */
|
||||
#define TP_Z_TIME 0x5E /* How sharp of a press */
|
||||
#define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */
|
||||
#define TP_DRIFT_TIME 0x5F /* How long a 'hands off' condition */
|
||||
/* must last (x*107ms) for drift */
|
||||
/* correction to occur */
|
||||
|
||||
/*
|
||||
* Toggling Flag bits
|
||||
|
@ -120,6 +123,7 @@
|
|||
#define TP_DEF_UP_THRESH 0xFF
|
||||
#define TP_DEF_Z_TIME 0x26
|
||||
#define TP_DEF_JENKS_CURV 0x87
|
||||
#define TP_DEF_DRIFT_TIME 0x05
|
||||
|
||||
/* Toggles */
|
||||
#define TP_DEF_MB 0x00
|
||||
|
@ -137,6 +141,7 @@ struct trackpoint_data
|
|||
unsigned char draghys, mindrag;
|
||||
unsigned char thresh, upthresh;
|
||||
unsigned char ztime, jenks;
|
||||
unsigned char drift_time;
|
||||
|
||||
/* toggles */
|
||||
unsigned char press_to_select;
|
||||
|
|
|
@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
|
|||
}
|
||||
|
||||
#define EDT_ATTR_CHECKSET(name, reg) \
|
||||
do { \
|
||||
if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \
|
||||
pdata->name <= edt_ft5x06_attr_##name.limit_high) \
|
||||
edt_ft5x06_register_write(tsdata, reg, pdata->name)
|
||||
edt_ft5x06_register_write(tsdata, reg, pdata->name); \
|
||||
} while (0)
|
||||
|
||||
#define EDT_GET_PROP(name, reg) { \
|
||||
u32 val; \
|
||||
|
|
|
@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB,
|
||||
[STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
|
||||
[STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB,
|
||||
|
@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
|
||||
[STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW,
|
||||
};
|
||||
|
@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = {
|
|||
[STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB,
|
||||
[STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB,
|
||||
[STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB,
|
||||
[STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB,
|
||||
[STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB,
|
||||
[STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB,
|
||||
[STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB,
|
||||
[STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB,
|
||||
|
|
|
@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe);
|
|||
#define STMPE1601_REG_GPIO_ED_MSB 0x8A
|
||||
#define STMPE1601_REG_GPIO_RE_LSB 0x8D
|
||||
#define STMPE1601_REG_GPIO_FE_LSB 0x8F
|
||||
#define STMPE1601_REG_GPIO_PU_LSB 0x91
|
||||
#define STMPE1601_REG_GPIO_AF_U_MSB 0x92
|
||||
|
||||
#define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3)
|
||||
|
@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe);
|
|||
#define STMPE24XX_REG_GPEDR_MSB 0x8C
|
||||
#define STMPE24XX_REG_GPRER_LSB 0x91
|
||||
#define STMPE24XX_REG_GPFER_LSB 0x94
|
||||
#define STMPE24XX_REG_GPPUR_LSB 0x97
|
||||
#define STMPE24XX_REG_GPPDR_LSB 0x9a
|
||||
#define STMPE24XX_REG_GPAFR_U_MSB 0x9B
|
||||
|
||||
#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3)
|
||||
|
|
|
@ -50,6 +50,8 @@ enum {
|
|||
STMPE_IDX_GPEDR_MSB,
|
||||
STMPE_IDX_GPRER_LSB,
|
||||
STMPE_IDX_GPFER_LSB,
|
||||
STMPE_IDX_GPPUR_LSB,
|
||||
STMPE_IDX_GPPDR_LSB,
|
||||
STMPE_IDX_GPAFR_U_MSB,
|
||||
STMPE_IDX_IEGPIOR_LSB,
|
||||
STMPE_IDX_ISGPIOR_LSB,
|
||||
|
@ -113,24 +115,6 @@ extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins,
|
|||
extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks);
|
||||
extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks);
|
||||
|
||||
struct matrix_keymap_data;
|
||||
|
||||
/**
|
||||
* struct stmpe_keypad_platform_data - STMPE keypad platform data
|
||||
* @keymap_data: key map table and size
|
||||
* @debounce_ms: debounce interval, in ms. Maximum is
|
||||
* %STMPE_KEYPAD_MAX_DEBOUNCE.
|
||||
* @scan_count: number of key scanning cycles to confirm key data.
|
||||
* Maximum is %STMPE_KEYPAD_MAX_SCAN_COUNT.
|
||||
* @no_autorepeat: disable key autorepeat
|
||||
*/
|
||||
struct stmpe_keypad_platform_data {
|
||||
const struct matrix_keymap_data *keymap_data;
|
||||
unsigned int debounce_ms;
|
||||
unsigned int scan_count;
|
||||
bool no_autorepeat;
|
||||
};
|
||||
|
||||
#define STMPE_GPIO_NOREQ_811_TOUCH (0xf0)
|
||||
|
||||
/**
|
||||
|
@ -199,7 +183,6 @@ struct stmpe_ts_platform_data {
|
|||
* @irq_gpio: gpio number over which irq will be requested (significant only if
|
||||
* irq_over_gpio is true)
|
||||
* @gpio: GPIO-specific platform data
|
||||
* @keypad: keypad-specific platform data
|
||||
* @ts: touchscreen-specific platform data
|
||||
*/
|
||||
struct stmpe_platform_data {
|
||||
|
@ -212,7 +195,6 @@ struct stmpe_platform_data {
|
|||
int autosleep_timeout;
|
||||
|
||||
struct stmpe_gpio_platform_data *gpio;
|
||||
struct stmpe_keypad_platform_data *keypad;
|
||||
struct stmpe_ts_platform_data *ts;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue