diff options
author | jeongsup.jeong <jeongsup.jeong@samsung.com> | 2020-04-24 16:02:43 +0900 |
---|---|---|
committer | Chanwoo Choi <cw00.choi@samsung.com> | 2020-04-24 16:02:43 +0900 |
commit | b402b6d9a914d3f6543542ce88eaeed0548da28a (patch) | |
tree | 305f1eea86cd20b1adc7b4c24b11f822f001ba6d | |
parent | 0dadfbba8f1691ba68610dd0d70a5d401cde3dbd (diff) | |
download | linux-4.9-exynos9110-b402b6d9a914d3f6543542ce88eaeed0548da28a.tar.gz linux-4.9-exynos9110-b402b6d9a914d3f6543542ce88eaeed0548da28a.tar.bz2 linux-4.9-exynos9110-b402b6d9a914d3f6543542ce88eaeed0548da28a.zip |
Motor: add handling freq, overdrive param on ff effect
TODO
Signed-off-by: jeongsup.jeong <jeongsup.jeong@samsung.com>
[cw00.choi: Apply commit 84d896106285 ("Motor: add handling freq,
overdrive param on ff effect") from slp-info.sec.samsung.net with fixing
the merge conflit and add commit-msg]
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
-rw-r--r-- | drivers/motor/ztm620_motor.c | 146 | ||||
-rw-r--r-- | include/linux/ztm620_motor.h | 12 |
2 files changed, 102 insertions, 56 deletions
diff --git a/drivers/motor/ztm620_motor.c b/drivers/motor/ztm620_motor.c index c85f6091db92..4f6e18d5c61a 100644 --- a/drivers/motor/ztm620_motor.c +++ b/drivers/motor/ztm620_motor.c @@ -105,31 +105,44 @@ static int ztm620_motor_set_bits(struct ztm620_motor_data *pMotorData, static int ztm620_motor_run(void) { int ret = -EINVAL; unsigned char val, strength; - int freq; + int freq_reg, freq_hz; struct ztm620_motor_data *pMotorData = g_Ztm620MotorData; struct ztm620_motor_platform_data *pMotorPdata; - if (pMotorData == NULL) { + if (!pMotorData) { pr_err("[VIB] %s ztm620_motor_data NULL error\n", __func__); goto out; } else pMotorPdata = &pMotorData->msPlatData; - if (pMotorData->level == 0) { + if (!(pMotorData->level)) { pr_err("[VIB] %s: level 0\n", __func__); goto out; } ret = ztm620_motor_reg_write(pMotorData, MOTOR_REG_SOFT_EN, SOFT_ENABLE); if (ret < 0) { - pr_err("[VIB] %s SOFT_EN write fail %d\n", - __func__, ret); + pr_err("[VIB] %s SOFT_EN write fail (%d)\n", __func__, ret); goto out; } + if (pMotorPdata->soft_en_delay) msleep(pMotorPdata->soft_en_delay); + if (pMotorData->overdrive && pMotorPdata->overdrive_num) { + val = (pMotorData->overdrive & MOTOR_REG_OVER_DRV_EN_MASK) + << OVER_DRV_SHIFT_EN; + val |= (pMotorPdata->overdrive_num & MOTOR_REG_OVER_DRV_CNT_MASK) + << OVER_DRV_SHIFT_CNT; + ret = ztm620_motor_reg_write(pMotorData, MOTOR_REG_OVER_DRV, val); + if (ret < 0) { + pr_err("[VIB] %s OVER_DRV 0x%02x write fail (%d)\n", + __func__, MOTOR_REG_OVER_DRV, ret); + goto out; + } + } + if (pMotorData->level >= MAX_LEVEL) strength = pMotorPdata->strength_strong; else @@ -137,17 +150,17 @@ static int ztm620_motor_run(void) { ret = ztm620_motor_reg_write(pMotorData, MOTOR_REG_STRENGTH, strength); if (ret < 0) { - pr_err("[VIB] %s STRENGTH write %d fail %d\n", - __func__, strength, ret); + pr_err("[VIB] %s STRENGTH 0x%02x write %d fail (%d)\n", + __func__, MOTOR_REG_STRENGTH, strength, ret); goto out; } - val = (pMotorPdata->meLoop << MODE_01_SHIFT_DRV_MODE ); - ret = ztm620_motor_set_bits(pMotorData, - MOTOR_REG_MODE_01, (1 << MODE_01_SHIFT_DRV_MODE), val); + ret = ztm620_motor_set_bits(pMotorData, MOTOR_REG_MODE_01, + 1 << MODE_01_SHIFT_DRV_MODE, + pMotorPdata->meLoop << MODE_01_SHIFT_DRV_MODE); if (ret < 0) { pr_err("[VIB] %s MODE_01 0x%02x write fail (%d)\n", - __func__, MOTOR_REG_MODE_01, ret); + __func__, MOTOR_REG_MODE_01, ret); goto out; } @@ -156,49 +169,60 @@ static int ztm620_motor_run(void) { Clock Frequency / (16 Clocks * Driving Frequency) DRV_FREQ_H[7:0] = DRV_FREQ[15:8] DRV_FREQ_L[7:0] = DRV_FREQ[7:0] */ - if (pMotorData->level >= MAX_LEVEL) - freq = MOTOR_CLK / (16 * pMotorPdata->freq_strong); - else - freq = MOTOR_CLK / (16 * pMotorPdata->freq_weak); + if (pMotorData->level >= MAX_LEVEL) { + if (pMotorPdata->freq_strong) + freq_hz = pMotorPdata->freq_strong; + else if (pMotorData->frequency) + freq_hz = pMotorData->frequency; + else + freq_hz = DEFAULT_MOTOR_FREQ; + } else { + if (pMotorPdata->freq_weak) + freq_hz = pMotorPdata->freq_weak; + else if (pMotorData->frequency) + freq_hz = pMotorData->frequency; + else + freq_hz = DEFAULT_MOTOR_FREQ; + } + freq_reg = (MOTOR_CLK * 10) / (freq_hz * 16); ret = ztm620_motor_reg_write(pMotorData, - MOTOR_REG_DRV_FREQ_H, freq / 256); + MOTOR_REG_DRV_FREQ_H, freq_reg / 256); if (ret < 0) { pr_err("[VIB] %s DRV_FREQ_H 0x%02x write fail (%d)\n", - __func__, MOTOR_REG_DRV_FREQ_H, ret); + __func__, MOTOR_REG_DRV_FREQ_H, ret); goto out; } ret = ztm620_motor_reg_write(pMotorData, - MOTOR_REG_DRV_FREQ_L, freq % 256); + MOTOR_REG_DRV_FREQ_L, freq_reg % 256); if (ret < 0) { pr_err("[VIB] %s DRV_FREQ_L 0x%02x write fail (%d)\n", - __func__, MOTOR_REG_DRV_FREQ_L, ret); + __func__, MOTOR_REG_DRV_FREQ_L, ret); goto out; } ret = ztm620_motor_reg_write(pMotorData, - MOTOR_REG_RESO_FREQ_H, freq / 256); + MOTOR_REG_RESO_FREQ_H, freq_reg / 256); if (ret < 0) { pr_err("[VIB] %s RESO_FREQ_H 0x%02x write fail (%d)\n", - __func__, MOTOR_REG_RESO_FREQ_H, ret); + __func__, MOTOR_REG_RESO_FREQ_H, ret); goto out; } ret = ztm620_motor_reg_write(pMotorData, - MOTOR_REG_RESO_FREQ_L, freq % 256); + MOTOR_REG_RESO_FREQ_L, freq_reg % 256); if (ret < 0) { pr_err("[VIB] %s RESO_FREQ_L 0x%02x write fail (%d)\n", - __func__, MOTOR_REG_RESO_FREQ_L, ret); + __func__, MOTOR_REG_RESO_FREQ_L, ret); goto out; } - val = pMotorPdata->adc_sampling_time; ret = ztm620_motor_reg_write(pMotorData, - MOTOR_REG_ADC_SAMPLING_TIME, val); + MOTOR_REG_ADC_SAMPLING_TIME, pMotorPdata->adc_sampling_time); if (ret < 0) { - pr_err("[VIB] %s ADC_SAMPLING_TIME write fail %d\n", - __func__, ret); + pr_err("[VIB] %s ADC_SAMPLING_TIME 0x%02x write fail (%d)\n", + __func__, MOTOR_REG_ADC_SAMPLING_TIME, ret); goto out; } @@ -216,8 +240,11 @@ static int ztm620_motor_run(void) { } pMotorData->running = true; } - pr_info("[VIB] %s Run: level:0x%x freq:0x%x str:0x%x\n", - __func__, pMotorData->level, freq, strength); + + pr_info("[VIB] Start: str 0x%x(0x%x) freq 0x%x(%d.%d) ovd %d\n", + strength, pMotorData->level, + freq_reg, freq_hz / 10, freq_hz % 10, + pMotorData->overdrive?pMotorPdata->overdrive_num:-1); out: return ret; @@ -269,7 +296,7 @@ static void vibrator_work_routine(struct work_struct *work) } pMotorData->running = false; pMotorData->last_motor_off = CURRENT_TIME; - pr_info("[VIB] %s Stop\n", __func__); + pr_info("[VIB] Stop\n"); } out: @@ -323,6 +350,10 @@ static int ztm620_motor_haptic_play(struct input_dev *input, void *data, { struct ztm620_motor_data *pMotorData = input_get_drvdata(input); __u16 level = effect->u.rumble.strong_magnitude; + /* [14:0] */ + pMotorData->frequency = effect->u.rumble.weak_magnitude & 0x7fff; + /* [15:15] */ + pMotorData->overdrive = !!(effect->u.rumble.weak_magnitude & 0x8000 >> 15); if (level) { pMotorData->level = level; @@ -615,8 +646,7 @@ static int of_ztm620_motor_dt(struct i2c_client* client, struct ztm620_motor_pla pdata->break_delay = DEFAULT_BRAKE_DELAY; dev_warn(&client->dev, "[VIB] %s: brake-delay-ms read fail(%d) :%d\n", __func__, err, pdata->break_delay); - } - else + } else pr_info("[VIB] brake-delay-ms = %d\n", pdata->break_delay); pdata->count_init_regs = of_property_count_u32_elems(client->dev.of_node, @@ -651,62 +681,70 @@ static int of_ztm620_motor_dt(struct i2c_client* client, struct ztm620_motor_pla "ztm620_motor,adc-sampling-time", &pdata->adc_sampling_time); if (err < 0) { pdata->adc_sampling_time = DEFAULT_ADC_SAMPLING_TIME; - dev_warn(&client->dev, "[VIB] %s: adc-sampling-time read fail(%d) :%d\n", + pr_warn("[VIB] %s: adc-sampling-time read fail(%d) :%d\n", __func__, err, pdata->adc_sampling_time); - } - else + } else pr_info("[VIB] adc-sampling-time = %d\n", pdata->adc_sampling_time); err = of_property_read_u32(client->dev.of_node, "ztm620_motor,soft-en-delay-ms", &pdata->soft_en_delay); if (err < 0) { pdata->soft_en_delay = DEFAULT_SOFT_EN_DELAY; - dev_warn(&client->dev, "[VIB] %s: soft-en-delay-ms read fail(%d) :%d\n", + pr_warn("[VIB] %s: soft-en-delay-ms read fail(%d) :%d\n", __func__, err, pdata->soft_en_delay); - } - else + } else pr_info("[VIB] soft-en-delay-ms = %d\n", pdata->soft_en_delay); err = of_property_read_u32(client->dev.of_node, "ztm620_motor,freq-strong", &pdata->freq_strong); - if (err < 0) { - pdata->freq_strong = DEFAULT_MOTOR_FREQ; - dev_warn(&client->dev, "[VIB] %s: freq-strong read fail(%d) :%d\n", + if (err < 0) + pr_warn("[VIB] %s: freq-strong read fail(%d) :%d\n", __func__, err, pdata->freq_strong); + else { + /* TBD: need to handle float value from dt */ + pdata->freq_strong *= 10; + pr_info("[VIB] freq-strong = %d.%d\n", + pdata->freq_strong / 10, pdata->freq_strong % 10); } - else - pr_info("[VIB] freq-strong = %d\n", pdata->freq_strong); err = of_property_read_u32(client->dev.of_node, "ztm620_motor,freq-weak", &pdata->freq_weak); - if (err < 0) { - pdata->freq_weak = DEFAULT_MOTOR_FREQ; - dev_warn(&client->dev, "[VIB] %s: freq-weak read fail(%d) :%d\n", + if (err < 0) + pr_warn("[VIB] %s: freq-weak read fail(%d) :%d\n", __func__, err, pdata->freq_weak); + else { + /* TBD: need to handle float value from dt */ + pdata->freq_weak *= 10; + pr_info("[VIB] freq-weak = %d.%d\n", + pdata->freq_weak / 10, pdata->freq_weak % 10); } - else - pr_info("[VIB] freq-weak = %d\n", pdata->freq_weak); err = of_property_read_u32(client->dev.of_node, "ztm620_motor,strength-strong", &pdata->strength_strong); if (err < 0) { pdata->strength_strong = DEFAULT_MOTOR_STRENGTH; - dev_warn(&client->dev, "[VIB] %s: strength-strong read fail(%d) :%d\n", + pr_warn("[VIB] %s: strength-strong read fail(%d) :%d\n", __func__, err, pdata->strength_strong); - } - else + } else pr_info("[VIB] strength-strong = %d\n", pdata->strength_strong); err = of_property_read_u32(client->dev.of_node, "ztm620_motor,strength-weak", &pdata->strength_weak); if (err < 0) { pdata->strength_weak = DEFAULT_MOTOR_STRENGTH; - dev_warn(&client->dev, "[VIB] %s: strength-weak read fail(%d) :%d\n", + pr_warn("[VIB] %s: strength-weak read fail(%d) :%d\n", __func__, err, pdata->strength_weak); - } - else + } else pr_info("[VIB] strength-weak = %d\n", pdata->strength_weak); + err = of_property_read_u32(client->dev.of_node, + "ztm620_motor,overdrive-num", &pdata->overdrive_num); + if (err < 0) { + pr_warn("[VIB] %s: overdrive-num read fail(%d) :%d\n", + __func__, err, pdata->overdrive_num); + } else + pr_info("[VIB] overdrive-num = %d\n", pdata->overdrive_num); + dev_info(&client->dev, "[VIB] %s: dt parsing done\n", __func__); return ret; diff --git a/include/linux/ztm620_motor.h b/include/linux/ztm620_motor.h index 9efa64d1c31d..fa33b01a9196 100644 --- a/include/linux/ztm620_motor.h +++ b/include/linux/ztm620_motor.h @@ -81,6 +81,11 @@ #define MODE_13_SHIFT_PWR_CAL_EN 0x03 #define MODE_13_SHIFT_ERM_NLRA 0x00 +#define MOTOR_REG_OVER_DRV_EN_MASK 0x01 +#define MOTOR_REG_OVER_DRV_CNT_MASK 0x7F +#define OVER_DRV_SHIFT_EN 7 +#define OVER_DRV_SHIFT_CNT 0 + #define MAX_LEVEL 0xffff #define DEFAULT_MOTOR_FREQ 205 #define DEFAULT_MOTOR_STRENGTH 0x56 @@ -121,10 +126,11 @@ struct ztm620_motor_platform_data { const char *regulator_name; int adc_sampling_time; int soft_en_delay; - int freq_strong; - int freq_weak; + int freq_strong; /* in 0.1 hz*/ + int freq_weak; /* in 0.1 hz*/ int strength_strong; int strength_weak; + int overdrive_num; }; struct ztm620_motor_data { @@ -142,6 +148,8 @@ struct ztm620_motor_data { /* using FF_input_device */ __u16 level; + __u16 frequency; /* in 0.1 hz*/ + __u16 overdrive; bool running; struct regulator *regulator; int gpio_en; |