475 lines
14 KiB
C
Executable File
475 lines
14 KiB
C
Executable File
/*
|
|
** =========================================================================
|
|
** File:
|
|
** ImmVibeSPI.c
|
|
**
|
|
** Description:
|
|
** Device-dependent functions called by Immersion TSP API
|
|
** to control PWM duty cycle, amp enable/disable, save IVT file, etc...
|
|
**
|
|
** Portions Copyright (c) 2008-2010 Immersion Corporation. All Rights Reserved.
|
|
**
|
|
** This file contains Original Code and/or Modifications of Original Code
|
|
** as defined in and that are subject to the GNU Public License v2 -
|
|
** (the 'License'). You may not use this file except in compliance with the
|
|
** License. You should have received a copy of the GNU General Public License
|
|
** along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or contact
|
|
** TouchSenseSales@immersion.com.
|
|
**
|
|
** The Original Code and all software distributed under the License are
|
|
** distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
** EXPRESS OR IMPLIED, AND IMMERSION HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
|
** INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
** FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see
|
|
** the License for the specific language governing rights and limitations
|
|
** under the License.
|
|
** =========================================================================
|
|
*/
|
|
#include <linux/delay.h>
|
|
#include <linux/gpio.h>
|
|
#include "tspdrv.h"
|
|
|
|
/*
|
|
** This SPI supports only one actuator.
|
|
*/
|
|
#define NUM_ACTUATORS 1
|
|
#define PWM_DUTY_MAX 213 /* 13MHz / (579 + 1) = 22.4kHz */
|
|
#define PWM_DEVICE 1
|
|
|
|
static bool g_bampenabled;
|
|
|
|
struct pm_gpio vib_pwm = {
|
|
.direction = PM_GPIO_DIR_OUT,
|
|
.output_buffer = 0,
|
|
.output_value = 0,
|
|
.pull = PM_GPIO_PULL_NO,
|
|
.vin_sel = 0,
|
|
.out_strength = PM_GPIO_STRENGTH_HIGH,
|
|
.function = PM_GPIO_FUNC_1,
|
|
.inv_int_pol = 0,
|
|
};
|
|
|
|
int32_t vibe_set_pwm_freq(int nForce)
|
|
{
|
|
/* Put the MND counter in reset mode for programming */
|
|
HWIO_OUTM(GP1_CFG_RCGR, HWIO_GP_SRC_SEL_VAL_BMSK,
|
|
0 << HWIO_GP_SRC_SEL_VAL_SHFT); //SRC_SEL = 000(cxo)
|
|
#if defined(CONFIG_SEC_BERLUTI_PROJECT) || defined(CONFIG_MACH_S3VE3G_EUR)
|
|
HWIO_OUTM(GP1_CFG_RCGR, HWIO_GP_SRC_DIV_VAL_BMSK,
|
|
23 << HWIO_GP_SRC_DIV_VAL_SHFT); //SRC_DIV = 10111 (Div 12)
|
|
#else
|
|
HWIO_OUTM(GP1_CFG_RCGR, HWIO_GP_SRC_DIV_VAL_BMSK,
|
|
31 << HWIO_GP_SRC_DIV_VAL_SHFT); //SRC_DIV = 11111 (Div 16)
|
|
#endif
|
|
HWIO_OUTM(GP1_CFG_RCGR, HWIO_GP_MODE_VAL_BMSK,
|
|
2 << HWIO_GP_MODE_VAL_SHFT); //Mode Select 10
|
|
//M value
|
|
HWIO_OUTM(GP_M_REG, HWIO_GP_MD_REG_M_VAL_BMSK,
|
|
g_nlra_gp_clk_m << HWIO_GP_MD_REG_M_VAL_SHFT);
|
|
|
|
#if defined(CONFIG_MACH_LT03EUR) || defined(CONFIG_MACH_LT03SKT)\
|
|
|| defined(CONFIG_MACH_LT03KTT) || defined(CONFIG_MACH_LT03LGT) || defined(CONFIG_MACH_PICASSO_LTE)
|
|
|
|
if (nForce > 0){
|
|
g_nforce_32 = g_nlra_gp_clk_n - (((nForce * g_nlra_gp_clk_pwm_mul) >> 8));
|
|
if(g_nforce_32 < motor_min_strength)
|
|
g_nforce_32 = motor_min_strength;
|
|
else
|
|
g_nforce_32 = (g_nforce_32 - motor_min_strength) \
|
|
* (g_nlra_gp_clk_n * motor_strength / 100 - motor_min_strength) \
|
|
/ (g_nlra_gp_clk_n - motor_min_strength) + motor_min_strength;
|
|
}
|
|
else{
|
|
g_nforce_32 = ((nForce * g_nlra_gp_clk_pwm_mul) >> 8) + g_nlra_gp_clk_d;
|
|
if(g_nlra_gp_clk_n - g_nforce_32 > g_nlra_gp_clk_n * motor_strength /100)
|
|
g_nforce_32 = g_nlra_gp_clk_n - g_nlra_gp_clk_n * motor_strength /100;
|
|
}
|
|
#else
|
|
if (nForce > 0){
|
|
g_nforce_32 = g_nlra_gp_clk_n - (((nForce * g_nlra_gp_clk_pwm_mul) >> 8));
|
|
g_nforce_32 = g_nforce_32 * motor_strength /100;
|
|
if(g_nforce_32 < motor_min_strength)
|
|
g_nforce_32 = motor_min_strength;
|
|
}
|
|
else{
|
|
g_nforce_32 = ((nForce * g_nlra_gp_clk_pwm_mul) >> 8) + g_nlra_gp_clk_d;
|
|
if(g_nlra_gp_clk_n - g_nforce_32 > g_nlra_gp_clk_n * motor_strength /100)
|
|
g_nforce_32 = g_nlra_gp_clk_n - g_nlra_gp_clk_n * motor_strength /100;
|
|
}
|
|
#endif
|
|
// D value
|
|
HWIO_OUTM(GP_D_REG, HWIO_GP_MD_REG_D_VAL_BMSK,
|
|
(~((int16_t)g_nforce_32 << 1)) << HWIO_GP_MD_REG_D_VAL_SHFT);
|
|
|
|
//N value
|
|
HWIO_OUTM(GP_NS_REG, HWIO_GP_NS_REG_GP_N_VAL_BMSK,
|
|
~(g_nlra_gp_clk_n - g_nlra_gp_clk_m) << 0);
|
|
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
int32_t vibe_pwm_onoff(u8 onoff)
|
|
{
|
|
if (onoff) {
|
|
HWIO_OUTM(GP1_CMD_RCGR,HWIO_UPDATE_VAL_BMSK,
|
|
1 << HWIO_UPDATE_VAL_SHFT);//UPDATE ACTIVE
|
|
HWIO_OUTM(GP1_CMD_RCGR,HWIO_ROOT_EN_VAL_BMSK,
|
|
1 << HWIO_ROOT_EN_VAL_SHFT);//ROOT_EN
|
|
HWIO_OUTM(CAMSS_GP1_CBCR, HWIO_CLK_ENABLE_VAL_BMSK,
|
|
1 << HWIO_CLK_ENABLE_VAL_SHFT); //CLK_ENABLE
|
|
} else {
|
|
|
|
HWIO_OUTM(GP1_CMD_RCGR,HWIO_UPDATE_VAL_BMSK,
|
|
0 << HWIO_UPDATE_VAL_SHFT);
|
|
HWIO_OUTM(GP1_CMD_RCGR,HWIO_ROOT_EN_VAL_BMSK,
|
|
0 << HWIO_ROOT_EN_VAL_SHFT);
|
|
HWIO_OUTM(CAMSS_GP1_CBCR, HWIO_CLK_ENABLE_VAL_BMSK,
|
|
0 << HWIO_CLK_ENABLE_VAL_SHFT);
|
|
}
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
** Called to disable amp (disable output force)
|
|
*/
|
|
static int32_t ImmVibeSPI_ForceOut_AmpDisable(u_int8_t nActuatorIndex)
|
|
{
|
|
|
|
if (g_bampenabled) {
|
|
g_bampenabled = false;
|
|
if (vibrator_drvdata.power_onoff) {
|
|
if (!vibrator_drvdata.changed_chip)
|
|
vibrator_drvdata.power_onoff(0);
|
|
}
|
|
if (vibrator_drvdata.vib_model == HAPTIC_PWM) {
|
|
if(vibrator_drvdata.is_pmic_vib_pwm){ //PMIC PWM
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_OFF);
|
|
if(vibrator_drvdata.pwm_dev != NULL) //Disable the PWM device.
|
|
pwm_disable(vibrator_drvdata.pwm_dev);
|
|
} else{ //AP PWM
|
|
#if defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN)
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,\
|
|
0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, \
|
|
GPIO_CFG_2MA),GPIO_CFG_ENABLE);
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_OFF);
|
|
#else
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,\
|
|
0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, \
|
|
GPIO_CFG_2MA),GPIO_CFG_ENABLE);
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_OFF);
|
|
#endif
|
|
}
|
|
}
|
|
printk(KERN_DEBUG "tspdrv: %s\n", __func__);
|
|
#if defined(CONFIG_MOTOR_DRV_MAX77803)
|
|
max77803_vibtonz_en(0);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77804K)
|
|
if (vibrator_drvdata.changed_chip) {
|
|
gpio_direction_output(vibrator_drvdata.changed_en_gpio, VIBRATION_OFF);
|
|
gpio_set_value(vibrator_drvdata.changed_en_gpio,VIBRATION_OFF);
|
|
} else
|
|
max77804k_vibtonz_en(0);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77828)
|
|
max77828_vibtonz_en(0);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77888)
|
|
max77888_gpio_en(0);
|
|
max77888_vibtonz_en(0);
|
|
#elif defined(CONFIG_MOTOR_DRV_DRV2603)
|
|
drv2603_gpio_en(0);
|
|
#elif defined(CONFIG_MOTOR_ISA1000)
|
|
gpio_direction_output(vibrator_drvdata.vib_en_gpio,VIBRATION_OFF);
|
|
gpio_set_value(vibrator_drvdata.vib_en_gpio,VIBRATION_OFF);
|
|
#endif
|
|
}
|
|
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
** Called to enable amp (enable output force)
|
|
*/
|
|
static int32_t ImmVibeSPI_ForceOut_AmpEnable(u_int8_t nActuatorIndex)
|
|
{
|
|
if (!g_bampenabled) {
|
|
g_bampenabled = true;
|
|
if (vibrator_drvdata.power_onoff) {
|
|
if (!vibrator_drvdata.changed_chip)
|
|
vibrator_drvdata.power_onoff(1);
|
|
}
|
|
if (vibrator_drvdata.vib_model == HAPTIC_PWM) {
|
|
if(vibrator_drvdata.is_pmic_vib_pwm){ //PMIC PWM
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_ON);
|
|
} else { //AP PWM
|
|
#if defined(CONFIG_MACH_HLTEDCM) || defined(CONFIG_MACH_HLTEKDI) || \
|
|
defined(CONFIG_MACH_JS01LTEDCM) || defined(CONFIG_MACH_JS01LTESBM)
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,\
|
|
2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, \
|
|
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_ON);
|
|
#elif defined(CONFIG_SEC_BERLUTI_PROJECT) || defined(CONFIG_MACH_S3VE3G_EUR) || defined(CONFIG_MACH_VICTOR3GDSDTV_LTN) || defined(CONFIG_SEC_HESTIA_PROJECT)
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,\
|
|
3, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, \
|
|
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_ON);
|
|
#else
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,\
|
|
6, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, \
|
|
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
|
|
gpio_set_value(vibrator_drvdata.vib_pwm_gpio, \
|
|
VIBRATION_ON);
|
|
#endif
|
|
}
|
|
}
|
|
printk(KERN_DEBUG "tspdrv: %s\n", __func__);
|
|
#if defined(CONFIG_MOTOR_DRV_MAX77803)
|
|
max77803_vibtonz_en(1);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77804K)
|
|
if (vibrator_drvdata.changed_chip) {
|
|
gpio_direction_output(vibrator_drvdata.changed_en_gpio, VIBRATION_ON);
|
|
gpio_set_value(vibrator_drvdata.changed_en_gpio,VIBRATION_ON);
|
|
} else
|
|
max77804k_vibtonz_en(1);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77828)
|
|
max77828_vibtonz_en(1);
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77888)
|
|
max77888_gpio_en(1);
|
|
max77888_vibtonz_en(1);
|
|
#elif defined(CONFIG_MOTOR_DRV_DRV2603)
|
|
drv2603_gpio_en(1);
|
|
#elif defined(CONFIG_MOTOR_ISA1000)
|
|
gpio_direction_output(vibrator_drvdata.vib_en_gpio,VIBRATION_ON);
|
|
gpio_set_value(vibrator_drvdata.vib_en_gpio,VIBRATION_ON);
|
|
#endif
|
|
}
|
|
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
** Called at initialization time to set PWM freq,
|
|
** disable amp, etc...
|
|
*/
|
|
static int32_t ImmVibeSPI_ForceOut_Initialize(void)
|
|
{
|
|
int ret;
|
|
DbgOut((KERN_DEBUG "ImmVibeSPI_ForceOut_Initialize.\n"));
|
|
/* to force ImmVibeSPI_ForceOut_AmpDisable disabling the amp */
|
|
g_bampenabled = true;
|
|
|
|
/*
|
|
** Disable amp.
|
|
** If multiple actuators are supported, please make sure to call
|
|
** ImmVibeSPI_ForceOut_AmpDisable for each actuator
|
|
** (provide the actuator index as input argument).
|
|
*/
|
|
|
|
/* set gpio config */
|
|
if (vibrator_drvdata.vib_model == HAPTIC_PWM) {
|
|
if (vibrator_drvdata.is_pmic_vib_pwm) { //PMIC PWM
|
|
ret = gpio_request(vibrator_drvdata.vib_pwm_gpio, \
|
|
"vib pwm");
|
|
if (ret < 0) {
|
|
printk(KERN_ERR"vib pwm gpio_request is failed\n");
|
|
goto err2;
|
|
}
|
|
|
|
ret = pm8xxx_gpio_config(vibrator_drvdata.vib_pwm_gpio,\
|
|
&vib_pwm);
|
|
if (ret < 0) {
|
|
printk(KERN_ERR "failed to configure vib pwm pmic gpio\n");
|
|
goto err2;
|
|
}
|
|
} else { //AP PWM
|
|
#if defined(CONFIG_MACH_S3VE3G_EUR)
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,
|
|
0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
|
|
GPIO_CFG_ENABLE);
|
|
#else
|
|
gpio_tlmm_config(GPIO_CFG(vibrator_drvdata.vib_pwm_gpio,
|
|
0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
|
|
GPIO_CFG_ENABLE);
|
|
#endif
|
|
}
|
|
#if defined(CONFIG_MOTOR_ISA1000)
|
|
if (!vibrator_drvdata.is_pmic_vib_en) {
|
|
ret = gpio_request(vibrator_drvdata.vib_en_gpio,"vib enable");
|
|
if (ret < 0) {
|
|
printk(KERN_ERR "vib enable gpio_request is failed\n");
|
|
goto err2;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(CONFIG_MOTOR_DRV_DRV2603)
|
|
if (drv2603_gpio_init())
|
|
goto err2;
|
|
#elif defined(CONFIG_MOTOR_DRV_MAX77888)
|
|
if(max77888_gpio_init())
|
|
goto err2;
|
|
#endif
|
|
}
|
|
ImmVibeSPI_ForceOut_AmpDisable(0);
|
|
return VIBE_S_SUCCESS;
|
|
|
|
err2:
|
|
return VIBE_E_FAIL;
|
|
}
|
|
|
|
/*
|
|
** Called at termination time to set PWM freq, disable amp, etc...
|
|
*/
|
|
static int32_t ImmVibeSPI_ForceOut_Terminate(void)
|
|
{
|
|
DbgOut((KERN_DEBUG "ImmVibeSPI_ForceOut_Terminate.\n"));
|
|
|
|
/*
|
|
** Disable amp.
|
|
** If multiple actuators are supported, please make sure to call
|
|
** ImmVibeSPI_ForceOut_AmpDisable for each actuator
|
|
** (provide the actuator index as input argument).
|
|
*/
|
|
ImmVibeSPI_ForceOut_AmpDisable(0);
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
|
|
int vib_config_pwm_device(void)
|
|
{
|
|
int ret = 0;
|
|
if(vibrator_drvdata.pwm_dev == NULL){
|
|
//u32 pwm_period_us, duty_us;
|
|
#if defined(CONFIG_MACH_HLTEDCM) || defined(CONFIG_MACH_HLTEKDI) || \
|
|
defined(CONFIG_MACH_JS01LTEDCM) || defined(CONFIG_MACH_JS01LTESBM)
|
|
vibrator_drvdata.pwm_dev = pwm_request(0,"lpg_3"); // 0 index for LPG3 channel.
|
|
#else
|
|
vibrator_drvdata.pwm_dev = pwm_request(0,"lpg_1"); // 0 index for LPG1 channel.
|
|
#endif
|
|
|
|
if (IS_ERR_OR_NULL(vibrator_drvdata.pwm_dev)) {
|
|
pr_err("could not acquire PWM Channel 0, "
|
|
"error %ld\n",PTR_ERR(vibrator_drvdata.pwm_dev));
|
|
vibrator_drvdata.pwm_dev = NULL;
|
|
return -ENODEV;
|
|
}
|
|
//pwm_period_us = 19; // 2000000;
|
|
//duty_us = 18; //1000000; (90% Duty Cycle)
|
|
|
|
ret = pwm_config(vibrator_drvdata.pwm_dev,
|
|
vibrator_drvdata.duty_us,
|
|
vibrator_drvdata.pwm_period_us);
|
|
if (ret) {
|
|
pr_err("pwm_config in vibrator enable failed %d\n", ret);
|
|
return ret;
|
|
}
|
|
ret = pwm_enable(vibrator_drvdata.pwm_dev);
|
|
if (ret < 0) {
|
|
pr_err("pwm_enable in vibrator failed %d\n", ret);
|
|
return ret;
|
|
}
|
|
} else {
|
|
ret = pwm_enable(vibrator_drvdata.pwm_dev);
|
|
if (ret < 0) {
|
|
pr_err("pwm_enable in vibrator failed %d\n", ret);
|
|
return ret;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
** Called by the real-time loop to set PWM duty cycle
|
|
*/
|
|
#ifdef CONFIG_TACTILE_ASSIST
|
|
static bool g_bOutputDataBufferEmpty = 1;
|
|
#endif
|
|
static int32_t ImmVibeSPI_ForceOut_SetSamples(u_int8_t nActuatorIndex,
|
|
u_int16_t nOutputSignalBitDepth,
|
|
u_int16_t nBufferSizeInBytes,
|
|
int8_t *pForceOutputBuffer)
|
|
{
|
|
int8_t nforce;
|
|
static int8_t pre_nforce;
|
|
int ret;
|
|
|
|
#ifdef CONFIG_TACTILE_ASSIST
|
|
if (g_bOutputDataBufferEmpty) {
|
|
nActuatorIndex = 0;
|
|
nOutputSignalBitDepth = 8;
|
|
nBufferSizeInBytes = 1;
|
|
pForceOutputBuffer[0] = 0;
|
|
}
|
|
#endif
|
|
|
|
switch (nOutputSignalBitDepth) {
|
|
case 8:
|
|
/* pForceOutputBuffer is expected to contain 1 byte */
|
|
if (nBufferSizeInBytes != 1) {
|
|
DbgOut(KERN_ERR
|
|
"[ImmVibeSPI] ImmVibeSPI_ForceOut_SetSamples nBufferSizeInBytes = %d\n",
|
|
nBufferSizeInBytes);
|
|
return VIBE_E_FAIL;
|
|
}
|
|
nforce = pForceOutputBuffer[0];
|
|
break;
|
|
case 16:
|
|
/* pForceOutputBuffer is expected to contain 2 byte */
|
|
if (nBufferSizeInBytes != 2)
|
|
return VIBE_E_FAIL;
|
|
|
|
/* Map 16-bit value to 8-bit */
|
|
nforce = ((int16_t *)pForceOutputBuffer)[0] >> 8;
|
|
break;
|
|
default:
|
|
/* Unexpected bit depth */
|
|
return VIBE_E_FAIL;
|
|
}
|
|
|
|
if (nforce == 0) {
|
|
/* Set 50% duty cycle or disable amp */
|
|
ImmVibeSPI_ForceOut_AmpDisable(0);
|
|
if (!vibrator_drvdata.is_pmic_vib_pwm){
|
|
//AP PWM
|
|
vibe_pwm_onoff(0);
|
|
}
|
|
nforce = 0;
|
|
pre_nforce = 0;
|
|
} else {
|
|
if (nforce > 0)
|
|
nforce = 127 - nforce;
|
|
/* Map force from [-127, 127] to [0, PWM_DUTY_MAX] */
|
|
/* printk(KERN_DEBUG "[tspdrv]nForce===%d\n", nforce); */
|
|
if (pre_nforce != nforce) {
|
|
if (vibrator_drvdata.is_pmic_vib_pwm){
|
|
//PMIC PWM
|
|
ret = vib_config_pwm_device();
|
|
if(ret < 0)
|
|
return ret;
|
|
}else {
|
|
//AP PWM
|
|
vibe_set_pwm_freq(nforce);
|
|
vibe_pwm_onoff(1);
|
|
}
|
|
ImmVibeSPI_ForceOut_AmpEnable(0);
|
|
pre_nforce = nforce;
|
|
}
|
|
}
|
|
return VIBE_S_SUCCESS;
|
|
}
|
|
|
|
/*
|
|
** Called to get the device name (device name must be returned as ANSI char)
|
|
*/
|
|
static int32_t ImmVibeSPI_Device_GetName(
|
|
u_int8_t nActuatorIndex, char *szDevName, int nSize)
|
|
{
|
|
return VIBE_S_SUCCESS;
|
|
}
|