diff --git a/drivers/misc/cs40l2x.c b/drivers/misc/cs40l2x.c index ab738f6d2635..73070b89b686 100644 --- a/drivers/misc/cs40l2x.c +++ b/drivers/misc/cs40l2x.c @@ -1887,6 +1887,58 @@ static void cs40l2x_dsp_start(struct cs40l2x_private *cs40l2x) } } + if (cs40l2x->pdata.gpio1_rise_index > 0 + && cs40l2x->pdata.gpio1_rise_index + < cs40l2x->num_waves) { + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "INDEXBUTTONPRESS", + CS40L2X_XM_UNPACKED_TYPE), + cs40l2x->pdata.gpio1_rise_index); + if (ret) { + dev_err(dev, + "Failed to write default gpio1_rise_index\n"); + return; + } + } else if (cs40l2x->pdata.gpio1_rise_index >= cs40l2x->num_waves) { + dev_warn(dev, "Ignored default gpio1_rise_index\n"); + } + + if (cs40l2x->pdata.gpio1_fall_index > 0 + && cs40l2x->pdata.gpio1_fall_index + < cs40l2x->num_waves) { + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "INDEXBUTTONRELEASE", + CS40L2X_XM_UNPACKED_TYPE), + cs40l2x->pdata.gpio1_fall_index); + if (ret) { + dev_err(dev, + "Failed to write default gpio1_fall_index\n"); + return; + } + } else if (cs40l2x->pdata.gpio1_fall_index >= cs40l2x->num_waves) { + dev_warn(dev, "Ignored default gpio1_fall_index\n"); + } + + if (cs40l2x->pdata.gpio1_fall_timeout > 0 + && (cs40l2x->pdata.gpio1_fall_timeout + & CS40L2X_PDATA_MASK) + <= CS40L2X_PR_TIMEOUT_MAX) { + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, + "PRESS_RELEASE_TIMEOUT", + CS40L2X_XM_UNPACKED_TYPE), + cs40l2x->pdata.gpio1_fall_timeout + & CS40L2X_PDATA_MASK); + if (ret) { + dev_err(dev, + "Failed to write default gpio1_fall_timeout\n"); + return; + } + } else if ((cs40l2x->pdata.gpio1_fall_timeout + & CS40L2X_PDATA_MASK) > CS40L2X_PR_TIMEOUT_MAX) { + dev_warn(dev, "Ignored default gpio1_fall_timeout\n"); + } + dev_info(dev, "Normal-mode haptics successfully started\n"); cs40l2x_vibe_init(cs40l2x); @@ -2604,6 +2656,18 @@ static int cs40l2x_handle_of_data(struct i2c_client *i2c_client, if (!ret) pdata->redc_max = out_val; + ret = of_property_read_u32(np, "cirrus,gpio1-rise-index", &out_val); + if (!ret) + pdata->gpio1_rise_index = out_val; + + ret = of_property_read_u32(np, "cirrus,gpio1-fall-index", &out_val); + if (!ret) + pdata->gpio1_fall_index = out_val; + + ret = of_property_read_u32(np, "cirrus,gpio1-fall-timeout", &out_val); + if (!ret) + pdata->gpio1_fall_timeout = out_val | CS40L2X_PDATA_PRESENT; + return 0; } diff --git a/drivers/misc/cs40l2x.h b/drivers/misc/cs40l2x.h index 8dc895ec2bd1..fd5791c376c0 100644 --- a/drivers/misc/cs40l2x.h +++ b/drivers/misc/cs40l2x.h @@ -743,6 +743,9 @@ #define CS40L2X_WT_NAME "cs40l20.bin" +#define CS40L2X_PDATA_PRESENT 0x80000000 +#define CS40L2X_PDATA_MASK ~CS40L2X_PDATA_PRESENT + bool cs40l2x_readable_reg(struct device *dev, unsigned int reg); bool cs40l2x_precious_reg(struct device *dev, unsigned int reg); diff --git a/include/linux/platform_data/cs40l2x.h b/include/linux/platform_data/cs40l2x.h index b2cafa28dead..7d2c02c12287 100644 --- a/include/linux/platform_data/cs40l2x.h +++ b/include/linux/platform_data/cs40l2x.h @@ -23,6 +23,9 @@ struct cs40l2x_platform_data { unsigned int redc_default; unsigned int redc_min; unsigned int redc_max; + unsigned int gpio1_rise_index; + unsigned int gpio1_fall_index; + unsigned int gpio1_fall_timeout; }; #endif /* __CS40L2X_H */