forked from nuttx/nuttx-update
drivers/input: support RTP file simulation in RAMLOOP mode
For resource-constrained devices, simulate RTP playback effects using preset custom RAMLOOP combinations instead of using RTP files to play custom vibration effects. Signed-off-by: fangpeina <fangpeina@xiaomi.com>
This commit is contained in:
parent
ea20ae588a
commit
a719db1b58
4 changed files with 136 additions and 31 deletions
|
@ -46,13 +46,22 @@ config FF_AW86225
|
|||
---help---
|
||||
Enable aw86225 haptic controller chip.
|
||||
|
||||
config FF_RTP_FILE_PATH
|
||||
if FF_AW86225
|
||||
|
||||
config AW86225_RTP_FILE_SUPPORT
|
||||
bool "Enable aw86225 rtp file support"
|
||||
default n
|
||||
---help---
|
||||
Enable support for aw86225 rtp file.
|
||||
|
||||
config AW86225_RTP_FILE_PATH
|
||||
string "Path of aw86225 rtp file"
|
||||
default "/etc"
|
||||
depends on FF_AW86225
|
||||
---help---
|
||||
File path depend on the opening of FF_AW86225.
|
||||
|
||||
endif # FF_AW86225
|
||||
|
||||
endif # INPUT_FF
|
||||
|
||||
config INPUT_MOUSE
|
||||
|
|
|
@ -64,6 +64,7 @@ static void aw86225_ram_work_routine(FAR void *arg);
|
|||
****************************************************************************/
|
||||
|
||||
static FAR const char *g_aw86225_ram_name = "aw86225_haptic.bin";
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
static FAR const char g_aw86225_rtp_name[][AW86225_RTP_NAME_MAX] =
|
||||
{
|
||||
{"door_open_RTP.bin"},
|
||||
|
@ -240,6 +241,7 @@ static FAR const char g_aw86225_rtp_name[][AW86225_RTP_NAME_MAX] =
|
|||
{"signal_transition_rtp.bin"},
|
||||
{"haptics_video_rtp.bin"},
|
||||
};
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -334,6 +336,7 @@ static int aw86225_i2c_read(FAR struct aw86225 *aw86225, uint8_t reg_addr,
|
|||
return aw86225_i2c_read_cnt(aw86225, reg_addr, reg_data, 1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
static int aw86225_i2c_writes(FAR struct aw86225 *aw86225,
|
||||
unsigned char reg_addr,
|
||||
FAR unsigned char *buf,
|
||||
|
@ -341,6 +344,7 @@ static int aw86225_i2c_writes(FAR struct aw86225 *aw86225,
|
|||
{
|
||||
return aw86225_i2c_write_cnt(aw86225, reg_addr, buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aw86225_i2c_write_bits(FAR struct aw86225 *aw86225,
|
||||
unsigned char reg_addr, unsigned int mask,
|
||||
|
@ -381,8 +385,8 @@ static int aw86225_request_firmware(FAR struct aw86225_firmware *fw,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
snprintf(file_path, PATH_MAX, "%s/%s", CONFIG_FF_RTP_FILE_PATH,
|
||||
filename);
|
||||
snprintf(file_path, PATH_MAX, "%s/%s",
|
||||
CONFIG_AW86225_RTP_FILE_PATH, filename);
|
||||
ret = file_open(&file, file_path, O_RDONLY);
|
||||
lib_put_pathbuffer(file_path);
|
||||
if (ret < 0)
|
||||
|
@ -418,32 +422,6 @@ static void aw86225_release_firmware(FAR struct aw86225_firmware *fw)
|
|||
fw->size = 0;
|
||||
}
|
||||
|
||||
static uint8_t aw86225_haptic_rtp_get_fifo_afs(FAR struct aw86225 *aw86225)
|
||||
{
|
||||
uint8_t reg_val = 0;
|
||||
|
||||
aw86225_i2c_read(aw86225, AW86225_REG_SYSST, ®_val);
|
||||
reg_val &= AW86225_BIT_SYSST_FF_AFS;
|
||||
return reg_val >> 3;
|
||||
}
|
||||
|
||||
static void aw86225_haptic_set_rtp_aei(FAR struct aw86225 *aw86225,
|
||||
bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
aw86225_i2c_write_bits(aw86225, AW86225_REG_SYSINTM,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_MASK,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
aw86225_i2c_write_bits(aw86225, AW86225_REG_SYSINTM,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_MASK,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
static void aw86225_haptic_upload_lra(FAR struct aw86225 *aw86225,
|
||||
unsigned int flag)
|
||||
{
|
||||
|
@ -758,6 +736,14 @@ static int aw86225_haptic_set_wav_loop(FAR struct aw86225 *aw86225,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int aw86225_haptic_set_main_loop(FAR struct aw86225 *aw86225,
|
||||
uint8_t loop)
|
||||
{
|
||||
aw86225_i2c_write_bits(aw86225, AW86225_REG_WAVCFG13,
|
||||
AW86225_BIT_WAVCFG13_MAINLOOP_MASK, loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aw86225_haptic_read_lra_f0(FAR struct aw86225 *aw86225)
|
||||
{
|
||||
unsigned char reg_val = 0;
|
||||
|
@ -934,6 +920,33 @@ static int aw86225_haptic_cont_get_f0(FAR struct aw86225 *aw86225)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
static uint8_t aw86225_haptic_rtp_get_fifo_afs(FAR struct aw86225 *aw86225)
|
||||
{
|
||||
uint8_t reg_val = 0;
|
||||
|
||||
aw86225_i2c_read(aw86225, AW86225_REG_SYSST, ®_val);
|
||||
reg_val &= AW86225_BIT_SYSST_FF_AFS;
|
||||
return reg_val >> 3;
|
||||
}
|
||||
|
||||
static void aw86225_haptic_set_rtp_aei(FAR struct aw86225 *aw86225,
|
||||
bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
aw86225_i2c_write_bits(aw86225, AW86225_REG_SYSINTM,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_MASK,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_ON);
|
||||
}
|
||||
else
|
||||
{
|
||||
aw86225_i2c_write_bits(aw86225, AW86225_REG_SYSINTM,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_MASK,
|
||||
AW86225_BIT_SYSINTM_FF_AEM_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
static int aw86225_haptic_rtp_init(FAR struct aw86225 *aw86225)
|
||||
{
|
||||
unsigned int buf_len = 0;
|
||||
|
@ -1009,6 +1022,7 @@ static int aw86225_haptic_rtp_init(FAR struct aw86225 *aw86225)
|
|||
iinfo("%s exit\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aw86225_haptic_set_repeat_wav_seq(FAR struct aw86225 *aw86225,
|
||||
unsigned char seq)
|
||||
|
@ -1080,6 +1094,7 @@ aw86225_haptic_effect_strength(FAR struct aw86225 *aw86225)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
static void aw86225_rtp_work_routine(FAR void *arg)
|
||||
{
|
||||
FAR struct aw86225 *aw86225 = arg;
|
||||
|
@ -1243,6 +1258,7 @@ static void aw86225_rtp_work_routine(FAR void *arg)
|
|||
nxmutex_unlock(&aw86225->lock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aw86225_container_update(FAR struct aw86225 *aw86225,
|
||||
FAR struct aw86225_container *aw86225_cont)
|
||||
|
@ -1677,7 +1693,16 @@ static int aw86225_haptic_start(FAR struct aw86225 *aw86225)
|
|||
static int aw86225_haptic_play_effect_seq(FAR struct aw86225 *aw86225,
|
||||
unsigned char flag)
|
||||
{
|
||||
if (aw86225->effect_id > aw86225->config->effect_id_boundary)
|
||||
if ((aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RAM_MODE ||
|
||||
aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RAM_LOOP_MODE) &&
|
||||
aw86225->effect_id > aw86225->config->effect_id_boundary)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RTP_MODE &&
|
||||
(aw86225->effect_id > aw86225->config->effect_max ||
|
||||
aw86225->effect_id < aw86225->config->effect_id_boundary))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -1725,6 +1750,33 @@ static int aw86225_haptic_play_effect_seq(FAR struct aw86225 *aw86225,
|
|||
aw86225_haptic_set_gain(aw86225, aw86225->level);
|
||||
aw86225_haptic_play_repeat_seq(aw86225, true);
|
||||
}
|
||||
|
||||
if (aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RTP_MODE)
|
||||
{
|
||||
int budry = aw86225->effect_id -
|
||||
aw86225->config->effect_id_boundary;
|
||||
iinfo("budry = %d\n", budry);
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
{
|
||||
iinfo("wav_seq[%d] = %d\n", i,
|
||||
aw86225->pattern[budry].patternid[i]);
|
||||
iinfo("wav_loop[%d] = %d\n", i,
|
||||
aw86225->pattern[budry].waveloop[i]);
|
||||
aw86225_haptic_set_wav_seq(aw86225, i,
|
||||
aw86225->pattern[budry].patternid[i] + 1);
|
||||
aw86225_haptic_set_wav_loop(aw86225, i,
|
||||
aw86225->pattern[budry].waveloop[i]);
|
||||
}
|
||||
|
||||
iinfo("main_loop = %d\n", aw86225->pattern[budry].mainloop);
|
||||
aw86225_haptic_set_main_loop(aw86225,
|
||||
aw86225->pattern[budry].mainloop);
|
||||
aw86225_haptic_set_pwm(aw86225, AW86225_PWM_12K);
|
||||
aw86225_haptic_play_mode(aw86225, AW86225_HAPTIC_RAM_LOOP_MODE);
|
||||
aw86225_haptic_effect_strength(aw86225);
|
||||
aw86225_haptic_set_gain(aw86225, aw86225->level);
|
||||
aw86225_haptic_start(aw86225);
|
||||
}
|
||||
}
|
||||
|
||||
iinfo("%s: exit\n", __func__);
|
||||
|
@ -1969,6 +2021,23 @@ static void aw86225_long_vibrate_work_routine(FAR void *arg)
|
|||
wd_start(&aw86225->timer, MSEC2TICK(aw86225->duration),
|
||||
aw86225_vibrator_timer_func, (wdparm_t)aw86225);
|
||||
}
|
||||
else if (aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RTP_MODE)
|
||||
{
|
||||
int budry = aw86225->effect_id -
|
||||
aw86225->config->effect_id_boundary;
|
||||
iinfo("activate_mode(AW86225_HAPTIC_ACTIVATE_RTP_MODE) = %d\n",
|
||||
aw86225->activate_mode);
|
||||
aw86225_haptic_ram_vbat_compensate(aw86225, true);
|
||||
aw86225_haptic_play_effect_seq(aw86225, true);
|
||||
|
||||
/* run ms timer */
|
||||
|
||||
iinfo("pattern duration = %d", aw86225->pattern[budry].duration);
|
||||
wd_start(&aw86225->timer,
|
||||
MSEC2TICK(aw86225->pattern[budry].duration),
|
||||
aw86225_vibrator_timer_func, (wdparm_t)aw86225);
|
||||
aw86225->wk_lock_flag = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ierr("%s: activate_mode error\n", __func__);
|
||||
|
@ -2150,11 +2219,18 @@ static int aw86225_haptics_upload_effect(FAR struct ff_lowerhalf_s *lower,
|
|||
__func__, aw86225->effect_id, aw86225->activate_mode);
|
||||
int budry = aw86225->effect_id -
|
||||
aw86225->config->effect_id_boundary;
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
data[1] = aw86225->config->rtp_time[budry] / 1000;
|
||||
data[2] = aw86225->config->rtp_time[budry] % 1000;
|
||||
iinfo("%s: data[1] = %d data[2] = %d, rtp_time %d\n", __func__,
|
||||
data[1], data[2],
|
||||
aw86225->config->rtp_time[budry]);
|
||||
#else
|
||||
data[1] = 0;
|
||||
data[2] = aw86225->pattern[budry].duration;
|
||||
iinfo("data[2] = %d, waveloop time = %d\n", data[2],
|
||||
aw86225->pattern[budry].duration);
|
||||
#endif
|
||||
}
|
||||
|
||||
memcpy(effect->u.periodic.custom_data, data, sizeof(int16_t) * 3);
|
||||
|
@ -2207,12 +2283,17 @@ static int aw86225_haptics_playback(struct ff_lowerhalf_s *lower,
|
|||
aw86225->activate_mode == AW86225_HAPTIC_ACTIVATE_RTP_MODE)
|
||||
{
|
||||
iinfo("%s: enter rtp_mode\n", __func__);
|
||||
#ifdef CONFIG_AW86225_RTP_FILE_SUPPORT
|
||||
work_queue(HPWORK, &aw86225->rtp_work,
|
||||
aw86225_rtp_work_routine, aw86225, 0);
|
||||
if (val == 0)
|
||||
{
|
||||
atomic_store(&aw86225->exit_in_rtp_loop, 1);
|
||||
}
|
||||
#else
|
||||
work_queue(HPWORK, &aw86225->long_vibrate_work,
|
||||
aw86225_long_vibrate_work_routine, aw86225, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -2329,6 +2410,7 @@ int aw86225_initialize(FAR struct i2c_master_s *master,
|
|||
aw86225->effects_count = config->effects_count;
|
||||
aw86225->is_used_irq = config->is_used_irq;
|
||||
aw86225->predefined = config->predefined;
|
||||
aw86225->pattern = config->pattern;
|
||||
aw86225->config = config->config;
|
||||
aw86225->irq = config->irq;
|
||||
aw86225->i2c = master;
|
||||
|
|
|
@ -227,6 +227,7 @@ struct aw86225
|
|||
struct work_s ram_work;
|
||||
struct aw86225_hap_config hap_config;
|
||||
struct aw86225_hap_play_info play;
|
||||
FAR struct aw86225_pattern_s *pattern;
|
||||
FAR struct aw86225_hap_effect *predefined;
|
||||
struct aw86225_hap_effect constant;
|
||||
FAR struct aw86225_config *config;
|
||||
|
|
|
@ -43,6 +43,18 @@
|
|||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* struct aw86225_pattern_s - effect pattern configuration parameters
|
||||
*/
|
||||
|
||||
struct aw86225_pattern_s
|
||||
{
|
||||
uint8_t patternid[8];
|
||||
uint8_t waveloop[8];
|
||||
uint8_t mainloop;
|
||||
float strength;
|
||||
uint32_t duration; /* in millisecond */
|
||||
};
|
||||
|
||||
/* struct aw86225_hap_effect - effect configuration parameters
|
||||
*/
|
||||
|
||||
|
@ -129,6 +141,7 @@ struct aw86225_board_config
|
|||
uint8_t addr; /* I2C address */
|
||||
int freq; /* I2C frequency */
|
||||
FAR struct aw86225_hap_effect *predefined;
|
||||
FAR struct aw86225_pattern_s *pattern;
|
||||
|
||||
/* Motor driver registration path */
|
||||
|
||||
|
|
Loading…
Reference in a new issue