コード例 #1
0
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;
}
コード例 #2
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;
}
コード例 #3
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;
}