From ea5a03d280ea957b533b4938afc628aa6e323a4a Mon Sep 17 00:00:00 2001 From: Vladimir Karpovich <vkarpovich@motorola.com> Date: Tue, 28 Oct 2014 23:21:06 -0500 Subject: [PATCH] misc: drv2605 : Add default calibration data config Restore calibration data from device tree if it is configured. Bug 18069509 Change-Id: Iad84adf4279e716c57da7a59232503e073a01602 Signed-off-by: Vladimir Karpovich <vkarpovich@motorola.com> --- .../devicetree/bindings/haptic/ti-drv2605.txt | 3 ++ drivers/misc/drv2605.c | 33 +++++++++++++++++++ include/linux/drv2605.h | 1 + 3 files changed, 37 insertions(+) diff --git a/Documentation/devicetree/bindings/haptic/ti-drv2605.txt b/Documentation/devicetree/bindings/haptic/ti-drv2605.txt index 358bf403de29..ad592b9a0694 100644 --- a/Documentation/devicetree/bindings/haptic/ti-drv2605.txt +++ b/Documentation/devicetree/bindings/haptic/ti-drv2605.txt @@ -22,10 +22,13 @@ Required properties: rated voltage for the motor - overdrive_voltage: overdrive voltage for the motor +Optional: - disable_calibration: disable boot-up calibration.The calibration data should be store in OTP memory on factory. If OTP memory is not programmed the driver will ignore this option. + - calibration-data: + Default calibration data. Example: i2c@1a200000 { diff --git a/drivers/misc/drv2605.c b/drivers/misc/drv2605.c index 98332263fa5f..1d620c6cecbe 100755 --- a/drivers/misc/drv2605.c +++ b/drivers/misc/drv2605.c @@ -178,6 +178,8 @@ static struct drv260x { unsigned char rated_voltage; unsigned char overdrive_voltage; struct regulator *vibrator_vdd; + int use_default_calibration; + unsigned char default_calibration[5]; } *drv260x; static struct vibrator { @@ -299,6 +301,8 @@ static struct drv260x_platform_data *drv260x_of_init(struct i2c_client *client) { struct drv260x_platform_data *pdata; struct device_node *np = client->dev.of_node; + const u32 *regs_arr; + int regs_len , i; pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); @@ -320,6 +324,21 @@ static struct drv260x_platform_data *drv260x_of_init(struct i2c_client *client) pdata->vibrator_vdd = devm_regulator_get(&client->dev, "vibrator_vdd"); pdata->static_vdd = devm_regulator_get(&client->dev, "static-vdd"); + regs_arr = of_get_property(np, "calibration-data", + ®s_len); + regs_len /= sizeof(u32); + + if (!regs_arr || (regs_len != 5)) { + pr_warn("drv2605: No default calibration data\n"); + regs_len = 0; + } else { + pdata->calibration_data = devm_kzalloc(&client->dev, + sizeof(unsigned char) * regs_len, + GFP_KERNEL); + for (i = 0; i < regs_len; i++) + pdata->calibration_data[i] = be32_to_cpu(regs_arr[i]); + } + return pdata; } #else @@ -743,6 +762,12 @@ static int drv260x_probe(struct i2c_client *client, if ((pdata->effects_library >= LIBRARY_A) && (pdata->effects_library <= LIBRARY_F)) g_effect_bank = pdata->effects_library; + if (pdata->calibration_data) { + drv260x->use_default_calibration = 1; + memcpy(&drv260x->default_calibration, + pdata->calibration_data, + sizeof(drv260x->default_calibration)); + } INIT_WORK(&vibdata.work_probe, probe_work); schedule_work(&vibdata.work_probe); @@ -851,6 +876,14 @@ static void probe_work(struct work_struct *work) /* Read calibration results */ drv260x_read_reg_val(reinit_sequence, sizeof(reinit_sequence)); + if (drv260x->use_default_calibration) { + reinit_sequence[3] = drv260x->default_calibration[0]; + reinit_sequence[5] = drv260x->default_calibration[1]; + reinit_sequence[7] = drv260x->default_calibration[2]; + reinit_sequence[9] = drv260x->default_calibration[3]; + reinit_sequence[11] = drv260x->default_calibration[4]; + } + /* Read device ID */ device_id = (status & DEV_ID_MASK); switch (device_id) { diff --git a/include/linux/drv2605.h b/include/linux/drv2605.h index 7ccf76b4c0cf..490f5da690fe 100755 --- a/include/linux/drv2605.h +++ b/include/linux/drv2605.h @@ -344,5 +344,6 @@ struct drv260x_platform_data { int disable_calibration; struct regulator *vibrator_vdd; struct regulator *static_vdd; + unsigned char *calibration_data; }; #endif /* __KERNEL__ */ -- GitLab