Lines Matching +full:haptic +full:- +full:driver

1 // SPDX-License-Identifier: GPL-2.0+
3 * DA7280 Haptic device driver
288 /* The patterns should be updated when haptic is not working */ in da7280_haptic_mem_update()
289 error = regmap_read(haptics->regmap, DA7280_IRQ_STATUS1, &val); in da7280_haptic_mem_update()
293 dev_warn(haptics->dev, in da7280_haptic_mem_update()
294 "Warning! Please check HAPTIC status.\n"); in da7280_haptic_mem_update()
295 return -EBUSY; in da7280_haptic_mem_update()
300 error = regmap_read(haptics->regmap, DA7280_MEM_CTL2, &val); in da7280_haptic_mem_update()
304 dev_warn(haptics->dev, "Please unlock the bit first\n"); in da7280_haptic_mem_update()
305 return -EACCES; in da7280_haptic_mem_update()
309 error = regmap_update_bits(haptics->regmap, in da7280_haptic_mem_update()
316 error = regmap_read(haptics->regmap, DA7280_MEM_CTL1, &val); in da7280_haptic_mem_update()
320 return regmap_bulk_write(haptics->regmap, val, haptics->snp_mem, in da7280_haptic_mem_update()
321 DA7280_SNP_MEM_MAX - val + 1); in da7280_haptic_mem_update()
330 if (!haptics->gain && enabled) { in da7280_haptic_set_pwm()
331 dev_err(haptics->dev, "Unable to enable pwm with 0 gain\n"); in da7280_haptic_set_pwm()
332 return -EINVAL; in da7280_haptic_set_pwm()
335 pwm_get_state(haptics->pwm_dev, &state); in da7280_haptic_set_pwm()
338 period_mag_multi = (u64)state.period * haptics->gain; in da7280_haptic_set_pwm()
346 if (!haptics->acc_en) { in da7280_haptic_set_pwm()
354 error = pwm_apply_might_sleep(haptics->pwm_dev, &state); in da7280_haptic_set_pwm()
356 dev_err(haptics->dev, "Failed to apply pwm state: %d\n", error); in da7280_haptic_set_pwm()
365 if (haptics->active) in da7280_haptic_activate()
368 switch (haptics->op_mode) { in da7280_haptic_activate()
371 if (haptics->acc_en && haptics->level > 0x7F) in da7280_haptic_activate()
372 haptics->level = 0x7F; in da7280_haptic_activate()
373 else if (haptics->level > 0xFF) in da7280_haptic_activate()
374 haptics->level = 0xFF; in da7280_haptic_activate()
377 error = regmap_write(haptics->regmap, DA7280_TOP_CTL2, in da7280_haptic_activate()
378 haptics->level); in da7280_haptic_activate()
380 dev_err(haptics->dev, in da7280_haptic_activate()
382 haptics->level, error); in da7280_haptic_activate()
408 dev_err(haptics->dev, "Invalid op mode %d\n", haptics->op_mode); in da7280_haptic_activate()
412 error = regmap_update_bits(haptics->regmap, in da7280_haptic_activate()
415 haptics->op_mode); in da7280_haptic_activate()
417 dev_err(haptics->dev, in da7280_haptic_activate()
422 if (haptics->op_mode == DA7280_PWM_MODE || in da7280_haptic_activate()
423 haptics->op_mode == DA7280_RTWM_MODE) { in da7280_haptic_activate()
424 error = regmap_update_bits(haptics->regmap, in da7280_haptic_activate()
429 dev_err(haptics->dev, in da7280_haptic_activate()
435 haptics->active = true; in da7280_haptic_activate()
442 if (!haptics->active) in da7280_haptic_deactivate()
446 error = regmap_update_bits(haptics->regmap, in da7280_haptic_deactivate()
450 dev_err(haptics->dev, in da7280_haptic_deactivate()
455 switch (haptics->op_mode) { in da7280_haptic_deactivate()
457 error = regmap_write(haptics->regmap, in da7280_haptic_deactivate()
460 dev_err(haptics->dev, in da7280_haptic_deactivate()
473 error = regmap_update_bits(haptics->regmap, in da7280_haptic_deactivate()
477 dev_err(haptics->dev, in da7280_haptic_deactivate()
485 dev_err(haptics->dev, "Invalid op mode %d\n", haptics->op_mode); in da7280_haptic_deactivate()
489 haptics->active = false; in da7280_haptic_deactivate()
496 int val = haptics->val; in da7280_haptic_work()
514 /* The effect should be uploaded when haptic is not working */ in da7280_haptics_upload_effect()
515 if (haptics->active) in da7280_haptics_upload_effect()
516 return -EBUSY; in da7280_haptics_upload_effect()
518 switch (effect->type) { in da7280_haptics_upload_effect()
521 haptics->op_mode = haptics->const_op_mode; in da7280_haptics_upload_effect()
522 if (haptics->op_mode == DA7280_DRO_MODE) { in da7280_haptics_upload_effect()
523 tmp = effect->u.constant.level * 254; in da7280_haptics_upload_effect()
524 haptics->level = tmp / 0x7FFF; in da7280_haptics_upload_effect()
528 haptics->gain = effect->u.constant.level <= 0 ? in da7280_haptics_upload_effect()
529 0 : effect->u.constant.level; in da7280_haptics_upload_effect()
534 if (effect->u.periodic.waveform != FF_CUSTOM) { in da7280_haptics_upload_effect()
535 dev_err(haptics->dev, in da7280_haptics_upload_effect()
537 return -EINVAL; in da7280_haptics_upload_effect()
547 if (effect->u.periodic.custom_len == DA7280_CUSTOM_DATA_LEN) in da7280_haptics_upload_effect()
550 if (effect->u.periodic.custom_len == DA7280_CUSTOM_GP_DATA_LEN) in da7280_haptics_upload_effect()
553 if (effect->u.periodic.custom_len < DA7280_CUSTOM_DATA_LEN || in da7280_haptics_upload_effect()
554 effect->u.periodic.custom_len > DA7280_SNP_MEM_SIZE) { in da7280_haptics_upload_effect()
555 dev_err(haptics->dev, "Invalid waveform data size\n"); in da7280_haptics_upload_effect()
556 return -EINVAL; in da7280_haptics_upload_effect()
559 if (copy_from_user(data, effect->u.periodic.custom_data, in da7280_haptics_upload_effect()
561 effect->u.periodic.custom_len)) in da7280_haptics_upload_effect()
562 return -EFAULT; in da7280_haptics_upload_effect()
564 memset(haptics->snp_mem, 0, DA7280_SNP_MEM_SIZE); in da7280_haptics_upload_effect()
566 for (i = 0; i < effect->u.periodic.custom_len; i++) { in da7280_haptics_upload_effect()
568 dev_err(haptics->dev, in da7280_haptics_upload_effect()
571 return -EINVAL; in da7280_haptics_upload_effect()
573 haptics->snp_mem[i] = (u8)data[i]; in da7280_haptics_upload_effect()
578 dev_err(haptics->dev, in da7280_haptics_upload_effect()
585 if (copy_from_user(data, effect->u.periodic.custom_data, in da7280_haptics_upload_effect()
587 return -EFAULT; in da7280_haptics_upload_effect()
593 dev_err(haptics->dev, in da7280_haptics_upload_effect()
597 return -EINVAL; in da7280_haptics_upload_effect()
600 haptics->ps_seq_id = data[DA7280_CUSTOM_SEQ_ID_IDX] & 0x0f; in da7280_haptics_upload_effect()
601 haptics->ps_seq_loop = data[DA7280_CUSTOM_SEQ_LOOP_IDX] & 0x0f; in da7280_haptics_upload_effect()
602 haptics->op_mode = haptics->periodic_op_mode; in da7280_haptics_upload_effect()
604 val = FIELD_PREP(DA7280_PS_SEQ_ID_MASK, haptics->ps_seq_id) | in da7280_haptics_upload_effect()
606 haptics->ps_seq_loop); in da7280_haptics_upload_effect()
607 error = regmap_write(haptics->regmap, DA7280_SEQ_CTL2, val); in da7280_haptics_upload_effect()
609 dev_err(haptics->dev, in da7280_haptics_upload_effect()
616 if (copy_from_user(data, effect->u.periodic.custom_data, in da7280_haptics_upload_effect()
618 return -EFAULT; in da7280_haptics_upload_effect()
624 dev_err(haptics->dev, in da7280_haptics_upload_effect()
628 return -EINVAL; in da7280_haptics_upload_effect()
632 haptics->gpi_ctl[num].seq_id = in da7280_haptics_upload_effect()
634 haptics->op_mode = haptics->periodic_op_mode; in da7280_haptics_upload_effect()
637 haptics->gpi_ctl[num].seq_id); in da7280_haptics_upload_effect()
638 error = regmap_update_bits(haptics->regmap, in da7280_haptics_upload_effect()
643 dev_err(haptics->dev, in da7280_haptics_upload_effect()
650 dev_err(haptics->dev, "Unsupported effect type: %d\n", in da7280_haptics_upload_effect()
651 effect->type); in da7280_haptics_upload_effect()
652 return -EINVAL; in da7280_haptics_upload_effect()
663 if (!haptics->op_mode) { in da7280_haptics_playback()
664 dev_warn(haptics->dev, "No effects have been uploaded\n"); in da7280_haptics_playback()
665 return -EINVAL; in da7280_haptics_playback()
668 if (likely(!haptics->suspended)) { in da7280_haptics_playback()
669 haptics->val = val; in da7280_haptics_playback()
670 schedule_work(&haptics->work); in da7280_haptics_playback()
680 error = regmap_update_bits(haptics->regmap, in da7280_haptic_start()
685 dev_err(haptics->dev, "Unable to enable device: %d\n", error); in da7280_haptic_start()
696 cancel_work_sync(&haptics->work); in da7280_haptic_stop()
701 error = regmap_update_bits(haptics->regmap, DA7280_TOP_CTL1, in da7280_haptic_stop()
704 dev_err(haptics->dev, "Failed to disable device: %d\n", error); in da7280_haptic_stop()
726 } else if (!strcmp(str, "ERM-bar")) { in da7280_haptic_of_mode_str()
728 } else if (!strcmp(str, "ERM-coin")) { in da7280_haptic_of_mode_str()
731 dev_warn(dev, "Invalid string - set to LRA\n"); in da7280_haptic_of_mode_str()
739 if (!strcmp(str, "Single-pattern")) { in da7280_haptic_of_gpi_mode_str()
741 } else if (!strcmp(str, "Multi-pattern")) { in da7280_haptic_of_gpi_mode_str()
744 dev_warn(dev, "Invalid string - set to Single-pattern\n"); in da7280_haptic_of_gpi_mode_str()
752 if (!strcmp(str, "Rising-edge")) { in da7280_haptic_of_gpi_pol_str()
754 } else if (!strcmp(str, "Falling-edge")) { in da7280_haptic_of_gpi_pol_str()
756 } else if (!strcmp(str, "Both-edge")) { in da7280_haptic_of_gpi_pol_str()
759 dev_warn(dev, "Invalid string - set to Rising-edge\n"); in da7280_haptic_of_gpi_pol_str()
775 char gpi_str1[] = "dlg,gpi0-seq-id"; in da7280_parse_properties()
776 char gpi_str2[] = "dlg,gpi0-mode"; in da7280_parse_properties()
777 char gpi_str3[] = "dlg,gpi0-polarity"; in da7280_parse_properties()
785 haptics->dev_type = DA7280_DEV_MAX; in da7280_parse_properties()
786 error = device_property_read_string(dev, "dlg,actuator-type", &str); in da7280_parse_properties()
788 haptics->dev_type = da7280_haptic_of_mode_str(dev, str); in da7280_parse_properties()
790 haptics->const_op_mode = DA7280_DRO_MODE; in da7280_parse_properties()
791 error = device_property_read_u32(dev, "dlg,const-op-mode", &val); in da7280_parse_properties()
793 haptics->const_op_mode = DA7280_PWM_MODE; in da7280_parse_properties()
795 haptics->periodic_op_mode = DA7280_RTWM_MODE; in da7280_parse_properties()
796 error = device_property_read_u32(dev, "dlg,periodic-op-mode", &val); in da7280_parse_properties()
798 haptics->periodic_op_mode = DA7280_ETWM_MODE; in da7280_parse_properties()
800 haptics->nommax = DA7280_SKIP_INIT; in da7280_parse_properties()
801 error = device_property_read_u32(dev, "dlg,nom-microvolt", &val); in da7280_parse_properties()
803 haptics->nommax = da7280_haptic_of_volt_rating_set(val); in da7280_parse_properties()
805 haptics->absmax = DA7280_SKIP_INIT; in da7280_parse_properties()
806 error = device_property_read_u32(dev, "dlg,abs-max-microvolt", &val); in da7280_parse_properties()
808 haptics->absmax = da7280_haptic_of_volt_rating_set(val); in da7280_parse_properties()
810 haptics->imax = DA7280_IMAX_DEFAULT; in da7280_parse_properties()
811 error = device_property_read_u32(dev, "dlg,imax-microamp", &val); in da7280_parse_properties()
813 haptics->imax = (val - 28600) / DA7280_IMAX_STEP + 1; in da7280_parse_properties()
815 haptics->impd = DA7280_IMPD_DEFAULT; in da7280_parse_properties()
816 error = device_property_read_u32(dev, "dlg,impd-micro-ohms", &val); in da7280_parse_properties()
818 haptics->impd = val; in da7280_parse_properties()
820 haptics->resonant_freq_h = DA7280_SKIP_INIT; in da7280_parse_properties()
821 haptics->resonant_freq_l = DA7280_SKIP_INIT; in da7280_parse_properties()
822 error = device_property_read_u32(dev, "dlg,resonant-freq-hz", &val); in da7280_parse_properties()
826 haptics->resonant_freq_h = in da7280_parse_properties()
828 haptics->resonant_freq_l = in da7280_parse_properties()
831 haptics->resonant_freq_h = DA7280_RESONT_FREQH_DFT; in da7280_parse_properties()
832 haptics->resonant_freq_l = DA7280_RESONT_FREQL_DFT; in da7280_parse_properties()
837 haptics->ps_seq_id = 0; in da7280_parse_properties()
838 error = device_property_read_u32(dev, "dlg,ps-seq-id", &val); in da7280_parse_properties()
840 haptics->ps_seq_id = val; in da7280_parse_properties()
842 haptics->ps_seq_loop = 0; in da7280_parse_properties()
843 error = device_property_read_u32(dev, "dlg,ps-seq-loop", &val); in da7280_parse_properties()
845 haptics->ps_seq_loop = val; in da7280_parse_properties()
850 haptics->gpi_ctl[i].seq_id = DA7280_GPI_SEQ_ID_DFT + i; in da7280_parse_properties()
853 haptics->gpi_ctl[i].seq_id = val; in da7280_parse_properties()
856 haptics->gpi_ctl[i].mode = 0; in da7280_parse_properties()
859 haptics->gpi_ctl[i].mode = in da7280_parse_properties()
863 haptics->gpi_ctl[i].polarity = 0; in da7280_parse_properties()
866 haptics->gpi_ctl[i].polarity = in da7280_parse_properties()
870 haptics->bemf_sense_en = in da7280_parse_properties()
871 device_property_read_bool(dev, "dlg,bemf-sens-enable"); in da7280_parse_properties()
872 haptics->freq_track_en = in da7280_parse_properties()
873 device_property_read_bool(dev, "dlg,freq-track-enable"); in da7280_parse_properties()
874 haptics->acc_en = in da7280_parse_properties()
875 device_property_read_bool(dev, "dlg,acc-enable"); in da7280_parse_properties()
876 haptics->rapid_stop_en = in da7280_parse_properties()
877 device_property_read_bool(dev, "dlg,rapid-stop-enable"); in da7280_parse_properties()
878 haptics->amp_pid_en = in da7280_parse_properties()
879 device_property_read_bool(dev, "dlg,amp-pid-enable"); in da7280_parse_properties()
881 haptics->mem_update = false; in da7280_parse_properties()
882 error = device_property_read_u32_array(dev, "dlg,mem-array", in da7280_parse_properties()
885 haptics->mem_update = true; in da7280_parse_properties()
886 memset(haptics->snp_mem, 0, DA7280_SNP_MEM_SIZE); in da7280_parse_properties()
889 haptics->snp_mem[i] = (u8)mem[i]; in da7280_parse_properties()
891 dev_err(haptics->dev, in da7280_parse_properties()
892 "Invalid data in mem-array at %d: %x\n", in da7280_parse_properties()
894 haptics->mem_update = false; in da7280_parse_properties()
904 struct device *dev = haptics->dev; in da7280_irq_handler()
909 error = regmap_bulk_read(haptics->regmap, DA7280_IRQ_EVENT1, in da7280_irq_handler()
917 error = regmap_write(haptics->regmap, DA7280_IRQ_EVENT1, events[0]); in da7280_irq_handler()
925 * Stop first if haptic is active, otherwise, the fault may in da7280_irq_handler()
928 error = regmap_update_bits(haptics->regmap, DA7280_TOP_CTL1, in da7280_irq_handler()
936 haptics->active = false; in da7280_irq_handler()
941 dev_warn(dev, "Please reduce the driver level\n"); in da7280_irq_handler()
945 dev_warn(dev, "Over-temperature warning\n"); in da7280_irq_handler()
972 if (haptics->dev_type == DA7280_DEV_MAX) { in da7280_init()
973 error = regmap_read(haptics->regmap, DA7280_TOP_CFG1, &val); in da7280_init()
977 haptics->dev_type = val & DA7280_ACTUATOR_TYPE_MASK ? in da7280_init()
982 if (haptics->dev_type == DA7280_LRA && in da7280_init()
983 haptics->resonant_freq_l != DA7280_SKIP_INIT) { in da7280_init()
984 error = regmap_write(haptics->regmap, DA7280_FRQ_LRA_PER_H, in da7280_init()
985 haptics->resonant_freq_h); in da7280_init()
988 error = regmap_write(haptics->regmap, DA7280_FRQ_LRA_PER_L, in da7280_init()
989 haptics->resonant_freq_l); in da7280_init()
992 } else if (haptics->dev_type == DA7280_ERM_COIN) { in da7280_init()
993 error = regmap_update_bits(haptics->regmap, DA7280_TOP_INT_CFG1, in da7280_init()
1002 error = regmap_update_bits(haptics->regmap, DA7280_TOP_CFG4, in da7280_init()
1007 haptics->acc_en = false; in da7280_init()
1008 haptics->rapid_stop_en = false; in da7280_init()
1009 haptics->amp_pid_en = false; in da7280_init()
1019 (haptics->dev_type ? 1 : 0)) | in da7280_init()
1021 (haptics->bemf_sense_en ? 1 : 0)) | in da7280_init()
1023 (haptics->freq_track_en ? 1 : 0)) | in da7280_init()
1025 (haptics->acc_en ? 1 : 0)) | in da7280_init()
1027 (haptics->rapid_stop_en ? 1 : 0)) | in da7280_init()
1029 (haptics->amp_pid_en ? 1 : 0)); in da7280_init()
1031 error = regmap_update_bits(haptics->regmap, DA7280_TOP_CFG1, mask, val); in da7280_init()
1035 error = regmap_update_bits(haptics->regmap, DA7280_TOP_CFG5, in da7280_init()
1037 haptics->acc_en ? in da7280_init()
1042 error = regmap_update_bits(haptics->regmap, in da7280_init()
1045 haptics->acc_en ? in da7280_init()
1050 if (haptics->nommax != DA7280_SKIP_INIT) { in da7280_init()
1051 error = regmap_write(haptics->regmap, DA7280_ACTUATOR1, in da7280_init()
1052 haptics->nommax); in da7280_init()
1057 if (haptics->absmax != DA7280_SKIP_INIT) { in da7280_init()
1058 error = regmap_write(haptics->regmap, DA7280_ACTUATOR2, in da7280_init()
1059 haptics->absmax); in da7280_init()
1064 error = regmap_update_bits(haptics->regmap, DA7280_ACTUATOR3, in da7280_init()
1065 DA7280_IMAX_MASK, haptics->imax); in da7280_init()
1069 v2i_factor = haptics->impd * (haptics->imax + 4) / 1610400; in da7280_init()
1070 error = regmap_write(haptics->regmap, DA7280_CALIB_V2I_L, in da7280_init()
1074 error = regmap_write(haptics->regmap, DA7280_CALIB_V2I_H, in da7280_init()
1079 error = regmap_update_bits(haptics->regmap, in da7280_init()
1086 if (haptics->mem_update) { in da7280_init()
1093 val = FIELD_PREP(DA7280_PS_SEQ_ID_MASK, haptics->ps_seq_id) | in da7280_init()
1094 FIELD_PREP(DA7280_PS_SEQ_LOOP_MASK, haptics->ps_seq_loop); in da7280_init()
1095 error = regmap_write(haptics->regmap, DA7280_SEQ_CTL2, val); in da7280_init()
1102 haptics->gpi_ctl[i].seq_id) | in da7280_init()
1104 haptics->gpi_ctl[i].mode) | in da7280_init()
1106 haptics->gpi_ctl[i].polarity); in da7280_init()
1107 error = regmap_write(haptics->regmap, in da7280_init()
1114 error = regmap_update_bits(haptics->regmap, in da7280_init()
1122 error = regmap_write(haptics->regmap, DA7280_IRQ_EVENT1, 0xff); in da7280_init()
1126 error = regmap_update_bits(haptics->regmap, in da7280_init()
1134 haptics->active = false; in da7280_init()
1138 dev_err(haptics->dev, "chip initialization error: %d\n", error); in da7280_init()
1144 struct device *dev = &client->dev; in da7280_probe()
1151 if (!client->irq) { in da7280_probe()
1153 return -EINVAL; in da7280_probe()
1158 return -ENOMEM; in da7280_probe()
1160 haptics->dev = dev; in da7280_probe()
1164 if (haptics->const_op_mode == DA7280_PWM_MODE) { in da7280_probe()
1165 haptics->pwm_dev = devm_pwm_get(dev, NULL); in da7280_probe()
1166 error = PTR_ERR_OR_ZERO(haptics->pwm_dev); in da7280_probe()
1168 if (error != -EPROBE_DEFER) in da7280_probe()
1175 pwm_init_state(haptics->pwm_dev, &state); in da7280_probe()
1177 error = pwm_apply_might_sleep(haptics->pwm_dev, &state); in da7280_probe()
1190 return -EINVAL; in da7280_probe()
1194 INIT_WORK(&haptics->work, da7280_haptic_work); in da7280_probe()
1196 haptics->client = client; in da7280_probe()
1199 haptics->regmap = devm_regmap_init_i2c(client, in da7280_probe()
1201 error = PTR_ERR_OR_ZERO(haptics->regmap); in da7280_probe()
1213 /* Initialize input device for haptic device */ in da7280_probe()
1217 return -ENOMEM; in da7280_probe()
1220 input_dev->name = "da7280-haptic"; in da7280_probe()
1221 input_dev->dev.parent = client->dev.parent; in da7280_probe()
1222 input_dev->open = da7280_haptic_open; in da7280_probe()
1223 input_dev->close = da7280_haptic_close; in da7280_probe()
1225 haptics->input_dev = input_dev; in da7280_probe()
1227 input_set_capability(haptics->input_dev, EV_FF, FF_PERIODIC); in da7280_probe()
1228 input_set_capability(haptics->input_dev, EV_FF, FF_CUSTOM); in da7280_probe()
1229 input_set_capability(haptics->input_dev, EV_FF, FF_CONSTANT); in da7280_probe()
1230 input_set_capability(haptics->input_dev, EV_FF, FF_GAIN); in da7280_probe()
1232 error = input_ff_create(haptics->input_dev, in da7280_probe()
1239 ff = input_dev->ff; in da7280_probe()
1240 ff->upload = da7280_haptics_upload_effect; in da7280_probe()
1241 ff->playback = da7280_haptics_playback; in da7280_probe()
1249 error = devm_request_threaded_irq(dev, client->irq, in da7280_probe()
1252 "da7280-haptics", haptics); in da7280_probe()
1255 client->irq, error); in da7280_probe()
1266 guard(mutex)(&haptics->input_dev->mutex); in da7280_suspend()
1272 scoped_guard(spinlock_irq, &haptics->input_dev->event_lock) { in da7280_suspend()
1273 haptics->suspended = true; in da7280_suspend()
1286 guard(mutex)(&haptics->input_dev->mutex); in da7280_resume()
1292 scoped_guard(spinlock_irq, &haptics->input_dev->event_lock) { in da7280_resume()
1293 haptics->suspended = false; in da7280_resume()
1316 .driver = {
1326 MODULE_DESCRIPTION("DA7280 haptics driver");