Uwe Kleine-König (The Capable Hub)Input: Use named initializers for arrays of i2c_device_data47ceab25 months agoHistory
1328 lines · 34.1 KB · C
RawDownload
// 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	= 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_SEQ_ID_IDX	= 0,	DA7280_CUSTOM_SEQ_LOOP_IDX	= 1,	DA7280_CUSTOM_DATA_LEN		= 2,}; enum da7280_custom_gpi_effect_param {	DA7280_CUSTOM_GPI_SEQ_ID_IDX	= 0,	DA7280_CUSTOM_GPI_NUM_IDX	= 2,	DA7280_CUSTOM_GP_DATA_LEN	= 3,}; struct da7280_gpi_ctl {	u8 seq_id;	u8 mode;	u8 polarity;}; struct da7280_haptic {	struct regmap *regmap;	struct input_dev *input_dev;	struct device *dev;	struct i2c_client *client;	struct pwm_device *pwm_dev; 	struct work_struct work;	int val;	u16 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];	bool active;	bool suspended;}; 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){	unsigned int val;	int error; 	/* The patterns should be updated when haptic is not working */	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; 	if (!haptics->gain && enabled) {		dev_err(haptics->dev, "Unable to enable pwm with 0 gain\n");		return -EINVAL;	} 	pwm_get_state(haptics->pwm_dev, &state);	state.enabled = enabled;	if (enabled) {		period_mag_multi = (u64)state.period * haptics->gain;		period_mag_multi >>= DA7280_MAX_MAGNITUDE_SHIFT; 		/*		 * The interpretation of duty cycle depends on the acc_en,		 * it should be between 50% and 100% for acc_en = 0.		 * See datasheet 'PWM mode' section.		 */		if (!haptics->acc_en) {			period_mag_multi += state.period;			period_mag_multi /= 2;		} 		state.duty_cycle = period_mag_multi;	} 	error = pwm_apply_might_sleep(haptics->pwm_dev, &state);	if (error)		dev_err(haptics->dev, "Failed to apply pwm state: %d\n", error); 	return error;} static void da7280_haptic_activate(struct da7280_haptic *haptics){	int error; 	if (haptics->active)		return; 	switch (haptics->op_mode) {	case DA7280_DRO_MODE:		/* the valid range check when acc_en is enabled */		if (haptics->acc_en && haptics->level > 0x7F)			haptics->level = 0x7F;		else if (haptics->level > 0xFF)			haptics->level = 0xFF; 		/* Set level as a % of ACTUATOR_NOMMAX (nommax) */		error = regmap_write(haptics->regmap, DA7280_TOP_CTL2,				     haptics->level);		if (error) {			dev_err(haptics->dev,				"Failed to set level to %d: %d\n",				haptics->level, error);			return;		}		break; 	case DA7280_PWM_MODE:		if (da7280_haptic_set_pwm(haptics, true))			return;		break; 	case DA7280_RTWM_MODE:		/*		 * The pattern will be played by the PS_SEQ_ID and the		 * PS_SEQ_LOOP		 */		break; 	case DA7280_ETWM_MODE:		/*		 * The pattern will be played by the GPI[N] state,		 * GPI(N)_SEQUENCE_ID and the PS_SEQ_LOOP. See the		 * datasheet for the details.		 */		break; 	default:		dev_err(haptics->dev, "Invalid op mode %d\n", haptics->op_mode);		return;	} 	error = regmap_update_bits(haptics->regmap,				   DA7280_TOP_CTL1,				   DA7280_OPERATION_MODE_MASK,				   haptics->op_mode);	if (error) {		dev_err(haptics->dev,			"Failed to set operation mode: %d", error);		return;	} 	if (haptics->op_mode == DA7280_PWM_MODE ||	    haptics->op_mode == DA7280_RTWM_MODE) {		error = regmap_update_bits(haptics->regmap,					   DA7280_TOP_CTL1,					   DA7280_SEQ_START_MASK,					   DA7280_SEQ_START_MASK);		if (error) {			dev_err(haptics->dev,				"Failed to start sequence: %d\n", error);			return;		}	} 	haptics->active = true;} static void da7280_haptic_deactivate(struct da7280_haptic *haptics){	int error; 	if (!haptics->active)		return; 	/* Set to Inactive mode */	error = regmap_update_bits(haptics->regmap,				   DA7280_TOP_CTL1,				   DA7280_OPERATION_MODE_MASK, 0);	if (error) {		dev_err(haptics->dev,			"Failed to clear operation mode: %d", error);		return;	} 	switch (haptics->op_mode) {	case DA7280_DRO_MODE:		error = regmap_write(haptics->regmap,				     DA7280_TOP_CTL2, 0);		if (error) {			dev_err(haptics->dev,				"Failed to disable DRO mode: %d\n", error);			return;		}		break; 	case DA7280_PWM_MODE:		if (da7280_haptic_set_pwm(haptics, false))			return;		break; 	case DA7280_RTWM_MODE:	case DA7280_ETWM_MODE:		error = regmap_update_bits(haptics->regmap,					   DA7280_TOP_CTL1,					   DA7280_SEQ_START_MASK, 0);		if (error) {			dev_err(haptics->dev,				"Failed to disable RTWM/ETWM mode: %d\n",				error);			return;		}		break; 	default:		dev_err(haptics->dev, "Invalid op mode %d\n", haptics->op_mode);		return;	} 	haptics->active = false;} static void da7280_haptic_work(struct work_struct *work){	struct da7280_haptic *haptics =		container_of(work, struct da7280_haptic, work);	int val = haptics->val; 	if (val)		da7280_haptic_activate(haptics);	else

Lines 1–500 of 1328.