input: misc: qcom-hv-haptics: Import changes from yudi-t-oss
Change-Id: Idaaf0e677f9212d32254f92d2d8eb9ce655ddb27 Signed-off-by: Jens Reidel <adrian@travitia.xyz>
This commit is contained in:
parent
0b7362e433
commit
eea21f2798
@ -31,3 +31,31 @@ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
|
||||
obj-$(CONFIG_RMI4_CORE) += rmi4/
|
||||
obj-$(CONFIG_INPUT_FINGERPRINT) += fingerprint/
|
||||
obj-$(CONFIG_STMVL53L5) += stmvl53l5/
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), diting)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_DITING
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), mayfly)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_MAYFLY
|
||||
KBUILD_CPPFLAGS += -DQCOM_HAPTIC_F0_PROTECT
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), zizhan)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_ZIZHAN
|
||||
KBUILD_CPPFLAGS += -DQCOM_HAPTIC_F0_PROTECT
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), mondrian)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_MONDRIAN
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), marble)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_MARBLE
|
||||
KBUILD_CPPFLAGS += -DQCOM_HAPTIC_F0_PROTECT
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT), yudi)
|
||||
KBUILD_CPPFLAGS += -DCONFIG_TARGET_PRODUCT_YUDI
|
||||
KBUILD_CPPFLAGS += -DQCOM_HAPTIC_F0_PROTECT
|
||||
endif
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <linux/types.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/qpnp/qpnp-pbs.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/mmhardware_sysfs.h>
|
||||
|
||||
#include <linux/soc/qcom/battery_charger.h>
|
||||
|
||||
@ -40,6 +42,7 @@
|
||||
#define HAP_CFG_V3 0x3
|
||||
#define HAP_CFG_V4 0x4
|
||||
|
||||
#define DEBUG
|
||||
#define HAP_CFG_STATUS_DATA_MSB_REG 0x09
|
||||
/* STATUS_DATA_MSB definitions while MOD_STATUS_SEL is 0 */
|
||||
#define AUTO_RES_CAL_DONE_BIT BIT(5)
|
||||
@ -141,6 +144,10 @@
|
||||
#define HAP_CFG_DRV_DUTY_CFG_REG 0x60
|
||||
#define ADT_DRV_DUTY_EN_BIT BIT(7)
|
||||
|
||||
#define DRV_DUTY_MASK GENMASK(5, 3)
|
||||
#define DRV_DUTY_62P5_PERCENT 0x2
|
||||
#define DRV_DUTY_SHIFT 3
|
||||
|
||||
#define HAP_CFG_ADT_DRV_DUTY_CFG_REG 0x61
|
||||
#define HAP_CFG_ZX_WIND_CFG_REG 0x62
|
||||
|
||||
@ -149,6 +156,7 @@
|
||||
#define AUTORES_EN_DLY_MASK GENMASK(5, 2)
|
||||
#define AUTORES_EN_DLY(cycles) ((cycles) * 2)
|
||||
#define AUTORES_EN_DLY_6_CYCLES AUTORES_EN_DLY(6)
|
||||
#define AUTORES_EN_DLY_7_CYCLES AUTORES_EN_DLY(7)
|
||||
#define AUTORES_EN_DLY_SHIFT 2
|
||||
#define AUTORES_ERR_WINDOW_MASK GENMASK(1, 0)
|
||||
#define AUTORES_ERR_WINDOW_12P5_PERCENT 0x0
|
||||
@ -335,6 +343,11 @@
|
||||
#define is_between(val, min, max) \
|
||||
(((min) <= (max)) && ((min) <= (val)) && ((val) <= (max)))
|
||||
|
||||
#if IS_ENABLED(CONFIG_MMHARDWARE_DETECTION)
|
||||
static DEFINE_MUTEX(haptic_lock);
|
||||
static int dev_cnt = 0;
|
||||
#endif
|
||||
|
||||
enum hap_status_sel {
|
||||
CAL_TLRA_CL_STS = 0x00,
|
||||
T_WIND_STS,
|
||||
@ -565,6 +578,9 @@ struct haptics_hw_config {
|
||||
enum drv_sig_shape drv_wf;
|
||||
bool is_erm;
|
||||
bool measure_lra_impedance;
|
||||
#if defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
bool lra_calibrated;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct custom_fifo_data {
|
||||
@ -592,6 +608,11 @@ struct haptics_chip {
|
||||
struct class hap_class;
|
||||
struct regulator *hpwr_vreg;
|
||||
struct hrtimer hbst_off_timer;
|
||||
struct hrtimer dph_off_timer; /*DIRECT_PLAY turning off timer*/
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
struct power_supply *wls_psy;
|
||||
#endif
|
||||
bool hboost_quick_off;
|
||||
struct notifier_block hboost_nb;
|
||||
int fifo_empty_irq;
|
||||
u32 hpwr_voltage_mv;
|
||||
@ -1050,6 +1071,13 @@ static int haptics_get_closeloop_lra_period(
|
||||
u64 tmp;
|
||||
int rc;
|
||||
|
||||
#ifdef QCOM_HAPTIC_F0_PROTECT
|
||||
//protect low rate of xbl f0 abnormal for L18 only
|
||||
int f0_mix, f0_max, f0_default, f0_cnt;
|
||||
int rc1, rc2, rc3, rc4;
|
||||
struct device_node *node = chip->dev->of_node;
|
||||
#endif
|
||||
|
||||
/* read RC_CLK_CAL enabling mode */
|
||||
rc = haptics_read(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_CAL_EN_REG, val, 1);
|
||||
@ -1089,9 +1117,13 @@ static int haptics_get_closeloop_lra_period(
|
||||
tlra_cl_err_sts =
|
||||
((val[0] & TLRA_CL_ERR_MSB_MASK) << 8) | val[1];
|
||||
|
||||
dev_dbg(chip->dev, "rc_clk_cal = %u, auto_res_done = %d\n",
|
||||
dev_info(chip->dev, "rc_clk_cal = %u, auto_res_done = %d\n",
|
||||
rc_clk_cal, auto_res_done);
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
chip->config.lra_calibrated = auto_res_done;
|
||||
#endif
|
||||
|
||||
if (rc_clk_cal == CAL_RC_CLK_DISABLED_VAL && !auto_res_done) {
|
||||
/* TLRA_CL_ERR(us) = TLRA_CL_ERR_STS * 1.667 us */
|
||||
tmp = tlra_cl_err_sts * TLRA_AUTO_RES_ERR_NO_CAL_STEP_PSEC;
|
||||
@ -1177,12 +1209,46 @@ static int haptics_get_closeloop_lra_period(
|
||||
tmp = div_u64(tmp, last_good_tlra_cl_sts);
|
||||
tmp = div_u64(tmp, 293);
|
||||
config->rc_clk_cal_count = div_u64(tmp, config->t_lra_us);
|
||||
|
||||
} else {
|
||||
dev_err(chip->dev, "Can't get close-loop LRA period in rc_clk_cal mode %u\n",
|
||||
rc_clk_cal);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef QCOM_HAPTIC_F0_PROTECT
|
||||
/* protect low rate of xbl f0 abnormal */
|
||||
if(in_boot){
|
||||
u32 xbl_f0 = USEC_PER_SEC / config->cl_t_lra_us;
|
||||
dev_info(chip->dev, "xbl f0 =%d \n", xbl_f0);
|
||||
rc1 = of_property_read_u32(node, "qcom,lra-f0-min", &f0_mix);
|
||||
if (rc1 < 0) {
|
||||
dev_err(chip->dev, "lra-f0-min failed, rc=%d\n", rc);
|
||||
}
|
||||
rc2 = of_property_read_u32(node, "qcom,lra-f0-max", &f0_max);
|
||||
if (rc2 < 0) {
|
||||
dev_err(chip->dev, "lra-f0-max failed, rc=%d\n", rc);
|
||||
}
|
||||
rc3 = of_property_read_u32(node, "qcom,lra-f0-default", &f0_default);
|
||||
if (rc3 < 0) {
|
||||
dev_err(chip->dev, "lra-f0-default failed, rc=%d\n", rc);
|
||||
}
|
||||
rc4 = of_property_read_u32(node, "qcom,lra-f0-cal-count", &f0_cnt);
|
||||
if (rc4 < 0) {
|
||||
dev_err(chip->dev, "lra-f0-cal-count failed, rc=%d\n", rc);
|
||||
}
|
||||
if (rc1 >= 0 && rc2 >= 0 && rc3 >= 0 && rc4 >= 0) {
|
||||
if (xbl_f0 > f0_max || xbl_f0 < f0_mix) {
|
||||
dev_info(chip->dev, "xbl f0 abnormal: %d ~ 0x%x use default: %d ~ 0x%x f0:%d - %d after boot\n",xbl_f0, config->rc_clk_cal_count, f0_default, f0_cnt, f0_mix, f0_max);
|
||||
config->cl_t_lra_us = USEC_PER_SEC / f0_default;
|
||||
config->rc_clk_cal_count = f0_cnt;
|
||||
}
|
||||
} else {
|
||||
dev_err(chip->dev, "lra-f0: default min max count must set together in dtsi\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dev_dbg(chip->dev, "OL_TLRA %u us, CL_TLRA %u us, RC_CLK_CAL_COUNT %#x\n",
|
||||
chip->config.t_lra_us, chip->config.cl_t_lra_us,
|
||||
chip->config.rc_clk_cal_count);
|
||||
@ -1609,8 +1675,6 @@ static int haptics_enable_play(struct haptics_chip *chip, bool en)
|
||||
if (chip->hw_type == HAP525_HV && play->pattern_src == PATTERN_MEM)
|
||||
val |= FIELD_PREP(PATX_MEM_SEL_MASK, play->effect->pat_sel);
|
||||
|
||||
if (play->brake && !play->brake->disabled)
|
||||
val |= BRAKE_EN_BIT;
|
||||
|
||||
if (en)
|
||||
val |= PLAY_EN_BIT;
|
||||
@ -1893,11 +1957,39 @@ static int haptics_get_fifo_fill_status(struct haptics_chip *chip, u32 *fill)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
static bool get_wls_backcharge_enable(struct haptics_chip *chip) {
|
||||
int rc;
|
||||
union power_supply_propval val;
|
||||
if(!chip->wls_psy) {
|
||||
chip->wls_psy = power_supply_get_by_name("wireless");
|
||||
}
|
||||
if (chip->wls_psy) {
|
||||
rc = power_supply_get_property(chip->wls_psy,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
&val);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Couldn't get POWER_SUPPLY_PROP_PRESENT, rc=%d\n",
|
||||
rc);
|
||||
return false;
|
||||
}
|
||||
return val.intval == 1;
|
||||
}
|
||||
dev_err(chip->dev, "Couldn't get wls_backcharge_enable, wsl_psy is null!");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int haptics_get_available_fifo_memory(struct haptics_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
u32 fill, available;
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
if (get_wls_backcharge_enable(chip)) {
|
||||
dev_dbg(chip->dev, "wireless backcharge enabled, skip haptics!");
|
||||
return -EBUSY;
|
||||
}
|
||||
#endif
|
||||
rc = haptics_get_fifo_fill_status(chip, &fill);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@ -2060,7 +2152,7 @@ static int haptics_set_fifo(struct haptics_chip *chip, struct fifo_cfg *fifo)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int haptics_load_constant_effect(struct haptics_chip *chip, u8 amplitude)
|
||||
static int haptics_load_constant_effect(struct haptics_chip *chip, u8 amplitude, u32 length_us)
|
||||
{
|
||||
struct haptics_play_info *play = &chip->play;
|
||||
u32 hdrm_mv, vmax_mv = chip->config.vmax_mv;
|
||||
@ -2076,6 +2168,10 @@ static int haptics_load_constant_effect(struct haptics_chip *chip, u8 amplitude)
|
||||
/* No effect data when playing constant waveform */
|
||||
play->effect = NULL;
|
||||
|
||||
/*set play time*/
|
||||
play->length_us = length_us;
|
||||
dev_dbg(chip->dev, "play->length_us is %u us", play->length_us);
|
||||
|
||||
/* Fix Vmax to (hpwr_vreg_mv - hdrm_mv) in non-HBOOST regulator case */
|
||||
if (is_haptics_external_powered(chip)) {
|
||||
rc = haptics_get_vmax_headroom_mv(chip, &hdrm_mv);
|
||||
@ -2103,7 +2199,7 @@ static int haptics_load_constant_effect(struct haptics_chip *chip, u8 amplitude)
|
||||
goto unlock;
|
||||
|
||||
/* Always enable LRA auto resonance for DIRECT_PLAY */
|
||||
rc = haptics_enable_autores(chip, !chip->config.is_erm);
|
||||
rc = haptics_enable_autores(chip, false);
|
||||
if (rc < 0)
|
||||
goto unlock;
|
||||
|
||||
@ -2212,7 +2308,19 @@ static int haptics_init_custom_effect(struct haptics_chip *chip)
|
||||
chip->custom_effect->pattern = NULL;
|
||||
chip->custom_effect->brake = NULL;
|
||||
chip->custom_effect->id = UINT_MAX;
|
||||
chip->custom_effect->vmax_mv = chip->config.vmax_mv;
|
||||
#ifdef CONFIG_TARGET_PRODUCT_DITING
|
||||
chip->custom_effect->vmax_mv = 9000;
|
||||
#elif defined(CONFIG_TARGET_PRODUCT_MONDRIAN)
|
||||
chip->custom_effect->vmax_mv = 9000;
|
||||
#elif defined(CONFIG_TARGET_PRODUCT_MAYFLY)
|
||||
chip->custom_effect->vmax_mv = 9100;
|
||||
#elif defined(CONFIG_TARGET_PRODUCT_MARBLE)
|
||||
chip->custom_effect->vmax_mv = 9100;
|
||||
#elif defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
chip->custom_effect->vmax_mv = 5000;
|
||||
#else
|
||||
chip->custom_effect->vmax_mv = 4200; //chip->config.vmax_mv
|
||||
#endif
|
||||
chip->custom_effect->t_lra_us = chip->config.t_lra_us;
|
||||
chip->custom_effect->src = FIFO;
|
||||
chip->custom_effect->auto_res_disable = true;
|
||||
@ -2328,7 +2436,8 @@ static int haptics_load_custom_effect(struct haptics_chip *chip,
|
||||
|
||||
play->effect = chip->custom_effect;
|
||||
play->brake = NULL;
|
||||
play->vmax_mv = (magnitude * chip->custom_effect->vmax_mv) / 0x7fff;
|
||||
dev_dbg(chip->dev, "set magnitude on custom effect, rc=%d\n", magnitude);
|
||||
play->vmax_mv = (magnitude * chip->custom_effect->vmax_mv) / 0x7fff;
|
||||
rc = haptics_set_vmax_mv(chip, play->vmax_mv);
|
||||
if (rc < 0)
|
||||
goto cleanup;
|
||||
@ -2526,7 +2635,17 @@ static int haptics_upload_effect(struct input_dev *dev,
|
||||
s16 level;
|
||||
u8 amplitude;
|
||||
int rc = 0;
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
if(effect->type == FF_DAMPER){
|
||||
chip->hboost_quick_off = true;
|
||||
dev_info(chip->dev, "set hboost quick off!");
|
||||
return 0;
|
||||
}
|
||||
if (get_wls_backcharge_enable(chip)) {
|
||||
dev_info(chip->dev, "wireless backcharge enabled, skip haptics!");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
switch (effect->type) {
|
||||
case FF_CONSTANT:
|
||||
length_us = effect->replay.length * USEC_PER_MSEC;
|
||||
@ -2536,7 +2655,7 @@ static int haptics_upload_effect(struct input_dev *dev,
|
||||
amplitude = tmp / 0x7fff;
|
||||
dev_dbg(chip->dev, "upload constant effect, length = %dus, amplitude = %#x\n",
|
||||
length_us, amplitude);
|
||||
haptics_load_constant_effect(chip, amplitude);
|
||||
haptics_load_constant_effect(chip, amplitude, length_us);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "set direct play failed, rc=%d\n",
|
||||
rc);
|
||||
@ -2610,12 +2729,23 @@ static int haptics_playback(struct input_dev *dev, int effect_id, int val)
|
||||
struct haptics_chip *chip = input_get_drvdata(dev);
|
||||
struct haptics_play_info *play = &chip->play;
|
||||
int rc;
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
if (get_wls_backcharge_enable(chip)) {
|
||||
dev_dbg(chip->dev, "wireless backcharge enabled, skip haptics!");
|
||||
val = 0;
|
||||
}
|
||||
#endif
|
||||
dev_dbg(chip->dev, "playback val = %d\n", val);
|
||||
if (!!val) {
|
||||
rc = haptics_enable_play(chip, true);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (play->pattern_src == DIRECT_PLAY) {
|
||||
u64 length_ns = play->length_us * NSEC_PER_USEC;
|
||||
hrtimer_start(&chip->dph_off_timer,
|
||||
ns_to_ktime(length_ns),
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
} else {
|
||||
if (play->pattern_src == FIFO &&
|
||||
atomic_read(&play->fifo_status.is_busy)) {
|
||||
@ -2635,6 +2765,16 @@ static int haptics_erase(struct input_dev *dev, int effect_id)
|
||||
struct haptics_play_info *play = &chip->play;
|
||||
int rc;
|
||||
|
||||
dev_info(chip->dev, "haptics_erase\n");
|
||||
if(chip->hboost_quick_off){
|
||||
rc = haptics_boost_vreg_enable(chip, false);
|
||||
if(rc < 0)
|
||||
dev_err(chip->dev, "hboost quick off failed, rc=%d\n", rc);
|
||||
else
|
||||
dev_info(chip->dev, "hboost quick off\n");
|
||||
chip->hboost_quick_off = false;
|
||||
return 0;
|
||||
}
|
||||
mutex_lock(&play->lock);
|
||||
if ((play->pattern_src == FIFO) &&
|
||||
atomic_read(&play->fifo_status.is_busy)) {
|
||||
@ -2642,7 +2782,11 @@ static int haptics_erase(struct input_dev *dev, int effect_id)
|
||||
dev_dbg(chip->dev, "cancelling FIFO playing\n");
|
||||
atomic_set(&play->fifo_status.cancelled, 1);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MAYFLY) || defined(CONFIG_TARGET_PRODUCT_DITING) || defined(CONFIG_TARGET_PRODUCT_ZIZHAN) || defined(CONFIG_TARGET_PRODUCT_MONDRIAN) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
#define FIFO_PLAY_STOP_DELAY 9
|
||||
msleep(FIFO_PLAY_STOP_DELAY);
|
||||
dev_info(chip->dev, "fifo play stop delay %d ms\n", FIFO_PLAY_STOP_DELAY);
|
||||
#endif
|
||||
rc = haptics_stop_fifo_play(chip);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "stop FIFO playing failed, rc=%d\n",
|
||||
@ -3343,6 +3487,7 @@ static ssize_t pattern_s_dbgfs_write(struct file *fp,
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tmp[i++] = val;
|
||||
}
|
||||
|
||||
@ -5099,13 +5244,22 @@ static int haptics_detect_lra_frequency(struct haptics_chip *chip)
|
||||
rc = haptics_masked_write(chip, chip->cfg_addr_base,
|
||||
HAP_CFG_AUTORES_CFG_REG, AUTORES_EN_BIT |
|
||||
AUTORES_EN_DLY_MASK | AUTORES_ERR_WINDOW_MASK,
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MONDRIAN) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
AUTORES_EN_DLY_7_CYCLES << AUTORES_EN_DLY_SHIFT
|
||||
#else
|
||||
AUTORES_EN_DLY_6_CYCLES << AUTORES_EN_DLY_SHIFT
|
||||
#endif
|
||||
| AUTORES_ERR_WINDOW_50_PERCENT | AUTORES_EN_BIT);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = haptics_masked_write(chip, chip->cfg_addr_base,
|
||||
#if defined(CONFIG_TARGET_PRODUCT_MONDRIAN) || defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
HAP_CFG_DRV_DUTY_CFG_REG, ADT_DRV_DUTY_EN_BIT |
|
||||
DRV_DUTY_MASK, DRV_DUTY_62P5_PERCENT << DRV_DUTY_SHIFT);
|
||||
#else
|
||||
HAP_CFG_DRV_DUTY_CFG_REG, ADT_DRV_DUTY_EN_BIT, 0);
|
||||
#endif
|
||||
if (rc < 0)
|
||||
goto restore;
|
||||
|
||||
@ -5249,7 +5403,7 @@ static ssize_t lra_frequency_hz_show(struct class *c,
|
||||
if (chip->config.cl_t_lra_us == 0)
|
||||
return -EINVAL;
|
||||
|
||||
cl_f_lra = USEC_PER_SEC / chip->config.cl_t_lra_us;
|
||||
cl_f_lra = USEC_PER_SEC * 10 / chip->config.cl_t_lra_us;
|
||||
return scnprintf(buf, PAGE_SIZE, "%d Hz\n", cl_f_lra);
|
||||
}
|
||||
static CLASS_ATTR_RO(lra_frequency_hz);
|
||||
@ -5277,6 +5431,17 @@ static ssize_t lra_impedance_show(struct class *c,
|
||||
}
|
||||
static CLASS_ATTR_RO(lra_impedance);
|
||||
|
||||
#if defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
static ssize_t lra_calibration_check_show(struct class *c,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
struct haptics_chip *chip = container_of(c,
|
||||
struct haptics_chip, hap_class);
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", chip->config.lra_calibrated);
|
||||
}
|
||||
static CLASS_ATTR_RO(lra_calibration_check);
|
||||
#endif
|
||||
|
||||
static ssize_t primitive_duration_show(struct class *c,
|
||||
struct class_attribute *attr, char *buf)
|
||||
{
|
||||
@ -5319,6 +5484,9 @@ static struct attribute *hap_class_attrs[] = {
|
||||
&class_attr_lra_frequency_hz.attr,
|
||||
&class_attr_lra_impedance.attr,
|
||||
&class_attr_primitive_duration.attr,
|
||||
#if defined(CONFIG_TARGET_PRODUCT_YUDI)
|
||||
&class_attr_lra_calibration_check.attr,
|
||||
#endif
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(hap_class);
|
||||
@ -5338,6 +5506,19 @@ static enum hrtimer_restart haptics_disable_hbst_timer(struct hrtimer *timer)
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
|
||||
static enum hrtimer_restart haptics_disable_dph_timer(struct hrtimer *timer)
|
||||
{
|
||||
struct haptics_chip *chip = container_of(timer,
|
||||
struct haptics_chip, dph_off_timer);
|
||||
int rc;
|
||||
rc = haptics_enable_play(chip, false);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "disable haptics play failed, rc =%d\n", rc);
|
||||
else
|
||||
dev_dbg(chip->dev, "disable direct play haptics with timer\n");
|
||||
|
||||
return HRTIMER_NORESTART;
|
||||
}
|
||||
static bool is_swr_supported(struct haptics_chip *chip)
|
||||
{
|
||||
/* HAP520_MV does not support soundwire */
|
||||
@ -5439,6 +5620,8 @@ static int haptics_probe(struct platform_device *pdev)
|
||||
chip->fifo_empty_irq_en = false;
|
||||
hrtimer_init(&chip->hbst_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
chip->hbst_off_timer.function = haptics_disable_hbst_timer;
|
||||
hrtimer_init(&chip->dph_off_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
chip->dph_off_timer.function = haptics_disable_dph_timer;
|
||||
|
||||
atomic_set(&chip->play.fifo_status.is_busy, 0);
|
||||
atomic_set(&chip->play.fifo_status.written_done, 0);
|
||||
@ -5452,6 +5635,7 @@ static int haptics_probe(struct platform_device *pdev)
|
||||
if ((chip->effects_count != 0) || (chip->primitives_count != 0)) {
|
||||
input_set_capability(input_dev, EV_FF, FF_PERIODIC);
|
||||
input_set_capability(input_dev, EV_FF, FF_CUSTOM);
|
||||
input_set_capability(input_dev, EV_FF, FF_DAMPER);
|
||||
}
|
||||
|
||||
if (chip->effects_count + chip->primitives_count > MAX_EFFECT_COUNT)
|
||||
@ -5479,6 +5663,23 @@ static int haptics_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
dev_set_drvdata(chip->dev, chip);
|
||||
#if IS_ENABLED(CONFIG_MMHARDWARE_DETECTION)
|
||||
mutex_lock(&haptic_lock);
|
||||
dev_cnt++;
|
||||
mutex_unlock(&haptic_lock);
|
||||
|
||||
dev_err(chip->dev, "%s: dev_cnt %d \n", __func__, dev_cnt);
|
||||
switch (dev_cnt) {
|
||||
case 1:
|
||||
register_kobj_under_mmsysfs(MM_HW_HAPTIC_1, "haptic1");
|
||||
break;
|
||||
case 2:
|
||||
register_kobj_under_mmsysfs(MM_HW_HAPTIC_2, "haptic2");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
chip->hap_class.name = "qcom-haptics";
|
||||
chip->hap_class.class_groups = hap_class_groups;
|
||||
rc = class_register(&chip->hap_class);
|
||||
@ -5596,6 +5797,8 @@ static int haptics_suspend_config(struct device *dev)
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
hrtimer_cancel(&chip->dph_off_timer);
|
||||
|
||||
return haptics_module_enable(chip, false);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user