Merge branch 'next' into for-linus

Second round of input updates for 3.19.
This commit is contained in:
Dmitry Torokhov 2014-12-18 10:02:39 -08:00
commit 6d32af019a
14 changed files with 299 additions and 177 deletions

View File

@ -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:

View File

@ -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:

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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; \

View File

@ -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,

View File

@ -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)

View File

@ -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;
};