static ssize_t write(struct file *file, const char *buf, size_t count, loff_t *ppos) { int i = 0; *ppos = 0; /* file position not used, always set to 0 */ /* DbgOut((KERN_ERR "tspdrv: write....\n")); */ /* ** Prevent unauthorized caller to write data. ** TouchSense service is the only valid caller. */ if (file->private_data != (void *)TSPDRV_MAGIC_NUMBER) { DbgOut((KERN_ERR "tspdrv: unauthorized write.\n")); return 0; } #ifdef CONFIG_TACTILE_ASSIST /* Check buffer size */ if ((count < SPI_HEADER_SIZE) || (count > SPI_BUFFER_SIZE)) { DbgOut((KERN_ERR "tspdrv: invalid write buffer size.\n")); return 0; } if (count == SPI_HEADER_SIZE) g_bOutputDataBufferEmpty = 1; else g_bOutputDataBufferEmpty = 0; #else if ((count <= SPI_HEADER_SIZE) || (count > SPI_BUFFER_SIZE)) { DbgOut((KERN_ERR "tspdrv: invalid write buffer size.\n")); return 0; } #endif /* Copy immediately the input buffer */ if (0 != copy_from_user(g_cwrite_buffer, buf, count)) { /* Failed to copy all the data, exit */ DbgOut((KERN_ERR "tspdrv: copy_from_user failed.\n")); return 0; } while (i < count) { int nindex_free_buffer; /* initialized below */ samples_buffer *pinput_buffer = (samples_buffer *)(&g_cwrite_buffer[i]); #ifdef CONFIG_TACTILE_ASSIST if ((i + SPI_HEADER_SIZE) > count) { #else if ((i + SPI_HEADER_SIZE) >= count) { #endif /* ** Index is about to go beyond the buffer size. ** (Should never happen). */ DbgOut((KERN_EMERG "tspdrv: invalid buffer index.\n")); return 0; } /* Check bit depth */ if (8 != pinput_buffer->nbit_depth) DbgOut((KERN_WARNING "tspdrv: invalid bit depth.Use default value(8).\n")); /* The above code not valid if SPI header size is not 3 */ #if (SPI_HEADER_SIZE != 3) #error "SPI_HEADER_SIZE expected to be 3" #endif /* Check buffer size */ if ((i + SPI_HEADER_SIZE + pinput_buffer->nbuffer_size) > count) { /* ** Index is about to go beyond the buffer size. ** (Should never happen). */ DbgOut((KERN_EMERG "tspdrv: invalid data size.\n")); return 0; } /* Check actuator index */ if (NUM_ACTUATORS <= pinput_buffer->nactuator_index) { DbgOut((KERN_ERR "tspdrv: invalid actuator index.\n")); i += (SPI_HEADER_SIZE + pinput_buffer->nbuffer_size); continue; } if (0 == g_samples_buffer[pinput_buffer->nactuator_index] .actuator_samples[0].nbuffer_size) { nindex_free_buffer = 0; } else if (0 == g_samples_buffer[pinput_buffer->nactuator_index] .actuator_samples[1].nbuffer_size) { nindex_free_buffer = 1; } else { /* No room to store new samples */ DbgOut((KERN_ERR "tspdrv: no room to store new samples.\n")); return 0; } /* Store the data in the free buffer of the given actuator */ memcpy( &(g_samples_buffer[pinput_buffer->nactuator_index] .actuator_samples[nindex_free_buffer]), &g_cwrite_buffer[i], (SPI_HEADER_SIZE + pinput_buffer->nbuffer_size)); /* If the no buffer is playing, prepare to play ** g_samples_buffer[pinput_buffer->nactuator_index]. ** actuator_samples[nindex_free_buffer] */ if (-1 == g_samples_buffer[pinput_buffer->nactuator_index] .nindex_playing_buffer) { g_samples_buffer[pinput_buffer->nactuator_index] .nindex_playing_buffer = nindex_free_buffer; g_samples_buffer[pinput_buffer->nactuator_index] .nindex_output_value = 0; } /* Increment buffer index */ i += (SPI_HEADER_SIZE + pinput_buffer->nbuffer_size); } #ifdef QA_TEST g_nforcelog[g_nforcelog_index++] = g_cSPIBuffer[0]; if (g_nforcelog_index >= FORCE_LOG_BUFFER_SIZE) { for (i = 0; i < FORCE_LOG_BUFFER_SIZE; i++) { printk(KERN_INFO "%d\t%d\n", g_ntime, g_nforcelog[i]); g_ntime += TIME_INCREMENT; } g_nforcelog_index = 0; } #endif /* Start the timer after receiving new output force */ g_bisplaying = true; VibeOSKernelLinuxStartTimer(); return count; } static long ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { #ifdef QA_TEST int i; #endif printk(KERN_DEBUG "tspdrv: %s %d\n", __func__, cmd); /* DbgOut(KERN_INFO "tspdrv: ioctl cmd[0x%x].\n", cmd); */ switch (cmd) { case TSPDRV_STOP_KERNEL_TIMER: /* ** As we send one sample ahead of time, we need to finish ** playing the last sample before stopping the timer. ** So we just set a flag here. */ if (true == g_bisplaying) g_bstoprequested = true; #ifdef VIBEOSKERNELPROCESSDATA /* Last data processing to disable amp and stop timer */ VibeOSKernelProcessData(NULL); #endif #ifdef QA_TEST if (g_nforcelog_index) { for (i = 0; i < g_nforcelog_index; i++) { printk(KERN_INFO "%d\t%d\n" , g_ntime, g_nforcelog[i]); g_ntime += TIME_INCREMENT; } } g_ntime = 0; g_nforcelog_index = 0; #endif break; case TSPDRV_MAGIC_NUMBER: #ifdef CONFIG_TACTILE_ASSIST case TSPDRV_SET_MAGIC_NUMBER: #endif filp->private_data = (void *)TSPDRV_MAGIC_NUMBER; break; case TSPDRV_ENABLE_AMP: wake_lock(&vib_wake_lock); vibe_set_pwm_freq(0); vibe_pwm_onoff(1); ImmVibeSPI_ForceOut_AmpEnable(arg); DbgRecorderReset((arg)); DbgRecord((arg, ";------- TSPDRV_ENABLE_AMP ---------\n")); break; case TSPDRV_DISABLE_AMP: /* ** Small fix for now to handle proper combination of ** TSPDRV_STOP_KERNEL_TIMER and TSPDRV_DISABLE_AMP together ** If a stop was requested, ignore the request as the amp ** will be disabled by the timer proc when it's ready */ #ifdef CONFIG_TACTILE_ASSIST g_bstoprequested = true; /* Last data processing to disable amp and stop timer */ VibeOSKernelProcessData(NULL); g_bisplaying = false; #else if (!g_bstoprequested) ImmVibeSPI_ForceOut_AmpDisable(arg); #endif wake_unlock(&vib_wake_lock); break; case TSPDRV_GET_NUM_ACTUATORS: return NUM_ACTUATORS; } return 0; }
static long ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { #ifdef QA_TEST int i; #endif /* DbgOut(KERN_INFO "tspdrv: ioctl cmd[0x%x].\n", cmd); */ switch (cmd) { case TSPDRV_STOP_KERNEL_TIMER: /* ** As we send one sample ahead of time, we need to finish ** playing the last sample before stopping the timer. ** So we just set a flag here. */ if (true == g_bisplaying) g_bstoprequested = true; #ifdef VIBEOSKERNELPROCESSDATA /* Last data processing to disable amp and stop timer */ VibeOSKernelProcessData(NULL); #endif #ifdef QA_TEST if (g_nforcelog_index) { for (i = 0; i < g_nforcelog_index; i++) { printk(KERN_INFO "%d\t%d\n" , g_ntime, g_nforcelog[i]); g_ntime += TIME_INCREMENT; } } g_ntime = 0; g_nforcelog_index = 0; #endif break; case TSPDRV_MAGIC_NUMBER: filp->private_data = (void *)TSPDRV_MAGIC_NUMBER; break; case TSPDRV_ENABLE_AMP: wake_lock(&vib_wake_lock); vibe_set_pwm_freq(0); vibe_pwm_onoff(1); ImmVibeSPI_ForceOut_AmpEnable(arg); DbgRecorderReset((arg)); DbgRecord((arg, ";------- TSPDRV_ENABLE_AMP ---------\n")); break; case TSPDRV_DISABLE_AMP: /* ** Small fix for now to handle proper combination of ** TSPDRV_STOP_KERNEL_TIMER and TSPDRV_DISABLE_AMP together ** If a stop was requested, ignore the request as the amp ** will be disabled by the timer proc when it's ready */ if (!g_bstoprequested) ImmVibeSPI_ForceOut_AmpDisable(arg); wake_unlock(&vib_wake_lock); break; case TSPDRV_GET_NUM_ACTUATORS: return NUM_ACTUATORS; } return 0; }
static int set_vibetonz(int timeout) { if(!timeout) { printk("[VIBETONZ] DISABLE\n"); #if defined (CONFIG_KOR_MODEL_SHV_E110S) if (get_hw_rev() > 0x00 ){ vib_isa1200_onoff(0); vibe_pwm_onoff(0); } else { gpio_set_value(VIB_EN, VIBRATION_OFF); } #elif defined (CONFIG_KOR_SHV_E120L_HD720) || defined(CONFIG_KOR_MODEL_SHV_E120K) || defined(CONFIG_KOR_MODEL_SHV_E120S) || defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) vib_isa1200_onoff(0); vibe_pwm_onoff(0); #elif defined (CONFIG_USA_MODEL_SGH_T989)|| defined (CONFIG_USA_MODEL_SGH_I727) || defined (CONFIG_USA_MODEL_SGH_T769) if (get_hw_rev() > 0x04 ){ vib_isa1200_onoff(0); vibe_pwm_onoff(0); } else { gpio_set_value(VIB_EN, VIBRATION_OFF); } #elif defined (CONFIG_USA_MODEL_SGH_I717) || defined(CONFIG_USA_MODEL_SGH_I757) || defined(CONFIG_USA_MODEL_SGH_I577) || defined(CONFIG_CAN_MODEL_SGH_I577R) || defined(CONFIG_CAN_MODEL_SGH_I757M) vib_isa1200_onoff(0); vibe_pwm_onoff(0); #elif defined (CONFIG_JPN_MODEL_SC_03D) if (get_hw_rev() > 0x00 ){ vib_isa1200_onoff(0); vibe_pwm_onoff(0); } else { gpio_set_value(VIB_EN, VIBRATION_OFF); } #else gpio_set_value(VIB_EN, VIBRATION_OFF); #endif } else { printk("[VIBETONZ] ENABLE\n"); #if defined (CONFIG_KOR_MODEL_SHV_E110S) if (get_hw_rev() > 0x00 ){ vibe_pwm_onoff(1); vibe_set_pwm_freq(258); vib_isa1200_onoff(1); } else { gpio_set_value(VIB_EN, VIBRATION_ON); } #elif defined (CONFIG_KOR_SHV_E120L_HD720) || defined(CONFIG_KOR_MODEL_SHV_E120K) || defined(CONFIG_KOR_MODEL_SHV_E120S) || defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) vibe_pwm_onoff(1); vibe_set_pwm_freq(258); vib_isa1200_onoff(1); #elif defined (CONFIG_USA_MODEL_SGH_T989)|| defined (CONFIG_USA_MODEL_SGH_I727) || defined (CONFIG_USA_MODEL_SGH_T769) if (get_hw_rev() > 0x04 ){ vibe_pwm_onoff(1); vibe_set_pwm_freq(258); vib_isa1200_onoff(1); } else { gpio_set_value(VIB_EN, VIBRATION_ON); } #elif defined (CONFIG_USA_MODEL_SGH_I717) || defined(CONFIG_USA_MODEL_SGH_I757) || defined(CONFIG_USA_MODEL_SGH_I577) || defined(CONFIG_CAN_MODEL_SGH_I577R) || defined(CONFIG_CAN_MODEL_SGH_I757M) vibe_pwm_onoff(1); vibe_set_pwm_freq(258); vib_isa1200_onoff(1); #elif defined (CONFIG_JPN_MODEL_SC_03D) if (get_hw_rev() > 0x00 ){ vibe_pwm_onoff(1); vibe_set_pwm_freq(258); vib_isa1200_onoff(1); } else { gpio_set_value(VIB_EN, VIBRATION_ON); } #else gpio_set_value(VIB_EN, VIBRATION_ON); #endif } vibrator_value = timeout; return 0; }