diff options
| author | Nick Dyer <nick.dyer@itdev.co.uk> | 2012-08-09 17:32:35 +0100 | 
|---|---|---|
| committer | Nick Dyer <nick.dyer@itdev.co.uk> | 2014-07-04 14:25:51 +0100 | 
| commit | ba10e0677efa4e8d6013b2bdfc29dce39fbb864c (patch) | |
| tree | 8aaaa6ffe4585e5a07aae7659ce52d4466e4550f | |
| parent | 495bf888c3ebd008b2383e46059a308448c09019 (diff) | |
| download | olio-linux-3.10-ba10e0677efa4e8d6013b2bdfc29dce39fbb864c.tar.xz olio-linux-3.10-ba10e0677efa4e8d6013b2bdfc29dce39fbb864c.zip  | |
Input: atmel_mxt_ts - implement support for T15 Key Array
There is a key array object in many maXTouch chips which allows some X/Y lines
to be used as a key array. This patch maps them to a series of keys which may
be configured in a platform data array.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
| -rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 53 | ||||
| -rw-r--r-- | include/linux/i2c/atmel_mxt_ts.h | 2 | 
2 files changed, 55 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 6aaad83f1b5..4ec1bd548f6 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -275,6 +275,7 @@ struct mxt_data {  	u8 last_message_count;  	u8 num_touchids;  	u8 num_stylusids; +	unsigned long t15_keystatus;  	/* Cached parameters from object table */  	u16 T5_address; @@ -284,6 +285,8 @@ struct mxt_data {  	u16 T7_address;  	u8 T9_reportid_min;  	u8 T9_reportid_max; +	u8 T15_reportid_min; +	u8 T15_reportid_max;  	u8 T19_reportid;  	u8 T42_reportid_min;  	u8 T42_reportid_max; @@ -800,6 +803,38 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)  	data->update_input = true;  } +static void mxt_proc_t15_messages(struct mxt_data *data, u8 *msg) +{ +	struct input_dev *input_dev = data->input_dev; +	struct device *dev = &data->client->dev; +	int key; +	bool curr_state, new_state; +	bool sync = false; +	unsigned long keystates = le32_to_cpu(msg[2]); + +	for (key = 0; key < data->pdata->t15_num_keys; key++) { +		curr_state = test_bit(key, &data->t15_keystatus); +		new_state = test_bit(key, &keystates); + +		if (!curr_state && new_state) { +			dev_dbg(dev, "T15 key press: %u\n", key); +			__set_bit(key, &data->t15_keystatus); +			input_event(input_dev, EV_KEY, +				    data->pdata->t15_keymap[key], 1); +			sync = true; +		} else if (curr_state && !new_state) { +			dev_dbg(dev, "T15 key release: %u\n", key); +			__clear_bit(key, &data->t15_keystatus); +			input_event(input_dev, EV_KEY, +				    data->pdata->t15_keymap[key], 0); +			sync = true; +		} +	} + +	if (sync) +		input_sync(input_dev); +} +  static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg)  {  	struct device *dev = &data->client->dev; @@ -911,6 +946,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)  	} else if (report_id >= data->T63_reportid_min  		   && report_id <= data->T63_reportid_max) {  		mxt_proc_t63_messages(data, message); +	} else if (report_id >= data->T15_reportid_min +		   && report_id <= data->T15_reportid_max) { +		mxt_proc_t15_messages(data, message);  	} else {  		mxt_dump_message(data, message);  	} @@ -1554,6 +1592,8 @@ static void mxt_free_object_table(struct mxt_data *data)  	data->T7_address = 0;  	data->T9_reportid_min = 0;  	data->T9_reportid_max = 0; +	data->T15_reportid_min = 0; +	data->T15_reportid_max = 0;  	data->T19_reportid = 0;  	data->T42_reportid_min = 0;  	data->T42_reportid_max = 0; @@ -1639,6 +1679,10 @@ static int mxt_get_object_table(struct mxt_data *data)  			data->num_touchids = object->num_report_ids  						* mxt_obj_instances(object);  			break; +		case MXT_TOUCH_KEYARRAY_T15: +			data->T15_reportid_min = min_id; +			data->T15_reportid_max = max_id; +			break;  		case MXT_PROCI_TOUCHSUPPRESSION_T42:  			data->T42_reportid_min = min_id;  			data->T42_reportid_max = max_id; @@ -2201,6 +2245,15 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data)  			0, MT_TOOL_MAX, 0, 0);  	} +	/* For T15 key array */ +	if (data->T15_reportid_min) { +		data->t15_keystatus = 0; + +		for (i = 0; i < data->pdata->t15_num_keys; i++) +			input_set_capability(input_dev, EV_KEY, +					     data->pdata->t15_keymap[i]); +	} +  	input_set_drvdata(input_dev, data);  	error = input_register_device(input_dev); diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index 02bf6ea3170..b7d20924eb7 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h @@ -20,6 +20,8 @@ struct mxt_platform_data {  	unsigned long irqflags;  	u8 t19_num_keys;  	const unsigned int *t19_keymap; +	int t15_num_keys; +	const unsigned int *t15_keymap;  };  #endif /* __LINUX_ATMEL_MXT_TS_H */  |