1 /* arch/arm/mach-omap2/board-tuna-vibrator.c
3 * Copyright (C) 2011 Samsung Electronics Co. Ltd. All Rights Reserved.
4 * Author: Rom Lemarchand <rlemarchand@sta.samsung.com>
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include <linux/hrtimer.h>
18 #include <linux/gpio.h>
19 #include <linux/wakelock.h>
20 #include <linux/mutex.h>
21 #include <asm/mach-types.h>
22 #include <plat/dmtimer.h>
24 #include <../../../drivers/staging/android/timed_output.h>
27 #include "board-tuna.h"
29 /* Vibrator enable pin is changed on Rev 05 to block not intended vibration. */
30 #define GPIO_MOTOR_EN 162
31 #define GPIO_MOTOR_EN_REV05 54
33 #define VIB_GPTIMER_NUM 10
34 #define PWM_DUTY_MAX 1463
35 #define MAX_TIMEOUT 10000 /* 10s */
36 static unsigned long pwmval
= 127;
37 static unsigned long oldpwmval
;
39 static struct vibrator
{
40 struct wake_lock wklock
;
43 struct omap_dm_timer
*gptimer
;
48 static ssize_t
pwmvalue_show(struct device
*dev
,
49 struct device_attribute
*attr
, char *buf
)
54 count
= sprintf(buf
, "%lu\n", pwmval
);
55 pr_info("vibrator: pwmval: %lu\n", pwmval
);
60 ssize_t
pwmvalue_store(struct device
*dev
,
61 struct device_attribute
*attr
,
62 const char *buf
, size_t size
)
65 if (kstrtoul(buf
, 0, &pwmval
))
66 pr_err("vibrator: error in storing pwm value\n");
68 pr_info("vibrator: pwmval: %lu\n", pwmval
);
72 static DEVICE_ATTR(pwmvalue
, S_IRUGO
| S_IWUGO
,
73 pwmvalue_show
, pwmvalue_store
);
75 static int pwm_set(unsigned long force
)
79 pr_info("vibrator: pwm_set force=%lu\n", force
);
81 if (unlikely(vibdata
.gptimer
== NULL
))
85 * Formula for matching the user space force (-127 to +127)
87 * Duty cycle will vary from 0 to 45('0' means 0% duty cycle,
88 * '45' means 100% duty cycle.
89 * Also if user space force equals to -127 then duty
90 * cycle will be 0 (0%), if force equals to 0 duty cycle
91 * will be 22.5(50%), if +127 then duty cycle will
95 pwm_duty
= ((force
+ 128)
96 * (PWM_DUTY_MAX
>> 1)/128);
98 omap_dm_timer_set_load(vibdata
.gptimer
, 1, -PWM_DUTY_MAX
);
99 omap_dm_timer_set_match(vibdata
.gptimer
, 1, -pwm_duty
);
100 omap_dm_timer_set_pwm(vibdata
.gptimer
, 0, 1,
101 OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE
);
102 omap_dm_timer_enable(vibdata
.gptimer
);
103 omap_dm_timer_write_counter(vibdata
.gptimer
, -2);
104 omap_dm_timer_save_context(vibdata
.gptimer
);
109 static int tuna_create_vibrator_sysfs(void)
113 struct kobject
*vibrator_kobj
;
114 vibrator_kobj
= kobject_create_and_add("vibrator", NULL
);
115 if (unlikely(!vibrator_kobj
))
118 ret
= sysfs_create_file(vibrator_kobj
,
119 &dev_attr_pwmvalue
.attr
);
120 if (unlikely(ret
< 0)) {
121 pr_err("vibrator: sysfs_create_file failed: %d\n", ret
);
129 static void vibrator_off(void)
131 if (!vibdata
.enabled
)
133 omap_dm_timer_stop(vibdata
.gptimer
);
134 gpio_set_value(vibdata
.gpio_en
, 0);
135 vibdata
.enabled
= false;
136 wake_unlock(&vibdata
.wklock
);
139 static int vibrator_get_time(struct timed_output_dev
*dev
)
141 if (hrtimer_active(&vibdata
.timer
)) {
142 ktime_t r
= hrtimer_get_remaining(&vibdata
.timer
);
143 return ktime_to_ms(r
);
149 static void vibrator_enable(struct timed_output_dev
*dev
, int value
)
151 mutex_lock(&vibdata
.lock
);
153 /* make sure pwmval is between 0 and 127 */
156 } else if (pwmval
< 0) {
160 /* set the current pwmval */
161 if (pwmval
!= oldpwmval
) {
166 /* cancel previous timer and set GPIO according to value */
167 hrtimer_cancel(&vibdata
.timer
);
170 pr_info("vibrator: value=%d, pwmval=%lu\n", value
, pwmval
);
171 wake_lock(&vibdata
.wklock
);
173 gpio_set_value(vibdata
.gpio_en
, 1);
174 omap_dm_timer_start(vibdata
.gptimer
);
176 vibdata
.enabled
= true;
179 if (value
> MAX_TIMEOUT
)
182 hrtimer_start(&vibdata
.timer
,
183 ns_to_ktime((u64
)value
* NSEC_PER_MSEC
),
190 mutex_unlock(&vibdata
.lock
);
193 static struct timed_output_dev to_dev
= {
195 .get_time
= vibrator_get_time
,
196 .enable
= vibrator_enable
,
199 static enum hrtimer_restart
vibrator_timer_func(struct hrtimer
*timer
)
202 return HRTIMER_NORESTART
;
205 static int __init
vibrator_init(void)
209 pr_info("vibrator_init()\n");
210 vibdata
.enabled
= false;
212 hrtimer_init(&vibdata
.timer
, CLOCK_MONOTONIC
, HRTIMER_MODE_REL
);
213 vibdata
.timer
.function
= vibrator_timer_func
;
215 vibdata
.gptimer
= omap_dm_timer_request_specific(VIB_GPTIMER_NUM
);
216 if (vibdata
.gptimer
== NULL
)
219 ret
= omap_dm_timer_set_source(vibdata
.gptimer
,
220 OMAP_TIMER_SRC_SYS_CLK
);
222 pr_err("vibrator_init(): timer_set_source failed\n");
223 goto err_dm_timer_src
;
226 omap_dm_timer_set_load(vibdata
.gptimer
, 1, -PWM_DUTY_MAX
);
227 omap_dm_timer_set_match(vibdata
.gptimer
, 1, -PWM_DUTY_MAX
+10);
228 omap_dm_timer_set_pwm(vibdata
.gptimer
, 0, 1,
229 OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE
);
230 omap_dm_timer_enable(vibdata
.gptimer
);
231 omap_dm_timer_write_counter(vibdata
.gptimer
, -2);
232 omap_dm_timer_disable(vibdata
.gptimer
);
234 wake_lock_init(&vibdata
.wklock
, WAKE_LOCK_SUSPEND
, "vibrator");
235 mutex_init(&vibdata
.lock
);
237 tuna_create_vibrator_sysfs();
239 ret
= timed_output_dev_register(&to_dev
);
241 pr_err("vibrator_init(): failed to register timed_output device\n");
248 mutex_destroy(&vibdata
.lock
);
249 wake_lock_destroy(&vibdata
.wklock
);
252 omap_dm_timer_free(vibdata
.gptimer
);
253 vibdata
.gptimer
= NULL
;
258 static int __init
omap4_tuna_vibrator_init(void)
262 pr_info("omap4_tuna_vibrator_init()\n");
263 vibdata
.gpio_en
= (omap4_tuna_get_revision() >= 5) ?
264 GPIO_MOTOR_EN_REV05
: GPIO_MOTOR_EN
;
266 omap_mux_init_gpio(vibdata
.gpio_en
, OMAP_PIN_OUTPUT
|
267 OMAP_PIN_OFF_OUTPUT_LOW
);
268 omap_mux_init_signal("dpm_emu18.dmtimer10_pwm_evt", OMAP_PIN_OUTPUT
);
270 ret
= gpio_request(vibdata
.gpio_en
, "MOTOR_EN");
274 gpio_direction_output(vibdata
.gpio_en
, 0);
276 ret
= vibrator_init();
278 pr_err("omap4_tuna_vibrator_init(): vibrator_init() failed\n");
279 gpio_free(vibdata
.gpio_en
);
286 * This is needed because the vibrator is dependent on omap_dm_timers which get
287 * initialized at device_init time
289 late_initcall(omap4_tuna_vibrator_init
);