da7280: haptic driver submission
Subsystems (5)
v9 cover da7280: haptic driver submission
This patch adds support for the Dialog DA7280 Haptic driver IC.
In this patch set the following is provided:
[PATCH V9 1/3] MAINTAINERS file update for DA7280
[PATCH V9 2/3] DA7280 DT Binding
[PATCH V9 3/3] DA7280 Driver
This patch applies against linux-next and v5.5
Thank you,
Roy Im, Dialog Semiconductor Ltd.
Roy Im (3):
MAINTAINERS: da7280 updates to the Dialog Semiconductor search terms
dt-bindings: input: Add document bindings for DA7280
Input: new da7280 haptic driver
.../devicetree/bindings/input/dlg,da7280.txt | 109 ++ MAINTAINERS | 2 + drivers/input/misc/Kconfig | 13 + drivers/input/misc/Makefile | 1 + drivers/input/misc/da7280.c | 1880 ++++++++++++++++++++ 5 files changed, 2005 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/dlg,da7280.txt create mode 100644 drivers/input/misc/da7280.c
Signature · 1 line
end-of-patch for PATCH V9
PATCH v9 1/3 MAINTAINERS: da7280 updates to the Dialog Semiconductor search terms
This patch adds the da7280 bindings doc and driver to the Dialog Semiconductor support list.
---
v9: No changes.
v8: No changes.
v7: No changes.
v6: No changes.
v5: No changes.
v4: No changes.
v3: No changes.
v2: No changes.
MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+)
MAINTAINERS +2 -0
@@ -4856,6 +4856,7 @@ S: Supported F: Documentation/hwmon/da90??.rst F: Documentation/devicetree/bindings/mfd/da90*.txt F: Documentation/devicetree/bindings/input/da90??-onkey.txt +F: Documentation/devicetree/bindings/input/dlg,da72??.txt F: Documentation/devicetree/bindings/thermal/da90??-thermal.txt F: Documentation/devicetree/bindings/regulator/da92*.txt F: Documentation/devicetree/bindings/regulator/slg51000.txt
@@ -4865,6 +4866,7 @@ F: drivers/gpio/gpio-da90??.c F: drivers/hwmon/da90??-hwmon.c F: drivers/iio/adc/da91??-*.c F: drivers/input/misc/da90??_onkey.c +F: drivers/input/misc/da72??.[ch] F: drivers/input/touchscreen/da9052_tsi.c F: drivers/leds/leds-da90??.c F: drivers/mfd/da903x.c
Signature · 1 line
end-of-patch for PATCH V9
PATCH v9 2/3 dt-bindings: input: Add document bindings for DA7280
In reply to Roy ImAdd device tree binding information for DA7280 haptic driver. Example bindings for DA7280 are added.
---
v9: No changes.
v8: Updated descriptions for new properties.
v7: No changes.
v6: No changes.
v5: Updated descriptions and fixed errors.
v4: Fixed commit message, properties.
v3: Fixed subject format.
v2: No changes
.../devicetree/bindings/input/dlg,da7280.txt | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/dlg,da7280.txt
Documentation/devicetree/bindings/input/dlg,da7280.txt new file +109 -0
@@ -0,0 +1,109 @@ +Dialog Semiconductor DA7280 Haptics bindings + +Required properties: +- compatible: Should be "dlg,da7280". +- reg: Specifies the I2C slave address. + +- interrupt-parent : Specifies the phandle of the interrupt controller to + which the IRQs from DA7280 are delivered to. + +- dlg,actuator-type: Set Actuator type. it should be one of: + "LRA" - Linear Resonance Actuator type. + "ERM-bar" - Bar type Eccentric Rotating Mass. + "ERM-coin" - Coin type Eccentric Rotating Mass. + +- dlg,const-op-mode: Haptic operation mode for FF_CONSTANT. + Possible values: + 1 - Direct register override(DRO) mode triggered by i2c(default), + 2 - PWM data source mode controlled by PWM duty, +- dlg,periodic-op-mode: Haptic operation mode for FF_PERIODIC. + Possible values: + 1 - Register triggered waveform memory(RTWM) mode, the pattern + assigned to the PS_SEQ_ID played as much times as PS_SEQ_LOOP, + 2 - Edge triggered waveform memory(ETWM) mode, external GPI(N) + control are required to enable/disable and it needs to keep + device enabled by sending magnitude (X > 0), + the pattern is assigned to the GPI(N)_SEQUENCE_ID below. + The default value is 1 for both of the operation modes. + For more details, please see the datasheet. + +- dlg,nom-microvolt: Nominal actuator voltage rating. + Valid values: 0 - 6000000. +- dlg,abs-max-microvolt: Absolute actuator maximum voltage rating. + Valid values: 0 - 6000000. +- dlg,imax-microamp: Actuator max current rating. + Valid values: 0 - 252000. + Default: 130000. +- dlg,impd-micro-ohms: the impedance of the actuator in micro ohms. + Valid values: 0 - 1500000000. + +Optional properties: +- pwms : phandle to the physical PWM(Pulse Width Modulation) device. + PWM properties should be named "pwms". And number of cell is different + for each pwm device. + (See Documentation/devicetree/bindings/pwm/pwm.txt + for further information relating to pwm properties) + +- dlg,ps-seq-id: the PS_SEQ_ID(pattern ID in waveform memory inside chip) + to play back when RTWM-MODE is enabled. + Valid range: 0 - 15. +- dlg,ps-seq-loop: the PS_SEQ_LOOP, Number of times the pre-stored sequence + pointed to by PS_SEQ_ID or GPI(N)_SEQUENCE_ID is repeated. + Valid range: 0 - 15. +- dlg,gpiN-seq-id: the GPI(N)_SEQUENCE_ID, pattern to play + when gpi0 is triggered, 'N' must be 0 - 2. + Valid range: 0 - 15. +- dlg,gpiN-mode: the pattern mode which can select either + "Single-pattern" or "Multi-pattern", 'N' must be 0 - 2. +- dlg,gpiN-polarity: gpiN polarity which can be chosen among + "Rising-edge", "Falling-edge" and "Both-edge", + 'N' must be 0 - 2 + Haptic will work by this edge option in case of ETWM mode. + +- dlg,resonant-freq-hz: use in case of LRA. + the frequency range: 50 - 300. + Default: 205. + +- dlg,bemf-sens-enable: Enable for internal loop computations. +- dlg,freq-track-enable: Enable for resonant frequency tracking. +- dlg,acc-enable: Enable for active acceleration. +- dlg,rapid-stop-enable: Enable for rapid stop. +- dlg,amp-pid-enable: Enable for the amplitude PID. +- dlg,mem-array: Customized waveform memory(patterns) data downloaded to + the device during initialization. This is an array of 100 values(u8). + +For further information, see device datasheet. + +====== + +Example: + + haptics: da7280-haptics@4a { + compatible = "dlg,da7280"; + reg = <0x4a>; + interrupt-parent = <&gpio6>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + dlg,actuator-type = "LRA"; + dlg,dlg,const-op-mode = <1>; + dlg,dlg,periodic-op-mode = <1>; + dlg,nom-microvolt = <2000000>; + dlg,abs-max-microvolt = <2000000>; + dlg,imax-microamp = <170000>; + dlg,resonant-freq-hz = <180>; + dlg,impd-micro-ohms = <10500000>; + dlg,freq-track-enable; + dlg,rapid-stop-enable; + dlg,mem-array = < + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + >; + + };
Signature · 1 line
end-of-patch for PATCH V9
PATCH v9 3/3 Input: new da7280 haptic driver
In reply to Roy ImAdds support for the Dialog DA7280 LRA/ERM Haptic Driver with multiple mode and integrated waveform memory and wideband support. It communicates via an I2C bus to the device.
---
v9:
- Removed the header file and put the definitions into the c file.
- Updated the pwm code and error logs with %pE
v8:
- Added changes to support FF_PERIODIC/FF_CUSTOM and FF_CONSTANT.
- Updated the dt-related code.
- Removed memless related functions.
v7:
- Added more attributes to handle one value per file.
- Replaced and updated the dt-related code and functions called.
- Fixed error/functions.
- Rebased to v4.19-rc6.
v6: No changes.
v5: Fixed errors in Kconfig file.
v4: Updated code as dt-bindings are changed.
v3: No changes.
v2: Fixed kbuild error/warning
drivers/input/misc/Kconfig | 13 + drivers/input/misc/Makefile | 1 + drivers/input/misc/da7280.c | 1880 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1894 insertions(+) create mode 100644 drivers/input/misc/da7280.c
drivers/input/misc/Kconfig +13 -0
@@ -879,4 +879,17 @@ config INPUT_STPMIC1_ONKEY To compile this driver as a module, choose M here: the module will be called stpmic1_onkey. +config INPUT_DA7280_HAPTICS + tristate "Dialog Semiconductor DA7280 haptics support" + depends on INPUT && I2C + select INPUT_FF_MEMLESS + select REGMAP_I2C + help + Say Y to enable support for the Dialog DA7280 haptics driver. + The haptics can be controlled by i2c communication, + or by PWM input, or by GPI. + + To compile this driver as a module, choose M here: the + module will be called da7280. + endif
drivers/input/misc/Makefile +1 -0
@@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_CPCAP_PWRBUTTON) += cpcap-pwrbutton.o +obj-$(CONFIG_INPUT_DA7280_HAPTICS) += da7280.o obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o obj-$(CONFIG_INPUT_DA9063_ONKEY) += da9063_onkey.o
drivers/input/misc/da7280.c new file +1880 -0
1,880 lines not on this page · raw message
Signature · 1 line
end-of-patch for PATCH V9
Re: [PATCH V9 3/3] Input: new da7280 haptic driver
Hello,
Quoted 333 lines · Roy Im
Adds support for the Dialog DA7280 LRA/ERM Haptic Driver with multiple mode and integrated waveform memory and wideband support. It communicates via an I2C bus to the device.
Signed-off-by Roy Im <[email protected]>---
v9:
- Removed the header file and put the definitions into the c file.
- Updated the pwm code and error logs with %pE
v8:
- Added changes to support FF_PERIODIC/FF_CUSTOM andFF_CONSTANT.
- Updated the dt-related code.
- Removed memless related functions.
v7:
- Added more attributes to handle one value per file.
- Replaced and updated the dt-related code and functions called.
- Fixed error/functions.
- Rebased to v4.19-rc6.
v6: No changes.
v5: Fixed errors inKconfigfile.
v4: Updated code as dt-bindings are changed.
v3: No changes.
v2: Fixed kbuild error/warningdrivers/input/misc/Kconfig | 13 + drivers/input/misc/Makefile | 1 + drivers/input/misc/da7280.c | 1880 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1894 insertions(+) create mode 100644 drivers/input/misc/da7280.cdrivers/input/misc/Kconfig +13
-0@@ -879,4 +879,17 @@ config INPUT_STPMIC1_ONKEY To compile this driver as a module, choose M here: the module will be called stpmic1_onkey. +config INPUT_DA7280_HAPTICS + tristate "Dialog Semiconductor DA7280 haptics support" + depends on INPUT && I2C + select INPUT_FF_MEMLESS + select REGMAP_I2C + help + Say Y to enable support for the Dialog DA7280 haptics driver. + The haptics can be controlled by i2c communication, + or by PWM input, or by GPI. + + To compile this driver as a module, choose M here: the + module will be called da7280. + endifdrivers/input/misc/Makefile +1
-0@@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_CMA3000) += cma3000_d0x.o obj-$(CONFIG_INPUT_CMA3000_I2C) += cma3000_d0x_i2c.o obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_CPCAP_PWRBUTTON) += cpcap-pwrbutton.o +obj-$(CONFIG_INPUT_DA7280_HAPTICS) += da7280.o obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o obj-$(CONFIG_INPUT_DA9063_ONKEY) += da9063_onkey.odrivers/input/misc/da7280.c new file +261
-0@@ -0,0 +1,1880 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* +* DA7280 Haptic device driver +* +* Copyright (c) 2020 Dialog Semiconductor. +* Author: Roy Im <[email protected]> +*/ + +#include <linux/err.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/pwm.h> +#include <linux/regmap.h> +#include <linux/workqueue.h> +#include <linux/uaccess.h> +#include <linux/bitops.h> + +/* Registers */ +#define DA7280_IRQ_EVENT1 0x03 +#define DA7280_IRQ_EVENT_WARNING_DIAG 0x04 +#define DA7280_IRQ_EVENT_SEQ_DIAG 0x05 +#define DA7280_IRQ_STATUS1 0x06 +#define DA7280_IRQ_MASK1 0x07 +#define DA7280_FRQ_LRA_PER_H 0x0A +#define DA7280_FRQ_LRA_PER_L 0x0B +#define DA7280_ACTUATOR1 0x0C +#define DA7280_ACTUATOR2 0x0D +#define DA7280_ACTUATOR3 0x0E +#define DA7280_CALIB_V2I_H 0x0F +#define DA7280_CALIB_V2I_L 0x10 +#define DA7280_TOP_CFG1 0x13 +#define DA7280_TOP_CFG2 0x14 +#define DA7280_TOP_CFG4 0x16 +#define DA7280_TOP_INT_CFG1 0x17 +#define DA7280_TOP_CTL1 0x22 +#define DA7280_TOP_CTL2 0x23 +#define DA7280_SEQ_CTL2 0x28 +#define DA7280_GPI_0_CTL 0x29 +#define DA7280_GPI_1_CTL 0x2A +#define DA7280_GPI_2_CTL 0x2B +#define DA7280_MEM_CTL1 0x2C +#define DA7280_MEM_CTL2 0x2D +#define DA7280_TOP_CFG5 0x6E +#define DA7280_IRQ_MASK2 0x83 +#define DA7280_SNP_MEM_99 0xE7 + +/* Register field */ + +/* DA7280_IRQ_EVENT1 (Address 0x03) */ +#define DA7280_E_SEQ_CONTINUE_SHIFT 0 +#define DA7280_E_SEQ_CONTINUE_MASK BIT(0) +#define DA7280_E_UVLO_SHIFT 1 +#define DA7280_E_UVLO_MASK BIT(1) +#define DA7280_E_SEQ_DONE_SHIFT 2 +#define DA7280_E_SEQ_DONE_MASK BIT(2) +#define DA7280_E_OVERTEMP_CRIT_SHIFT 3 +#define DA7280_E_OVERTEMP_CRIT_MASK BIT(3) +#define DA7280_E_SEQ_FAULT_SHIFT 4 +#define DA7280_E_SEQ_FAULT_MASK BIT(4) +#define DA7280_E_WARNING_SHIFT 5 +#define DA7280_E_WARNING_MASK BIT(5) +#define DA7280_E_ACTUATOR_FAULT_SHIFT 6 +#define DA7280_E_ACTUATOR_FAULT_MASK BIT(6) +#define DA7280_E_OC_FAULT_SHIFT 7 +#define DA7280_E_OC_FAULT_MASK BIT(7) + +/* DA7280_IRQ_EVENT_WARNING_DIAG (Address 0x04) */ +#define DA7280_E_OVERTEMP_WARN_SHIFT 3 +#define DA7280_E_OVERTEMP_WARN_MASK BIT(3) +#define DA7280_E_MEM_TYPE_SHIFT 4 +#define DA7280_E_MEM_TYPE_MASK BIT(4) +#define DA7280_E_LIM_DRIVE_ACC_SHIFT 6 +#define DA7280_E_LIM_DRIVE_ACC_MASK BIT(6) +#define DA7280_E_LIM_DRIVE_SHIFT 7 +#define DA7280_E_LIM_DRIVE_MASK BIT(7) + +/* DA7280_IRQ_EVENT_PAT_DIAG (Address 0x05) */ +#define DA7280_E_PWM_FAULT_SHIFT 5 +#define DA7280_E_PWM_FAULT_MASK BIT(5) +#define DA7280_E_MEM_FAULT_SHIFT 6 +#define DA7280_E_MEM_FAULT_MASK BIT(6) +#define DA7280_E_SEQ_ID_FAULT_SHIFT 7 +#define DA7280_E_SEQ_ID_FAULT_MASK BIT(7) + +/* DA7280_IRQ_STATUS1 (Address 0x06) */ +#define DA7280_STA_SEQ_CONTINUE_SHIFT 0 +#define DA7280_STA_SEQ_CONTINUE_MASK BIT(0) +#define DA7280_STA_UVLO_VBAT_OK_SHIFT 1 +#define DA7280_STA_UVLO_VBAT_OK_MASK BIT(1) +#define DA7280_STA_SEQ_DONE_SHIFT 2 +#define DA7280_STA_SEQ_DONE_MASK BIT(2) +#define DA7280_STA_OVERTEMP_CRIT_SHIFT 3 +#define DA7280_STA_OVERTEMP_CRIT_MASK BIT(3) +#define DA7280_STA_SEQ_FAULT_SHIFT 4 +#define DA7280_STA_SEQ_FAULT_MASK BIT(4) +#define DA7280_STA_WARNING_SHIFT 5 +#define DA7280_STA_WARNING_MASK BIT(5) +#define DA7280_STA_ACTUATOR_SHIFT 6 +#define DA7280_STA_ACTUATOR_MASK BIT(6) +#define DA7280_STA_OC_SHIFT 7 +#define DA7280_STA_OC_MASK BIT(7) + +/* DA7280_IRQ_MASK1 (Address 0x07) */ +#define DA7280_SEQ_CONTINUE_M_SHIFT 0 +#define DA7280_SEQ_CONTINUE_M_MASK BIT(0) +#define DA7280_E_UVLO_M_SHIFT 1 +#define DA7280_E_UVLO_M_MASK BIT(1) +#define DA7280_SEQ_DONE_M_SHIFT 2 +#define DA7280_SEQ_DONE_M_MASK BIT(2) +#define DA7280_OVERTEMP_CRIT_M_SHIFT 3 +#define DA7280_OVERTEMP_CRIT_M_MASK BIT(3) +#define DA7280_SEQ_FAULT_M_SHIFT 4 +#define DA7280_SEQ_FAULT_M_MASK BIT(4) +#define DA7280_WARNING_M_SHIFT 5 +#define DA7280_WARNING_M_MASK BIT(5) +#define DA7280_ACTUATOR_M_SHIFT 6 +#define DA7280_ACTUATOR_M_MASK BIT(6) +#define DA7280_OC_M_SHIFT 7 +#define DA7280_OC_M_MASK BIT(7) + +/* DA7280_ACTUATOR3 (Address 0x0e) */ +#define DA7280_IMAX_MASK (31 << 0) + +/* DA7280_TOP_CFG1 (Address 0x13) */ +#define DA7280_AMP_PID_EN_SHIFT 0 +#define DA7280_AMP_PID_EN_MASK BIT(0) +#define DA7280_RAPID_STOP_EN_SHIFT 1 +#define DA7280_RAPID_STOP_EN_MASK BIT(1) +#define DA7280_ACCELERATION_EN_SHIFT 2 +#define DA7280_ACCELERATION_EN_MASK BIT(2) +#define DA7280_FREQ_TRACK_EN_SHIFT 3 +#define DA7280_FREQ_TRACK_EN_MASK BIT(3) +#define DA7280_BEMF_SENSE_EN_SHIFT 4 +#define DA7280_BEMF_SENSE_EN_MASK BIT(4) +#define DA7280_ACTUATOR_TYPE_SHIFT 5 +#define DA7280_ACTUATOR_TYPE_MASK BIT(5) + +/* DA7280_TOP_CFG2 (Address 0x14) */ +#define DA7280_FULL_BRAKE_THR_SHIFT 0 +#define DA7280_FULL_BRAKE_THR_MASK (15 << 0) +#define DA7280_MEM_DATA_SIGNED_SHIFT 4 +#define DA7280_MEM_DATA_SIGNED_MASK BIT(4) + +/* DA7280_TOP_CFG4 (Address 0x16) */ +#define DA7280_TST_CALIB_IMPEDANCE_DIS_SHIFT 6 +#define DA7280_TST_CALIB_IMPEDANCE_DIS_MASK BIT(6) +#define DA7280_V2I_FACTOR_FREEZE_SHIFT 7 +#define DA7280_V2I_FACTOR_FREEZE_MASK BIT(7) + +/* DA7280_TOP_INT_CFG1 (Address 0x17) */ +#define DA7280_BEMF_FAULT_LIM_SHIFT 0 +#define DA7280_BEMF_FAULT_LIM_MASK (3 << 0) + +/* DA7280_TOP_CTL1 (Address 0x22) */ +#define DA7280_OPERATION_MODE_SHIFT 0 +#define DA7280_OPERATION_MODE_MASK (7 << 0) +#define DA7280_STANDBY_EN_SHIFT 3 +#define DA7280_STANDBY_EN_MASK BIT(3) +#define DA7280_SEQ_START_SHIFT 4 +#define DA7280_SEQ_START_MASK BIT(4) + +/* DA7280_SEQ_CTL2 (Address 0x28) */ +#define DA7280_PS_SEQ_ID_SHIFT 0 +#define DA7280_PS_SEQ_ID_MASK (15 << 0) +#define DA7280_PS_SEQ_LOOP_SHIFT 4 +#define DA7280_PS_SEQ_LOOP_MASK (15 << 4) + +/* DA7280_GPIO_0_CTL (Address 0x29) */ +#define DA7280_GPI0_POLARITY_SHIFT 0 +#define DA7280_GPI0_MODE_SHIFT 2 +#define DA7280_GPI0_SEQUENCE_ID_SHIFT 3 +#define DA7280_GPI0_SEQUENCE_ID_MASK (15 << 3) + +/* DA7280_GPIO_1_CTL (Address 0x2a) */ +#define DA7280_GPI1_SEQUENCE_ID_SHIFT 3 +#define DA7280_GPI1_SEQUENCE_ID_MASK (15 << 3) + +/* DA7280_GPIO_2_CTL (Address 0x2b) */ +#define DA7280_GPI2_SEQUENCE_ID_SHIFT 3 +#define DA7280_GPI2_SEQUENCE_ID_MASK (15 << 3) + +/* DA7280_MEM_CTL2 (Address 0x2d) */ +#define DA7280_WAV_MEM_LOCK_MASK BIT(7) + +/* DA7280_TOP_CFG5 (Address 0x6e) */ +#define DA7280_V2I_FACTOR_OFFSET_EN_MASK BIT(0) + +/* DA7280_IRQ_MASK2 (Address 0x83) */ +#define DA7280_ADC_SAT_M_MASK BIT(7) + +/* Controls */ + +#define DA7280_VOLTAGE_RATE_MAX 6000000 +#define DA7280_VOLTAGE_RATE_STEP 23400 +#define DA7280_NOMMAX_DFT 0x6B +#define DA7280_ABSMAX_DFT 0x78 + +#define DA7280_IMPD_MAX 1500000000 +#define DA7280_IMPD_DEFAULT 22000000 + +#define DA7280_IMAX_DEFAULT 0x0E +#define DA7280_IMAX_STEP 7200 +#define DA7280_IMAX_LIMIT 252000 + +#define DA7280_RESONT_FREQH_DFT 0x39 +#define DA7280_RESONT_FREQL_DFT 0x32 +#define DA7280_MIN_RESONAT_FREQ_HZ 50 +#define DA7280_MAX_RESONAT_FREQ_HZ 300 +#define DA7280_MIN_PWM_FREQ_KHZ 10 +#define DA7280_MAX_PWM_FREQ_KHZ 250 + +#define DA7280_SEQ_ID_MAX 15 +#define DA7280_SEQ_LOOP_MAX 15 +#define DA7280_GPI_SEQ_ID_DFT 0x0 + +#define DA7280_SNP_MEM_SIZE 100 +#define DA7280_SNP_MEM_MAX DA7280_SNP_MEM_99 + +#define IRQ_NUM 3 + +#define DA7280_SKIP_INIT 0x100 + +#define DA7280_FF_EFFECT_COUNT_MAX 15 + +enum da7280_haptic_dev_t { +DA7280_LRA =0 , +DA7280_ERM_BAR =1 , +DA7280_ERM_COIN =2 , +DA7280_DEV_MAX , +}; + +enum da7280_op_mode { +DA7280_INACTIVE =0 , +DA7280_DRO_MODE =1 , +DA7280_PWM_MODE =2 , +DA7280_RTWM_MODE =3 , +DA7280_ETWM_MODE =4 , +DA7280_OPMODE_MAX , +}; + +#define DA7280_FF_CONSTANT_DRO 1 +#define DA7280_FF_PERIODIC_PWM 2 +#define DA7280_FF_PERIODIC_RTWM 1 +#define DA7280_FF_PERIODIC_ETWM 2 + +#define DA7280_FF_PERIODIC_MODE DA7280_RTWM_MODE +#define DA7280_FF_CONSTANT_MODE DA7280_DRO_MODE + +enum da7280_custom_effect_param { +DA7280_CUSTOM_DATA_SEQ_ID_IDX =0 , +DA7280_CUSTOM_DATA_SEQ_LOOP_IDX =1 , +DA7280_CUSTOM_DATA_LEN =2 , +}; + +struct da7280_gpi_ctl { +u8 seq_id; +u8 mode; +u8 polarity; +};
drivers/input/misc/da7280.c line 271
Quoted 10 lines
drivers/input/misc/da7280.c new file +10
-0+ +struct da7280_haptic { +struct regmap *regmap; +struct input_dev *input_dev; +struct device *dev; +struct i2c_client *client; +struct pwm_device *pwm_dev; + +bool legacy; +int pwm_id;
pwm_id is unused?
Quoted 103 lines
drivers/input/misc/da7280.c new file +103
-0+struct delayed_work work_duration; +struct work_struct work_playback; +struct work_struct work_setgain; +int val; +u16 gain; +u16 new_gain; + +s16 level; + +u8 dev_type; +u8 op_mode; +u8 const_op_mode; +u8 periodic_op_mode; +u16 nommax; +u16 absmax; +u32 imax; +u32 impd; +u32 resonant_freq_h; +u32 resonant_freq_l; +bool bemf_sense_en; +bool freq_track_en; +bool acc_en; +bool rapid_stop_en; +bool amp_pid_en; +u8 ps_seq_id; +u8 ps_seq_loop; +struct da7280_gpi_ctl gpi_ctl[3 ]; +bool mem_update; +u8 snp_mem[DA7280_SNP_MEM_SIZE ]; +u8 enabled; +int length_ms; +}; + +static bool da7280_volatile_register (struct device *dev,unsigned int reg) +{ +switch (reg) { +case DA7280_IRQ_EVENT1 : +case DA7280_IRQ_EVENT_WARNING_DIAG : +case DA7280_IRQ_EVENT_SEQ_DIAG : +case DA7280_IRQ_STATUS1 : +case DA7280_TOP_CTL1 : +return true; +default : +return false; + } +} + +static const struct regmap_config da7280_haptic_regmap_config = { + .reg_bits =8 , + .val_bits =8 , + .max_register =DA7280_SNP_MEM_MAX , + .volatile_reg = da7280_volatile_register, +}; + +static int da7280_haptic_mem_update (struct da7280_haptic *haptics) +{ +int error; +unsigned int val; + +/* It is recommended to update the patterns +* during haptic is not working in order to avoid conflict +*/ + error =regmap_read (haptics->regmap,DA7280_IRQ_STATUS1 , &val); +if (error) +return error; +if (val &DA7280_STA_WARNING_MASK ) { +dev_warn (haptics->dev, +"Warning! Please check HAPTIC status.\n" ); +return -EBUSY ; + } + +/* Patterns are not updated if the lock bit is enabled */ + val =0 ; + error =regmap_read (haptics->regmap,DA7280_MEM_CTL2 , &val); +if (error) +return error; +if (~val &DA7280_WAV_MEM_LOCK_MASK ) { +dev_warn (haptics->dev, +"Please unlock the bit first\n" ); +return -EACCES ; + } + +/* Set to Inactive mode to make sure safety */ + error =regmap_update_bits (haptics->regmap, +DA7280_TOP_CTL1 , +DA7280_OPERATION_MODE_MASK , +0 ); +if (error) +return error; + + error =regmap_read (haptics->regmap,DA7280_MEM_CTL1 , &val); +if (error) +return error; + +return regmap_bulk_write (haptics->regmap, val, + haptics->snp_mem,DA7280_SNP_MEM_MAX - val +1 ); +} + +static int da7280_haptic_set_pwm (struct da7280_haptic *haptics,bool enabled) +{ +struct pwm_state state; +u64 period_mag_multi; +int error;
drivers/input/misc/da7280.c line 384
Quoted 10 lines
drivers/input/misc/da7280.c new file +10
-0+ +if (!haptics->gain) { +dev_err (haptics->dev, +"Please set the gain first for the pwm mode\n" ); +return -EINVAL ; + } + +pwm_get_state (haptics->pwm_dev, &state); + state.enabled = enabled; + period_mag_multi = enabled ? state.period * haptics->gain :0 ;
if .enabled is false .duty_cycle has no effect on the output. So there is no good reason for setting the duty_cyle to something different for a disabled PWM.
drivers/input/misc/da7280.c line 388
Quoted 4 lines
drivers/input/misc/da7280.c new file +4
-0+ state.duty_cycle = (haptics->acc_en) ? + (unsigned int )(period_mag_multi >>15 ) : + (unsigned int )((period_mag_multi >>15 ) + + state.period) /2 ;
This can be written in a more readable way:
/* would be great to have a symbolic name for 15 */
period_mag_multi >>= 15;
/* comment with a rational here */
if (!haptics->acc_en) {
period_mag_multi += state.period;
period_mag_multi /= 2;
}
state.duty_cycle = period_mag_multi;Quoted 41 lines
drivers/input/misc/da7280.c new file +40
-0+ error =pwm_apply_state (haptics->pwm_dev, &state); +if (error) +dev_err (haptics->dev, +"failed to apply pwm state: %pE\n" , +ERR_PTR (error)); + +return error; +} +static int da7280_probe (struct i2c_client *client, +const struct i2c_device_id *id) +{ +struct device *dev = &client->dev; +struct da7280_haptic *haptics; +struct input_dev *input_dev; +struct ff_device *ff; +struct pwm_state state; +unsigned int period2freq; +int error; + + haptics =devm_kzalloc (dev,sizeof (*haptics),GFP_KERNEL ); +if (!haptics) +return -ENOMEM ; + haptics->dev = dev; + +if (!client->irq) { +dev_err (dev,"No IRQ configured\n" ); +return -EINVAL ; + } + +da7280_parse_properties (dev, haptics); + +if (haptics->const_op_mode ==DA7280_PWM_MODE ) { + haptics->pwm_dev =devm_pwm_get (dev,NULL ); +if (IS_ERR (haptics->pwm_dev)) { +dev_err (dev,"failed to get PWM device\n" ); +return PTR_ERR (haptics->pwm_dev); + } + +pwm_init_state (haptics->pwm_dev, &state); + state.enabled = false;
drivers/input/misc/da7280.c line 1728
Quoted 10 lines
drivers/input/misc/da7280.c new file +10
-0+ error =pwm_apply_state (haptics->pwm_dev, &state); +if (error) { +dev_err (dev, +"failed to apply initial PWM state: %pE\n" , +ERR_PTR (error)); +return error; + } + +/* Check PWM Period, it must be in 10k ~ 250kHz */ + period2freq =1000000 /pwm_get_period (haptics->pwm_dev);
You already know the return value of pwm_get_period(), it's state.period.
drivers/input/misc/da7280.c line 1730
Quoted 3 lines
drivers/input/misc/da7280.c new file +2
-0+if (period2freq <DA7280_MIN_PWM_FREQ_KHZ || + period2freq >DA7280_MAX_PWM_FREQ_KHZ ) {
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
RE: [PATCH V9 3/3] Input: new da7280 haptic driver
Quoted 7 lines · Uwe Kleine-König
Quoted 6 lines · Roy Im
Adds support for the Dialog DA7280 LRA/ERM Haptic Driver with multiple mode and integrated waveform memory and wideband support. It communicates via an I2C bus to the device.
Signed-off-by Roy Im <[email protected]>
Quoted 16 lines
Quoted 4 lines
---
v9:
- Removed the header file and put the definitions into the c file.
- Updated the pwm code and error logs with %pEdrivers/input/misc/da7280.c line 271
Quoted 10 lines
drivers/input/misc/da7280.c new file +10
-0+ +struct da7280_haptic { +struct regmap *regmap; +struct input_dev *input_dev; +struct device *dev; +struct i2c_client *client; +struct pwm_device *pwm_dev; + +bool legacy; +int pwm_id;
pwm_idis unused?
Okay, I will remove this.
[...]
Quoted 10 lines
Quoted 10 lines
drivers/input/misc/da7280.c new file +10
-0+static int da7280_haptic_set_pwm (struct da7280_haptic *haptics,bool +enabled) { +struct pwm_state state; +u64 period_mag_multi; +int error; + +if (!haptics->gain) { +dev_err (haptics->dev, +"Please set the gain first for the pwm mode\n" ); +return -EINVAL ;
Quoted 8 lines
drivers/input/misc/da7280.c line 384
Quoted 5 lines
drivers/input/misc/da7280.c new file +5
-0+ } + +pwm_get_state (haptics->pwm_dev, &state); + state.enabled = enabled; + period_mag_multi = enabled ? state.period * haptics->gain :0 ;if .enabled is false .duty_cycle has no effect on the output. So there is no good reason for setting the
duty_cyleto something different for a disabled PWM.
Okay, I will add a condition for this.
Quoted 7 lines
drivers/input/misc/da7280.c line 388
Quoted 4 lines
drivers/input/misc/da7280.c new file +4
-0+ state.duty_cycle = (haptics->acc_en) ? + (unsigned int )(period_mag_multi >>15 ) : + (unsigned int )((period_mag_multi >>15 ) + + state.period) /2 ;This can be written in a more readable way:
Quoted 10 lines
/* would be great to have a symbolic name for 15 */
period_mag_multi >>= 15;
/* comment with a rational here */
if (!haptics->acc_en) {
period_mag_multi += state.period;
period_mag_multi /= 2;
}
state.duty_cycle = period_mag_multi;Okay, thanks. I have tried to update that as below. Could I get your comment if you still see anything on this?
/* Maximum gain is 0x7fff for PWM mode */
#define MAX_MAGNITUDE_SHIFT 15
[...]
period_mag_multi >>= MAX_MAGNITUDE_SHIFT;
/* The interpretation of duty cycle depends on the acc_en,
* it should be from 50% to 100% for acc_en = 0.
* See datasheet 'PWM mode' section for more details.
*/
if (!haptics->acc_en) {
period_mag_multi += state.period;
period_mag_multi /= 2;
}Quoted 7 lines
Quoted 7 lines
[...]
drivers/input/misc/da7280.c new file +6
-0+pwm_init_state (haptics->pwm_dev, &state); + state.enabled = false; + error =pwm_apply_state (haptics->pwm_dev, &state); +if (error) { + dev_err(dev, + "failed to apply initial PWM state: %pE\n",
Quoted 8 lines
drivers/input/misc/da7280.c line 1728
Quoted 6 lines
drivers/input/misc/da7280.c new file +6
-0+ ERR_PTR(error)); +return error; + } + +/* Check PWM Period, it must be in 10k ~ 250kHz */ + period2freq =1000000 /pwm_get_period (haptics->pwm_dev);You already know the return value of
pwm_get_period(), it's state.period.
Right, I will replace that to state.period.
Quoted 10 lines
drivers/input/misc/da7280.c line 1730
Quoted 3 lines
drivers/input/misc/da7280.c new file +2
-0+if (period2freq <DA7280_MIN_PWM_FREQ_KHZ || + period2freq >DA7280_MAX_PWM_FREQ_KHZ ) {Best regards
Uwe--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
Hi Uwe,
Thanks a lot for your comments.
Best regards,
Roy
Re: [PATCH V9 3/3] Input: new da7280 haptic driver
Hello Roy,
Quoted 16 lines · Roy Im
Okay, thanks. I have tried to update that as below. Could I get your comment if you still see anything on this?
/* Maximum gain is 0x7fff for PWM mode */ #define MAX_MAGNITUDE_SHIFT 15 [...] period_mag_multi >>= MAX_MAGNITUDE_SHIFT; /* The interpretation of duty cycle depends on the acc_en, * it should be from 50% to 100% for acc_en = 0. * See datasheet 'PWM mode' section for more details. */ if (!haptics->acc_en) { period_mag_multi += state.period; period_mag_multi /= 2; }
Much better. Extra points if you add a link to the datasheet at the top of the driver. I didn't look at the datasheet and assume that the reasoning is obvious then.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
RE: [PATCH V9 3/3] Input: new da7280 haptic driver
Hello Uwe,
Quoted 18 lines · Uwe Kleine-König
Quoted 16 lines · Roy Im
Okay, thanks. I have tried to update that as below. Could I get your comment if you still see anything on this?
/* Maximum gain is 0x7fff for PWM mode */ #define MAX_MAGNITUDE_SHIFT 15 [...] period_mag_multi >>= MAX_MAGNITUDE_SHIFT; /* The interpretation of duty cycle depends on the acc_en, * it should be from 50% to 100% for acc_en = 0. * See datasheet 'PWM mode' section for more details. */ if (!haptics->acc_en) { period_mag_multi += state.period; period_mag_multi /= 2; }
Quoted 2 lines
Much better. Extra points if you add a link to the datasheet at the top of the driver. I didn't look at the datasheet and assume that the reasoning is obvious then.
Okay, then do you think it would be better to remove that comment(the 3rd line - datasheet)?.
Quoted 7 lines
Best regards
Uwe--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
Thanks for your comment.
Kind regards,
Roy
Re: [PATCH V9 3/3] Input: new da7280 haptic driver
Hey Roy,
Quoted 19 lines · Roy Im
Quoted 18 lines · Uwe Kleine-König
Quoted 16 lines · Roy Im
Okay, thanks. I have tried to update that as below. Could I get your comment if you still see anything on this?
/* Maximum gain is 0x7fff for PWM mode */ #define MAX_MAGNITUDE_SHIFT 15 [...] period_mag_multi >>= MAX_MAGNITUDE_SHIFT; /* The interpretation of duty cycle depends on the acc_en, * it should be from 50% to 100% for acc_en = 0. * See datasheet 'PWM mode' section for more details. */ if (!haptics->acc_en) { period_mag_multi += state.period; period_mag_multi /= 2; }
Quoted 4 lines
Quoted 2 lines
Much better. Extra points if you add a link to the datasheet at the top of the driver. I didn't look at the datasheet and assume that the reasoning is obvious then.
Okay, then do you think it would be better to remove that comment(the 3rd line - datasheet)?.
No, please keep the reference.
Best regards
Uwe
Signature · 2 lines
Pengutronix e.K. | Uwe Kleine-König | Industrial Linux Solutions | https://www.pengutronix.de/ |
RE: [PATCH V9 3/3] Input: new da7280 haptic driver
Monday, March 2, 2020 3:44 PM, Uwe Kleine-König Wrote:
Quoted 20 lines · Roy Im
Quoted 19 lines · Uwe Kleine-König
Quoted 18 lines · Roy Im
Quoted 16 lines
Okay, thanks. I have tried to update that as below. Could I get your comment if you still see anything on this?
/* Maximum gain is 0x7fff for PWM mode */ #define MAX_MAGNITUDE_SHIFT 15 [...] period_mag_multi >>= MAX_MAGNITUDE_SHIFT; /* The interpretation of duty cycle depends on the acc_en, * it should be from 50% to 100% for acc_en = 0. * See datasheet 'PWM mode' section for more details. */ if (!haptics->acc_en) { period_mag_multi += state.period; period_mag_multi /= 2; }
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Much better. Extra points if you add a link to the datasheet at the
top of the driver. I didn't look at the datasheet and assume that the reasoning is obvious then.Okay, then do you think it would be better to remove that comment(the 3rd line - datasheet)?.
No, please keep the reference.
Okay, I will do.
Quoted 7 lines
Best regards
Uwe--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | https://www.pengutronix.de/ |
Thanks.
Kind regards,
Roy