diff --git a/drivers/misc/cs40l2x.c b/drivers/misc/cs40l2x.c index 036d32bf28fe..824332238447 100644 --- a/drivers/misc/cs40l2x.c +++ b/drivers/misc/cs40l2x.c @@ -636,6 +636,12 @@ static ssize_t cs40l2x_f0_stored_store(struct device *dev, if (ret) return -EINVAL; + if (cs40l2x->pdata.f0_min > 0 && val < cs40l2x->pdata.f0_min) + return -EINVAL; + + if (cs40l2x->pdata.f0_max > 0 && val > cs40l2x->pdata.f0_max) + return -EINVAL; + mutex_lock(&cs40l2x->lock); ret = regmap_write(cs40l2x->regmap, cs40l2x_dsp_reg(cs40l2x, "F0_STORED", @@ -703,6 +709,12 @@ static ssize_t cs40l2x_redc_stored_store(struct device *dev, if (ret) return -EINVAL; + if (cs40l2x->pdata.redc_min > 0 && val < cs40l2x->pdata.redc_min) + return -EINVAL; + + if (cs40l2x->pdata.redc_max > 0 && val > cs40l2x->pdata.redc_max) + return -EINVAL; + mutex_lock(&cs40l2x->lock); ret = regmap_write(cs40l2x->regmap, cs40l2x_dsp_reg(cs40l2x, "REDC_STORED", @@ -1688,6 +1700,28 @@ static void cs40l2x_dsp_start(struct cs40l2x_private *cs40l2x) return; } + if (cs40l2x->pdata.f0_default) { + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "F0_STORED", + CS40L2X_XM_UNPACKED_TYPE), + cs40l2x->pdata.f0_default); + if (ret) { + dev_err(dev, "Failed to write default f0\n"); + return; + } + } + + if (cs40l2x->pdata.redc_default) { + ret = regmap_write(regmap, + cs40l2x_dsp_reg(cs40l2x, "REDC_STORED", + CS40L2X_XM_UNPACKED_TYPE), + cs40l2x->pdata.redc_default); + if (ret) { + dev_err(dev, "Failed to write default ReDC\n"); + return; + } + } + dev_info(dev, "Normal-mode haptics successfully started\n"); cs40l2x_vibe_init(cs40l2x); @@ -2370,6 +2404,30 @@ static int cs40l2x_handle_of_data(struct i2c_client *i2c_client, pdata->refclk_gpio2 = of_property_read_bool(np, "cirrus,refclk-gpio2"); + ret = of_property_read_u32(np, "cirrus,f0-default", &out_val); + if (!ret) + pdata->f0_default = out_val; + + ret = of_property_read_u32(np, "cirrus,f0-min", &out_val); + if (!ret) + pdata->f0_min = out_val; + + ret = of_property_read_u32(np, "cirrus,f0-max", &out_val); + if (!ret) + pdata->f0_max = out_val; + + ret = of_property_read_u32(np, "cirrus,redc-default", &out_val); + if (!ret) + pdata->redc_default = out_val; + + ret = of_property_read_u32(np, "cirrus,redc-min", &out_val); + if (!ret) + pdata->redc_min = out_val; + + ret = of_property_read_u32(np, "cirrus,redc-max", &out_val); + if (!ret) + pdata->redc_max = out_val; + return 0; } diff --git a/include/linux/platform_data/cs40l2x.h b/include/linux/platform_data/cs40l2x.h index 5e75813bda57..b2cafa28dead 100644 --- a/include/linux/platform_data/cs40l2x.h +++ b/include/linux/platform_data/cs40l2x.h @@ -17,6 +17,12 @@ struct cs40l2x_platform_data { unsigned int boost_cap; unsigned int boost_ipk; bool refclk_gpio2; + unsigned int f0_default; + unsigned int f0_min; + unsigned int f0_max; + unsigned int redc_default; + unsigned int redc_min; + unsigned int redc_max; }; #endif /* __CS40L2X_H */