Exemplo n.º 1
0
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, &reg,
						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);
}