lkml.org 
[lkml]   [2020]   [Mar]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v10 20/55] Input: atmel_mxt_ts - handle cfg filename via pdata/sysfs
    Date
    From: Nick Dyer <nick.dyer@itdev.co.uk>

    There may be multiple maXTouch chips on a single device which will require
    different configuration files. Add a platform data value for the
    configuration filename.

    Add sysfs entry to write configuration file if the platform data is not
    set.

    Split out the object initialisation code from mxt_initialize() into
    mxt_configure_objects() to allow this.

    Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
    Acked-by: Yufeng Shen <miletus@chromium.org>
    (cherry picked from ndyer/linux/for-upstream commit 71a2a4d1954460b949a16b607f72bafab294ca79)
    [gdavis: Resolve forward port conflicts due to applying upstream
    commit 96a938aa214e ("Input: atmel_mxt_ts - remove platform
    data support").]
    Signed-off-by: George G. Davis <george_davis@mentor.com>
    [gdavis: Squash fix from Vladimir Zapolskiy:
    - Input: atmel_mxt_ts - fix error paths in mxt_configure_objects()]
    Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
    [jiada: Separate Documentation/ portion change to another commit
    Rename mxt_update_cfg_store to update_cfg_store
    Replace DEVICE_ATTR with DEVICE_ATTR_WO]
    Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
    ---
    drivers/input/touchscreen/atmel_mxt_ts.c | 109 +++++++++++++++++++----
    1 file changed, 94 insertions(+), 15 deletions(-)

    diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
    index 720574417219..d1865250f492 100644
    --- a/drivers/input/touchscreen/atmel_mxt_ts.c
    +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
    @@ -34,7 +34,6 @@
    #include <dt-bindings/input/atmel_mxt_ts.h>

    /* Configuration file */
    -#define MXT_CFG_NAME "maxtouch.cfg"
    #define MXT_CFG_MAGIC "OBP_RAW V1"

    /* Registers */
    @@ -335,6 +334,8 @@ struct mxt_data {
    struct regulator *reg_vdd;
    struct regulator *reg_avdd;
    char *fw_name;
    + char *cfg_name;
    + const char *pcfg_name;

    /* Cached parameters from object table */
    u16 T5_address;
    @@ -377,6 +378,9 @@ struct mxt_data {

    /* Indicates whether device is in suspend */
    bool suspended;
    +
    + /* Indicates whether device is updating configuration */
    + bool updating_config;
    };

    struct mxt_vb2_buffer {
    @@ -833,9 +837,11 @@ static void mxt_input_button(struct mxt_data *data, u8 *message)

    static void mxt_input_sync(struct mxt_data *data)
    {
    - input_mt_report_pointer_emulation(data->input_dev,
    - data->t19_num_keys);
    - input_sync(data->input_dev);
    + if (data->input_dev) {
    + input_mt_report_pointer_emulation(data->input_dev,
    + data->t19_num_keys);
    + input_sync(data->input_dev);
    + }
    }

    static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
    @@ -2578,13 +2584,21 @@ static int mxt_initialize(struct mxt_data *data)
    if (error)
    return error;

    - error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME,
    - &client->dev, GFP_KERNEL, data,
    - mxt_config_cb);
    - if (error) {
    - dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
    - error);
    - goto err_free_sysfs;
    + if (data->cfg_name) {
    + error = request_firmware_nowait(THIS_MODULE, true,
    + data->cfg_name,
    + &client->dev,
    + GFP_KERNEL, data,
    + mxt_config_cb);
    + if (error) {
    + dev_err(&client->dev, "Failed to invoke firmware loader: %d\n",
    + error);
    + goto err_free_sysfs;
    + }
    + } else {
    + error = mxt_configure_objects(data, NULL);
    + if (error)
    + goto err_free_sysfs;
    }

    return 0;
    @@ -3081,19 +3095,21 @@ static int mxt_configure_objects(struct mxt_data *data,
    error = mxt_init_t7_power_cfg(data);
    if (error) {
    dev_err(dev, "Failed to initialize power cfg\n");
    - return error;
    + goto err_free_object_table;
    }

    if (cfg) {
    error = mxt_update_cfg(data, cfg);
    - if (error)
    + if (error) {
    dev_warn(dev, "Error %d updating config\n", error);
    + goto err_free_object_table;
    + }
    }

    if (data->multitouch) {
    error = mxt_initialize_input_device(data);
    if (error)
    - return error;
    + goto err_free_object_table;
    } else {
    dev_warn(dev, "No touch object detected\n");
    }
    @@ -3101,6 +3117,10 @@ static int mxt_configure_objects(struct mxt_data *data,
    mxt_debug_init(data);

    return 0;
    +
    +err_free_object_table:
    + mxt_free_object_table(data);
    + return error;
    }

    /* Firmware Version is returned as Major.Minor.Build */
    @@ -3392,6 +3412,55 @@ static ssize_t update_fw_store(struct device *dev,
    return count;
    }

    +static ssize_t update_cfg_store(struct device *dev,
    + struct device_attribute *attr,
    + const char *buf, size_t count)
    +{
    + struct mxt_data *data = dev_get_drvdata(dev);
    + const struct firmware *cfg;
    + int ret;
    +
    + ret = mxt_update_file_name(dev, &data->cfg_name, buf, count);
    + if (ret)
    + return ret;
    +
    + ret = request_firmware(&cfg, data->cfg_name, dev);
    + if (ret < 0) {
    + dev_err(dev, "Failure to request config file %s\n",
    + data->cfg_name);
    + ret = -ENOENT;
    + goto out;
    + }
    +
    + data->updating_config = true;
    +
    + mxt_free_input_device(data);
    +
    + if (data->suspended) {
    + if (data->suspend_mode == MXT_SUSPEND_REGULATOR) {
    + enable_irq(data->irq);
    + mxt_regulator_enable(data);
    + } else if (data->suspend_mode == MXT_SUSPEND_DEEP_SLEEP) {
    + mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
    + mxt_acquire_irq(data);
    + }
    +
    + data->suspended = false;
    + }
    +
    + ret = mxt_configure_objects(data, cfg);
    + if (ret)
    + goto release;
    +
    + ret = count;
    +
    +release:
    + release_firmware(cfg);
    +out:
    + data->updating_config = false;
    + return ret;
    +}
    +
    static DEVICE_ATTR_WO(update_fw);

    static struct attribute *mxt_fw_attrs[] = {
    @@ -3406,11 +3475,13 @@ static const struct attribute_group mxt_fw_attr_group = {
    static DEVICE_ATTR_RO(fw_version);
    static DEVICE_ATTR_RO(hw_version);
    static DEVICE_ATTR(object, S_IRUGO, mxt_object_show, NULL);
    +static DEVICE_ATTR_WO(update_cfg);

    static struct attribute *mxt_attrs[] = {
    &dev_attr_fw_version.attr,
    &dev_attr_hw_version.attr,
    &dev_attr_object.attr,
    + &dev_attr_update_cfg.attr,
    NULL
    };

    @@ -3511,7 +3582,7 @@ static int mxt_stop(struct mxt_data *data)
    {
    int ret;

    - if (data->suspended || data->in_bootloader)
    + if (data->suspended || data->in_bootloader || data->updating_config)
    return 0;

    switch (data->suspend_mode) {
    @@ -3580,6 +3651,8 @@ static int mxt_parse_device_properties(struct mxt_data *data)
    int n_keys;
    int error;

    + device_property_read_string(dev, "atmel,cfg_name", &data->pcfg_name);
    +
    if (device_property_present(dev, keymap_property)) {
    n_keys = device_property_count_u32(dev, keymap_property);
    if (n_keys <= 0) {
    @@ -3705,6 +3778,12 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
    if (error)
    return error;

    + if (data->pcfg_name)
    + mxt_update_file_name(&data->client->dev,
    + &data->cfg_name,
    + data->pcfg_name,
    + strlen(data->pcfg_name));
    +
    data->reset_gpio = devm_gpiod_get_optional(&client->dev,
    "reset", GPIOD_OUT_LOW);
    if (IS_ERR(data->reset_gpio)) {
    --
    2.17.1
    \
     
     \ /
      Last update: 2020-03-31 12:52    [W:8.706 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site