Commit 6d32af01 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Merge branch 'next' into for-linus

Second round of input updates for 3.19.
parents f20c86cd 27a560ba
...@@ -10,12 +10,13 @@ Optional properties: ...@@ -10,12 +10,13 @@ Optional properties:
Each button (key) is represented as a sub-node of "gpio-keys": Each button (key) is represented as a sub-node of "gpio-keys":
Subnode properties: Subnode properties:
- gpios: OF device-tree gpio specification.
- interrupts: the interrupt line for that input.
- label: Descriptive name of the key. - label: Descriptive name of the key.
- linux,code: Keycode to emit. - linux,code: Keycode to emit.
Required mutual exclusive subnode-properties: Note that either "interrupts" or "gpios" properties can be omitted, but not
- gpios: OF device-tree gpio specification. both at the same time. Specifying both properties is allowed.
- interrupts: the interrupt line for that input
Optional subnode-properties: Optional subnode-properties:
- linux,input-type: Specify event type this button/key generates. - linux,input-type: Specify event type this button/key generates.
...@@ -23,6 +24,9 @@ Optional subnode-properties: ...@@ -23,6 +24,9 @@ Optional subnode-properties:
- debounce-interval: Debouncing interval time in milliseconds. - debounce-interval: Debouncing interval time in milliseconds.
If not specified defaults to 5. If not specified defaults to 5.
- gpio-key,wakeup: Boolean, button can wake-up the system. - 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: Example nodes:
......
...@@ -8,6 +8,8 @@ Optional properties: ...@@ -8,6 +8,8 @@ Optional properties:
- debounce-interval : Debouncing interval time in milliseconds - debounce-interval : Debouncing interval time in milliseconds
- st,scan-count : Scanning cycles elapsed before key data is updated - st,scan-count : Scanning cycles elapsed before key data is updated
- st,no-autorepeat : If specified device will not autorepeat - st,no-autorepeat : If specified device will not autorepeat
- keypad,num-rows : See ./matrix-keymap.txt
- keypad,num-columns : See ./matrix-keymap.txt
Example: Example:
......
...@@ -28,6 +28,13 @@ ...@@ -28,6 +28,13 @@
#include <linux/cdev.h> #include <linux/cdev.h>
#include "input-compat.h" #include "input-compat.h"
enum evdev_clock_type {
EV_CLK_REAL = 0,
EV_CLK_MONO,
EV_CLK_BOOT,
EV_CLK_MAX
};
struct evdev { struct evdev {
int open; int open;
struct input_handle handle; struct input_handle handle;
...@@ -49,12 +56,32 @@ struct evdev_client { ...@@ -49,12 +56,32 @@ struct evdev_client {
struct fasync_struct *fasync; struct fasync_struct *fasync;
struct evdev *evdev; struct evdev *evdev;
struct list_head node; struct list_head node;
int clkid; int clk_type;
bool revoked; bool revoked;
unsigned int bufsize; unsigned int bufsize;
struct input_event buffer[]; 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 */ /* flush queued events of type @type, caller must hold client->buffer_lock */
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type) 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) ...@@ -108,8 +135,11 @@ static void evdev_queue_syn_dropped(struct evdev_client *client)
struct input_event ev; struct input_event ev;
ktime_t time; ktime_t time;
time = (client->clkid == CLOCK_MONOTONIC) ? time = client->clk_type == EV_CLK_REAL ?
ktime_get() : ktime_get_real(); ktime_get_real() :
client->clk_type == EV_CLK_MONO ?
ktime_get() :
ktime_get_boottime();
ev.time = ktime_to_timeval(time); ev.time = ktime_to_timeval(time);
ev.type = EV_SYN; ev.type = EV_SYN;
...@@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client, ...@@ -159,7 +189,7 @@ static void __pass_event(struct evdev_client *client,
static void evdev_pass_values(struct evdev_client *client, static void evdev_pass_values(struct evdev_client *client,
const struct input_value *vals, unsigned int count, const struct input_value *vals, unsigned int count,
ktime_t mono, ktime_t real) ktime_t *ev_time)
{ {
struct evdev *evdev = client->evdev; struct evdev *evdev = client->evdev;
const struct input_value *v; const struct input_value *v;
...@@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client, ...@@ -169,8 +199,7 @@ static void evdev_pass_values(struct evdev_client *client,
if (client->revoked) if (client->revoked)
return; return;
event.time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? event.time = ktime_to_timeval(ev_time[client->clk_type]);
mono : real);
/* Interrupts are disabled, just acquire the lock. */ /* Interrupts are disabled, just acquire the lock. */
spin_lock(&client->buffer_lock); spin_lock(&client->buffer_lock);
...@@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle, ...@@ -198,21 +227,22 @@ static void evdev_events(struct input_handle *handle,
{ {
struct evdev *evdev = handle->private; struct evdev *evdev = handle->private;
struct evdev_client *client; struct evdev_client *client;
ktime_t time_mono, time_real; ktime_t ev_time[EV_CLK_MAX];
time_mono = ktime_get(); ev_time[EV_CLK_MONO] = ktime_get();
time_real = ktime_mono_to_real(time_mono); 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(); rcu_read_lock();
client = rcu_dereference(evdev->grab); client = rcu_dereference(evdev->grab);
if (client) if (client)
evdev_pass_values(client, vals, count, time_mono, time_real); evdev_pass_values(client, vals, count, ev_time);
else else
list_for_each_entry_rcu(client, &evdev->client_list, node) list_for_each_entry_rcu(client, &evdev->client_list, node)
evdev_pass_values(client, vals, count, evdev_pass_values(client, vals, count, ev_time);
time_mono, time_real);
rcu_read_unlock(); rcu_read_unlock();
} }
...@@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, ...@@ -877,10 +907,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
case EVIOCSCLOCKID: case EVIOCSCLOCKID:
if (copy_from_user(&i, p, sizeof(unsigned int))) if (copy_from_user(&i, p, sizeof(unsigned int)))
return -EFAULT; return -EFAULT;
if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME)
return -EINVAL; return evdev_set_clk_type(client, i);
client->clkid = i;
return 0;
case EVIOCGKEYCODE: case EVIOCGKEYCODE:
return evdev_handle_get_keycode(dev, p); return evdev_handle_get_keycode(dev, p);
......
...@@ -1974,18 +1974,22 @@ static unsigned int input_estimate_events_per_packet(struct input_dev *dev) ...@@ -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 */ events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
for (i = 0; i < ABS_CNT; i++) { if (test_bit(EV_ABS, dev->evbit)) {
if (test_bit(i, dev->absbit)) { for (i = 0; i < ABS_CNT; i++) {
if (input_is_mt_axis(i)) if (test_bit(i, dev->absbit)) {
events += mt_slots; if (input_is_mt_axis(i))
else events += mt_slots;
events++; else
events++;
}
} }
} }
for (i = 0; i < REL_CNT; i++) if (test_bit(EV_REL, dev->evbit)) {
if (test_bit(i, dev->relbit)) for (i = 0; i < REL_CNT; i++)
events++; if (test_bit(i, dev->relbit))
events++;
}
/* Make room for KEY and MSC events */ /* Make room for KEY and MSC events */
events += 7; events += 7;
......
...@@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC ...@@ -559,6 +559,7 @@ config KEYBOARD_SH_KEYSC
config KEYBOARD_STMPE config KEYBOARD_STMPE
tristate "STMPE keypad support" tristate "STMPE keypad support"
depends on MFD_STMPE depends on MFD_STMPE
depends on OF
select INPUT_MATRIXKMAP select INPUT_MATRIXKMAP
help help
Say Y here if you want to use the keypad controller on STMPE I/O Say Y here if you want to use the keypad controller on STMPE I/O
......
...@@ -35,9 +35,13 @@ ...@@ -35,9 +35,13 @@
struct gpio_button_data { struct gpio_button_data {
const struct gpio_keys_button *button; const struct gpio_keys_button *button;
struct input_dev *input; struct input_dev *input;
struct timer_list timer;
struct work_struct work; struct timer_list release_timer;
unsigned int timer_debounce; /* in msecs */ 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; unsigned int irq;
spinlock_t lock; spinlock_t lock;
bool disabled; bool disabled;
...@@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata) ...@@ -116,11 +120,14 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
{ {
if (!bdata->disabled) { if (!bdata->disabled) {
/* /*
* Disable IRQ and possible debouncing timer. * Disable IRQ and associated timer/work structure.
*/ */
disable_irq(bdata->irq); 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; bdata->disabled = true;
} }
...@@ -343,7 +350,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata) ...@@ -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) static void gpio_keys_gpio_work_func(struct work_struct *work)
{ {
struct gpio_button_data *bdata = 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); gpio_keys_gpio_report_event(bdata);
...@@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work) ...@@ -351,13 +358,6 @@ static void gpio_keys_gpio_work_func(struct work_struct *work)
pm_relax(bdata->input->dev.parent); 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) static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
{ {
struct gpio_button_data *bdata = 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) ...@@ -366,11 +366,10 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
if (bdata->button->wakeup) if (bdata->button->wakeup)
pm_stay_awake(bdata->input->dev.parent); pm_stay_awake(bdata->input->dev.parent);
if (bdata->timer_debounce)
mod_timer(&bdata->timer, mod_delayed_work(system_wq,
jiffies + msecs_to_jiffies(bdata->timer_debounce)); &bdata->work,
else msecs_to_jiffies(bdata->software_debounce));
schedule_work(&bdata->work);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -408,7 +407,7 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) ...@@ -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_event(input, EV_KEY, button->code, 1);
input_sync(input); input_sync(input);
if (!bdata->timer_debounce) { if (!bdata->release_delay) {
input_event(input, EV_KEY, button->code, 0); input_event(input, EV_KEY, button->code, 0);
input_sync(input); input_sync(input);
goto out; goto out;
...@@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id) ...@@ -417,9 +416,9 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
bdata->key_pressed = true; bdata->key_pressed = true;
} }
if (bdata->timer_debounce) if (bdata->release_delay)
mod_timer(&bdata->timer, mod_timer(&bdata->release_timer,
jiffies + msecs_to_jiffies(bdata->timer_debounce)); jiffies + msecs_to_jiffies(bdata->release_delay));
out: out:
spin_unlock_irqrestore(&bdata->lock, flags); spin_unlock_irqrestore(&bdata->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data) ...@@ -429,10 +428,10 @@ static void gpio_keys_quiesce_key(void *data)
{ {
struct gpio_button_data *bdata = data; struct gpio_button_data *bdata = data;
if (bdata->timer_debounce) if (gpio_is_valid(bdata->button->gpio))
del_timer_sync(&bdata->timer); cancel_delayed_work_sync(&bdata->work);
else
cancel_work_sync(&bdata->work); del_timer_sync(&bdata->release_timer);
} }
static int gpio_keys_setup_key(struct platform_device *pdev, static int gpio_keys_setup_key(struct platform_device *pdev,
...@@ -466,23 +465,25 @@ 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); button->debounce_interval * 1000);
/* use timer if gpiolib doesn't provide debounce */ /* use timer if gpiolib doesn't provide debounce */
if (error < 0) if (error < 0)
bdata->timer_debounce = bdata->software_debounce =
button->debounce_interval; button->debounce_interval;
} }
irq = gpio_to_irq(button->gpio); if (button->irq) {
if (irq < 0) { bdata->irq = button->irq;
error = irq; } else {
dev_err(dev, irq = gpio_to_irq(button->gpio);
"Unable to get irq number for GPIO %d, error %d\n", if (irq < 0) {
button->gpio, error); error = irq;
return error; 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); INIT_DELAYED_WORK(&bdata->work, gpio_keys_gpio_work_func);
setup_timer(&bdata->timer,
gpio_keys_gpio_timer, (unsigned long)bdata);
isr = gpio_keys_gpio_isr; isr = gpio_keys_gpio_isr;
irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; irqflags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
...@@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, ...@@ -499,8 +500,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
return -EINVAL; return -EINVAL;
} }
bdata->timer_debounce = button->debounce_interval; bdata->release_delay = button->debounce_interval;
setup_timer(&bdata->timer, setup_timer(&bdata->release_timer,
gpio_keys_irq_timer, (unsigned long)bdata); gpio_keys_irq_timer, (unsigned long)bdata);
isr = gpio_keys_irq_isr; isr = gpio_keys_irq_isr;
...@@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, ...@@ -510,7 +511,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
input_set_capability(input, button->type ?: EV_KEY, button->code); 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. * workqueue item.
*/ */
error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata); error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
...@@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev) ...@@ -618,33 +619,30 @@ gpio_keys_get_devtree_pdata(struct device *dev)
i = 0; i = 0;
for_each_child_of_node(node, pp) { for_each_child_of_node(node, pp) {
int gpio = -1;
enum of_gpio_flags flags; enum of_gpio_flags flags;
button = &pdata->buttons[i++]; button = &pdata->buttons[i++];
if (!of_find_property(pp, "gpios", NULL)) { button->gpio = of_get_gpio_flags(pp, 0, &flags);
button->irq = irq_of_parse_and_map(pp, 0); if (button->gpio < 0) {
if (button->irq == 0) { error = button->gpio;
i--; if (error != -ENOENT) {
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;
if (error != -EPROBE_DEFER) if (error != -EPROBE_DEFER)
dev_err(dev, dev_err(dev,
"Failed to get gpio flags, error: %d\n", "Failed to get gpio flags, error: %d\n",
error); error);
return ERR_PTR(error); return ERR_PTR(error);
} }
} else {
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
} }
button->gpio = gpio; button->irq = irq_of_parse_and_map(pp, 0);
button->active_low = flags & OF_GPIO_ACTIVE_LOW;
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)) { if (of_property_read_u32(pp, "linux,code", &button->code)) {
dev_err(dev, "Button without keycode: 0x%x\n", dev_err(dev, "Button without keycode: 0x%x\n",
...@@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev) ...@@ -659,6 +657,8 @@ gpio_keys_get_devtree_pdata(struct device *dev)
button->wakeup = !!of_get_property(pp, "gpio-key,wakeup", NULL); 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", if (of_property_read_u32(pp, "debounce-interval",
&button->debounce_interval)) &button->debounce_interval))
button->debounce_interval = 5; button->debounce_interval = 5;
......
...@@ -45,13 +45,14 @@ ...@@ -45,13 +45,14 @@
#define STMPE_KEYPAD_MAX_ROWS 8 #define STMPE_KEYPAD_MAX_ROWS 8
#define STMPE_KEYPAD_MAX_COLS 8 #define STMPE_KEYPAD_MAX_COLS 8
#define STMPE_KEYPAD_ROW_SHIFT 3 #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) (STMPE_KEYPAD_MAX_ROWS * STMPE_KEYPAD_MAX_COLS)
/** /**
* struct stmpe_keypad_variant - model-specific attributes * struct stmpe_keypad_variant - model-specific attributes
* @auto_increment: whether the KPC_DATA_BYTE register address * @auto_increment: whether the KPC_DATA_BYTE register address
* auto-increments on multiple read * auto-increments on multiple read
* @set_pullup: whether the pins need to have their pull-ups set
* @num_data: number of data bytes * @num_data: number of data bytes
* @num_normal_data: number of normal keys' data bytes * @num_normal_data: number of normal keys' data bytes
* @max_cols: maximum number of columns supported * @max_cols: maximum number of columns supported
...@@ -61,6 +62,7 @@ ...@@ -61,6 +62,7 @@
*/ */
struct stmpe_keypad_variant { struct stmpe_keypad_variant {
bool auto_increment; bool auto_increment;
bool set_pullup;
int num_data; int num_data;
int num_normal_data; int num_normal_data;
int max_cols; int max_cols;
...@@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { ...@@ -81,6 +83,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
}, },
[STMPE2401] = { [STMPE2401] = {
.auto_increment = false, .auto_increment = false,
.set_pullup = true,
.num_data = 3, .num_data = 3,
.num_normal_data = 2, .num_normal_data = 2,
.max_cols = 8, .max_cols = 8,
...@@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { ...@@ -90,6 +93,7 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = {
}, },
[STMPE2403] = { [STMPE2403] = {
.auto_increment = true, .auto_increment = true,
.set_pullup = true,
.num_data = 5, .num_data = 5,
.num_normal_data = 3, .num_normal_data = 3,
.max_cols = 8, .max_cols = 8,
...@@ -99,16 +103,30 @@ static const struct stmpe_keypad_variant stmpe_keypad_variants[] = { ...@@ -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_keypad {
struct stmpe *stmpe; struct stmpe *stmpe;
struct input_dev *input; struct input_dev *input;
const struct stmpe_keypad_variant *variant; 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 rows;
unsigned int cols; unsigned int cols;
unsigned short keymap[STMPE_KEYPAD_KEYMAP_MAX_SIZE];
unsigned short keymap[STMPE_KEYPAD_KEYMAP_SIZE];
}; };
static int stmpe_keypad_read_data(struct stmpe_keypad *keypad, u8 *data) 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) ...@@ -171,7 +189,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
unsigned int col_gpios = variant->col_gpios; unsigned int col_gpios = variant->col_gpios;
unsigned int row_gpios = variant->row_gpios; unsigned int row_gpios = variant->row_gpios;
struct stmpe *stmpe = keypad->stmpe; struct stmpe *stmpe = keypad->stmpe;
u8 pureg = stmpe->regs[STMPE_IDX_GPPUR_LSB];
unsigned int pins = 0; unsigned int pins = 0;
unsigned int pu_pins = 0;
int ret;
int i; int i;
/* /*
...@@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) ...@@ -188,8 +209,10 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
for (i = 0; i < variant->max_cols; i++) { for (i = 0; i < variant->max_cols; i++) {
int num = __ffs(col_gpios); int num = __ffs(col_gpios);
if (keypad->cols & (1 << i)) if (keypad->cols & (1 << i)) {
pins |= 1 << num; pins |= 1 << num;
pu_pins |= 1 << num;
}
col_gpios &= ~(1 << num); col_gpios &= ~(1 << num);
} }
...@@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad) ...@@ -203,20 +226,43 @@ static int stmpe_keypad_altfunc_init(struct stmpe_keypad *keypad)
row_gpios &= ~(1 << num); 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) 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; const struct stmpe_keypad_variant *variant = keypad->variant;
struct stmpe *stmpe = keypad->stmpe; struct stmpe *stmpe = keypad->stmpe;
int ret; int ret;
if (plat->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE) if (keypad->debounce_ms > STMPE_KEYPAD_MAX_DEBOUNCE)
return -EINVAL; return -EINVAL;
if (plat->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT) if (keypad->scan_count > STMPE_KEYPAD_MAX_SCAN_COUNT)
return -EINVAL; return -EINVAL;
ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD); ret = stmpe_enable(stmpe, STMPE_BLOCK_KEYPAD);
...@@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) ...@@ -245,7 +291,7 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB, ret = stmpe_set_bits(stmpe, STMPE_KPC_CTRL_MSB,
STMPE_KPC_CTRL_MSB_SCAN_COUNT, STMPE_KPC_CTRL_MSB_SCAN_COUNT,
plat->scan_count << 4); keypad->scan_count << 4);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad) ...@@ -253,17 +299,18 @@ static int stmpe_keypad_chip_init(struct stmpe_keypad *keypad)
STMPE_KPC_CTRL_LSB_SCAN | STMPE_KPC_CTRL_LSB_SCAN |
STMPE_KPC_CTRL_LSB_DEBOUNCE, STMPE_KPC_CTRL_LSB_DEBOUNCE,
STMPE_KPC_CTRL_LSB_SCAN | 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; int row, col;
for (row = 0; row < STMPE_KEYPAD_MAX_ROWS; row++) { for (row = 0; row < used_rows; row++) {
for (col = 0; col < STMPE_KEYPAD_MAX_COLS; col++) { for (col = 0; col < used_cols; col++) {
int code = MATRIX_SCAN_CODE(row, col, int code = MATRIX_SCAN_CODE(row, col,
STMPE_KEYPAD_ROW_SHIFT); STMPE_KEYPAD_ROW_SHIFT);
if (keypad->keymap[code] != KEY_RESERVED) { if (keypad->keymap[code] != KEY_RESERVED) {
keypad->rows |= 1 << row; keypad->rows |= 1 << row;
keypad->cols |= 1 << col; keypad->cols |= 1 << col;
...@@ -272,51 +319,17 @@ static void stmpe_keypad_fill_used_pins(struct stmpe_keypad *keypad) ...@@ -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) static int stmpe_keypad_probe(struct platform_device *pdev)
{ {
struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent); 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 stmpe_keypad *keypad;
struct input_dev *input; struct input_dev *input;
u32 rows;
u32 cols;
int error; int error;
int irq; 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); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0)
return irq; return irq;
...@@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev) ...@@ -326,6 +339,13 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
if (!keypad) if (!keypad)
return -ENOMEM; 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); input = devm_input_allocate_device(&pdev->dev);
if (!input) if (!input)
return -ENOMEM; return -ENOMEM;
...@@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev) ...@@ -334,23 +354,22 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
input->dev.parent = &pdev->dev; input->dev.parent = &pdev->dev;
error = matrix_keypad_build_keymap(plat->keymap_data, NULL, error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
STMPE_KEYPAD_MAX_ROWS, if (error)
STMPE_KEYPAD_MAX_COLS, return error;
error = matrix_keypad_build_keymap(NULL, NULL, rows, cols,
keypad->keymap, input); keypad->keymap, input);
if (error) if (error)
return error; return error;
input_set_capability(input, EV_MSC, MSC_SCAN); input_set_capability(input, EV_MSC, MSC_SCAN);
if (!plat->no_autorepeat) if (!keypad->no_autorepeat)
__set_bit(EV_REP, input->evbit); __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->input = input;
keypad->variant = &stmpe_keypad_variants[stmpe->partnum];
error = stmpe_keypad_chip_init(keypad); error = stmpe_keypad_chip_init(keypad);
if (error < 0) if (error < 0)
......
...@@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, ...@@ -881,6 +881,34 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt,
unsigned char *pkt, unsigned char *pkt,
unsigned char pkt_id) 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] & 0x80) << 4);
mt[0].x |= ((pkt[2] & 0x3F) << 5); mt[0].x |= ((pkt[2] & 0x3F) << 5);
mt[0].x |= ((pkt[3] & 0x30) >> 1); mt[0].x |= ((pkt[3] & 0x30) >> 1);
...@@ -919,18 +947,21 @@ static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, ...@@ -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) 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++) for (i = 0; i < MAX_TOUCHES; i++) {
/* empty */; if (mt[i].x != 0 || mt[i].y != 0)
fingers++;
}
return i; return fingers;
} }
static int alps_decode_packet_v7(struct alps_fields *f, static int alps_decode_packet_v7(struct alps_fields *f,
unsigned char *p, unsigned char *p,
struct psmouse *psmouse) struct psmouse *psmouse)
{ {
struct alps_data *priv = psmouse->private;
unsigned char pkt_id; unsigned char pkt_id;
pkt_id = alps_get_packet_id_v7(p); pkt_id = alps_get_packet_id_v7(p);
...@@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f, ...@@ -938,19 +969,52 @@ static int alps_decode_packet_v7(struct alps_fields *f,
return 0; return 0;
if (pkt_id == V7_PACKET_ID_UNKNOWN) if (pkt_id == V7_PACKET_ID_UNKNOWN)
return -1; 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); alps_get_finger_coordinate_v7(f->mt, p, pkt_id);
if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) { if (pkt_id == V7_PACKET_ID_TWO)
f->left = (p[0] & 0x80) >> 7; 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->right = (p[0] & 0x20) >> 5;
f->middle = (p[0] & 0x10) >> 4; f->middle = (p[0] & 0x10) >> 4;
} }
if (pkt_id == V7_PACKET_ID_TWO) /* Sometimes a single touch is reported in mt[1] rather then mt[0] */
f->fingers = alps_get_mt_count(f->mt); if (f->fingers == 1 && f->mt[0].x == 0 && f->mt[0].y == 0) {
else if (pkt_id == V7_PACKET_ID_MULTI) f->mt[0].x = f->mt[1].x;
f->fingers = 3 + (p[5] & 0x03); f->mt[0].y = f->mt[1].y;
f->mt[1].x = 0;
f->mt[1].y = 0;
}
return 0; return 0;
} }
......
...@@ -227,6 +227,7 @@ TRACKPOINT_INT_ATTR(thresh, TP_THRESH, TP_DEF_THRESH); ...@@ -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(upthresh, TP_UP_THRESH, TP_DEF_UP_THRESH);
TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); 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(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, TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
TP_DEF_PTSON); TP_DEF_PTSON);
...@@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = { ...@@ -246,6 +247,7 @@ static struct attribute *trackpoint_attrs[] = {
&psmouse_attr_upthresh.dattr.attr, &psmouse_attr_upthresh.dattr.attr,
&psmouse_attr_ztime.dattr.attr, &psmouse_attr_ztime.dattr.attr,
&psmouse_attr_jenks.dattr.attr, &psmouse_attr_jenks.dattr.attr,
&psmouse_attr_drift_time.dattr.attr,
&psmouse_attr_press_to_select.dattr.attr, &psmouse_attr_press_to_select.dattr.attr,
&psmouse_attr_skipback.dattr.attr, &psmouse_attr_skipback.dattr.attr,
&psmouse_attr_ext_dev.dattr.attr, &psmouse_attr_ext_dev.dattr.attr,
...@@ -312,6 +314,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state) ...@@ -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, upthresh);
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, ztime); 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, jenks);
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, drift_time);
/* toggles */ /* toggles */
TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select); TRACKPOINT_UPDATE(in_power_on_state, psmouse, tp, press_to_select);
...@@ -332,6 +335,7 @@ static void trackpoint_defaults(struct trackpoint_data *tp) ...@@ -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, upthresh);
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, ztime);
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, jenks);
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, drift_time);
TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia); TRACKPOINT_SET_POWER_ON_DEFAULT(tp, inertia);
/* toggles */ /* toggles */
......
...@@ -70,6 +70,9 @@ ...@@ -70,6 +70,9 @@
#define TP_UP_THRESH 0x5A /* Used to generate a 'click' on Z-axis */ #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_Z_TIME 0x5E /* How sharp of a press */
#define TP_JENKS_CURV 0x5D /* Minimum curvature for double click */ #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 * Toggling Flag bits
...@@ -120,6 +123,7 @@ ...@@ -120,6 +123,7 @@
#define TP_DEF_UP_THRESH 0xFF #define TP_DEF_UP_THRESH 0xFF
#define TP_DEF_Z_TIME 0x26 #define TP_DEF_Z_TIME 0x26
#define TP_DEF_JENKS_CURV 0x87 #define TP_DEF_JENKS_CURV 0x87
#define TP_DEF_DRIFT_TIME 0x05
/* Toggles */ /* Toggles */
#define TP_DEF_MB 0x00 #define TP_DEF_MB 0x00
...@@ -137,6 +141,7 @@ struct trackpoint_data ...@@ -137,6 +141,7 @@ struct trackpoint_data
unsigned char draghys, mindrag; unsigned char draghys, mindrag;
unsigned char thresh, upthresh; unsigned char thresh, upthresh;
unsigned char ztime, jenks; unsigned char ztime, jenks;
unsigned char drift_time;
/* toggles */ /* toggles */
unsigned char press_to_select; unsigned char press_to_select;
......
...@@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client, ...@@ -850,9 +850,11 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
} }
#define EDT_ATTR_CHECKSET(name, reg) \ #define EDT_ATTR_CHECKSET(name, reg) \
do { \
if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \ if (pdata->name >= edt_ft5x06_attr_##name.limit_low && \
pdata->name <= edt_ft5x06_attr_##name.limit_high) \ 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) { \ #define EDT_GET_PROP(name, reg) { \
u32 val; \ u32 val; \
......
...@@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = { ...@@ -519,6 +519,7 @@ static const u8 stmpe1601_regs[] = {
[STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB,
[STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB,
[STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_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_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB,
[STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB,
[STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB,
...@@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = { ...@@ -667,6 +668,7 @@ static const u8 stmpe1801_regs[] = {
[STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW,
[STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW,
[STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_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_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW,
[STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW,
}; };
...@@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = { ...@@ -750,6 +752,8 @@ static const u8 stmpe24xx_regs[] = {
[STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB,
[STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB,
[STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_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_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB,
[STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB,
[STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB,
......
...@@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe); ...@@ -188,6 +188,7 @@ int stmpe_remove(struct stmpe *stmpe);
#define STMPE1601_REG_GPIO_ED_MSB 0x8A #define STMPE1601_REG_GPIO_ED_MSB 0x8A
#define STMPE1601_REG_GPIO_RE_LSB 0x8D #define STMPE1601_REG_GPIO_RE_LSB 0x8D
#define STMPE1601_REG_GPIO_FE_LSB 0x8F #define STMPE1601_REG_GPIO_FE_LSB 0x8F
#define STMPE1601_REG_GPIO_PU_LSB 0x91
#define STMPE1601_REG_GPIO_AF_U_MSB 0x92 #define STMPE1601_REG_GPIO_AF_U_MSB 0x92
#define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3)
...@@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe); ...@@ -276,6 +277,8 @@ int stmpe_remove(struct stmpe *stmpe);
#define STMPE24XX_REG_GPEDR_MSB 0x8C #define STMPE24XX_REG_GPEDR_MSB 0x8C
#define STMPE24XX_REG_GPRER_LSB 0x91 #define STMPE24XX_REG_GPRER_LSB 0x91
#define STMPE24XX_REG_GPFER_LSB 0x94 #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_REG_GPAFR_U_MSB 0x9B
#define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3)
......
...@@ -50,6 +50,8 @@ enum { ...@@ -50,6 +50,8 @@ enum {
STMPE_IDX_GPEDR_MSB, STMPE_IDX_GPEDR_MSB,
STMPE_IDX_GPRER_LSB, STMPE_IDX_GPRER_LSB,
STMPE_IDX_GPFER_LSB, STMPE_IDX_GPFER_LSB,
STMPE_IDX_GPPUR_LSB,
STMPE_IDX_GPPDR_LSB,
STMPE_IDX_GPAFR_U_MSB, STMPE_IDX_GPAFR_U_MSB,
STMPE_IDX_IEGPIOR_LSB, STMPE_IDX_IEGPIOR_LSB,
STMPE_IDX_ISGPIOR_LSB, STMPE_IDX_ISGPIOR_LSB,
...@@ -113,24 +115,6 @@ extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, ...@@ -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_enable(struct stmpe *stmpe, unsigned int blocks);
extern int stmpe_disable(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) #define STMPE_GPIO_NOREQ_811_TOUCH (0xf0)
/** /**
...@@ -199,7 +183,6 @@ struct stmpe_ts_platform_data { ...@@ -199,7 +183,6 @@ struct stmpe_ts_platform_data {
* @irq_gpio: gpio number over which irq will be requested (significant only if * @irq_gpio: gpio number over which irq will be requested (significant only if
* irq_over_gpio is true) * irq_over_gpio is true)
* @gpio: GPIO-specific platform data * @gpio: GPIO-specific platform data
* @keypad: keypad-specific platform data
* @ts: touchscreen-specific platform data * @ts: touchscreen-specific platform data
*/ */
struct stmpe_platform_data { struct stmpe_platform_data {
...@@ -212,7 +195,6 @@ struct stmpe_platform_data { ...@@ -212,7 +195,6 @@ struct stmpe_platform_data {
int autosleep_timeout; int autosleep_timeout;
struct stmpe_gpio_platform_data *gpio; struct stmpe_gpio_platform_data *gpio;
struct stmpe_keypad_platform_data *keypad;
struct stmpe_ts_platform_data *ts; struct stmpe_ts_platform_data *ts;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment