// SPDX-License-Identifier: GPL-2.0+
/*
* DA7280 Haptic device driver
*
* Copyright (c) 2020 Dialog Semiconductor.
* Author: Roy Im <Roy.Im.Opensource@diasemi.com>
*/
#include <linux/bitfield.h>
#include <linux/bitops.h>
#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>
/* 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_MASK BIT(0)
#define DA7280_E_UVLO_MASK BIT(1)
#define DA7280_E_SEQ_DONE_MASK BIT(2)
#define DA7280_E_OVERTEMP_CRIT_MASK BIT(3)
#define DA7280_E_SEQ_FAULT_MASK BIT(4)
#define DA7280_E_WARNING_MASK BIT(5)
#define DA7280_E_ACTUATOR_FAULT_MASK BIT(6)
#define DA7280_E_OC_FAULT_MASK BIT(7)
/* DA7280_IRQ_EVENT_WARNING_DIAG (Address 0x04) */
#define DA7280_E_OVERTEMP_WARN_MASK BIT(3)
#define DA7280_E_MEM_TYPE_MASK BIT(4)
#define DA7280_E_LIM_DRIVE_ACC_MASK BIT(6)
#define DA7280_E_LIM_DRIVE_MASK BIT(7)
/* DA7280_IRQ_EVENT_PAT_DIAG (Address 0x05) */
#define DA7280_E_PWM_FAULT_MASK BIT(5)
#define DA7280_E_MEM_FAULT_MASK BIT(6)
#define DA7280_E_SEQ_ID_FAULT_MASK BIT(7)
/* DA7280_IRQ_STATUS1 (Address 0x06) */
#define DA7280_STA_SEQ_CONTINUE_MASK BIT(0)
#define DA7280_STA_UVLO_VBAT_OK_MASK BIT(1)
#define DA7280_STA_SEQ_DONE_MASK BIT(2)
#define DA7280_STA_OVERTEMP_CRIT_MASK BIT(3)
#define DA7280_STA_SEQ_FAULT_MASK BIT(4)
#define DA7280_STA_WARNING_MASK BIT(5)
#define DA7280_STA_ACTUATOR_MASK BIT(6)
#define DA7280_STA_OC_MASK BIT(7)
/* DA7280_IRQ_MASK1 (Address 0x07) */
#define DA7280_SEQ_CONTINUE_M_MASK BIT(0)
#define DA7280_E_UVLO_M_MASK BIT(1)
#define DA7280_SEQ_DONE_M_MASK BIT(2)
#define DA7280_OVERTEMP_CRIT_M_MASK BIT(3)
#define DA7280_SEQ_FAULT_M_MASK BIT(4)
#define DA7280_WARNING_M_MASK BIT(5)
#define DA7280_ACTUATOR_M_MASK BIT(6)
#define DA7280_OC_M_MASK BIT(7)
/* DA7280_ACTUATOR3 (Address 0x0e) */
#define DA7280_IMAX_MASK GENMASK(4, 0)
/* DA7280_TOP_CFG1 (Address 0x13) */
#define DA7280_AMP_PID_EN_MASK BIT(0)
#define DA7280_RAPID_STOP_EN_MASK BIT(1)
#define DA7280_ACCELERATION_EN_MASK BIT(2)
#define DA7280_FREQ_TRACK_EN_MASK BIT(3)
#define DA7280_BEMF_SENSE_EN_MASK BIT(4)
#define DA7280_ACTUATOR_TYPE_MASK BIT(5)
/* DA7280_TOP_CFG2 (Address 0x14) */
#define DA7280_FULL_BRAKE_THR_MASK GENMASK(3, 0)
#define DA7280_MEM_DATA_SIGNED_MASK BIT(4)
/* DA7280_TOP_CFG4 (Address 0x16) */
#define DA7280_TST_CALIB_IMPEDANCE_DIS_MASK BIT(6)
#define DA7280_V2I_FACTOR_FREEZE_MASK BIT(7)
/* DA7280_TOP_INT_CFG1 (Address 0x17) */
#define DA7280_BEMF_FAULT_LIM_MASK GENMASK(1, 0)
/* DA7280_TOP_CTL1 (Address 0x22) */
#define DA7280_OPERATION_MODE_MASK GENMASK(2, 0)
#define DA7280_STANDBY_EN_MASK BIT(3)
#define DA7280_SEQ_START_MASK BIT(4)
/* DA7280_SEQ_CTL2 (Address 0x28) */
#define DA7280_PS_SEQ_ID_MASK GENMASK(3, 0)
#define DA7280_PS_SEQ_LOOP_MASK GENMASK(7, 4)
/* DA7280_GPIO_0_CTL (Address 0x29) */
#define DA7280_GPI0_POLARITY_MASK GENMASK(1, 0)
#define DA7280_GPI0_MODE_MASK BIT(2)
#define DA7280_GPI0_SEQUENCE_ID_MASK GENMASK(6, 3)
/* DA7280_GPIO_1_CTL (Address 0x2a) */
#define DA7280_GPI1_POLARITY_MASK GENMASK(1, 0)
#define DA7280_GPI1_MODE_MASK BIT(2)
#define DA7280_GPI1_SEQUENCE_ID_MASK GENMASK(6, 3)
/* DA7280_GPIO_2_CTL (Address 0x2b) */
#define DA7280_GPI2_POLARITY_MASK GENMASK(1, 0)
#define DA7280_GPI2_MODE_MASK BIT(2)
#define DA7280_GPI2_SEQUENCE_ID_MASK GENMASK(6, 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_SEQ_ID_MAX 15
#define DA7280_SEQ_LOOP_MAX 15
#define DA7280_GPI_SEQ_ID_DFT 0
#define DA7280_GPI_SEQ_ID_MAX 2
#define DA7280_SNP_MEM_SIZE 100
#define DA7280_SNP_MEM_MAX DA7280_SNP_MEM_99
#define DA7280_IRQ_NUM 3
#define DA7280_SKIP_INIT 0x100
#define DA7280_FF_EFFECT_COUNT_MAX 15
/* Maximum gain is 0x7fff for PWM mode */
#define DA7280_MAX_MAGNITUDE_SHIFT 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