static void vibrator_enable(struct timed_output_dev *dev, int value)
{
	struct timed_vibrator_data *data = (void *)NULL;
	unsigned long	flags;
	int gain;

	/* Add protection code for detect null point error */	
	if (dev == (void *)NULL) {
		printk(KERN_INFO "%s:dev is null\n",__FUNCTION__);
		return;
	}

	data = container_of(dev, struct timed_vibrator_data, dev);
	if (data == (void *)NULL) {
		printk(KERN_INFO "%s:data is null\n",__FUNCTION__);
		return;
	}

	gain = atomic_read(&vibe_gain);

	printk("%s time = %d msec\n", __FUNCTION__, value);
	spin_lock_irqsave(&data->lock, flags);

	hrtimer_cancel(&data->timer);
	if (value > 0) {
#ifndef CONFIG_LGE_DOMESTIC
		if (value > data->max_timeout)
			value = data->max_timeout;
#endif
#ifdef CONFIG_MACH_MSM8X55_VICTOR
		if (value > 20) {
			data->value = value - 20;
			data->overdrv = 10;
		} else {
			data->value = value;
			data->overdrv = 0;
		}
		data->state = PWM_DUTY_1;
		hrtimer_start(&data->timer, ktime_set(0, 0), HRTIMER_MODE_REL);
#else
		android_vibrator_force_set(gain);
		
		hrtimer_start(&data->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL);
#endif
	} else {
		android_vibrator_force_set(0);
	}

	spin_unlock_irqrestore(&data->lock, flags);
}
static void gen_pwm(struct timed_vibrator_data *data)
{
	int gain = atomic_read(&vibe_gain);
	
	switch (data->state) {
		case PWM_DUTY_1:
#ifdef CONFIG_LGE_DOMESTIC
			if(data->value < 1000)
			{
				gain = 52;
				if(data->value < 50)
					data->value = 50;
			}
			android_vibrator_force_set(gain);
			hrtimer_start(&data->timer,
					ktime_set(data->value  / 1000, (data->value % 1000) * 1000000),
					HRTIMER_MODE_REL);
#else
			android_vibrator_force_set(gain);
			hrtimer_start(&data->timer,
					ktime_set(data->value  / 1000, (data->value % 1000) * 1000000),
					HRTIMER_MODE_REL);
#endif
			data->state = PWM_DUTY_2;
			break;
		case PWM_DUTY_2:
			android_vibrator_force_set(52);
			hrtimer_start(&data->timer,
					ktime_set(data->overdrv / 1000, (data->overdrv % 1000) * 1000000),
					HRTIMER_MODE_REL);
			data->state = PWM_DUTY_3;
			break;
		case PWM_DUTY_3:
			android_vibrator_force_set(2);
			hrtimer_start(&data->timer,
					ktime_set(data->overdrv / 1000, (data->overdrv % 1000) * 1000000),
					HRTIMER_MODE_REL);
			data->state = PWM_DUTY_4;
			break;
		case PWM_DUTY_4:
		default:
			android_vibrator_force_set(0);
			data->state = 0;
			data->value = 0;
			data->overdrv = 0;
			break;
	}
}
static int android_vibrator_probe(struct platform_device *pdev)
{
	int ret = 0;

	vibe_data = (struct android_vibrator_platform_data *)pdev->dev.platform_data;
	atomic_set(&vibe_gain,vibe_data->amp_value);
	vibe_data->pwm_set(1, 32);

	if (android_vibrator_intialize() < 0) {
		printk(KERN_ERR "Android Vibrator Initialization was failed\n");
		return -1;
	}

	android_vibrator_force_set(0); /* disable vibrator */

	hrtimer_init(&android_vibrator_data.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	android_vibrator_data.timer.function = vibrator_timer_func;
	spin_lock_init(&android_vibrator_data.lock);

	ret = timed_output_dev_register(&android_vibrator_data.dev);
	if (ret < 0) {
		timed_output_dev_unregister(&android_vibrator_data.dev);
		return -ENODEV;
	}

	ret = device_create_file(android_vibrator_data.dev.dev, &dev_attr_amp);
	if (ret < 0) {
		timed_output_dev_unregister(&android_vibrator_data.dev);
		device_remove_file(android_vibrator_data.dev.dev, &dev_attr_amp);
		return -ENODEV;
	}
	
	printk(KERN_INFO "LGE: Android Vibrator Initialization was done\n");
	return 0;
}
static void android_vibrator_off(struct work_struct *work)
{
	struct timed_vibrator_data *vib =
		container_of(work, struct timed_vibrator_data,
				work_vibrator_off);

	pr_debug("%s\n", __func__);
	android_vibrator_force_set(vib, 0, vib->pdata->vibe_n_value);
}
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
#if defined(CONFIG_VIB_USE_WORK_QUEUE)
	atomic_set(&nForce, 0);
	schedule_work(&vib_power_set_work_queue);	/* disable vibrator */
#else	/* CONFIG_VIB_USE_WORK_QUEUE */
	android_vibrator_force_set(0);
#endif

	return HRTIMER_NORESTART;
}
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
#ifdef CONFIG_MACH_MSM8X55_VICTOR
	struct timed_vibrator_data *data;
	data = container_of(timer, struct timed_vibrator_data, timer);
	gen_pwm(data);
#else
	android_vibrator_force_set(0);
#endif

	return HRTIMER_NORESTART;
}
static void vibrator_enable(struct timed_output_dev *dev, int value)
{
	printk(KERN_INFO "LGE: vibrator_enable\n");
	struct timed_vibrator_data *data = container_of(dev, struct timed_vibrator_data, dev);
	unsigned long	flags;
	int gain = atomic_read(&vibe_gain);
	
	spin_lock_irqsave(&data->lock, flags);

	hrtimer_cancel(&data->timer);	
	if (value > 0) {
		if (value > data->max_timeout)
			value = data->max_timeout;
		android_vibrator_force_set(gain);
		hrtimer_start(&data->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL);
	} else {
		android_vibrator_force_set(0);
	}

	spin_unlock_irqrestore(&data->lock, flags);
}
Beispiel #8
0
static void android_vibrator_off(struct work_struct *work)
{
    struct timed_vibrator_data *vib = container_of(work, struct timed_vibrator_data, work_vibrator_off);

    // suspend /resume logging test
    // printk(KERN_INFO"%s is stating ... \n", __func__);

    //printk(KERN_INFO "LGE:%s\n", __func__);
    android_vibrator_force_set(vib, 0);

    // suspend /resume logging test
    // printk(KERN_INFO"%s is exting ... \n", __func__);
}
static void android_vibrator_on(struct work_struct *work)
{
	struct timed_vibrator_data *vib =
		container_of(work, struct timed_vibrator_data,
				work_vibrator_on);
	int gain = atomic_read(&vib->gain);
	int pwm = atomic_read(&vib->pwm);
	/* suspend /resume logging test */
	pr_debug("%s: gain = %d pwm = %d\n", __func__,
			gain, pwm);

	android_vibrator_force_set(vib, gain, pwm);
}
static int android_vibrator_probe(struct platform_device *pdev)
{
	int ret = 0;

	vibe_data = (struct lge_vibrator_platform_data *)pdev->dev.platform_data;
	atomic_set(&vibe_gain,vibe_data->amp_value);

	if (android_vibrator_intialize() < 0) {
		printk(KERN_ERR "Android Vibrator Initialization was failed\n");
		return -1;
	}

#ifdef CONFIG_VIB_USE_HIGH_VOL_OVERDRIVE
	INIT_WORK(&qcoin_overdrive_off_queue, vib_qcoin_off_work);
#endif

#if defined(CONFIG_VIB_USE_WORK_QUEUE)
	INIT_WORK(&vib_power_set_work_queue, vib_power_set_work);

	atomic_set(&nForce, 0);
	schedule_work(&vib_power_set_work_queue);	/* disable vibrator */
#else	/* CONFIG_VIB_USE_WORK_QUEUE */
	android_vibrator_force_set(0); /* disable vibrator */
#endif

	hrtimer_init(&android_vibrator_data.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	android_vibrator_data.timer.function = vibrator_timer_func;
	spin_lock_init(&android_vibrator_data.lock);

	ret = timed_output_dev_register(&android_vibrator_data.dev);
	if (ret < 0) {
		timed_output_dev_unregister(&android_vibrator_data.dev);
		return -ENODEV;
	}

#ifdef CONFIG_VIB_USE_HIGH_VOL_OVERDRIVE
	ret = device_create_file(android_vibrator_data.dev.dev, &dev_attr_rtime);
	ret = device_create_file(android_vibrator_data.dev.dev, &dev_attr_ftime);
#endif

	ret = device_create_file(android_vibrator_data.dev.dev, &dev_attr_amp);
	if (ret < 0) {
		timed_output_dev_unregister(&android_vibrator_data.dev);
		device_remove_file(android_vibrator_data.dev.dev, &dev_attr_amp);
		return -ENODEV;
	}

	printk(KERN_INFO "LGE: Android Vibrator Initialization was done\n");
	return 0;
}
static void android_vibrator_shutdown(struct platform_device *pdev)
{
	android_vibrator_force_set(0);
	vibe_data->power_set(0);
}
static int android_vibrator_suspend(struct platform_device *pdev, pm_message_t state)
{
	printk(KERN_INFO "LGE: Android Vibrator Driver Suspend\n");
	android_vibrator_force_set(0);
	return 0;
}
static void vibrator_enable(struct timed_output_dev *dev, int value)
{
	//struct timed_vibrator_data *data = container_of(dev, struct timed_vibrator_data, dev);
	struct timed_vibrator_data *data = (void *)NULL;
	unsigned long	flags;
#ifdef CONFIG_VIB_USE_HIGH_VOL_OVERDRIVE
	int rtime;
#endif
	//int gain = atomic_read(&vibe_gain);
	int gain;

	/* Add protection code for detect null point error */	
	if (dev == (void *)NULL) {
		printk(KERN_INFO "%s:dev is null\n",__FUNCTION__);
		return;
	}

	data = container_of(dev, struct timed_vibrator_data, dev);
	if (data == (void *)NULL) {
		printk(KERN_INFO "%s:data is null\n",__FUNCTION__);
		return;
	}

	gain = atomic_read(&vibe_gain);

	//printk("LGE:%s time = %d msec\n", __FUNCTION__, value);
	spin_lock_irqsave(&data->lock, flags);

	hrtimer_cancel(&data->timer);
	if (value > 0) {
		if (value > data->max_timeout)
			value = data->max_timeout;
#if defined(CONFIG_VIB_USE_WORK_QUEUE)
		atomic_set(&nForce, gain);
		schedule_work(&vib_power_set_work_queue);	/* disable vibrator */
#else	/* CONFIG_VIB_USE_WORK_QUEUE */
		android_vibrator_force_set(gain);
#endif

#ifdef CONFIG_VIB_USE_HIGH_VOL_OVERDRIVE
		rtime = atomic_read(&vibe_rtime);
		if (value >= (40+rtime)) {
			use_overdrive = true;
			value -= rtime;
		} else { /* the effect under 5msec will be ignored */
			use_overdrive = false;
			value -= 5;
		}
	/*	
		printk("LGE: Overdriving Enabled, rtime = %d, ftime = %d\n", 
				rtime, atomic_read(&vibe_ftime));
	*/
		
#endif

		hrtimer_start(&data->timer, ktime_set(value / 1000, (value % 1000) * 1000000), HRTIMER_MODE_REL);
	} else if (value == -100) {
#if defined(CONFIG_VIB_USE_WORK_QUEUE)
		atomic_set(&nForce, gain);
		schedule_work(&vib_power_set_work_queue);	/* disable vibrator */
#else	/* CONFIG_VIB_USE_WORK_QUEUE */
		android_vibrator_force_set(gain);
#endif
	} else {
#if defined(CONFIG_VIB_USE_WORK_QUEUE)
		atomic_set(&nForce, 0);
		schedule_work(&vib_power_set_work_queue);	/* disable vibrator */
#else	/* CONFIG_VIB_USE_WORK_QUEUE */
		android_vibrator_force_set(0);
#endif
	}

	spin_unlock_irqrestore(&data->lock, flags);
}
static void vib_power_set_work(struct work_struct *work)
{
	android_vibrator_force_set(atomic_read(&nForce));
}
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
	android_vibrator_force_set(0);
	return HRTIMER_NORESTART;
}