/*
** Called by the real-time loop to set the force
*/
IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_SetSamples(VibeUInt8 nActuatorIndex, VibeUInt16 nOutputSignalBitDepth, VibeUInt16 nBufferSizeInBytes, VibeInt8* pForceOutputBuffer)
{

#if GUARANTEE_AUTOTUNE_BRAKE_TIME
    VibeInt8 force = pForceOutputBuffer[0];
    if (force > 0 && g_lastForce <= 0)
    {
        g_brake = false;

        ImmVibeSPI_ForceOut_AmpEnable(nActuatorIndex);
    }
    else if (force <= 0 && g_lastForce > 0)
    {
        g_brake = force < 0;

        ImmVibeSPI_ForceOut_AmpDisable(nActuatorIndex);
    }

    if (g_lastForce != force)
    {
        /* AmpDisable sets force to zero, so need to here */
        if (force > 0)
            drv2604_set_rtp_val(pForceOutputBuffer[0]);

        g_lastForce = force;
    }
#else
    drv2604_set_rtp_val(pForceOutputBuffer[0]);
#endif

    return VIBE_S_SUCCESS;
}
/*
** Called to disable amp (disable output force)
*/
IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_AmpDisable(VibeUInt8 nActuatorIndex)
{
    if (g_bAmpEnabled)
    {
        /* Set the force to 0 */
        drv2604_set_rtp_val(0);

#if GUARANTEE_AUTOTUNE_BRAKE_TIME
        /* if a brake signal arrived from daemon, let the chip stay on
         * extra time to allow it to brake */
        if (g_brake && g_workqueue)
        {
            queue_delayed_work(g_workqueue,
                               &g_brake_complete,
                               msecs_to_jiffies(AUTOTUNE_BRAKE_TIME));
        }
        else /* disable immediately (smooth effect style) */
#endif
        {
#if USE_DRV2604_STANDBY
            /* Put hardware in standby via i2c */
            drv2604_change_mode(MODE_STANDBY);
#endif

#if USE_DRV2604_EN_PIN
            /* Disable hardware via pin */
            drv2604_set_en(false);
#endif
        }

        g_bAmpEnabled = false;
    }
    return VIBE_S_SUCCESS;
}
Exemplo n.º 3
0
static void vibrator_enable(struct timed_output_dev *dev, int value)
{
#if SUPPORT_TIMED_OUTPUT
    char mode;
    hrtimer_cancel(&vibdata.timer);
    cancel_work_sync(&vibdata.work);

#if SUPPORT_WRITE_PAT
    cancel_work_sync(&vibdata.pat_work);
#endif
    mutex_lock(&vibdata.lock);

    if (value) {
        wake_lock(&vibdata.wklock);
        drv2604_read_reg(STATUS_REG);

        /* Added by Ken on 20120531 */
        if (!g_bAmpEnabled) {
            mode = drv2604_read_reg(MODE_REG) & DRV2604_MODE_MASK;
            /* Modified by Ken on 20120530 */
#if DRV2604_USE_RTP_MODE
            /* Only change the mode if not already in RTP mode; RTP input already set at init */
            if (mode != MODE_REAL_TIME_PLAYBACK) {
                drv2604_change_mode(MODE_REAL_TIME_PLAYBACK);
                drv2604_set_rtp_val(vibe_strength);
                vibrator_is_playing = YES;
                g_bAmpEnabled = true;
            }
#endif
#if DRV2604_USE_PWM_MODE
            /* Only change the mode if not already in PWM mode */
            if (mode != MODE_PWM_OR_ANALOG_INPUT) {
                pwm_duty_enable(vibdata.pwm_dev, 0);
                drv2604_change_mode(MODE_PWM_OR_ANALOG_INPUT);
                vibrator_is_playing = YES;
                g_bAmpEnabled = true;
            }
#endif
        }

        if (value > 0) {
            if (value > MAX_TIMEOUT)
                value = MAX_TIMEOUT;
            hrtimer_start(&vibdata.timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL);
        }
    } else
        vibrator_off();

    mutex_unlock(&vibdata.lock);
#endif // SUPPORT_TIMED_OUTPUT
}
Exemplo n.º 4
0
/*
** Called to disable amp (disable output force)
*/
IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_AmpDisable(VibeUInt8 nActuatorIndex)
{
    if (g_bAmpEnabled)
    {
        DbgOut((DBL_VERBOSE, "ImmVibeSPI_ForceOut_AmpDisable.\n"));

        /* Set the force to 0 */
#if DRV2604_USE_RTP_MODE
        drv2604_set_rtp_val(0);
#endif
#if DRV2604_USE_PWM_MODE
        /* From Xiaomi start */
        pwm_duty_enable(vibdata.pwm_dev, 0);
        /* From Xiaomi end */
#endif

        /* if a brake signal arrived from daemon, let the chip stay on
         * extra time to allow it to brake */
        if (g_autotune_brake_enabled && g_brake && g_workqueue) {
            queue_delayed_work(g_workqueue,
                               &g_brake_complete,
                               msecs_to_jiffies(AUTOTUNE_BRAKE_TIME));
        } else /* disable immediately (smooth effect style) */
        {
#if USE_DRV2604_STANDBY
            /* Put hardware in standby via i2c */
            drv2604_change_mode(MODE_STANDBY);
#endif
#if USE_DRV2604_EN_PIN
            /* Disable hardware via pin */
            drv2604_set_en(false);
#endif
        }
        g_bAmpEnabled = false;
    }
    return VIBE_S_SUCCESS;
}
Exemplo n.º 5
0
/*
** Called by the real-time loop to set the force
*/
IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_SetSamples(VibeUInt8 nActuatorIndex,
        VibeUInt16 nOutputSignalBitDepth, VibeUInt16 nBufferSizeInBytes,
        VibeInt8* pForceOutputBuffer)
{
    if(g_autotune_brake_enabled) {
        VibeInt8 force = pForceOutputBuffer[0];
        if (force > 0 && g_lastForce <= 0) {
            g_brake = false;

            ImmVibeSPI_ForceOut_AmpEnable(nActuatorIndex);
        } else if (force <= 0 && g_lastForce > 0) {
            g_brake = force < 0;

            ImmVibeSPI_ForceOut_AmpDisable(nActuatorIndex);
        }

        if (g_lastForce != force) {
            /* AmpDisable sets force to zero, so need to here */
#if DRV2604_USE_RTP_MODE
            if (force > 0)
                drv2604_set_rtp_val(pForceOutputBuffer[0]);
#endif
#if DRV2604_USE_PWM_MODE
            /* From Xiaomi start */
            /* Xiaomi would like to use the PWM mode to change output level */
            u32 uForce;
            if (pForceOutputBuffer[0] != 0) {
                uForce = (pForceOutputBuffer[0] > 0)?(pForceOutputBuffer[0]):0;

                // Added by Ken on 20130530
                DbgOut((DBL_VERBOSE, "ImmVibeSPI_ForceOut_SetSamples(%d)\n", uForce));

                if (uForce > 126)
                    uForce = 256;
                else
                    uForce += 128;
                pwm_duty_enable(vibdata.pwm_dev, uForce);
            } else {
                // Added by Ken on 20130530
                DbgOut((DBL_VERBOSE, "ImmVibeSPI_ForceOut_SetSamples(0)\n"));

                pwm_duty_enable(vibdata.pwm_dev, 0);
            }
            /* From Xiaomi end */
#endif
        }
        g_lastForce = force;
    } else {
#if DRV2604_USE_RTP_MODE
        drv2604_set_rtp_val(pForceOutputBuffer[0]);
#endif
#if DRV2604_USE_PWM_MODE
        /* From Xiaomi start */
        /* Xiaomi would like to use the PWM mode to change output level */
        u32 uForce;
        if (pForceOutputBuffer[0] != 0) {
            uForce = (pForceOutputBuffer[0] > 0) ? (pForceOutputBuffer[0]) : 0;

            // Added by Ken on 20130530
            DbgOut((DBL_VERBOSE, "SetSamples(%d)\n", uForce));

            if(uForce > 126)
                uForce = 256;
            else
                uForce += 128;
            pwm_duty_enable(vibdata.pwm_dev, uForce);
        } else {

            // Added by Ken on 20130530
            DbgOut((DBL_VERBOSE, "SetSamples(0)\n"));

            pwm_duty_enable(vibdata.pwm_dev, 0);
        }
        /* From Xiaomi end */
#endif
    }

    g_bNeedToRestartPlayBack = false;

    return VIBE_S_SUCCESS;
}