static int Set_vibe_for_alarm(void) { if(ImmVibeSPI_ForceOut_Set(1, 40)==VIBE_S_SUCCESS) return 1; else return 0; }
static ssize_t immTest_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { char *after; unsigned long arg1=0, arg2=0; unsigned long value = simple_strtoul(buf, &after, 10); printk(KERN_INFO "[VIBETONZ] value:%ld\n", value); if (value > 0) ImmVibeSPI_ForceOut_Set(0, value); else ImmVibeSPI_ForceOut_AmpDisable(value); return size; }
static int ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case VTMDRV_STOP_KERNEL_TIMER: { ImmVibeSPI_ForceOut_Set(0); /* just in case ... */ VibeOSKernelLinuxStopTimer(); mutex_lock(&(timer_state.lock)); if(timer_state.state==TIMER_ENABLED) { GPtimer_disable(); timer_state.state = TIMER_DISABLED; } mutex_unlock(&(timer_state.lock)); #if 0 VibeOSKernelLinuxStopTimer(); #endif g_bIsPlaying = false; #ifdef QA_TEST if (g_nForceLogIndex) { int i; for (i=0; i<g_nForceLogIndex; i++) { printk("<6>%d\t%d\n", g_nTime, g_nForceLog[i]); g_nTime += TIME_INCREMENT; } } g_nTime = 0; g_nForceLogIndex = 0; #endif } break; case VTMDRV_IDENTIFY_CALLER: if (VTMDRV_MAGIC_NUMBER == arg) file->private_data = (void*)VTMDRV_MAGIC_NUMBER; break; } return 0; }
/* ** Called by the real-time loop to set force output, and enable amp if required */ IMMVIBESPIAPI VibeStatus ImmVibeSPI_ForceOut_SetSamples( VibeUInt8 nActuatorIndex, VibeUInt16 nOutputSignalBitDepth, VibeUInt16 nBufferSizeInBytes, VibeInt8* pForceOutputBuffer ) { VibeStatus status = VIBE_E_FAIL; /* nOutputSignalBitDepth should always be 8 */ if (1 == nBufferSizeInBytes) { status = ImmVibeSPI_ForceOut_Set(nActuatorIndex, pForceOutputBuffer[0]); } else { /* Send 'nBufferSizeInBytes' bytes of data to HW */ /* Will get here only if configured to handle Piezo actuators */ printk( "[ImmVibeSPI] ImmVibeSPI_ForceOut_SetSamples nBufferSizeInBytes = %d \n", nBufferSizeInBytes ); } return status; }
static int VibeOSKernelTimerProc(void* data) { int nActuatorNotPlaying; int i; int bReachEndBuffer = 0; while (!kthread_should_stop()) { if (g_bTimerThreadStarted) { /* Block until we get woken up by timer tick */ /* . only do this if we're not exiting entirely */ wait_for_completion(&g_tspCompletion); /* Reinitialized completion so it isn't free by default */ init_completion(&g_tspCompletion); } nActuatorNotPlaying = 0; /* Return right away if timer is not supposed to run */ if (g_bTimerStarted) { for (i = 0; i < NUM_ACTUATORS; i++) { actuator_samples_buffer *pCurrentActuatorSample = &(g_SamplesBuffer[i]); if (-1 == pCurrentActuatorSample->nIndexPlayingBuffer) { nActuatorNotPlaying++; if ((NUM_ACTUATORS == nActuatorNotPlaying) && ((++g_nWatchdogCounter) > WATCHDOG_TIMEOUT)) { /* Nothing to play for all actuators, turn off the timer when we reach the watchdog tick count limit */ ImmVibeSPI_ForceOut_Set(i, 0); ImmVibeSPI_ForceOut_AmpDisable(i); VibeOSKernelLinuxStopTimer(); /* Reset watchdog counter */ g_nWatchdogCounter = 0; } } else { /* Play the current buffer */ ImmVibeSPI_ForceOut_Set(i, pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].dataBuffer[(int)(pCurrentActuatorSample->nIndexOutputValue++)]); if (pCurrentActuatorSample->nIndexOutputValue >= pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize) { /* We were playing in the last tick */ /* Reach the end of the current buffer */ pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize = 0; bReachEndBuffer = 1; /* Check stop request and empty buffer */ if ((g_bStopRequested) || (0 == (pCurrentActuatorSample->actuatorSamples[(int)((pCurrentActuatorSample->nIndexPlayingBuffer) ^ 1)].nBufferSize))) { pCurrentActuatorSample->nIndexPlayingBuffer = -1; if (g_bStopRequested) { /* g_bStopReqested is set, so turn off all actuators */ ImmVibeSPI_ForceOut_Set(i, 0); ImmVibeSPI_ForceOut_AmpDisable(i); /* If it's the last actuator, stop the timer */ if (i == (NUM_ACTUATORS-1)) { VibeOSKernelLinuxStopTimer(); /* Reset watchdog counter */ g_nWatchdogCounter = 0; } } } else { /* The other buffer has data in it */ /* Switch buffer */ (pCurrentActuatorSample->nIndexPlayingBuffer) ^= 1; pCurrentActuatorSample->nIndexOutputValue = 0; } } } } /* Release the mutex if locked */ if (bReachEndBuffer && VibeSemIsLocked(&g_hMutex)) { up(&g_hMutex); } } } return 0; }
static ssize_t write(struct file *file, const char *buf, size_t count, loff_t *ppos) { char cBuffer[1]; mutex_lock(&(timer_state.lock)); if(timer_state.state==TIMER_DISABLED) { GPtimer_enable(); timer_state.state = TIMER_ENABLED; } mutex_unlock(&(timer_state.lock)); *ppos = 0; /* file position not used, always set to 0 */ /* ** Prevent unauthorized caller to write data. ** VibeTonz service is the only valid caller. */ if (file->private_data != (void*)VTMDRV_MAGIC_NUMBER) { DbgOut((KERN_ERR "vtmdrv: unauthorized write.\n")); return 0; } /* Check buffer size */ if (count != 1) { DbgOut((KERN_ERR "vtmdrv: invalid write buffer size.\n")); return 0; } if (0 != copy_from_user(cBuffer, buf, count)) { /* Failed to copy all the data, exit */ DbgOut((KERN_ERR "vtmdrv: copy_from_user failed.\n")); return 0; } g_bIsPlaying = true; ImmVibeSPI_ForceOut_Set(cBuffer[0]); #ifdef QA_TEST g_nForceLog[g_nForceLogIndex++] = cBuffer[0]; if (g_nForceLogIndex >= FORCE_LOG_BUFFER_SIZE) { int i; for (i=0; i<FORCE_LOG_BUFFER_SIZE; i++) { printk("<6>%d\t%d\n", g_nTime, g_nForceLog[i]); g_nTime += TIME_INCREMENT; } g_nForceLogIndex = 0; } #endif #if 1 /* Start the timer after receiving new output force */ VibeOSKernelLinuxStartTimer(); #endif return count; }
static int VibeOSKernelProcessData(void* data) { int i; int nActuatorNotPlaying = 0; for (i = 0; i < NUM_ACTUATORS; i++) { actuator_samples_buffer *pCurrentActuatorSample = &(g_SamplesBuffer[i]); if (-1 == pCurrentActuatorSample->nIndexPlayingBuffer) { nActuatorNotPlaying++; if ((NUM_ACTUATORS == nActuatorNotPlaying) && ((++g_nWatchdogCounter) > WATCHDOG_TIMEOUT)) { /* Nothing to play for all actuators, turn off the timer when we reach the watchdog tick count limit */ ImmVibeSPI_ForceOut_Set(i, 0); ImmVibeSPI_ForceOut_AmpDisable(i); VibeOSKernelLinuxStopTimer(); /* Reset watchdog counter */ g_nWatchdogCounter = 0; } } else { /* Play the current buffer */ if (VIBE_E_FAIL == ImmVibeSPI_ForceOut_SetSamples( pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nActuatorIndex, pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBitDepth, pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize, pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].dataBuffer)) { /* VIBE_E_FAIL means NAK has been handled. Schedule timer to restart 5 ms from now */ hrtimer_forward_now(&g_tspTimer, g_ktFiveMs); } pCurrentActuatorSample->nIndexOutputValue += pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize; if (pCurrentActuatorSample->nIndexOutputValue >= pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize) { /* Reach the end of the current buffer */ pCurrentActuatorSample->actuatorSamples[(int)pCurrentActuatorSample->nIndexPlayingBuffer].nBufferSize = 0; /* Switch buffer */ (pCurrentActuatorSample->nIndexPlayingBuffer) ^= 1; pCurrentActuatorSample->nIndexOutputValue = 0; /* Finished playing, disable amp for actuator (i) */ if (g_bStopRequested) { pCurrentActuatorSample->nIndexPlayingBuffer = -1; ImmVibeSPI_ForceOut_AmpDisable(i); } } } } /* If finished playing, stop timer */ if (g_bStopRequested) { VibeOSKernelLinuxStopTimer(); /* Reset watchdog counter */ g_nWatchdogCounter = 0; if (VibeSemIsLocked(&g_hMutex)) up(&g_hMutex); return 1; /* tell the caller this is the last iteration */ } return 0; }