From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Thu, 19 Dec 2024 01:47:39 +0000 Subject: [PATCH] add wifi6 8852be driver --- kernel/drivers/input/touchscreen/atmel_mxt_ts.c | 105 +++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 75 insertions(+), 30 deletions(-) diff --git a/kernel/drivers/input/touchscreen/atmel_mxt_ts.c b/kernel/drivers/input/touchscreen/atmel_mxt_ts.c index a2e10ca..3c152e9 100644 --- a/kernel/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/kernel/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Atmel maXTouch Touchscreen driver * @@ -7,12 +8,6 @@ * Copyright (C) 2016 Zodiac Inflight Innovations * * Author: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * */ #include <linux/acpi.h> @@ -25,11 +20,11 @@ #include <linux/i2c.h> #include <linux/input/mt.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/of.h> #include <linux/property.h> #include <linux/slab.h> #include <linux/gpio/consumer.h> -#include <linux/property.h> #include <asm/unaligned.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> @@ -135,6 +130,7 @@ /* MXT_SPT_COMMSCONFIG_T18 */ #define MXT_COMMS_CTRL 0 #define MXT_COMMS_CMD 1 +#define MXT_COMMS_RETRIGEN BIT(6) /* MXT_DEBUG_DIAGNOSTIC_T37 */ #define MXT_DIAGNOSTIC_PAGEUP 0x01 @@ -262,16 +258,6 @@ MXT_V4L_INPUT_MAX, }; -static const struct v4l2_file_operations mxt_video_fops = { - .owner = THIS_MODULE, - .open = v4l2_fh_open, - .release = vb2_fop_release, - .unlocked_ioctl = video_ioctl2, - .read = vb2_fop_read, - .mmap = vb2_fop_mmap, - .poll = vb2_fop_poll, -}; - enum mxt_suspend_mode { MXT_SUSPEND_DEEP_SLEEP = 0, MXT_SUSPEND_T9_CTRL = 1, @@ -324,6 +310,7 @@ struct t7_config t7_cfg; struct mxt_dbg dbg; struct gpio_desc *reset_gpio; + bool use_retrigen_workaround; /* Cached parameters from object table */ u16 T5_address; @@ -334,6 +321,7 @@ u16 T71_address; u8 T9_reportid_min; u8 T9_reportid_max; + u16 T18_address; u8 T19_reportid; u16 T44_address; u8 T100_reportid_min; @@ -489,7 +477,7 @@ bootloader = appmode - 0x24; break; } - /* Fall through for normal case */ + fallthrough; /* for normal case */ case 0x4c: case 0x4d: case 0x5a: @@ -838,8 +826,7 @@ * have happened. */ if (status & MXT_T9_RELEASE) { - input_mt_report_slot_state(input_dev, - MT_TOOL_FINGER, 0); + input_mt_report_slot_inactive(input_dev); mxt_input_sync(data); } @@ -855,7 +842,7 @@ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area); } else { /* Touch no longer active, close out slot */ - input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); + input_mt_report_slot_inactive(input_dev); } data->update_input = true; @@ -963,7 +950,7 @@ dev_dbg(dev, "[%u] release\n", id); /* close out slot */ - input_mt_report_slot_state(input_dev, 0, 0); + input_mt_report_slot_inactive(input_dev); } data->update_input = true; @@ -1207,9 +1194,11 @@ enable_irq(data->irq); - error = mxt_process_messages_until_invalid(data); - if (error) - return error; + if (data->use_retrigen_workaround) { + error = mxt_process_messages_until_invalid(data); + if (error) + return error; + } return 0; } @@ -1297,6 +1286,38 @@ crc &= 0x00FFFFFF; return crc; +} + +static int mxt_check_retrigen(struct mxt_data *data) +{ + struct i2c_client *client = data->client; + int error; + int val; + struct irq_data *irqd; + + data->use_retrigen_workaround = false; + + irqd = irq_get_irq_data(data->irq); + if (!irqd) + return -EINVAL; + + if (irqd_is_level_type(irqd)) + return 0; + + if (data->T18_address) { + error = __mxt_read_reg(client, + data->T18_address + MXT_COMMS_CTRL, + 1, &val); + if (error) + return error; + + if (val & MXT_COMMS_RETRIGEN) + return 0; + } + + dev_warn(&client->dev, "Enabling RETRIGEN workaround\n"); + data->use_retrigen_workaround = true; + return 0; } static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg) @@ -1527,7 +1548,8 @@ } else if (config_crc == data->config_crc) { dev_dbg(dev, "Config CRC 0x%06X: OK\n", data->config_crc); - return 0; + ret = 0; + goto release_raw; } else { dev_info(dev, "Config CRC 0x%06X: does not match file 0x%06X\n", data->config_crc, config_crc); @@ -1577,6 +1599,10 @@ mxt_update_crc(data, MXT_COMMAND_BACKUPNV, MXT_BACKUP_VALUE); + ret = mxt_check_retrigen(data); + if (ret) + goto release_mem; + ret = mxt_soft_reset(data); if (ret) goto release_mem; @@ -1620,6 +1646,7 @@ data->T71_address = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; + data->T18_address = 0; data->T19_reportid = 0; data->T44_address = 0; data->T100_reportid_min = 0; @@ -1693,6 +1720,9 @@ data->T9_reportid_max = min_id + object->num_report_ids - 1; data->num_touchids = object->num_report_ids; + break; + case MXT_SPT_COMMSCONFIG_T18: + data->T18_address = object->start_address; break; case MXT_SPT_MESSAGECOUNT_T44: data->T44_address = object->start_address; @@ -2153,6 +2183,10 @@ msleep(MXT_FW_RESET_TIME); } + error = mxt_check_retrigen(data); + if (error) + return error; + error = mxt_acquire_irq(data); if (error) return error; @@ -2224,6 +2258,16 @@ } #ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 +static const struct v4l2_file_operations mxt_video_fops = { + .owner = THIS_MODULE, + .open = v4l2_fh_open, + .release = vb2_fop_release, + .unlocked_ioctl = video_ioctl2, + .read = vb2_fop_read, + .mmap = vb2_fop_mmap, + .poll = vb2_fop_poll, +}; + static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, unsigned int y) { @@ -2995,8 +3039,7 @@ int error; if (device_property_present(dev, keymap_property)) { - n_keys = device_property_read_u32_array(dev, keymap_property, - NULL, 0); + n_keys = device_property_count_u32(dev, keymap_property); if (n_keys <= 0) { error = n_keys < 0 ? n_keys : -EINVAL; dev_err(dev, "invalid/malformed '%s' property: %d\n", @@ -3091,8 +3134,9 @@ if (error) return error; + /* Request the RESET line as asserted so we go into reset */ data->reset_gpio = devm_gpiod_get_optional(&client->dev, - "reset", GPIOD_OUT_LOW); + "reset", GPIOD_OUT_HIGH); if (IS_ERR(data->reset_gpio)) { error = PTR_ERR(data->reset_gpio); dev_err(&client->dev, "Failed to get reset gpio: %d\n", error); @@ -3110,8 +3154,9 @@ disable_irq(client->irq); if (data->reset_gpio) { + /* Wait a while and then de-assert the RESET GPIO line */ msleep(MXT_RESET_GPIO_TIME); - gpiod_set_value(data->reset_gpio, 1); + gpiod_set_value(data->reset_gpio, 0); msleep(MXT_RESET_INVALID_CHG); } -- Gitblit v1.6.2