diff mbox series

[2/2] Input: atmel_mxt_ts - support capacitive keys

Message ID 20230227205035.18551-2-git@apitzsch.eu (mailing list archive)
State New, archived
Headers show
Series [1/2] dt-bindings: input: atmel,maxtouch: add linux,keycodes | expand

Commit Message

André Apitzsch Feb. 27, 2023, 8:50 p.m. UTC
Add support for touch keys found in some Atmel touch controller
configurations.

Signed-off-by: André Apitzsch <git@apitzsch.eu>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 85 ++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

Comments

Linus Walleij March 6, 2023, 10:54 p.m. UTC | #1
On Mon, Feb 27, 2023 at 9:50 PM André Apitzsch <git@apitzsch.eu> wrote:

> Add support for touch keys found in some Atmel touch controller
> configurations.
>
> Signed-off-by: André Apitzsch <git@apitzsch.eu>

Looks good to me.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
Claudiu Beznea March 7, 2023, 8:57 a.m. UTC | #2
On 27.02.2023 22:50, André Apitzsch wrote:
> [Some people who received this message don't often get email from git@apitzsch.eu. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Add support for touch keys found in some Atmel touch controller
> configurations.
> 
> Signed-off-by: André Apitzsch <git@apitzsch.eu>

Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com>


> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 85 ++++++++++++++++++++++++
>  1 file changed, 85 insertions(+)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 996bf434e1cb..eb368dd1abf0 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -55,6 +55,7 @@
>  #define MXT_TOUCH_KEYARRAY_T15         15
>  #define MXT_TOUCH_PROXIMITY_T23                23
>  #define MXT_TOUCH_PROXKEY_T52          52
> +#define MXT_TOUCH_PTC_KEYS_T97         97
>  #define MXT_PROCI_GRIPFACE_T20         20
>  #define MXT_PROCG_NOISE_T22            22
>  #define MXT_PROCI_ONETOUCH_T24         24
> @@ -326,9 +327,13 @@ struct mxt_data {
>         u16 T71_address;
>         u8 T9_reportid_min;
>         u8 T9_reportid_max;
> +       u8 T15_reportid_min;
> +       u8 T15_reportid_max;
>         u16 T18_address;
>         u8 T19_reportid;
>         u16 T44_address;
> +       u8 T97_reportid_min;
> +       u8 T97_reportid_max;
>         u8 T100_reportid_min;
>         u8 T100_reportid_max;
> 
> @@ -344,6 +349,9 @@ struct mxt_data {
>         u32 *t19_keymap;
>         unsigned int t19_num_keys;
> 
> +       u32 *t15_keymap;
> +       unsigned int t15_num_keys;
> +
>         enum mxt_suspend_mode suspend_mode;
> 
>         u32 wakeup_method;
> @@ -375,6 +383,7 @@ static bool mxt_object_readable(unsigned int type)
>         case MXT_TOUCH_KEYARRAY_T15:
>         case MXT_TOUCH_PROXIMITY_T23:
>         case MXT_TOUCH_PROXKEY_T52:
> +       case MXT_TOUCH_PTC_KEYS_T97:
>         case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>         case MXT_PROCI_GRIPFACE_T20:
>         case MXT_PROCG_NOISE_T22:
> @@ -891,6 +900,25 @@ 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 *message)
> +{
> +       struct input_dev *input_dev = data->input_dev;
> +       unsigned long keystates = get_unaligned_le32(&message[2]);
> +       int key;
> +
> +       for (key = 0; key < data->t15_num_keys; key++) {
> +               input_report_key(input_dev, data->t15_keymap[key],
> +                       !!(keystates & BIT(key)));
> +       }
> +
> +       data->update_input = true;
> +}
> +
> +static void mxt_proc_t97_messages(struct mxt_data *data, u8 *message)
> +{
> +       mxt_proc_t15_messages(data, message);
> +}
> +
>  static void mxt_proc_t100_message(struct mxt_data *data, u8 *message)
>  {
>         struct device *dev = &data->client->dev;
> @@ -1017,6 +1045,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
>         } else if (report_id >= data->T9_reportid_min &&
>                    report_id <= data->T9_reportid_max) {
>                 mxt_proc_t9_message(data, message);
> +       } else if (report_id >= data->T15_reportid_min &&
> +                  report_id <= data->T15_reportid_max) {
> +               mxt_proc_t15_messages(data, message);
> +       } else if (report_id >= data->T97_reportid_min &&
> +                  report_id <= data->T97_reportid_max) {
> +               mxt_proc_t97_messages(data, message);
>         } else if (report_id >= data->T100_reportid_min &&
>                    report_id <= data->T100_reportid_max) {
>                 mxt_proc_t100_message(data, message);
> @@ -1689,9 +1723,13 @@ static void mxt_free_object_table(struct mxt_data *data)
>         data->T71_address = 0;
>         data->T9_reportid_min = 0;
>         data->T9_reportid_max = 0;
> +       data->T15_reportid_min = 0;
> +       data->T15_reportid_max = 0;
>         data->T18_address = 0;
>         data->T19_reportid = 0;
>         data->T44_address = 0;
> +       data->T97_reportid_min = 0;
> +       data->T97_reportid_max = 0;
>         data->T100_reportid_min = 0;
>         data->T100_reportid_max = 0;
>         data->max_reportid = 0;
> @@ -1764,6 +1802,10 @@ static int mxt_parse_object_table(struct mxt_data *data,
>                                                 object->num_report_ids - 1;
>                         data->num_touchids = object->num_report_ids;
>                         break;
> +               case MXT_TOUCH_KEYARRAY_T15:
> +                       data->T15_reportid_min = min_id;
> +                       data->T15_reportid_max = max_id;
> +                       break;
>                 case MXT_SPT_COMMSCONFIG_T18:
>                         data->T18_address = object->start_address;
>                         break;
> @@ -1773,6 +1815,10 @@ static int mxt_parse_object_table(struct mxt_data *data,
>                 case MXT_SPT_GPIOPWM_T19:
>                         data->T19_reportid = min_id;
>                         break;
> +               case MXT_TOUCH_PTC_KEYS_T97:
> +                       data->T97_reportid_min = min_id;
> +                       data->T97_reportid_max = max_id;
> +                       break;
>                 case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>                         data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100;
>                         data->T100_reportid_min = min_id;
> @@ -2050,6 +2096,7 @@ static int mxt_initialize_input_device(struct mxt_data *data)
>         int error;
>         unsigned int num_mt_slots;
>         unsigned int mt_flags = 0;
> +       int i;
> 
>         switch (data->multitouch) {
>         case MXT_TOUCH_MULTI_T9:
> @@ -2095,6 +2142,10 @@ static int mxt_initialize_input_device(struct mxt_data *data)
>         input_dev->open = mxt_input_open;
>         input_dev->close = mxt_input_close;
> 
> +       input_dev->keycode = data->t15_keymap;
> +       input_dev->keycodemax = data->t15_num_keys;
> +       input_dev->keycodesize = sizeof(data->t15_keymap[0]);
> +
>         input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
> 
>         /* For single touch */
> @@ -2162,6 +2213,12 @@ static int mxt_initialize_input_device(struct mxt_data *data)
>                                      0, 255, 0, 0);
>         }
> 
> +       /* For T15 and T97 Key Array */
> +       if (data->T15_reportid_min || data->T97_reportid_min) {
> +               for (i = 0; i < data->t15_num_keys; i++)
> +                       input_set_capability(input_dev, EV_KEY, data->t15_keymap[i]);
> +       }
> +
>         input_set_drvdata(input_dev, data);
> 
>         error = input_register_device(input_dev);
> @@ -3080,8 +3137,10 @@ static void mxt_input_close(struct input_dev *dev)
>  static int mxt_parse_device_properties(struct mxt_data *data)
>  {
>         static const char keymap_property[] = "linux,gpio-keymap";
> +       static const char buttons_property[] = "linux,keycodes";
>         struct device *dev = &data->client->dev;
>         u32 *keymap;
> +       u32 *buttonmap;
>         int n_keys;
>         int error;
> 
> @@ -3111,6 +3170,32 @@ static int mxt_parse_device_properties(struct mxt_data *data)
>                 data->t19_num_keys = n_keys;
>         }
> 
> +       if (device_property_present(dev, buttons_property)) {
> +               n_keys = device_property_count_u32(dev, buttons_property);
> +               if (n_keys <= 0) {
> +                       error = n_keys < 0 ? n_keys : -EINVAL;
> +                       dev_err(dev, "invalid/malformed '%s' property: %d\n",
> +                               buttons_property, error);
> +                       return error;
> +               }
> +
> +               buttonmap = devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap),
> +                                              GFP_KERNEL);
> +               if (!buttonmap)
> +                       return -ENOMEM;
> +
> +               error = device_property_read_u32_array(dev, buttons_property,
> +                                                      buttonmap, n_keys);
> +               if (error) {
> +                       dev_err(dev, "failed to parse '%s' property: %d\n",
> +                               buttons_property, error);
> +                       return error;
> +               }
> +
> +               data->t15_keymap = buttonmap;
> +               data->t15_num_keys = n_keys;
> +       }
> +
>         return 0;
>  }
> 
> --
> 2.39.2
>
diff mbox series

Patch

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 996bf434e1cb..eb368dd1abf0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -55,6 +55,7 @@ 
 #define MXT_TOUCH_KEYARRAY_T15		15
 #define MXT_TOUCH_PROXIMITY_T23		23
 #define MXT_TOUCH_PROXKEY_T52		52
+#define MXT_TOUCH_PTC_KEYS_T97		97
 #define MXT_PROCI_GRIPFACE_T20		20
 #define MXT_PROCG_NOISE_T22		22
 #define MXT_PROCI_ONETOUCH_T24		24
@@ -326,9 +327,13 @@  struct mxt_data {
 	u16 T71_address;
 	u8 T9_reportid_min;
 	u8 T9_reportid_max;
+	u8 T15_reportid_min;
+	u8 T15_reportid_max;
 	u16 T18_address;
 	u8 T19_reportid;
 	u16 T44_address;
+	u8 T97_reportid_min;
+	u8 T97_reportid_max;
 	u8 T100_reportid_min;
 	u8 T100_reportid_max;
 
@@ -344,6 +349,9 @@  struct mxt_data {
 	u32 *t19_keymap;
 	unsigned int t19_num_keys;
 
+	u32 *t15_keymap;
+	unsigned int t15_num_keys;
+
 	enum mxt_suspend_mode suspend_mode;
 
 	u32 wakeup_method;
@@ -375,6 +383,7 @@  static bool mxt_object_readable(unsigned int type)
 	case MXT_TOUCH_KEYARRAY_T15:
 	case MXT_TOUCH_PROXIMITY_T23:
 	case MXT_TOUCH_PROXKEY_T52:
+	case MXT_TOUCH_PTC_KEYS_T97:
 	case MXT_TOUCH_MULTITOUCHSCREEN_T100:
 	case MXT_PROCI_GRIPFACE_T20:
 	case MXT_PROCG_NOISE_T22:
@@ -891,6 +900,25 @@  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 *message)
+{
+	struct input_dev *input_dev = data->input_dev;
+	unsigned long keystates = get_unaligned_le32(&message[2]);
+	int key;
+
+	for (key = 0; key < data->t15_num_keys; key++) {
+		input_report_key(input_dev, data->t15_keymap[key],
+			!!(keystates & BIT(key)));
+	}
+
+	data->update_input = true;
+}
+
+static void mxt_proc_t97_messages(struct mxt_data *data, u8 *message)
+{
+	mxt_proc_t15_messages(data, message);
+}
+
 static void mxt_proc_t100_message(struct mxt_data *data, u8 *message)
 {
 	struct device *dev = &data->client->dev;
@@ -1017,6 +1045,12 @@  static int mxt_proc_message(struct mxt_data *data, u8 *message)
 	} else if (report_id >= data->T9_reportid_min &&
 		   report_id <= data->T9_reportid_max) {
 		mxt_proc_t9_message(data, message);
+	} else if (report_id >= data->T15_reportid_min &&
+		   report_id <= data->T15_reportid_max) {
+		mxt_proc_t15_messages(data, message);
+	} else if (report_id >= data->T97_reportid_min &&
+		   report_id <= data->T97_reportid_max) {
+		mxt_proc_t97_messages(data, message);
 	} else if (report_id >= data->T100_reportid_min &&
 		   report_id <= data->T100_reportid_max) {
 		mxt_proc_t100_message(data, message);
@@ -1689,9 +1723,13 @@  static void mxt_free_object_table(struct mxt_data *data)
 	data->T71_address = 0;
 	data->T9_reportid_min = 0;
 	data->T9_reportid_max = 0;
+	data->T15_reportid_min = 0;
+	data->T15_reportid_max = 0;
 	data->T18_address = 0;
 	data->T19_reportid = 0;
 	data->T44_address = 0;
+	data->T97_reportid_min = 0;
+	data->T97_reportid_max = 0;
 	data->T100_reportid_min = 0;
 	data->T100_reportid_max = 0;
 	data->max_reportid = 0;
@@ -1764,6 +1802,10 @@  static int mxt_parse_object_table(struct mxt_data *data,
 						object->num_report_ids - 1;
 			data->num_touchids = object->num_report_ids;
 			break;
+		case MXT_TOUCH_KEYARRAY_T15:
+			data->T15_reportid_min = min_id;
+			data->T15_reportid_max = max_id;
+			break;
 		case MXT_SPT_COMMSCONFIG_T18:
 			data->T18_address = object->start_address;
 			break;
@@ -1773,6 +1815,10 @@  static int mxt_parse_object_table(struct mxt_data *data,
 		case MXT_SPT_GPIOPWM_T19:
 			data->T19_reportid = min_id;
 			break;
+		case MXT_TOUCH_PTC_KEYS_T97:
+			data->T97_reportid_min = min_id;
+			data->T97_reportid_max = max_id;
+			break;
 		case MXT_TOUCH_MULTITOUCHSCREEN_T100:
 			data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100;
 			data->T100_reportid_min = min_id;
@@ -2050,6 +2096,7 @@  static int mxt_initialize_input_device(struct mxt_data *data)
 	int error;
 	unsigned int num_mt_slots;
 	unsigned int mt_flags = 0;
+	int i;
 
 	switch (data->multitouch) {
 	case MXT_TOUCH_MULTI_T9:
@@ -2095,6 +2142,10 @@  static int mxt_initialize_input_device(struct mxt_data *data)
 	input_dev->open = mxt_input_open;
 	input_dev->close = mxt_input_close;
 
+	input_dev->keycode = data->t15_keymap;
+	input_dev->keycodemax = data->t15_num_keys;
+	input_dev->keycodesize = sizeof(data->t15_keymap[0]);
+
 	input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
 
 	/* For single touch */
@@ -2162,6 +2213,12 @@  static int mxt_initialize_input_device(struct mxt_data *data)
 				     0, 255, 0, 0);
 	}
 
+	/* For T15 and T97 Key Array */
+	if (data->T15_reportid_min || data->T97_reportid_min) {
+		for (i = 0; i < data->t15_num_keys; i++)
+			input_set_capability(input_dev, EV_KEY, data->t15_keymap[i]);
+	}
+
 	input_set_drvdata(input_dev, data);
 
 	error = input_register_device(input_dev);
@@ -3080,8 +3137,10 @@  static void mxt_input_close(struct input_dev *dev)
 static int mxt_parse_device_properties(struct mxt_data *data)
 {
 	static const char keymap_property[] = "linux,gpio-keymap";
+	static const char buttons_property[] = "linux,keycodes";
 	struct device *dev = &data->client->dev;
 	u32 *keymap;
+	u32 *buttonmap;
 	int n_keys;
 	int error;
 
@@ -3111,6 +3170,32 @@  static int mxt_parse_device_properties(struct mxt_data *data)
 		data->t19_num_keys = n_keys;
 	}
 
+	if (device_property_present(dev, buttons_property)) {
+		n_keys = device_property_count_u32(dev, buttons_property);
+		if (n_keys <= 0) {
+			error = n_keys < 0 ? n_keys : -EINVAL;
+			dev_err(dev, "invalid/malformed '%s' property: %d\n",
+				buttons_property, error);
+			return error;
+		}
+
+		buttonmap = devm_kmalloc_array(dev, n_keys, sizeof(*buttonmap),
+					       GFP_KERNEL);
+		if (!buttonmap)
+			return -ENOMEM;
+
+		error = device_property_read_u32_array(dev, buttons_property,
+						       buttonmap, n_keys);
+		if (error) {
+			dev_err(dev, "failed to parse '%s' property: %d\n",
+				buttons_property, error);
+			return error;
+		}
+
+		data->t15_keymap = buttonmap;
+		data->t15_num_keys = n_keys;
+	}
+
 	return 0;
 }