static int qpnp_hap_mod_enable(struct qpnp_hap *hap, int on) { u8 val; int rc, i; val = hap->reg_en_ctl; if (on) { val |= QPNP_HAP_EN; } else { for (i = 0; i < QPNP_HAP_MAX_RETRIES; i++) { rc = qpnp_hap_read_reg(hap, &val, QPNP_HAP_STATUS(hap->base)); dev_dbg(&hap->spmi->dev, "HAP_STATUS=0x%x\n", val); /* wait for QPNP_HAP_CYCLS cycles of play rate */ if (val & QPNP_HAP_STATUS_BUSY) { usleep(QPNP_HAP_CYCLS * hap->wave_play_rate_us); if (hap->play_mode == QPNP_HAP_DIRECT) break; } else break; } if (i >= QPNP_HAP_MAX_RETRIES) dev_dbg(&hap->spmi->dev, "Haptics Busy. Force disable\n"); val &= ~QPNP_HAP_EN; } rc = qpnp_hap_write_reg(hap, &val, QPNP_HAP_EN_CTL_REG(hap->base)); if (rc < 0) return rc; hap->reg_en_ctl = val; return 0; }
/* worker to opeate haptics */ static void qpnp_hap_worker(struct work_struct *work) { struct qpnp_hap *hap = container_of(work, struct qpnp_hap, work); u8 reg = 0; int rc; if (hap->play_mode == QPNP_HAP_DIRECT) { if (hap->state) { /* haptic on */ rc = qpnp_hap_read_reg(hap, ®, QPNP_HAP_STATUS(hap->base)); if (rc < 0) return; if ((reg & QPNP_HAP_STATUS_BUSY) == 0) { /* */ #if 0 /* Over Drive : 2 vmax */ hap->vmax_mv = hap->vmax_mv_orig * 2; #endif /* */ hap->vmax_mv =QPNP_HAP_OV_RB_MV; qpnp_hap_vmax_config(hap ,1); qpnp_hap_set(hap, 1); /* */ usleep(2*hap->wave_play_rate_us); /* recover original vmax */ hap->vmax_mv = hap->vmax_mv_orig; qpnp_hap_vmax_config(hap ,0 ); } } } qpnp_hap_set(hap, hap->state); }