summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Li2017-08-03 08:46:36 -0500
committerPeter Li2017-08-03 08:46:36 -0500
commit2aa9a7bb8ed0794453fa05d7034a595821e5dbcf (patch)
tree65a796cbbbd4f9f65796be252d082441924b247d
parentc6d2ed49c012233fc05a668d781d52bad89b2d35 (diff)
downloaddrv2605-android-driver-2aa9a7bb8ed0794453fa05d7034a595821e5dbcf.tar.gz
drv2605-android-driver-2aa9a7bb8ed0794453fa05d7034a595821e5dbcf.tar.xz
drv2605-android-driver-2aa9a7bb8ed0794453fa05d7034a595821e5dbcf.zip
reference code based on SD800HEADmaster
-rwxr-xr-xarch_arm_mach-msm_lge_mako_board-mako-haptics.c188
-rwxr-xr-xdrivers_haptics_drv2605.c1002
-rwxr-xr-xdrv2605.c1306
-rwxr-xr-xdrv2605.h229
-rwxr-xr-xdts.readme12
-rwxr-xr-xinclude_linux_haptics_drv2605.h462
6 files changed, 1547 insertions, 1652 deletions
diff --git a/arch_arm_mach-msm_lge_mako_board-mako-haptics.c b/arch_arm_mach-msm_lge_mako_board-mako-haptics.c
deleted file mode 100755
index 7f2eefb..0000000
--- a/arch_arm_mach-msm_lge_mako_board-mako-haptics.c
+++ /dev/null
@@ -1,188 +0,0 @@
1/*
2** =============================================================================
3** Copyright (c) 2014 Texas Instruments Inc.
4**
5** This program is free software; you can redistribute it and/or
6** modify it under the terms of the GNU General Public License
7** as published by the Free Software Foundation; either version 2
8** of the License, or (at your option) any later version.
9**
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.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18**
19** File:
20** board-mako-haptics.c
21**
22** Description:
23** platform data for Haptics devices
24**
25** =============================================================================
26*/
27
28#include <linux/i2c.h>
29#include <linux/platform_device.h>
30#include <mach/board_lge.h>
31#include <linux/regulator/consumer.h>
32#include "devices.h"
33#include "board-mako.h"
34#if defined(CONFIG_HAPTICS_DRV2605)
35#include <linux/haptics/drv2605.h>
36#elif defined(CONFIG_HAPTICS_DRV2604)
37#include <linux/haptics/drv2604.h>
38#elif defined(CONFIG_HAPTICS_DRV2604L)
39#include <linux/haptics/drv2604l.h>
40#elif defined(CONFIG_HAPTICS_DRV2667)
41#include <linux/haptics/drv2667.h>
42#endif
43
44#define APQ8064_GSBI3_QUP_I2C_BUS_ID 3
45
46#if defined(CONFIG_HAPTICS_DRV2605)
47static struct drv2605_platform_data drv2605_plat_data = {
48 .GpioEnable = 0, //enable the chip
49 .GpioTrigger = 0, //external trigger pin, (0: internal trigger)
50#if defined(CONFIG_HAPTICS_LRA_SEMCO1030)
51 //rated = 1.5Vrms, ov=2.1Vrms, f=204hz
52 .loop = CLOSE_LOOP,
53 .RTPFormat = Signed,
54 .BIDIRInput = BiDirectional,
55 .actuator = {
56 .device_type = LRA,
57 .rated_vol = 0x3d,
58 .g_effect_bank = LIBRARY_F,
59 .over_drive_vol = 0x87,
60 .LRAFreq = 204,
61 },
62 .a2h = {
63 .a2h_min_input = AUDIO_HAPTICS_MIN_INPUT_VOLTAGE,
64 .a2h_max_input = AUDIO_HAPTICS_MAX_INPUT_VOLTAGE,
65 .a2h_min_output = AUDIO_HAPTICS_MIN_OUTPUT_VOLTAGE,
66 .a2h_max_output = AUDIO_HAPTICS_MAX_OUTPUT_VOLTAGE,
67 },
68#elif defined(CONFIG_HAPTICS_ERM_EVOWAVE_Z4TJGB1512658)
69 //rated vol = 3.0 v, ov = 3.6 v, risetime = 150 ms
70 .loop = CLOSE_LOOP,
71 .RTPFormat = Signed,
72 .BIDIRInput = BiDirectional,
73 .actuator = {
74 .device_type = ERM,
75 .g_effect_bank = LIBRARY_E,
76 .rated_vol = 0x8d,
77 .over_drive_vol = 0xa9,
78 },
79 .a2h = {
80 .a2h_min_input = AUDIO_HAPTICS_MIN_INPUT_VOLTAGE,
81 .a2h_max_input = AUDIO_HAPTICS_MAX_INPUT_VOLTAGE,
82 .a2h_min_output = AUDIO_HAPTICS_MIN_OUTPUT_VOLTAGE,
83 .a2h_max_output = AUDIO_HAPTICS_MAX_OUTPUT_VOLTAGE,
84 },
85#else
86#error "please define actuator type"
87#endif
88};
89#elif defined(CONFIG_HAPTICS_DRV2604)
90static struct drv2604_platform_data drv2604_plat_data = {
91 .GpioEnable = 0, //enable the chip
92 .GpioTrigger = 0, //external trigger pin, (0: internal trigger)
93#if defined(CONFIG_HAPTICS_LRA_SEMCO1030)
94 //rated = 1.5Vrms, ov=2.1Vrms, f=204hz
95 .loop = CLOSE_LOOP,
96 .RTPFormat = Signed,
97 .BIDIRInput = BiDirectional,
98 .actuator = {
99 .device_type = LRA,
100 .rated_vol = 0x3d,
101 .over_drive_vol = 0x87,
102 .LRAFreq = 204,
103 },
104#elif defined(CONFIG_HAPTICS_ERM_EVOWAVE_Z4TJGB1512658)
105 //rated vol = 3.0 v, ov = 3.6 v, risetime = 150 ms
106 .loop = CLOSE_LOOP,
107 .RTPFormat = Signed,
108 .BIDIRInput = BiDirectional,
109 .actuator = {
110 .device_type = ERM,
111 .rated_vol = 0x8d,
112 .over_drive_vol = 0xa9,
113 },
114#else
115#error "please define actuator type"
116#endif
117};
118#elif defined(CONFIG_HAPTICS_DRV2604L)
119static struct DRV2604L_platform_data drv2604l_plat_data = {
120 .GpioEnable = 0, //enable the chip
121 .GpioTrigger = 0, //external trigger pin, (0: internal trigger)
122#if defined(CONFIG_HAPTICS_LRA_SEMCO1030)
123 //rated = 1.5Vrms, ov=2.1Vrms, f=204hz
124 .loop = CLOSE_LOOP,
125 .RTPFormat = Signed,
126 .BIDIRInput = BiDirectional,
127 .actuator = {
128 .device_type = LRA,
129 .rated_vol = 0x3d,
130 .over_drive_vol = 0x87,
131 .LRAFreq = 204,
132 },
133#elif defined(CONFIG_HAPTICS_ERM_EVOWAVE_Z4TJGB1512658)
134 //rated vol = 3.0 v, ov = 3.6 v, risetime = 150 ms
135 .loop = CLOSE_LOOP,
136 .RTPFormat = Signed,
137 .BIDIRInput = BiDirectional,
138 .actuator = {
139 .device_type = ERM,
140 .rated_vol = 0x8d,
141 .over_drive_vol = 0xa9,
142 },
143#else
144#error "please define actuator type"
145#endif
146};
147#elif defined(CONFIG_HAPTICS_DRV2667)
148static struct drv2667_platform_data drv2667_plat_data = {
149 .inputGain = DRV2667_GAIN_50VPP,
150 .boostTimeout = DRV2667_IDLE_TIMEOUT_20MS,
151};
152#endif
153
154static struct i2c_board_info haptics_dev[] __initdata = {
155#if defined(CONFIG_HAPTICS_DRV2605)
156 {
157 I2C_BOARD_INFO(HAPTICS_DEVICE_NAME, 0x5a),
158 .platform_data = &drv2605_plat_data,
159 },
160#elif defined(CONFIG_HAPTICS_DRV2604)
161 {
162 I2C_BOARD_INFO(HAPTICS_DEVICE_NAME, 0x5a),
163 .platform_data = &drv2604_plat_data,
164 },
165#elif defined(CONFIG_HAPTICS_DRV2604L)
166 {
167 I2C_BOARD_INFO(HAPTICS_DEVICE_NAME, 0x5a),
168 .platform_data = &drv2604l_plat_data,
169 },
170#elif defined(CONFIG_HAPTICS_DRV2667)
171 {
172 I2C_BOARD_INFO(HAPTICS_DEVICE_NAME, 0x59),
173 .platform_data = &drv2667_plat_data,
174 },
175#endif
176 };
177
178static void __init lge_add_i2c_haptics_device(void)
179{
180 i2c_register_board_info(APQ8064_GSBI3_QUP_I2C_BUS_ID,
181 haptics_dev,
182 ARRAY_SIZE(haptics_dev));
183}
184
185void __init lge_add_haptics_device(void)
186{
187 lge_add_i2c_haptics_device();
188}
diff --git a/drivers_haptics_drv2605.c b/drivers_haptics_drv2605.c
deleted file mode 100755
index 346fb71..0000000
--- a/drivers_haptics_drv2605.c
+++ /dev/null
@@ -1,1002 +0,0 @@
1/*
2** =============================================================================
3** Copyright (c) 2014 Texas Instruments Inc.
4**
5** This program is free software; you can redistribute it and/or
6** modify it under the terms of the GNU General Public License
7** as published by the Free Software Foundation; either version 2
8** of the License, or (at your option) any later version.
9**
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.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18**
19** File:
20** drv2605.c
21**
22** Description:
23** DRV2605 chip driver
24**
25** =============================================================================
26*/
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/types.h>
32#include <linux/fs.h>
33#include <linux/i2c.h>
34#include <linux/semaphore.h>
35#include <linux/device.h>
36#include <linux/syscalls.h>
37#include <asm/uaccess.h>
38#include <linux/gpio.h>
39#include <linux/sched.h>
40#include <linux/spinlock_types.h>
41#include <linux/spinlock.h>
42#include <linux/delay.h>
43#include <linux/jiffies.h>
44#include <linux/err.h>
45#include <linux/clk.h>
46#include <linux/haptics/drv2605.h>
47
48static struct drv2605_data *pDRV2605data = NULL;
49
50static int drv2605_reg_read(struct drv2605_data *pDrv2605data, unsigned int reg)
51{
52 unsigned int val;
53 int ret;
54
55 ret = regmap_read(pDrv2605data->regmap, reg, &val);
56
57 if (ret < 0)
58 return ret;
59 else
60 return val;
61}
62
63static int drv2605_reg_write(struct drv2605_data *pDrv2605data, unsigned char reg, char val)
64{
65 return regmap_write(pDrv2605data->regmap, reg, val);
66}
67
68static int drv2605_bulk_read(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned int count, u8 *buf)
69{
70 return regmap_bulk_read(pDrv2605data->regmap, reg, buf, count);
71}
72
73static int drv2605_bulk_write(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned int count, const u8 *buf)
74{
75 return regmap_bulk_write(pDrv2605data->regmap, reg, buf, count);
76}
77
78static int drv2605_set_bits(struct drv2605_data *pDrv2605data, unsigned char reg, unsigned char mask, unsigned char val)
79{
80 return regmap_update_bits(pDrv2605data->regmap, reg, mask, val);
81}
82
83static int drv2605_set_go_bit(struct drv2605_data *pDrv2605data, unsigned char val)
84{
85 return drv2605_reg_write(pDrv2605data, GO_REG, (val&0x01));
86}
87
88static void drv2605_poll_go_bit(struct drv2605_data *pDrv2605data)
89{
90 while (drv2605_reg_read(pDrv2605data, GO_REG) == GO)
91 schedule_timeout_interruptible(msecs_to_jiffies(GO_BIT_POLL_INTERVAL));
92}
93
94static int drv2605_select_library(struct drv2605_data *pDrv2605data, unsigned char lib)
95{
96 return drv2605_reg_write(pDrv2605data, LIBRARY_SELECTION_REG, (lib&0x07));
97}
98
99static int drv2605_set_rtp_val(struct drv2605_data *pDrv2605data, char value)
100{
101 /* please be noted: in unsigned mode, maximum is 0xff, in signed mode, maximum is 0x7f */
102 return drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, value);
103}
104
105static int drv2605_set_waveform_sequence(struct drv2605_data *pDrv2605data, unsigned char* seq, unsigned int size)
106{
107 return drv2605_bulk_write(pDrv2605data, WAVEFORM_SEQUENCER_REG, (size>WAVEFORM_SEQUENCER_MAX)?WAVEFORM_SEQUENCER_MAX:size, seq);
108}
109
110static void drv2605_change_mode(struct drv2605_data *pDrv2605data, char work_mode, char dev_mode)
111{
112 /* please be noted : LRA open loop cannot be used with analog input mode */
113 if(dev_mode == DEV_IDLE){
114 pDrv2605data->dev_mode = dev_mode;
115 pDrv2605data->work_mode = work_mode;
116 }else if(dev_mode == DEV_STANDBY){
117 if(pDrv2605data->dev_mode != DEV_STANDBY){
118 pDrv2605data->dev_mode = DEV_STANDBY;
119 drv2605_reg_write(pDrv2605data, MODE_REG, MODE_STANDBY);
120 schedule_timeout_interruptible(msecs_to_jiffies(WAKE_STANDBY_DELAY));
121 }
122 pDrv2605data->work_mode = WORK_IDLE;
123 }else if(dev_mode == DEV_READY){
124 if((work_mode != pDrv2605data->work_mode)
125 ||(dev_mode != pDrv2605data->dev_mode)){
126 pDrv2605data->work_mode = work_mode;
127 pDrv2605data->dev_mode = dev_mode;
128 if((pDrv2605data->work_mode == WORK_VIBRATOR)
129 ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON)
130 ||(pDrv2605data->work_mode == WORK_SEQ_RTP_ON)
131 ||(pDrv2605data->work_mode == WORK_RTP)){
132 drv2605_reg_write(pDrv2605data, MODE_REG, MODE_REAL_TIME_PLAYBACK);
133 }else if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){
134 drv2605_reg_write(pDrv2605data, MODE_REG, MODE_AUDIOHAPTIC);
135 }else if(pDrv2605data->work_mode == WORK_CALIBRATION){
136 drv2605_reg_write(pDrv2605data, MODE_REG, AUTO_CALIBRATION);
137 }else{
138 drv2605_reg_write(pDrv2605data, MODE_REG, MODE_INTERNAL_TRIGGER);
139 schedule_timeout_interruptible(msecs_to_jiffies(STANDBY_WAKE_DELAY));
140 }
141 }
142 }
143}
144
145static void setAudioHapticsEnabled(struct drv2605_data *pDrv2605data, int enable)
146{
147 if (enable)
148 {
149 if(pDrv2605data->work_mode != WORK_AUDIO2HAPTIC){
150 pDrv2605data->vibrator_is_playing = YES;
151 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY);
152
153 drv2605_set_bits(pDrv2605data,
154 Control1_REG,
155 Control1_REG_AC_COUPLE_MASK,
156 AC_COUPLE_ENABLED );
157
158 drv2605_set_bits(pDrv2605data,
159 Control3_REG,
160 Control3_REG_PWMANALOG_MASK,
161 INPUT_ANALOG);
162
163 drv2605_change_mode(pDrv2605data, WORK_AUDIO2HAPTIC, DEV_READY);
164 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_AUDIO2HAPTIC);
165 }
166 } else {
167 // Chip needs to be brought out of standby to change the registers
168 if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){
169 pDrv2605data->vibrator_is_playing = NO;
170 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY);
171
172 drv2605_set_bits(pDrv2605data,
173 Control1_REG,
174 Control1_REG_AC_COUPLE_MASK,
175 AC_COUPLE_DISABLED );
176
177 drv2605_set_bits(pDrv2605data,
178 Control3_REG,
179 Control3_REG_PWMANALOG_MASK,
180 INPUT_PWM);
181
182 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE);
183 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY); // Disable audio-to-haptics
184 }
185 }
186}
187
188static void play_effect(struct drv2605_data *pDrv2605data)
189{
190 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_SEQUENCE_PLAYBACK);
191 drv2605_change_mode(pDrv2605data, WORK_SEQ_PLAYBACK, DEV_READY);
192 drv2605_set_waveform_sequence(pDrv2605data, pDrv2605data->sequence, WAVEFORM_SEQUENCER_MAX);
193 pDrv2605data->vibrator_is_playing = YES;
194 drv2605_set_go_bit(pDrv2605data, GO);
195
196 while((drv2605_reg_read(pDrv2605data, GO_REG) == GO) && (pDrv2605data->should_stop == NO)){
197 schedule_timeout_interruptible(msecs_to_jiffies(GO_BIT_POLL_INTERVAL));
198 }
199
200 if(pDrv2605data->should_stop == YES){
201 drv2605_set_go_bit(pDrv2605data, STOP);
202 }
203
204 if (pDrv2605data->audio_haptics_enabled){
205 setAudioHapticsEnabled(pDrv2605data, YES);
206 } else {
207 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY);
208 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE);
209 pDrv2605data->vibrator_is_playing = NO;
210 wake_unlock(&pDrv2605data->wklock);
211 }
212}
213
214static void play_Pattern_RTP(struct drv2605_data *pDrv2605data)
215{
216 if(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON){
217 drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_OFF, DEV_READY);
218 if(pDrv2605data->repeat_times == 0){
219 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY);
220 pDrv2605data->vibrator_is_playing = NO;
221 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE);
222 wake_unlock(&pDrv2605data->wklock);
223 }else{
224 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->silience_time * NSEC_PER_MSEC), HRTIMER_MODE_REL);
225 }
226 }else if(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF){
227 pDrv2605data->repeat_times--;
228 drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_ON, DEV_READY);
229 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->vibration_time * NSEC_PER_MSEC), HRTIMER_MODE_REL);
230 }
231}
232
233static void play_Seq_RTP(struct drv2605_data *pDrv2605data)
234{
235 if(pDrv2605data->RTPSeq.RTPindex < pDrv2605data->RTPSeq.RTPCounts){
236 int RTPTime = pDrv2605data->RTPSeq.RTPData[pDrv2605data->RTPSeq.RTPindex] >> 8;
237 int RTPVal = pDrv2605data->RTPSeq.RTPData[pDrv2605data->RTPSeq.RTPindex] & 0x00ff ;
238
239 pDrv2605data->vibrator_is_playing = YES;
240 pDrv2605data->RTPSeq.RTPindex++;
241 drv2605_change_mode(pDrv2605data, WORK_SEQ_RTP_ON, DEV_READY);
242 drv2605_set_rtp_val(pDrv2605data, RTPVal);
243
244 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)RTPTime * NSEC_PER_MSEC), HRTIMER_MODE_REL);
245 }else{
246 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY);
247 pDrv2605data->vibrator_is_playing = NO;
248 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE);
249 wake_unlock(&pDrv2605data->wklock);
250 }
251}
252
253static void vibrator_off(struct drv2605_data *pDrv2605data)
254{
255 if (pDrv2605data->vibrator_is_playing) {
256 if(pDrv2605data->audio_haptics_enabled == YES){
257 setAudioHapticsEnabled(pDrv2605data, YES);
258 }else{
259 pDrv2605data->vibrator_is_playing = NO;
260 drv2605_set_go_bit(pDrv2605data, STOP);
261 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY);
262 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_IDLE);
263 wake_unlock(&pDrv2605data->wklock);
264 }
265 }
266}
267
268static void drv2605_stop(struct drv2605_data *pDrv2605data)
269{
270 if(pDrv2605data->vibrator_is_playing){
271 if(pDrv2605data->work_mode == WORK_AUDIO2HAPTIC){
272 setAudioHapticsEnabled(pDrv2605data, NO);
273 }else if((pDrv2605data->work_mode == WORK_VIBRATOR)
274 ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_ON)
275 ||(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF)
276 ||(pDrv2605data->work_mode == WORK_SEQ_RTP_ON)
277 ||(pDrv2605data->work_mode == WORK_SEQ_RTP_OFF)
278 ||(pDrv2605data->work_mode == WORK_RTP)){
279 vibrator_off(pDrv2605data);
280 }else if(pDrv2605data->work_mode == WORK_SEQ_PLAYBACK){
281 }else{
282 printk("%s, err mode=%d \n", __FUNCTION__, pDrv2605data->work_mode);
283 }
284 }
285}
286
287static int vibrator_get_time(struct timed_output_dev *dev)
288{
289 struct drv2605_data *pDrv2605data = container_of(dev, struct drv2605_data, to_dev);
290
291 if (hrtimer_active(&pDrv2605data->timer)) {
292 ktime_t r = hrtimer_get_remaining(&pDrv2605data->timer);
293 return ktime_to_ms(r);
294 }
295
296 return 0;
297}
298
299static void vibrator_enable( struct timed_output_dev *dev, int value)
300{
301 struct drv2605_data *pDrv2605data = container_of(dev, struct drv2605_data, to_dev);
302
303 pDrv2605data->should_stop = YES;
304 hrtimer_cancel(&pDrv2605data->timer);
305 cancel_work_sync(&pDrv2605data->vibrator_work);
306
307 mutex_lock(&pDrv2605data->lock);
308
309 drv2605_stop(pDrv2605data);
310
311 if (value > 0) {
312 if(pDrv2605data->audio_haptics_enabled == NO){
313 wake_lock(&pDrv2605data->wklock);
314 }
315
316 drv2605_change_mode(pDrv2605data, WORK_VIBRATOR, DEV_READY);
317 pDrv2605data->vibrator_is_playing = YES;
318 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK);
319
320 value = (value>MAX_TIMEOUT)?MAX_TIMEOUT:value;
321 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL);
322 }
323
324 mutex_unlock(&pDrv2605data->lock);
325}
326
327static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
328{
329 struct drv2605_data *pDrv2605data = container_of(timer, struct drv2605_data, timer);
330
331 schedule_work(&pDrv2605data->vibrator_work);
332
333 return HRTIMER_NORESTART;
334}
335
336static void vibrator_work_routine(struct work_struct *work)
337{
338 struct drv2605_data *pDrv2605data = container_of(work, struct drv2605_data, vibrator_work);
339
340 mutex_lock(&pDrv2605data->lock);
341
342 if((pDrv2605data->work_mode == WORK_VIBRATOR)
343 ||(pDrv2605data->work_mode == WORK_RTP)){
344 vibrator_off(pDrv2605data);
345 }else if(pDrv2605data->work_mode == WORK_SEQ_PLAYBACK){
346 play_effect(pDrv2605data);
347 }else if((pDrv2605data->work_mode == WORK_PATTERN_RTP_ON)||(pDrv2605data->work_mode == WORK_PATTERN_RTP_OFF)){
348 play_Pattern_RTP(pDrv2605data);
349 }else if((pDrv2605data->work_mode == WORK_SEQ_RTP_ON)||(pDrv2605data->work_mode == WORK_SEQ_RTP_OFF)){
350 play_Seq_RTP(pDrv2605data);
351 }
352
353 mutex_unlock(&pDrv2605data->lock);
354}
355
356static int dev2605_open (struct inode * i_node, struct file * filp)
357{
358 if(pDRV2605data == NULL){
359 return -ENODEV;
360 }
361
362 filp->private_data = pDRV2605data;
363 return 0;
364}
365
366static ssize_t dev2605_read(struct file* filp, char* buff, size_t length, loff_t* offset)
367{
368 struct drv2605_data *pDrv2605data = (struct drv2605_data *)filp->private_data;
369 int ret = 0;
370
371 if(pDrv2605data->ReadLen > 0){
372 ret = copy_to_user(buff, pDrv2605data->ReadBuff, pDrv2605data->ReadLen);
373 if (ret != 0){
374 printk("%s, copy_to_user err=%d \n", __FUNCTION__, ret);
375 }else{
376 ret = pDrv2605data->ReadLen;
377 }
378 pDrv2605data->ReadLen = 0;
379 }
380
381 return ret;
382}
383
384static bool isforDebug(int cmd){
385 return ((cmd == HAPTIC_CMDID_REG_WRITE)
386 ||(cmd == HAPTIC_CMDID_REG_READ)
387 ||(cmd == HAPTIC_CMDID_REG_SETBIT));
388}
389
390static ssize_t dev2605_write(struct file* filp, const char* buff, size_t len, loff_t* off)
391{
392 struct drv2605_data *pDrv2605data = (struct drv2605_data *)filp->private_data;
393
394 if(isforDebug(buff[0])){
395 }else{
396 pDrv2605data->should_stop = YES;
397 hrtimer_cancel(&pDrv2605data->timer);
398 cancel_work_sync(&pDrv2605data->vibrator_work);
399 }
400
401 mutex_lock(&pDrv2605data->lock);
402
403 if(isforDebug(buff[0])){
404 }else{
405 drv2605_stop(pDrv2605data);
406 }
407
408 switch(buff[0])
409 {
410 case HAPTIC_CMDID_PLAY_SINGLE_EFFECT:
411 case HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE:
412 {
413 memset(&pDrv2605data->sequence, 0, WAVEFORM_SEQUENCER_MAX);
414 if (!copy_from_user(&pDrv2605data->sequence, &buff[1], len - 1))
415 {
416 if(pDrv2605data->audio_haptics_enabled == NO){
417 wake_lock(&pDrv2605data->wklock);
418 }
419 pDrv2605data->should_stop = NO;
420 drv2605_change_mode(pDrv2605data, WORK_SEQ_PLAYBACK, DEV_IDLE);
421 schedule_work(&pDrv2605data->vibrator_work);
422 }
423 break;
424 }
425 case HAPTIC_CMDID_PLAY_TIMED_EFFECT:
426 {
427 unsigned int value = 0;
428 value = buff[2];
429 value <<= 8;
430 value |= buff[1];
431
432 if (value > 0)
433 {
434 if(pDrv2605data->audio_haptics_enabled == NO){
435 wake_lock(&pDrv2605data->wklock);
436 }
437 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK);
438 pDrv2605data->vibrator_is_playing = YES;
439 value = (value > MAX_TIMEOUT)?MAX_TIMEOUT:value;
440 drv2605_change_mode(pDrv2605data, WORK_RTP, DEV_READY);
441
442 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL);
443 }
444 break;
445 }
446
447 case HAPTIC_CMDID_PATTERN_RTP:
448 {
449 unsigned char strength = 0;
450
451 pDrv2605data->vibration_time = (int)((((int)buff[2])<<8) | (int)buff[1]);
452 pDrv2605data->silience_time = (int)((((int)buff[4])<<8) | (int)buff[3]);
453 strength = buff[5];
454 pDrv2605data->repeat_times = buff[6];
455
456 if(pDrv2605data->vibration_time > 0){
457 if(pDrv2605data->audio_haptics_enabled == NO){
458 wake_lock(&pDrv2605data->wklock);
459 }
460 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK);
461 pDrv2605data->vibrator_is_playing = YES;
462 if(pDrv2605data->repeat_times > 0)
463 pDrv2605data->repeat_times--;
464 if (pDrv2605data->vibration_time > MAX_TIMEOUT)
465 pDrv2605data->vibration_time = MAX_TIMEOUT;
466 drv2605_change_mode(pDrv2605data, WORK_PATTERN_RTP_ON, DEV_READY);
467 drv2605_set_rtp_val(pDrv2605data, strength);
468
469 hrtimer_start(&pDrv2605data->timer, ns_to_ktime((u64)pDrv2605data->vibration_time * NSEC_PER_MSEC), HRTIMER_MODE_REL);
470 }
471 break;
472 }
473
474 case HAPTIC_CMDID_RTP_SEQUENCE:
475 {
476 memset(&pDrv2605data->RTPSeq, 0, sizeof(struct RTP_Seq));
477 if(((len-1)%2) == 0){
478 pDrv2605data->RTPSeq.RTPCounts = (len-1)/2;
479 if((pDrv2605data->RTPSeq.RTPCounts <= MAX_RTP_SEQ)&&(pDrv2605data->RTPSeq.RTPCounts>0)){
480 if(copy_from_user(pDrv2605data->RTPSeq.RTPData, &buff[1], pDrv2605data->RTPSeq.RTPCounts*2) != 0){
481 printk("%s, rtp_seq copy seq err\n", __FUNCTION__);
482 break;
483 }
484
485 if(pDrv2605data->audio_haptics_enabled == NO){
486 wake_lock(&pDrv2605data->wklock);
487 }
488 switch_set_state(&pDrv2605data->sw_dev, SW_STATE_RTP_PLAYBACK);
489 drv2605_change_mode(pDrv2605data, WORK_SEQ_RTP_OFF, DEV_IDLE);
490 schedule_work(&pDrv2605data->vibrator_work);
491 }else{
492 printk("%s, rtp_seq count error,maximum=%d\n", __FUNCTION__,MAX_RTP_SEQ);
493 }
494 }else{
495 printk("%s, rtp_seq len error\n", __FUNCTION__);
496 }
497 break;
498 }
499
500 case HAPTIC_CMDID_STOP:
501 {
502 break;
503 }
504
505 case HAPTIC_CMDID_AUDIOHAPTIC_ENABLE:
506 {
507 if(pDrv2605data->audio_haptics_enabled == NO){
508 wake_lock(&pDrv2605data->wklock);
509 }
510 pDrv2605data->audio_haptics_enabled = YES;
511 setAudioHapticsEnabled(pDrv2605data, YES);
512 break;
513 }
514
515 case HAPTIC_CMDID_AUDIOHAPTIC_DISABLE:
516 {
517 if(pDrv2605data->audio_haptics_enabled == YES){
518 pDrv2605data->audio_haptics_enabled = NO;
519 wake_unlock(&pDrv2605data->wklock);
520 }
521 break;
522 }
523
524 case HAPTIC_CMDID_REG_READ:
525 {
526 if(len == 2){
527 pDrv2605data->ReadLen = 1;
528 pDrv2605data->ReadBuff[0] = drv2605_reg_read(pDrv2605data, buff[1]);
529 }else if(len == 3){
530 pDrv2605data->ReadLen = (buff[2]>MAX_READ_BYTES)?MAX_READ_BYTES:buff[2];
531 drv2605_bulk_read(pDrv2605data, buff[1], pDrv2605data->ReadLen, pDrv2605data->ReadBuff);
532 }else{
533 printk("%s, reg_read len error\n", __FUNCTION__);
534 }
535 break;
536 }
537
538 case HAPTIC_CMDID_REG_WRITE:
539 {
540 if((len-1) == 2){
541 drv2605_reg_write(pDrv2605data, buff[1], buff[2]);
542 }else if((len-1)>2){
543 unsigned char *data = (unsigned char *)kzalloc(len-2, GFP_KERNEL);
544 if(data != NULL){
545 if(copy_from_user(data, &buff[2], len-2) != 0){
546 printk("%s, reg copy err\n", __FUNCTION__);
547 }else{
548 drv2605_bulk_write(pDrv2605data, buff[1], len-2, data);
549 }
550 kfree(data);
551 }
552 }else{
553 printk("%s, reg_write len error\n", __FUNCTION__);
554 }
555 break;
556 }
557
558 case HAPTIC_CMDID_REG_SETBIT:
559 {
560 int i=1;
561 for(i=1; i< len; ){
562 drv2605_set_bits(pDrv2605data, buff[i], buff[i+1], buff[i+2]);
563 i += 3;
564 }
565 break;
566 }
567 default:
568 printk("%s, unknown HAPTIC cmd\n", __FUNCTION__);
569 break;
570 }
571
572 mutex_unlock(&pDrv2605data->lock);
573
574 return len;
575}
576
577
578static struct file_operations fops =
579{
580 .open = dev2605_open,
581 .read = dev2605_read,
582 .write = dev2605_write,
583};
584
585void drv2605_early_suspend(struct early_suspend *h){
586 struct drv2605_data *pDrv2605data = container_of(h, struct drv2605_data, early_suspend);
587
588 pDrv2605data->should_stop = YES;
589 hrtimer_cancel(&pDrv2605data->timer);
590 cancel_work_sync(&pDrv2605data->vibrator_work);
591
592 mutex_lock(&pDrv2605data->lock);
593
594 drv2605_stop(pDrv2605data);
595 if(pDrv2605data->audio_haptics_enabled == YES){
596 wake_unlock(&pDrv2605data->wklock);
597 }
598
599 mutex_unlock(&pDrv2605data->lock);
600 return ;
601}
602
603void drv2605_late_resume(struct early_suspend *h) {
604 struct drv2605_data *pDrv2605data = container_of(h, struct drv2605_data, early_suspend);
605
606 mutex_lock(&pDrv2605data->lock);
607 if(pDrv2605data->audio_haptics_enabled == YES){
608 wake_lock(&pDrv2605data->wklock);
609 setAudioHapticsEnabled(pDrv2605data, YES);
610 }
611 mutex_unlock(&pDrv2605data->lock);
612 return ;
613 }
614
615static int Haptics_init(struct drv2605_data *pDrv2605data)
616{
617 int reval = -ENOMEM;
618
619 pDrv2605data->version = MKDEV(0,0);
620 reval = alloc_chrdev_region(&pDrv2605data->version, 0, 1, HAPTICS_DEVICE_NAME);
621 if (reval < 0)
622 {
623 printk(KERN_ALERT"drv2605: error getting major number %d\n", reval);
624 goto fail0;
625 }
626
627 pDrv2605data->class = class_create(THIS_MODULE, HAPTICS_DEVICE_NAME);
628 if (!pDrv2605data->class)
629 {
630 printk(KERN_ALERT"drv2605: error creating class\n");
631 goto fail1;
632 }
633
634 pDrv2605data->device = device_create(pDrv2605data->class, NULL, pDrv2605data->version, NULL, HAPTICS_DEVICE_NAME);
635 if (!pDrv2605data->device)
636 {
637 printk(KERN_ALERT"drv2605: error creating device 2605\n");
638 goto fail2;
639 }
640
641 cdev_init(&pDrv2605data->cdev, &fops);
642 pDrv2605data->cdev.owner = THIS_MODULE;
643 pDrv2605data->cdev.ops = &fops;
644 reval = cdev_add(&pDrv2605data->cdev, pDrv2605data->version, 1);
645 if (reval)
646 {
647 printk(KERN_ALERT"drv2605: fail to add cdev\n");
648 goto fail3;
649 }
650
651 pDrv2605data->sw_dev.name = "haptics";
652 reval = switch_dev_register(&pDrv2605data->sw_dev);
653 if (reval < 0) {
654 printk(KERN_ALERT"drv2605: fail to register switch\n");
655 goto fail4;
656 }
657
658 pDrv2605data->to_dev.name = "vibrator";
659 pDrv2605data->to_dev.get_time = vibrator_get_time;
660 pDrv2605data->to_dev.enable = vibrator_enable;
661
662 if (timed_output_dev_register(&(pDrv2605data->to_dev)) < 0)
663 {
664 printk(KERN_ALERT"drv2605: fail to create timed output dev\n");
665 goto fail3;
666 }
667
668#ifdef CONFIG_HAS_EARLYSUSPEND
669 pDrv2605data->early_suspend.suspend = drv2605_early_suspend;
670 pDrv2605data->early_suspend.resume = drv2605_late_resume;
671 pDrv2605data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
672 register_early_suspend(&pDrv2605data->early_suspend);
673#endif
674
675 hrtimer_init(&pDrv2605data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
676 pDrv2605data->timer.function = vibrator_timer_func;
677 INIT_WORK(&pDrv2605data->vibrator_work, vibrator_work_routine);
678
679 wake_lock_init(&pDrv2605data->wklock, WAKE_LOCK_SUSPEND, "vibrator");
680 mutex_init(&pDrv2605data->lock);
681
682 return 0;
683
684fail4:
685 switch_dev_unregister(&pDrv2605data->sw_dev);
686fail3:
687 device_destroy(pDrv2605data->class, pDrv2605data->version);
688fail2:
689 class_destroy(pDrv2605data->class);
690fail1:
691 unregister_chrdev_region(pDrv2605data->version, 1);
692fail0:
693 return reval;
694}
695
696static void dev_init_platform_data(struct drv2605_data *pDrv2605data)
697{
698 struct drv2605_platform_data *pDrv2605Platdata = &pDrv2605data->PlatData;
699 struct actuator_data actuator = pDrv2605Platdata->actuator;
700 struct audio2haptics_data a2h = pDrv2605Platdata->a2h;
701 unsigned char temp = 0;
702
703 drv2605_select_library(pDrv2605data, actuator.g_effect_bank);
704
705 //OTP memory saves data from 0x16 to 0x1a
706 if(pDrv2605data->OTP == 0) {
707 if(actuator.rated_vol != 0){
708 drv2605_reg_write(pDrv2605data, RATED_VOLTAGE_REG, actuator.rated_vol);
709 }else{
710 printk("%s, ERROR Rated ZERO\n", __FUNCTION__);
711 }
712
713 if(actuator.over_drive_vol != 0){
714 drv2605_reg_write(pDrv2605data, OVERDRIVE_CLAMP_VOLTAGE_REG, actuator.over_drive_vol);
715 }else{
716 printk("%s, ERROR OverDriveVol ZERO\n", __FUNCTION__);
717 }
718
719 drv2605_set_bits(pDrv2605data,
720 FEEDBACK_CONTROL_REG,
721 FEEDBACK_CONTROL_DEVICE_TYPE_MASK,
722 (actuator.device_type == LRA)?FEEDBACK_CONTROL_MODE_LRA:FEEDBACK_CONTROL_MODE_ERM);
723 }else{
724 printk("%s, OTP programmed\n", __FUNCTION__);
725 }
726
727 if(pDrv2605Platdata->loop == OPEN_LOOP){
728 temp = BIDIR_INPUT_BIDIRECTIONAL;
729 }else{
730 if(pDrv2605Platdata->BIDIRInput == UniDirectional){
731 temp = BIDIR_INPUT_UNIDIRECTIONAL;
732 }else{
733 temp = BIDIR_INPUT_BIDIRECTIONAL;
734 }
735 }
736
737 if(actuator.device_type == LRA){
738 unsigned char DriveTime = 5*(1000 - actuator.LRAFreq)/actuator.LRAFreq;
739 drv2605_set_bits(pDrv2605data,
740 Control1_REG,
741 Control1_REG_DRIVE_TIME_MASK,
742 DriveTime);
743 printk("%s, LRA = %d, DriveTime=0x%x\n", __FUNCTION__, actuator.LRAFreq, DriveTime);
744 }
745
746 drv2605_set_bits(pDrv2605data,
747 Control2_REG,
748 Control2_REG_BIDIR_INPUT_MASK,
749 temp);
750
751 if((pDrv2605Platdata->loop == OPEN_LOOP)&&(actuator.device_type == LRA))
752 {
753 temp = LRA_OpenLoop_Enabled;
754 }
755 else if((pDrv2605Platdata->loop == OPEN_LOOP)&&(actuator.device_type == ERM))
756 {
757 temp = ERM_OpenLoop_Enabled;
758 }
759 else
760 {
761 temp = ERM_OpenLoop_Disable|LRA_OpenLoop_Disable;
762 }
763
764 if((pDrv2605Platdata->loop == CLOSE_LOOP) &&(pDrv2605Platdata->BIDIRInput == UniDirectional))
765 {
766 temp |= RTP_FORMAT_UNSIGNED;
767 drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0xff);
768 }
769 else
770 {
771 if(pDrv2605Platdata->RTPFormat == Signed)
772 {
773 temp |= RTP_FORMAT_SIGNED;
774 drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0x7f);
775 }
776 else
777 {
778 temp |= RTP_FORMAT_UNSIGNED;
779 drv2605_reg_write(pDrv2605data, REAL_TIME_PLAYBACK_REG, 0xff);
780 }
781 }
782 drv2605_set_bits(pDrv2605data,
783 Control3_REG,
784 Control3_REG_LOOP_MASK|Control3_REG_FORMAT_MASK,
785 temp);
786
787 //for audio to haptics
788 if(pDrv2605Platdata->GpioTrigger == 0) //not used as external trigger
789 {
790 drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MIN_INPUT_REG, a2h.a2h_min_input);
791 drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MAX_INPUT_REG, a2h.a2h_max_input);
792 drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MIN_OUTPUT_REG, a2h.a2h_min_output);
793 drv2605_reg_write(pDrv2605data, AUDIO_HAPTICS_MAX_OUTPUT_REG, a2h.a2h_max_output);
794 }
795}
796
797static int dev_auto_calibrate(struct drv2605_data *pDrv2605data)
798{
799 int err = 0, status=0;
800
801 drv2605_change_mode(pDrv2605data, WORK_CALIBRATION, DEV_READY);
802 drv2605_set_go_bit(pDrv2605data, GO);
803
804 /* Wait until the procedure is done */
805 drv2605_poll_go_bit(pDrv2605data);
806 /* Read status */
807 status = drv2605_reg_read(pDrv2605data, STATUS_REG);
808
809 printk("%s, calibration status =0x%x\n", __FUNCTION__, status);
810
811 /* Read calibration results */
812 drv2605_reg_read(pDrv2605data, AUTO_CALI_RESULT_REG);
813 drv2605_reg_read(pDrv2605data, AUTO_CALI_BACK_EMF_RESULT_REG);
814 drv2605_reg_read(pDrv2605data, FEEDBACK_CONTROL_REG);
815
816 return err;
817}
818
819static struct regmap_config drv2605_i2c_regmap = {
820 .reg_bits = 8,
821 .val_bits = 8,
822 .cache_type = REGCACHE_NONE,
823};
824
825static int drv2605_probe(struct i2c_client* client, const struct i2c_device_id* id)
826{
827 struct drv2605_data *pDrv2605data;
828 struct drv2605_platform_data *pDrv2605Platdata = client->dev.platform_data;
829
830 int err = 0;
831 int status = 0;
832
833 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
834 {
835 printk(KERN_ERR"%s:I2C check failed\n", __FUNCTION__);
836 return -ENODEV;
837 }
838
839 pDrv2605data = devm_kzalloc(&client->dev, sizeof(struct drv2605_data), GFP_KERNEL);
840 if (pDrv2605data == NULL){
841 printk(KERN_ERR"%s:no memory\n", __FUNCTION__);
842 return -ENOMEM;
843 }
844
845 pDrv2605data->regmap = devm_regmap_init_i2c(client, &drv2605_i2c_regmap);
846 if (IS_ERR(pDrv2605data->regmap)) {
847 err = PTR_ERR(pDrv2605data->regmap);
848 printk(KERN_ERR"%s:Failed to allocate register map: %d\n",__FUNCTION__,err);
849 return err;
850 }
851
852 memcpy(&pDrv2605data->PlatData, pDrv2605Platdata, sizeof(struct drv2605_platform_data));
853 i2c_set_clientdata(client,pDrv2605data);
854
855 if(pDrv2605data->PlatData.GpioTrigger){
856 err = gpio_request(pDrv2605data->PlatData.GpioTrigger,HAPTICS_DEVICE_NAME"Trigger");
857 if(err < 0){
858 printk(KERN_ERR"%s: GPIO request Trigger error\n", __FUNCTION__);
859 goto exit_gpio_request_failed;
860 }
861 }
862
863 if(pDrv2605data->PlatData.GpioEnable){
864 err = gpio_request(pDrv2605data->PlatData.GpioEnable,HAPTICS_DEVICE_NAME"Enable");
865 if(err < 0){
866 printk(KERN_ERR"%s: GPIO request enable error\n", __FUNCTION__);
867 goto exit_gpio_request_failed;
868 }
869
870 /* Enable power to the chip */
871 gpio_direction_output(pDrv2605data->PlatData.GpioEnable, 1);
872
873 /* Wait 30 us */
874 udelay(30);
875 }
876
877 err = drv2605_reg_read(pDrv2605data, STATUS_REG);
878 if(err < 0){
879 printk("%s, i2c bus fail (%d)\n", __FUNCTION__, err);
880 goto exit_gpio_request_failed;
881 }else{
882 printk("%s, i2c status (0x%x)\n", __FUNCTION__, err);
883 status = err;
884 }
885 /* Read device ID */
886 pDrv2605data->device_id = (status & DEV_ID_MASK);
887 switch (pDrv2605data->device_id)
888 {
889 case DRV2605_VER_1DOT1:
890 printk("drv2605 driver found: drv2605 v1.1.\n");
891 break;
892 case DRV2605_VER_1DOT0:
893 printk("drv2605 driver found: drv2605 v1.0.\n");
894 break;
895 case DRV2604:
896 printk(KERN_ALERT"drv2605 driver found: drv2604.\n");
897 break;
898 default:
899 printk(KERN_ERR"drv2605 driver found: unknown.\n");
900 break;
901 }
902
903 if((pDrv2605data->device_id != DRV2605_VER_1DOT1)
904 &&(pDrv2605data->device_id != DRV2605_VER_1DOT0)){
905 printk("%s, status(0x%x),device_id(%d) fail\n",
906 __FUNCTION__, status, pDrv2605data->device_id);
907 goto exit_gpio_request_failed;
908 }
909
910 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_READY);
911 schedule_timeout_interruptible(msecs_to_jiffies(STANDBY_WAKE_DELAY));
912
913 pDrv2605data->OTP = drv2605_reg_read(pDrv2605data, AUTOCAL_MEM_INTERFACE_REG) & AUTOCAL_MEM_INTERFACE_REG_OTP_MASK;
914
915 dev_init_platform_data(pDrv2605data);
916
917 if(pDrv2605data->OTP == 0){
918 err = dev_auto_calibrate(pDrv2605data);
919 if(err < 0){
920 printk("%s, ERROR, calibration fail\n", __FUNCTION__);
921 }
922 }
923
924 /* Put hardware in standby */
925 drv2605_change_mode(pDrv2605data, WORK_IDLE, DEV_STANDBY);
926
927 Haptics_init(pDrv2605data);
928
929 pDRV2605data = pDrv2605data;
930 printk("drv2605 probe succeeded\n");
931
932 return 0;
933
934exit_gpio_request_failed:
935 if(pDrv2605data->PlatData.GpioTrigger){
936 gpio_free(pDrv2605data->PlatData.GpioTrigger);
937 }
938
939 if(pDrv2605data->PlatData.GpioEnable){
940 gpio_free(pDrv2605data->PlatData.GpioEnable);
941 }
942
943 printk(KERN_ERR"%s failed, err=%d\n",__FUNCTION__, err);
944 return err;
945}
946
947static int drv2605_remove(struct i2c_client* client)
948{
949 struct drv2605_data *pDrv2605data = i2c_get_clientdata(client);
950
951 device_destroy(pDrv2605data->class, pDrv2605data->version);
952 class_destroy(pDrv2605data->class);
953 unregister_chrdev_region(pDrv2605data->version, 1);
954
955 if(pDrv2605data->PlatData.GpioTrigger)
956 gpio_free(pDrv2605data->PlatData.GpioTrigger);
957
958 if(pDrv2605data->PlatData.GpioEnable)
959 gpio_free(pDrv2605data->PlatData.GpioEnable);
960
961#ifdef CONFIG_HAS_EARLYSUSPEND
962 unregister_early_suspend(&pDrv2605data->early_suspend);
963#endif
964
965 printk(KERN_ALERT"drv2605 remove");
966
967 return 0;
968}
969
970static struct i2c_device_id drv2605_id_table[] =
971{
972 { HAPTICS_DEVICE_NAME, 0 },
973 {}
974};
975MODULE_DEVICE_TABLE(i2c, drv2605_id_table);
976
977static struct i2c_driver drv2605_driver =
978{
979 .driver = {
980 .name = HAPTICS_DEVICE_NAME,
981 .owner = THIS_MODULE,
982 },
983 .id_table = drv2605_id_table,
984 .probe = drv2605_probe,
985 .remove = drv2605_remove,
986};
987
988static int __init drv2605_init(void)
989{
990 return i2c_add_driver(&drv2605_driver);
991}
992
993static void __exit drv2605_exit(void)
994{
995 i2c_del_driver(&drv2605_driver);
996}
997
998module_init(drv2605_init);
999module_exit(drv2605_exit);
1000
1001MODULE_AUTHOR("Texas Instruments Inc.");
1002MODULE_DESCRIPTION("Driver for "HAPTICS_DEVICE_NAME); \ No newline at end of file
diff --git a/drv2605.c b/drv2605.c
new file mode 100755
index 0000000..dd3308f
--- /dev/null
+++ b/drv2605.c
@@ -0,0 +1,1306 @@
1/*
2** =============================================================================
3** Copyright (c) 2016 Texas Instruments Inc.
4**
5** This program is free software; you can redistribute it and/or
6** modify it under the terms of the GNU General Public License
7** as published by the Free Software Foundation; either version 2
8** of the License, or (at your option) any later version.
9**
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.
14**
15** File:
16** drv2605.c
17**
18** Description:
19** DRV2605 chip driver
20**
21** =============================================================================
22*/
23#define DEBUG
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/types.h>
30#include <linux/fs.h>
31#include <linux/i2c.h>
32#include <linux/semaphore.h>
33#include <linux/device.h>
34#include <linux/syscalls.h>
35#include <asm/uaccess.h>
36#include <linux/gpio.h>
37#include <linux/sched.h>
38#include <linux/spinlock_types.h>
39#include <linux/spinlock.h>
40#include <linux/delay.h>
41#include <linux/of.h>
42#include <linux/of_gpio.h>
43#include <linux/jiffies.h>
44#include <linux/err.h>
45#include <linux/clk.h>
46#include <linux/miscdevice.h>
47#include "drv2605.h"
48
49static struct drv2605_data *g_DRV2605data = NULL;
50static bool g_logEnable = false;
51
52const char *TS2200EffectNameStr[] = {
53 "1 Strong Click - 100%",
54 "2 Strong Click - 60%",
55 "3 Strong Click - 30%",
56 "4 Sharp Click - 100%",
57 "5 Sharp Click - 60%",
58 "6 Sharp Click - 30%",
59 "7 Soft Bump - 100%",
60 "8 Soft Bump - 60%",
61 "9 Soft Bump - 30%",
62 "10 Double Click - 100%",
63 "11 Double Click - 60%",
64 "12 Triple Click - 100%",
65 "13 Soft Fuzz - 60%",
66 "14 Strong Buzz - 100%",
67 "15 750 ms Alert 100%",
68 "16 1000 ms Alert 100%",
69 "17 Strong Click 1 - 100%",
70 "18 Strong Click 2 - 80%",
71 "19 Strong Click 3 - 60%",
72 "20 Strong Click 4 - 30%",
73 "21 Medium Click 1 - 100%",
74 "22 Medium Click 2 - 80%",
75 "23 Medium Click 3 - 60%",
76 "24 Sharp Tick 1 - 100%",
77 "25 Sharp Tick 2 - 80%",
78 "26 Sharp Tick 3 – 60%",
79 "27 Short Double Click Strong 1 – 100%",
80 "28 Short Double Click Strong 2 – 80%",
81 "29 Short Double Click Strong 3 – 60%",
82 "30 Short Double Click Strong 4 – 30%",
83 "31 Short Double Click Medium 1 – 100%",
84 "32 Short Double Click Medium 2 – 80%",
85 "33 Short Double Click Medium 3 – 60%",
86 "34 Short Double Sharp Tick 1 – 100%",
87 "35 Short Double Sharp Tick 2 – 80%",
88 "36 Short Double Sharp Tick 3 – 60%",
89 "37 Long Double Sharp Click Strong 1 – 100%",
90 "38 Long Double Sharp Click Strong 2 – 80%",
91 "39 Long Double Sharp Click Strong 3 – 60%",
92 "40 Long Double Sharp Click Strong 4 – 30%",
93 "41 Long Double Sharp Click Medium 1 – 100%",
94 "42 Long Double Sharp Click Medium 2 – 80%",
95 "43 Long Double Sharp Click Medium 3 – 60%",
96 "44 Long Double Sharp Tick 1 – 100%",
97 "45 Long Double Sharp Tick 2 – 80%",
98 "46 Long Double Sharp Tick 3 – 60%",
99 "47 Buzz 1 – 100%",
100 "48 Buzz 2 – 80%",
101 "49 Buzz 3 – 60%",
102 "50 Buzz 4 – 40%",
103 "51 Buzz 5 – 20%",
104 "52 Pulsing Strong 1 – 100%",
105 "53 Pulsing Strong 2 – 60%",
106 "54 Pulsing Medium 1 – 100%",
107 "55 Pulsing Medium 2 – 60%",
108 "56 Pulsing Sharp 1 – 100%",
109 "57 Pulsing Sharp 2 – 60%",
110 "58 Transition Click 1 – 100%",
111 "59 Transition Click 2 – 80%",
112 "60 Transition Click 3 – 60%",
113 "61 Transition Click 4 – 40%",
114 "62 Transition Click 5 – 20%",
115 "63 Transition Click 6 – 10%",
116 "64 Transition Hum 1 – 100%",
117 "65 Transition Hum 2 – 80%",
118 "66 Transition Hum 3 – 60%",
119 "67 Transition Hum 4 – 40%",
120 "68 Transition Hum 5 – 20%",
121 "69 Transition Hum 6 – 10%",
122 "70 Transition Ramp Down Long Smooth 1 – 100 to 0%",
123 "71 Transition Ramp Down Long Smooth 2 – 100 to 0%",
124 "72 Transition Ramp Down Medium Smooth 1 – 100 to 0%",
125 "73 Transition Ramp Down Medium Smooth 2 – 100 to 0%",
126 "74 Transition Ramp Down Short Smooth 1 – 100 to 0%",
127 "75 Transition Ramp Down Short Smooth 2 – 100 to 0%",
128 "76 Transition Ramp Down Long Sharp 1 – 100 to 0%",
129 "77 Transition Ramp Down Long Sharp 2 – 100 to 0%",
130 "78 Transition Ramp Down Medium Sharp 1 – 100 to 0%",
131 "79 Transition Ramp Down Medium Sharp 2 – 100 to 0%",
132 "80 Transition Ramp Down Short Sharp 1 – 100 to 0%",
133 "81 Transition Ramp Down Short Sharp 2 – 100 to 0%",
134 "82 Transition Ramp Up Long Smooth 1 – 0 to 100%",
135 "83 Transition Ramp Up Long Smooth 2 – 0 to 100%",
136 "84 Transition Ramp Up Medium Smooth 1 – 0 to 100%",
137 "85 Transition Ramp Up Medium Smooth 2 – 0 to 100%",
138 "86 Transition Ramp Up Short Smooth 1 – 0 to 100%",
139 "87 Transition Ramp Up Short Smooth 2 – 0 to 100%",
140 "88 Transition Ramp Up Long Sharp 1 – 0 to 100%",
141 "89 Transition Ramp Up Long Sharp 2 – 0 to 100%",
142 "90 Transition Ramp Up Medium Sharp 1 – 0 to 100%",
143 "91 Transition Ramp Up Medium Sharp 2 – 0 to 100%",
144 "92 Transition Ramp Up Short Sharp 1 – 0 to 100%",
145 "93 Transition Ramp Up Short Sharp 2 – 0 to 100%",
146 "94 Transition Ramp Down Long Smooth 1 – 50 to 0%",
147 "95 Transition Ramp Down Long Smooth 2 – 50 to 0%",
148 "96 Transition Ramp Down Medium Smooth 1 – 50 to 0%",
149 "97 Transition Ramp Down Medium Smooth 2 – 50 to 0%",
150 "98 Transition Ramp Down Short Smooth 1 – 50 to 0%",
151 "99 Transition Ramp Down Short Smooth 2 – 50 to 0%",
152 "100 Transition Ramp Down Long Sharp 1 – 50 to 0%",
153 "101 Transition Ramp Down Long Sharp 2 – 50 to 0%",
154 "102 Transition Ramp Down Medium Sharp 1 – 50 to 0%",
155 "103 Transition Ramp Down Medium Sharp 2 – 50 to 0%",
156 "104 Transition Ramp Down Short Sharp 1 – 50 to 0%",
157 "105 Transition Ramp Down Short Sharp 2 – 50 to 0%",
158 "106 Transition Ramp Up Long Smooth 1 – 0 to 50%",
159 "107 Transition Ramp Up Long Smooth 2 – 0 to 50%",
160 "108 Transition Ramp Up Medium Smooth 1 – 0 to 50%",
161 "109 Transition Ramp Up Medium Smooth 2 – 0 to 50%",
162 "110 Transition Ramp Up Short Smooth 1 – 0 to 50%",
163 "111 Transition Ramp Up Short Smooth 2 – 0 to 50%",
164 "112 Transition Ramp Up Long Sharp 1 – 0 to 50%",
165 "113 Transition Ramp Up Long Sharp 2 – 0 to 50%",
166 "114 Transition Ramp Up Medium Sharp 1 – 0 to 50%",
167 "115 Transition Ramp Up Medium Sharp 2 – 0 to 50%",
168 "116 Transition Ramp Up Short Sharp 1 – 0 to 50%",
169 "117 Transition Ramp Up Short Sharp 2 – 0 to 50%",
170 "118 Long buzz for programmatic stopping – 100%",
171 "119 Smooth Hum 1 (No kick or brake pulse) – 50%",
172 "120 Smooth Hum 2 (No kick or brake pulse) – 40%",
173 "121 Smooth Hum 3 (No kick or brake pulse) – 30%",
174 "122 Smooth Hum 4 (No kick or brake pulse) – 20%",
175 "123 Smooth Hum 5 (No kick or brake pulse) – 10%"
176};
177
178static int drv2605_reg_read(struct drv2605_data *pDRV2605,
179 unsigned char reg, unsigned char *pVal)
180{
181 unsigned int val;
182 int nResult;
183
184 mutex_lock(&pDRV2605->dev_lock);
185 nResult = regmap_read(pDRV2605->mpRegmap, reg, &val);
186 if (nResult < 0)
187 dev_err(pDRV2605->dev, "%s I2C error %d\n", __func__, nResult);
188 else {
189 if (g_logEnable)
190 dev_dbg(pDRV2605->dev, "%s, Reg[0x%x]=0x%x\n", __func__, reg, val);
191 *pVal = (unsigned char)val;
192 }
193 mutex_unlock(&pDRV2605->dev_lock);
194 return nResult;
195}
196
197static int drv2605_reg_write(struct drv2605_data *pDRV2605,
198 unsigned char reg, unsigned char val)
199{
200 int nResult;
201
202 mutex_lock(&pDRV2605->dev_lock);
203 nResult = regmap_write(pDRV2605->mpRegmap, reg, val);
204 if (nResult < 0)
205 dev_err(pDRV2605->dev, "%s reg=0x%x, value=0%x error %d\n",
206 __func__, reg, val, nResult);
207 else {
208 if (g_logEnable)
209 dev_dbg(pDRV2605->dev, "%s, Reg[0x%x]=0x%x\n", __func__, reg, val);
210 }
211 mutex_unlock(&pDRV2605->dev_lock);
212 return nResult;
213}
214
215static int drv2605_bulk_read(struct drv2605_data *pDRV2605,
216 unsigned char reg, unsigned char *buf, unsigned int count)
217{
218 int nResult, i;
219
220 mutex_lock(&pDRV2605->dev_lock);
221 nResult = regmap_bulk_read(pDRV2605->mpRegmap, reg, buf, count);
222 if (nResult < 0)
223 dev_err(pDRV2605->dev, "%s reg=0%x, count=%d error %d\n",
224 __func__, reg, count, nResult);
225 else {
226 if (g_logEnable) {
227 for (i = 0; i < count; i++)
228 dev_dbg(pDRV2605->dev, "%s, Reg[0x%x]=0x%x\n",
229 __func__, reg + i, buf[i]);
230 }
231 }
232 mutex_unlock(&pDRV2605->dev_lock);
233 return nResult;
234}
235
236static int drv2605_bulk_write(struct drv2605_data *pDRV2605,
237 unsigned char reg, const u8 *buf, unsigned int count)
238{
239 int nResult, i;
240
241 mutex_lock(&pDRV2605->dev_lock);
242 nResult = regmap_bulk_write(pDRV2605->mpRegmap, reg, buf, count);
243 if (nResult < 0)
244 dev_err(pDRV2605->dev, "%s reg=0%x, count=%d error %d\n",
245 __func__, reg, count, nResult);
246 else {
247 if (g_logEnable)
248 for (i = 0; i < count; i++)
249 dev_dbg(pDRV2605->dev, "%s, Reg[0x%x]=0x%x\n",
250 __func__, reg + i, buf[i]);
251 }
252 mutex_unlock(&pDRV2605->dev_lock);
253 return nResult;
254}
255
256static int drv2605_set_bits(struct drv2605_data *pDRV2605,
257 unsigned char reg, unsigned char mask, unsigned char val)
258{
259 int nResult;
260
261 mutex_lock(&pDRV2605->dev_lock);
262 nResult = regmap_update_bits(pDRV2605->mpRegmap, reg, mask, val);
263 if (nResult < 0)
264 dev_err(pDRV2605->dev, "%s reg=%x, mask=0x%x, value=0x%x error %d\n",
265 __func__, reg, mask, val, nResult);
266 else {
267 if (g_logEnable)
268 dev_dbg(pDRV2605->dev, "%s, Reg[0x%x]:M=0x%x, V=0x%x\n",
269 __func__, reg, mask, val);
270 }
271 mutex_unlock(&pDRV2605->dev_lock);
272 return nResult;
273}
274
275static int drv2605_set_RTPStrength(struct drv2605_data *pDRV2605, char nStrength)
276{
277 int nResult = 0;
278
279 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_RTP_INPUT, nStrength);
280 return nResult;
281}
282
283static int drv2605_set_devMode(struct drv2605_data *pDRV2605,
284 enum dev_mode mode)
285{
286 int nResult = 0;
287
288 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_MODE, mode);
289 if (nResult >= 0) {
290 if (pDRV2605->mnDevMode == MODE_STANDBY)
291 mdelay(2);
292 pDRV2605->mnDevMode = mode;
293 if (pDRV2605->mnDevMode == MODE_STANDBY)
294 mdelay(2);
295 dev_dbg(pDRV2605->dev, "%s, mode=0x%x\n", __func__, mode);
296 }
297
298 return nResult;
299}
300
301static int drv2605_RTPStop(struct drv2605_data *pDRV2605)
302{
303 int nResult = 0;
304
305 /* perform auto brake */
306 nResult = drv2605_set_RTPStrength(pDRV2605, 0);
307 if (nResult >= 0) {
308 /* wait 20ms for the auto-brake to finish */
309 msleep(20);
310 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
311 }
312
313 return nResult;
314}
315
316static int drv2605_set_go_bit(struct drv2605_data *pDRV2605, unsigned char val)
317{
318 int nResult = 0;
319 unsigned char value = 0;
320 int retry = POLL_GO_BIT_RETRY;
321
322 val &= 0x01;
323 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_GO, val);
324 if (nResult < 0)
325 goto end;
326
327 mdelay(POLL_GO_BIT_INTERVAL);
328 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_GO, &value);
329 if (nResult < 0)
330 goto end;
331
332 if (val) {
333 if (value != GO) {
334 nResult = -EIO;
335 dev_warn(pDRV2605->dev, "%s, GO fail, stop action\n", __func__);
336 }
337 } else {
338 while (retry > 0) {
339 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_GO, &value);
340 if (nResult < 0)
341 break;
342
343 if(value==0)
344 break;
345
346 mdelay(POLL_GO_BIT_INTERVAL);
347 retry--;
348 }
349
350 if (retry == 0)
351 dev_err(pDRV2605->dev,
352 "%s, ERROR: clear GO fail\n", __func__);
353 else {
354 if (g_logEnable)
355 dev_dbg(pDRV2605->dev,
356 "%s, clear GO, remain=%d\n", __func__, retry);
357 }
358 }
359
360end:
361
362 return nResult;
363}
364
365
366static int vibrator_get_time(struct timed_output_dev *dev)
367{
368 struct drv2605_data *pDRV2605 = container_of(dev, struct drv2605_data, to_dev);
369
370 if (hrtimer_active(&pDRV2605->timer)) {
371 ktime_t r = hrtimer_get_remaining(&pDRV2605->timer);
372 return ktime_to_ms(r);
373 }
374
375 return 0;
376}
377
378static void drv2605_set_stopflag(struct drv2605_data *pDRV2605)
379{
380 pDRV2605->mnVibratorPlaying = NO;
381 pDRV2605->mnWorkMode = WORK_IDLE;
382 wake_unlock(&pDRV2605->wklock);
383 if (g_logEnable)
384 dev_dbg(pDRV2605->dev, "wklock unlock");
385}
386
387static int drv2605_get_diag_result(struct drv2605_data *pDRV2605, unsigned char nStatus)
388{
389 int nResult = 0;
390
391 pDRV2605->mDiagResult.mnResult = nStatus;
392 if ((nStatus & DIAG_MASK) != DIAG_SUCCESS)
393 dev_err(pDRV2605->dev, "Diagnostic fail\n");
394
395 return nResult;
396}
397
398static int drv2605_get_calibration_result(struct drv2605_data *pDRV2605, unsigned char nStatus)
399{
400 int nResult = 0;
401 unsigned char value;
402
403 pDRV2605->mAutoCalResult.mnResult = nStatus;
404 if ((nStatus & DIAG_MASK) != DIAG_SUCCESS)
405 dev_err(pDRV2605->dev, "Calibration fail\n");
406 else {
407 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_CAL_COMP, &value);
408 if (nResult < 0)
409 goto end;
410 pDRV2605->mAutoCalResult.mnCalComp = value;
411
412 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_CAL_BEMF, &value);
413 if (nResult < 0)
414 goto end;
415 pDRV2605->mAutoCalResult.mnCalBemf = value;
416
417 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_LOOP_CONTROL, &value) & BEMFGAIN_MASK;
418 if (nResult < 0)
419 goto end;
420 pDRV2605->mAutoCalResult.mnCalGain = value;
421
422 dev_dbg(pDRV2605->dev, "AutoCal : Comp=0x%x, Bemf=0x%x, Gain=0x%x\n",
423 pDRV2605->mAutoCalResult.mnCalComp,
424 pDRV2605->mAutoCalResult.mnCalBemf,
425 pDRV2605->mAutoCalResult.mnCalGain);
426 }
427end:
428 return nResult;
429}
430
431static int drv2605_stop(struct drv2605_data *pDRV2605)
432{
433 int nResult = 0;
434
435 if (pDRV2605->mnVibratorPlaying == YES) {
436 dev_dbg(pDRV2605->dev, "%s\n", __func__);
437 if (hrtimer_active(&pDRV2605->timer))
438 hrtimer_cancel(&pDRV2605->timer);
439 if (pDRV2605->mnWorkMode == WORK_RTP)
440 nResult = drv2605_RTPStop(pDRV2605);
441 else
442 nResult = drv2605_set_go_bit(pDRV2605, STOP);
443
444 drv2605_set_stopflag(pDRV2605);
445 }
446
447 return nResult;
448}
449
450static void vibrator_enable( struct timed_output_dev *dev, int value)
451{
452 int nResult = 0;
453 struct drv2605_data *pDRV2605 =
454 container_of(dev, struct drv2605_data, to_dev);
455
456 dev_dbg(pDRV2605->dev, "%s, value=%d\n", __func__, value);
457
458 mutex_lock(&pDRV2605->lock);
459
460 nResult = drv2605_stop(pDRV2605);
461 if (nResult < 0)
462 goto exit;
463
464 if (value > 0) {
465 wake_lock(&pDRV2605->wklock);
466 if (g_logEnable)
467 dev_dbg(pDRV2605->dev, "wklock lock");
468
469 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
470 if (nResult < 0)
471 goto end;
472 nResult = drv2605_set_RTPStrength(pDRV2605, 0x7f);
473 if (nResult < 0)
474 goto end;
475 nResult = drv2605_set_devMode(pDRV2605, MODE_RTP);
476 if (nResult >= 0) {
477 value = (value > MAX_TIMEOUT) ? MAX_TIMEOUT : value;
478 hrtimer_start(&pDRV2605->timer,
479 ns_to_ktime((u64)value * NSEC_PER_MSEC), HRTIMER_MODE_REL);
480 pDRV2605->mnVibratorPlaying = YES;
481 pDRV2605->mnWorkMode = WORK_RTP;
482 }
483 } else {
484 nResult = drv2605_set_devMode(pDRV2605, MODE_STANDBY);
485 if (nResult < 0)
486 goto exit;
487 }
488
489end:
490 if (nResult < 0) {
491 nResult = drv2605_set_devMode(pDRV2605, MODE_STANDBY);
492 wake_unlock(&pDRV2605->wklock);
493 if (g_logEnable)
494 dev_dbg(pDRV2605->dev, "wklock unlock");
495 }
496exit:
497 mutex_unlock(&pDRV2605->lock);
498}
499
500static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
501{
502 struct drv2605_data *pDRV2605 =
503 container_of(timer, struct drv2605_data, timer);
504
505 dev_dbg(pDRV2605->dev, "%s\n", __func__);
506 schedule_work(&pDRV2605->vibrator_work);
507 return HRTIMER_NORESTART;
508}
509
510static void vibrator_work_routine(struct work_struct *work)
511{
512 struct drv2605_data *pDRV2605 =
513 container_of(work, struct drv2605_data, vibrator_work);
514 unsigned char status, GOStatus;
515 int nResult = 0;
516
517 mutex_lock(&pDRV2605->lock);
518
519 if (g_logEnable)
520 dev_dbg(pDRV2605->dev, "%s, afer mnWorkMode=0x%x\n",
521 __func__, pDRV2605->mnWorkMode);
522
523 if (pDRV2605->mnVibratorPlaying == YES) {
524 dev_dbg(pDRV2605->dev, "%s\n", __func__);
525 if (pDRV2605->mnWorkMode == WORK_RTP) {
526 nResult = drv2605_RTPStop(pDRV2605);
527 goto standby;
528 } else if ((pDRV2605->mnWorkMode == WORK_CALIBRATION)
529 || (pDRV2605->mnWorkMode == WORK_DIAGNOSTIC)
530 || (pDRV2605->mnWorkMode == WORK_SEQER)) {
531 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_GO, &GOStatus);
532 if (nResult < 0)
533 goto standby;
534 if ((GOStatus & 0x01) == STOP) {
535 if (pDRV2605->mnWorkMode == WORK_SEQER)
536 goto standby;
537 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_STATUS, &status);
538 if (nResult < 0)
539 goto standby;
540 if (pDRV2605->mnWorkMode == WORK_CALIBRATION)
541 nResult = drv2605_get_calibration_result(pDRV2605, status);
542 else if (pDRV2605->mnWorkMode == WORK_DIAGNOSTIC)
543 nResult = drv2605_get_diag_result(pDRV2605, status);
544 } else {
545 if (!hrtimer_active(&pDRV2605->timer)) {
546 if (g_logEnable)
547 dev_dbg(pDRV2605->dev, "will check GO bit after %d ms\n", POLL_STATUS_INTERVAL);
548 hrtimer_start(&pDRV2605->timer,
549 ns_to_ktime((u64)POLL_STATUS_INTERVAL * NSEC_PER_MSEC), HRTIMER_MODE_REL);
550 }
551 goto exit;
552 }
553 }
554 }
555
556standby:
557 drv2605_set_devMode(pDRV2605, MODE_STANDBY);
558 drv2605_set_stopflag(pDRV2605);
559exit:
560 mutex_unlock(&pDRV2605->lock);
561}
562
563static int dev_auto_calibrate(struct drv2605_data *pDRV2605)
564{
565 int nResult = 0;
566
567 dev_info(pDRV2605->dev, "%s\n", __func__);
568 wake_lock(&pDRV2605->wklock);
569 if (g_logEnable)
570 dev_dbg(pDRV2605->dev, "wklock lock");
571
572 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
573 if (nResult < 0)
574 goto end;
575
576 nResult = drv2605_set_devMode(pDRV2605, MODE_CALIBRATION);
577 if (nResult < 0)
578 goto end;
579
580 nResult = drv2605_set_go_bit(pDRV2605, GO);
581 if (nResult < 0)
582 goto end;
583
584 dev_dbg(pDRV2605->dev, "calibration start\n");
585 pDRV2605->mnVibratorPlaying = YES;
586 pDRV2605->mnWorkMode = WORK_CALIBRATION;
587 schedule_work(&pDRV2605->vibrator_work);
588
589end:
590 if (nResult < 0) {
591 nResult = drv2605_set_devMode(pDRV2605, MODE_STANDBY);
592 wake_unlock(&pDRV2605->wklock);
593 if (g_logEnable)
594 dev_dbg(pDRV2605->dev, "wklock unlock");
595 }
596 return nResult;
597}
598
599static int dev_run_diagnostics(struct drv2605_data *pDRV2605)
600{
601 int nResult = 0;
602
603 dev_info(pDRV2605->dev, "%s\n", __func__);
604 wake_lock(&pDRV2605->wklock);
605 if (g_logEnable)
606 dev_dbg(pDRV2605->dev, "wklock lock");
607
608 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
609 if (nResult < 0)
610 goto end;
611
612 nResult = drv2605_set_devMode(pDRV2605, MODE_DIAG);
613 if (nResult < 0)
614 goto end;
615
616 nResult = drv2605_set_go_bit(pDRV2605, GO);
617 if (nResult < 0)
618 goto end;
619
620 dev_dbg(pDRV2605->dev, "Diag start\n");
621 pDRV2605->mnVibratorPlaying = YES;
622 pDRV2605->mnWorkMode = WORK_DIAGNOSTIC;
623 schedule_work(&pDRV2605->vibrator_work);
624
625end:
626 if (nResult < 0) {
627 nResult = drv2605_set_devMode(pDRV2605, MODE_STANDBY);
628 wake_unlock(&pDRV2605->wklock);
629 if (g_logEnable)
630 dev_dbg(pDRV2605->dev, "wklock unlock");
631 }
632 return nResult;
633}
634
635static int drv2605_playEffect(struct drv2605_data *pDRV2605)
636{
637 int nResult = 0;
638
639 dev_info(pDRV2605->dev, "%s\n", __func__);
640 wake_lock(&pDRV2605->wklock);
641 if (g_logEnable)
642 dev_dbg(pDRV2605->dev, "wklock lock");
643
644 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
645 if (nResult < 0)
646 goto end;
647
648 nResult = drv2605_set_go_bit(pDRV2605, GO);
649 if (nResult < 0)
650 goto end;
651
652 dev_dbg(pDRV2605->dev, "effects start\n");
653 pDRV2605->mnVibratorPlaying = YES;
654 pDRV2605->mnWorkMode = WORK_SEQER;
655 schedule_work(&pDRV2605->vibrator_work);
656
657end:
658 if (nResult < 0) {
659 nResult = drv2605_set_devMode(pDRV2605, MODE_STANDBY);
660 wake_unlock(&pDRV2605->wklock);
661 dev_dbg(pDRV2605->dev, "wklock unlock");
662 }
663 return nResult;
664}
665
666static int drv2605_set_waveform(struct drv2605_data *pDRV2605,
667 struct drv2605_waveform_sequencer *pSequencer)
668{
669 int nResult = 0;
670 int i = 0;
671 unsigned char effects[DRV2605_SEQUENCER_SIZE] = {0};
672 unsigned char len = 0;
673
674 for (i = 0; i < DRV2605_SEQUENCER_SIZE; i++) {
675 if (pSequencer->msWaveform[i].mnEffect != 0) {
676 effects[i] = pSequencer->msWaveform[i].mnEffect;
677 if (effects[i] <= 123)
678 dev_dbg(pDRV2605->dev, "[%d] %s\n", i, TS2200EffectNameStr[effects[i] - 1]);
679 else if (effects[i] >= 0x80)
680 dev_dbg(pDRV2605->dev, "[%d] Delay %d ms\n", i, (effects[i] & 0x7f) * 10);
681 else {
682 dev_err(pDRV2605->dev, "[%d] invalid %d effect index\n", i, effects[i]);
683 goto end;
684 }
685 } else
686 break;
687
688 len ++;
689 }
690
691 if (len == 0)
692 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_SEQUENCER_1, 0);
693 else {
694 len = (len < 8) ? (len + 1) : 8;
695 nResult = drv2605_bulk_write(pDRV2605, DRV2605_REG_SEQUENCER_1, effects, len);
696 }
697
698 if (nResult < 0) {
699 dev_err(pDRV2605->dev, "sequence error\n");
700 }
701
702end:
703
704 return nResult;
705}
706
707static int drv2605_file_open(struct inode *inode, struct file *file)
708{
709 if (!try_module_get(THIS_MODULE))
710 return -ENODEV;
711
712 file->private_data = (void*)g_DRV2605data;
713 return 0;
714}
715
716static int drv2605_file_release(struct inode *inode, struct file *file)
717{
718 file->private_data = (void*)NULL;
719 module_put(THIS_MODULE);
720 return 0;
721}
722
723static long drv2605_file_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
724{
725 struct drv2605_data *pDRV2605 = file->private_data;
726 //void __user *user_arg = (void __user *)arg;
727 int nResult = 0;
728
729 mutex_lock(&pDRV2605->lock);
730
731 dev_dbg(pDRV2605->dev, "ioctl 0x%x\n", cmd);
732
733 switch (cmd) {
734
735 }
736
737 mutex_unlock(&pDRV2605->lock);
738
739 return nResult;
740}
741
742static ssize_t drv2605_file_read(struct file* filp, char* buff, size_t length, loff_t* offset)
743{
744 struct drv2605_data *pDRV2605 = (struct drv2605_data *)filp->private_data;
745 int nResult = 0;
746 unsigned char value = 0;
747 unsigned char *p_kBuf = NULL;
748
749 mutex_lock(&pDRV2605->lock);
750
751 switch (pDRV2605->mnFileCmd) {
752 case HAPTIC_CMDID_REG_READ:
753 if (length == 1) {
754 nResult = drv2605_reg_read(pDRV2605, pDRV2605->mnCurrentReg, &value);
755 if (nResult >= 0) {
756 nResult = copy_to_user(buff, &value, 1);
757 if (0 != nResult) {
758 /* Failed to copy all the data, exit */
759 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
760 }
761 }
762 } else if (length > 1) {
763 p_kBuf = (unsigned char *)kzalloc(length, GFP_KERNEL);
764 if (p_kBuf != NULL) {
765 nResult = drv2605_bulk_read(pDRV2605,
766 pDRV2605->mnCurrentReg, p_kBuf, length);
767 if (nResult >= 0) {
768 nResult = copy_to_user(buff, p_kBuf, length);
769 if (0 != nResult) {
770 /* Failed to copy all the data, exit */
771 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
772 }
773 }
774
775 kfree(p_kBuf);
776 } else {
777 dev_err(pDRV2605->dev, "read no mem\n");
778 nResult = -ENOMEM;
779 }
780 }
781 break;
782
783 case HAPTIC_CMDID_RUN_DIAG:
784 if (pDRV2605->mnVibratorPlaying)
785 length = 0;
786 else {
787 unsigned char buf[3];
788 buf[0] = pDRV2605->mDiagResult.mnResult;
789 nResult = copy_to_user(buff, buf, 1);
790 if (0 != nResult) {
791 /* Failed to copy all the data, exit */
792 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
793 }
794 }
795 break;
796
797 case HAPTIC_CMDID_RUN_CALIBRATION:
798 if (pDRV2605->mnVibratorPlaying)
799 length = 0;
800 else {
801 unsigned char buf[4];
802
803 buf[0] = pDRV2605->mAutoCalResult.mnResult;
804 buf[1] = pDRV2605->mAutoCalResult.mnCalComp;
805 buf[2] = pDRV2605->mAutoCalResult.mnCalBemf;
806 buf[3] = pDRV2605->mAutoCalResult.mnCalGain;
807 nResult = copy_to_user(buff, buf, 4);
808 if (0 != nResult) {
809 /* Failed to copy all the data, exit */
810 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
811 }
812 }
813 break;
814
815 case HAPTIC_CMDID_SET_SEQUENCER:
816 if (length == sizeof(struct drv2605_waveform_sequencer)) {
817 struct drv2605_waveform_sequencer sequencer;
818 unsigned char effects[DRV2605_SEQUENCER_SIZE] = {0};
819 int i = 0;
820
821 nResult = drv2605_bulk_read(pDRV2605, DRV2605_REG_SEQUENCER_1,
822 effects, DRV2605_SEQUENCER_SIZE);
823 if (nResult < 0)
824 break;
825
826 for(i = 0; i < DRV2605_SEQUENCER_SIZE; i++) {
827 if (effects[i] != 0)
828 sequencer.msWaveform[i].mnEffect = effects[i];
829 else
830 break;
831 }
832
833 nResult = copy_to_user(buff, &sequencer, length);
834 if (0 != nResult) {
835 /* Failed to copy all the data, exit */
836 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
837 }
838 }
839 break;
840
841 case HAPTIC_CMDID_REGLOG_ENABLE:
842 if (length == 1) {
843 nResult = copy_to_user(buff, &g_logEnable, 1);
844 if (0 != nResult) {
845 /* Failed to copy all the data, exit */
846 dev_err(pDRV2605->dev, "copy to user fail %d\n", nResult);
847 }
848 }
849 break;
850
851 default:
852 pDRV2605->mnFileCmd = 0;
853 break;
854 }
855
856 mutex_unlock(&pDRV2605->lock);
857
858 return length;
859}
860
861static ssize_t drv2605_file_write(struct file* filp, const char* buff, size_t len, loff_t* off)
862{
863 struct drv2605_data *pDRV2605 = (struct drv2605_data *)filp->private_data;
864 unsigned char *p_kBuf = NULL;
865 int nResult = 0;
866
867 mutex_lock(&pDRV2605->lock);
868
869 p_kBuf = (unsigned char *)kzalloc(len, GFP_KERNEL);
870 if (p_kBuf == NULL) {
871 dev_err(pDRV2605->dev, "write no mem\n");
872 goto err;
873 }
874
875 nResult = copy_from_user(p_kBuf, buff, len);
876 if (0 != nResult) {
877 dev_err(pDRV2605->dev,"copy_from_user failed.\n");
878 goto err;
879 }
880
881 pDRV2605->mnFileCmd = p_kBuf[0];
882
883 switch(pDRV2605->mnFileCmd) {
884 case HAPTIC_CMDID_REG_READ:
885 if (len == 2)
886 pDRV2605->mnCurrentReg = p_kBuf[1];
887 else
888 dev_err(pDRV2605->dev, " read cmd len %d err\n", len);
889 break;
890
891 case HAPTIC_CMDID_REG_WRITE:
892 if ((len - 1) == 2)
893 nResult = drv2605_reg_write(pDRV2605, p_kBuf[1], p_kBuf[2]);
894 else if ((len - 1) > 2)
895 nResult = drv2605_bulk_write(pDRV2605, p_kBuf[1], &p_kBuf[2], len - 2);
896 else
897 dev_err(pDRV2605->dev, "%s, reg_write len %d error\n", __func__, len);
898 break;
899
900 case HAPTIC_CMDID_REG_SETBIT:
901 if (len == 4)
902 nResult = drv2605_set_bits(pDRV2605, p_kBuf[1], p_kBuf[2], p_kBuf[3]);
903 else
904 dev_err(pDRV2605->dev, "setbit len %d error\n", len);
905 break;
906
907 case HAPTIC_CMDID_RUN_DIAG:
908 nResult = drv2605_stop(pDRV2605);
909 if (nResult < 0)
910 break;
911 nResult = dev_run_diagnostics(pDRV2605);
912 break;
913
914 case HAPTIC_CMDID_RUN_CALIBRATION:
915 nResult = drv2605_stop(pDRV2605);
916 if (nResult < 0)
917 break;
918 nResult = dev_auto_calibrate(pDRV2605);
919 break;
920
921 case HAPTIC_CMDID_SET_SEQUENCER:
922 if (len == (1 + sizeof(struct drv2605_waveform_sequencer))) {
923 struct drv2605_waveform_sequencer sequencer;
924
925 memcpy(&sequencer, &p_kBuf[1], sizeof(struct drv2605_waveform_sequencer));
926 nResult = drv2605_set_waveform(pDRV2605, &sequencer);
927 } else
928 dev_dbg(pDRV2605->dev, "pass cmd, prepare for read\n");
929 break;
930
931 case HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE:
932 nResult = drv2605_stop(pDRV2605);
933 if (nResult < 0)
934 break;
935 nResult = drv2605_playEffect(pDRV2605);
936 break;
937
938 case HAPTIC_CMDID_STOP:
939 nResult = drv2605_stop(pDRV2605);
940 break;
941
942 case HAPTIC_CMDID_REGLOG_ENABLE:
943 if (len == 2)
944 g_logEnable = p_kBuf[1];
945 break;
946
947 default:
948 dev_err(pDRV2605->dev, "%s, unknown cmd\n", __func__);
949 break;
950 }
951
952err:
953 if (p_kBuf != NULL)
954 kfree(p_kBuf);
955
956 mutex_unlock(&pDRV2605->lock);
957
958 return len;
959}
960
961static struct file_operations fops =
962{
963 .owner = THIS_MODULE,
964 .read = drv2605_file_read,
965 .write = drv2605_file_write,
966 .unlocked_ioctl = drv2605_file_unlocked_ioctl,
967 .open = drv2605_file_open,
968 .release = drv2605_file_release,
969};
970
971static struct miscdevice drv2605_misc =
972{
973 .minor = MISC_DYNAMIC_MINOR,
974 .name = HAPTICS_DEVICE_NAME,
975 .fops = &fops,
976};
977
978static int Haptics_init(struct drv2605_data *pDRV2605)
979{
980 int nResult = 0;
981
982 pDRV2605->to_dev.name = "vibrator";
983 pDRV2605->to_dev.get_time = vibrator_get_time;
984 pDRV2605->to_dev.enable = vibrator_enable;
985
986 nResult = timed_output_dev_register(&(pDRV2605->to_dev));
987 if (nResult < 0) {
988 dev_err(pDRV2605->dev, "drv2605: fail to create timed output dev\n");
989 return nResult;
990 }
991
992 nResult = misc_register(&drv2605_misc);
993 if (nResult) {
994 dev_err(pDRV2605->dev, "drv2605 misc fail: %d\n", nResult);
995 return nResult;
996 }
997
998 hrtimer_init(&pDRV2605->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
999 pDRV2605->timer.function = vibrator_timer_func;
1000 INIT_WORK(&pDRV2605->vibrator_work, vibrator_work_routine);
1001
1002 wake_lock_init(&pDRV2605->wklock, WAKE_LOCK_SUSPEND, "vibrator");
1003 mutex_init(&pDRV2605->lock);
1004
1005 return 0;
1006}
1007
1008static int dev_init_platform_data(struct drv2605_data *pDRV2605)
1009{
1010 struct drv2605_platform_data *pDrv2605Platdata = &pDRV2605->msPlatData;
1011 struct actuator_data actuator = pDrv2605Platdata->msActuator;
1012 int nResult = 0;
1013
1014 nResult = drv2605_set_devMode(pDRV2605, MODE_INTL_TRIG);
1015 if (nResult < 0)
1016 goto end;
1017
1018 if (actuator.mnActuatorType == ERM) {
1019 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_LOOP_CONTROL, 0x80, 0x00);
1020 if (pDrv2605Platdata->mnLoop == CLOSE_LOOP)
1021 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_CONTROL3, 0x20, 0x00);
1022 else if (pDrv2605Platdata->mnLoop == OPEN_LOOP)
1023 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_CONTROL3, 0x20, 0x20);
1024 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_LIBSEL, actuator.mnEffectLib);
1025 } else if (actuator.mnActuatorType == LRA) {
1026 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_LOOP_CONTROL, 0x80, 0x80);
1027 if (pDrv2605Platdata->mnLoop == CLOSE_LOOP) {
1028 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_CONTROL3, 0x01, 0x00);
1029 nResult = drv2605_reg_write(pDRV2605, DRV2605_REG_LIBSEL, 0x06);
1030 } else if (pDrv2605Platdata->mnLoop == OPEN_LOOP)
1031 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_CONTROL3, 0x01, 0x01);
1032 }
1033
1034 if (actuator.mnRatedVoltage != 0)
1035 drv2605_reg_write(pDRV2605, DRV2605_REG_RATED_VOLTAGE, actuator.mnRatedVoltage);
1036 else
1037 dev_err(pDRV2605->dev, "%s, ERROR Rated ZERO\n", __func__);
1038
1039 if (actuator.mnOverDriveClampVoltage != 0)
1040 drv2605_reg_write(pDRV2605, DRV2605_REG_OVERDRIVE_CLAMP, actuator.mnOverDriveClampVoltage);
1041 else
1042 dev_err(pDRV2605->dev,"%s, ERROR OverDriveVol ZERO\n", __func__);
1043
1044 if (actuator.mnActuatorType == LRA) {
1045 unsigned char DriveTime = 5 * (1000 - actuator.mnLRAFreq) / actuator.mnLRAFreq;
1046 nResult = drv2605_set_bits(pDRV2605, DRV2605_REG_DRIVE_TIME,
1047 DRIVE_TIME_MASK, DriveTime);
1048
1049 dev_info(pDRV2605->dev, "%s, LRA = %d, DriveTime=0x%x\n",
1050 __func__, actuator.mnLRAFreq, DriveTime);
1051 }
1052
1053end:
1054 return nResult;
1055}
1056
1057static int drv2605_parse_dt(struct device *dev, struct drv2605_data *pDRV2605)
1058{
1059 struct device_node *np = dev->of_node;
1060 struct drv2605_platform_data *pPlatData = &pDRV2605->msPlatData;
1061 int rc= 0, nResult = 0;
1062 unsigned int value;
1063
1064 pPlatData->mnGpioEN = of_get_named_gpio(np, "ti,enable-gpio", 0);
1065 if (pPlatData->mnGpioEN < 0) {
1066 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1067 "ti,enable-gpio", np->full_name, pPlatData->mnGpioEN);
1068 nResult = -EINVAL;
1069 } else
1070 dev_dbg(pDRV2605->dev, "ti,reset-gpio=%d\n", pPlatData->mnGpioEN);
1071
1072 if (nResult >= 0) {
1073 rc = of_property_read_u32(np, "ti,smart-loop", &value);
1074 if (rc) {
1075 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1076 "ti,smart-loop", np->full_name, rc);
1077 nResult = -EINVAL;
1078 } else {
1079 pPlatData->mnLoop = value & 0x01;
1080 dev_dbg(pDRV2605->dev, "ti,smart-loop=%d\n", pPlatData->mnLoop);
1081 }
1082 }
1083
1084 if (nResult >= 0) {
1085 rc = of_property_read_u32(np, "ti,actuator", &value);
1086 if (rc) {
1087 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1088 "ti,actuator", np->full_name, rc);
1089 nResult = -EINVAL;
1090 } else {
1091 pPlatData->msActuator.mnActuatorType = value & 0x01;
1092 dev_dbg(pDRV2605->dev, "ti,actuator=%d\n",
1093 pPlatData->msActuator.mnActuatorType);
1094 }
1095 }
1096
1097 if (nResult >= 0) {
1098 rc = of_property_read_u32(np, "ti,rated-voltage", &value);
1099 if (rc) {
1100 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1101 "ti,rated-voltage", np->full_name, rc);
1102 nResult = -EINVAL;
1103 }else{
1104 pPlatData->msActuator.mnRatedVoltage = value;
1105 dev_dbg(pDRV2605->dev, "ti,rated-voltage=0x%x\n",
1106 pPlatData->msActuator.mnRatedVoltage);
1107 }
1108 }
1109
1110 if (nResult >= 0) {
1111 rc = of_property_read_u32(np, "ti,odclamp-voltage", &value);
1112 if (rc) {
1113 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1114 "ti,odclamp-voltage", np->full_name, rc);
1115 nResult = -EINVAL;
1116 } else {
1117 pPlatData->msActuator.mnOverDriveClampVoltage = value;
1118 dev_dbg(pDRV2605->dev, "ti,odclamp-voltage=0x%x\n",
1119 pPlatData->msActuator.mnOverDriveClampVoltage);
1120 }
1121 }
1122
1123 if (nResult >= 0) {
1124 if (pPlatData->msActuator.mnActuatorType == LRA) {
1125 rc = of_property_read_u32(np, "ti,lra-frequency", &value);
1126 if (rc) {
1127 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1128 "ti,lra-frequency", np->full_name, rc);
1129 nResult = -EINVAL;
1130 } else {
1131 if ((value >= 125) && (value <= 300)) {
1132 pPlatData->msActuator.mnLRAFreq = value;
1133 dev_dbg(pDRV2605->dev, "ti,lra-frequency=%d\n",
1134 pPlatData->msActuator.mnLRAFreq);
1135 } else {
1136 nResult = -EINVAL;
1137 dev_err(pDRV2605->dev, "ERROR, ti,lra-frequency=%d, out of range\n",
1138 pPlatData->msActuator.mnLRAFreq);
1139 }
1140 }
1141 } else if (pPlatData->msActuator.mnActuatorType == ERM) {
1142 rc = of_property_read_u32(np, "ti,erm-lib", &value);
1143 if (rc) {
1144 dev_err(pDRV2605->dev, "Looking up %s property in node %s failed %d\n",
1145 "ti,lra-frequency", np->full_name, rc);
1146 nResult = -EINVAL;
1147 } else {
1148 if ((value >= 1) && (value <= 5)) {
1149 pPlatData->msActuator.mnERMLib = value;
1150 dev_dbg(pDRV2605->dev, "ti,erm-lib = %d\n",
1151 pPlatData->msActuator.mnERMLib);
1152 } else {
1153 nResult = -EINVAL;
1154 dev_err(pDRV2605->dev, "ERROR, ti,erm-lib=%d, out of range\n",
1155 pPlatData->msActuator.mnERMLib);
1156 }
1157 }
1158 }
1159 }
1160
1161 return nResult;
1162}
1163
1164static struct regmap_config drv2605_i2c_regmap = {
1165 .reg_bits = 8,
1166 .val_bits = 8,
1167 .cache_type = REGCACHE_NONE,
1168};
1169
1170static int drv2605_i2c_probe(struct i2c_client* client, const struct i2c_device_id* id)
1171{
1172 struct drv2605_data *pDRV2605;
1173 int nResult = 0;
1174
1175 dev_info(&client->dev, "%s enter\n", __func__);
1176
1177 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1178 dev_err(&client->dev, "%s:I2C check failed\n", __func__);
1179 return -ENODEV;
1180 }
1181
1182 pDRV2605 = devm_kzalloc(&client->dev, sizeof(struct drv2605_data), GFP_KERNEL);
1183 if (pDRV2605 == NULL) {
1184 dev_err(&client->dev, "%s:no memory\n", __func__);
1185 return -ENOMEM;
1186 }
1187
1188 pDRV2605->dev = &client->dev;
1189 i2c_set_clientdata(client,pDRV2605);
1190 dev_set_drvdata(&client->dev, pDRV2605);
1191
1192 pDRV2605->mpRegmap = devm_regmap_init_i2c(client, &drv2605_i2c_regmap);
1193 if (IS_ERR(pDRV2605->mpRegmap)) {
1194 nResult = PTR_ERR(pDRV2605->mpRegmap);
1195 dev_err(pDRV2605->dev, "%s:Failed to allocate register map: %d\n",
1196 __func__, nResult);
1197 return nResult;
1198 }
1199
1200 if (client->dev.of_node) {
1201 dev_dbg(pDRV2605->dev, "of node parse\n");
1202 nResult = drv2605_parse_dt(&client->dev, pDRV2605);
1203 }
1204
1205 if ((nResult < 0) || !gpio_is_valid(pDRV2605->msPlatData.mnGpioEN)) {
1206 dev_err(pDRV2605->dev, "%s: platform data error\n",__func__);
1207 return -EINVAL;
1208 }
1209
1210 if (gpio_is_valid(pDRV2605->msPlatData.mnGpioEN)) {
1211 nResult = gpio_request(pDRV2605->msPlatData.mnGpioEN, "DRV2605-EN");
1212 if (nResult < 0) {
1213 dev_err(pDRV2605->dev, "%s: GPIO %d request EN error\n",
1214 __func__, pDRV2605->msPlatData.mnGpioEN);
1215 return nResult;
1216 }
1217
1218 gpio_direction_output(pDRV2605->msPlatData.mnGpioEN, 0);
1219 mdelay(5);
1220 gpio_direction_output(pDRV2605->msPlatData.mnGpioEN, 1);
1221 mdelay(2);
1222 pDRV2605->mnDevMode = MODE_STANDBY;
1223 }
1224
1225 mutex_init(&pDRV2605->dev_lock);
1226 nResult = drv2605_reg_read(pDRV2605, DRV2605_REG_ID, &pDRV2605->mnDeviceID);
1227 if (nResult < 0)
1228 goto exit_gpio_request_failed;
1229 else
1230 dev_info(pDRV2605->dev, "%s, ID status (0x%x)\n", __func__, pDRV2605->mnDeviceID);
1231
1232 if ((pDRV2605->mnDeviceID & 0xe0) != DRV2605_ID) {
1233 dev_err(pDRV2605->dev, "%s, device_id(0x%x) fail\n",
1234 __func__, pDRV2605->mnDeviceID);
1235 goto exit_gpio_request_failed;
1236 }
1237
1238 nResult = dev_init_platform_data(pDRV2605);
1239 if (nResult < 0)
1240 goto exit_gpio_request_failed;
1241
1242 g_DRV2605data = pDRV2605;
1243 Haptics_init(pDRV2605);
1244
1245 dev_info(pDRV2605->dev, "drv2605 probe succeeded\n");
1246 return 0;
1247
1248exit_gpio_request_failed:
1249 if (gpio_is_valid(pDRV2605->msPlatData.mnGpioEN))
1250 gpio_free(pDRV2605->msPlatData.mnGpioEN);
1251
1252 mutex_destroy(&pDRV2605->dev_lock);
1253
1254 dev_err(pDRV2605->dev, "%s failed, err=%d\n", __func__, nResult);
1255 return nResult;
1256}
1257
1258static int drv2605_i2c_remove(struct i2c_client* client)
1259{
1260 struct drv2605_data *pDRV2605 = i2c_get_clientdata(client);
1261
1262 if(pDRV2605->msPlatData.mnGpioEN)
1263 gpio_free(pDRV2605->msPlatData.mnGpioEN);
1264
1265 misc_deregister(&drv2605_misc);
1266
1267 mutex_destroy(&pDRV2605->lock);
1268 mutex_destroy(&pDRV2605->dev_lock);
1269
1270 return 0;
1271}
1272
1273static const struct i2c_device_id drv2605_i2c_id[] = {
1274 {"drv2605", 0},
1275 {}
1276};
1277
1278MODULE_DEVICE_TABLE(i2c, drv2605_i2c_id);
1279
1280#if defined(CONFIG_OF)
1281static const struct of_device_id drv2605_of_match[] = {
1282 {.compatible = "ti,drv2605"},
1283 {},
1284};
1285
1286MODULE_DEVICE_TABLE(of, drv2605_of_match);
1287#endif
1288
1289static struct i2c_driver drv2605_i2c_driver = {
1290 .driver = {
1291 .name = "drv2605",
1292 .owner = THIS_MODULE,
1293#if defined(CONFIG_OF)
1294 .of_match_table = of_match_ptr(drv2605_of_match),
1295#endif
1296 },
1297 .probe = drv2605_i2c_probe,
1298 .remove = drv2605_i2c_remove,
1299 .id_table = drv2605_i2c_id,
1300};
1301
1302module_i2c_driver(drv2605_i2c_driver);
1303
1304MODULE_AUTHOR("Texas Instruments Inc.");
1305MODULE_DESCRIPTION("DRV2605 I2C Haptics driver");
1306MODULE_LICENSE("GPL v2"); \ No newline at end of file
diff --git a/drv2605.h b/drv2605.h
new file mode 100755
index 0000000..32a9c4f
--- /dev/null
+++ b/drv2605.h
@@ -0,0 +1,229 @@
1#ifndef __DRV2605_H__
2#define __DRV2605_H__
3/*
4** =============================================================================
5** Copyright (c)2016 Texas Instruments Inc.
6**
7** This program is free software; you can redistribute it and/or
8** modify it under the terms of the GNU General Public License
9** as published by the Free Software Foundation; either version 2
10** of the License, or (at your option) any later version.
11**
12** This program is distributed in the hope that it will be useful,
13** but WITHOUT ANY WARRANTY; without even the implied warranty of
14** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15** GNU General Public License for more details.
16**
17** You should have received a copy of the GNU General Public License
18** along with this program; if not, write to the Free Software
19** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20**
21** File:
22** drv2605.h
23**
24** Description:
25** Header file for drv2605.c
26**
27** =============================================================================
28*/
29
30#include <linux/regmap.h>
31#include <linux/timer.h>
32#include <linux/workqueue.h>
33#include <../../../drivers/staging/android/timed_output.h>
34#include <linux/hrtimer.h>
35#include <linux/wakelock.h>
36#include <linux/mutex.h>
37#include <linux/cdev.h>
38
39#define HAPTICS_DEVICE_NAME "drv2605"
40
41#define DRV2605_REG_ID 0x00
42#define DRV2605_ID 0x60
43
44#define DRV2605_REG_STATUS 0x00
45#define DIAG_MASK 0x08
46#define DIAG_SUCCESS 0x00
47#define DIAG_SHIFT 0x07
48#define INT_MASK 0x1f
49#define PRG_ERR_MASK 0x10
50#define PROCESS_DONE_MASK 0x08
51#define ULVO_MASK 0x04
52#define OVERTEMPRATURE_MASK 0x02
53#define OVERCURRENT_MASK 0x01
54
55#define DRV2605_REG_MODE 0x01
56#define WORKMODE_MASK 0x03
57
58#define DRV2605_REG_RTP_INPUT 0x02
59
60#define DRV2605_REG_LIBSEL 0x03
61
62#define DRV2605_REG_SEQUENCER_1 0x04
63
64#define DRV2605_REG_CONTROL1 0x08
65#define ACTUATOR_MASK 0x80
66#define ACTUATOR_SHIFT 7
67#define LOOP_MASK 0x40
68#define LOOP_SHIFT 6
69#define AUTOBRK_OK_MASK 0x10
70#define AUTOBRK_OK_ENABLE 0x10
71
72#define DRV2605_REG_GO 0x0c
73
74#define DRV2605_REG_CONTROL2 0x0d
75
76#define DRV2605_REG_RATED_VOLTAGE 0x16
77#define DRV2605_REG_OVERDRIVE_CLAMP 0x17
78#define DRV2605_REG_CAL_COMP 0x18
79#define DRV2605_REG_CAL_BEMF 0x19
80
81#define DRV2605_REG_LOOP_CONTROL 0x1a
82#define BEMFGAIN_MASK 0x03
83#define DRV2605_REG_CONTROL3 0x1d
84
85#define DRV2605_REG_DRIVE_TIME 0x1b
86#define DRIVE_TIME_MASK 0x1f
87
88#define GO_BIT_POLL_INTERVAL 15
89#define STANDBY_WAKE_DELAY 1
90#define WAKE_STANDBY_DELAY 3
91
92/* Commands */
93#define HAPTIC_CMDID_PLAY_SINGLE_EFFECT 0x01
94#define HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE 0x02
95#define HAPTIC_CMDID_PLAY_TIMED_EFFECT 0x03
96#define HAPTIC_CMDID_GET_DEV_ID 0x04
97#define HAPTIC_CMDID_RUN_DIAG 0x05
98#define HAPTIC_CMDID_AUDIOHAPTIC_ENABLE 0x06
99#define HAPTIC_CMDID_AUDIOHAPTIC_DISABLE 0x07
100#define HAPTIC_CMDID_AUDIOHAPTIC_GETSTATUS 0x08
101#define HAPTIC_CMDID_REG_WRITE 0x09
102#define HAPTIC_CMDID_REG_READ 0x0a
103#define HAPTIC_CMDID_REG_SETBIT 0x0b
104#define HAPTIC_CMDID_PATTERN_RTP 0x0c
105#define HAPTIC_CMDID_RTP_SEQUENCE 0x0d
106#define HAPTIC_CMDID_GET_EFFECT_COUNT 0x10
107#define HAPTIC_CMDID_UPDATE_FIRMWARE 0x11
108#define HAPTIC_CMDID_READ_FIRMWARE 0x12
109#define HAPTIC_CMDID_RUN_CALIBRATION 0x13
110#define HAPTIC_CMDID_CONFIG_WAVEFORM 0x14
111#define HAPTIC_CMDID_SET_SEQUENCER 0x15
112#define HAPTIC_CMDID_REGLOG_ENABLE 0x16
113
114#define HAPTIC_CMDID_STOP 0xFF
115
116#define MAX_TIMEOUT 10000 /* 10s */
117#define MAX_READ_BYTES 0xff
118#define DRV2605_SEQUENCER_SIZE 8
119
120enum dev_mode {
121 MODE_INTL_TRIG = 0x00,
122 MODE_EXTL_TRIG_E = 0x01,
123 MODE_EXTL_TRIG_L = 0x02,
124 MODE_PWM_ANG = 0x03,
125 MODE_AUDIOHAPTICS = 0x04,
126 MODE_RTP = 0x05,
127 MODE_DIAG = 0x06,
128 MODE_CALIBRATION = 0x07,
129 MODE_STANDBY = 0x40
130};
131
132enum work_mode {
133 WORK_IDLE = 0,
134 WORK_SEQER = 0x01,
135 WORK_RTP = 0x02,
136 WORK_CALIBRATION = 0x03,
137 WORK_DIAGNOSTIC = 0x04
138};
139
140
141#define YES 1
142#define NO 0
143#define GO 1
144#define STOP 0
145
146#define POLL_GO_BIT_INTERVAL 2 /* 2 ms */
147#define POLL_STATUS_INTERVAL 10 /* 10 ms */
148#define POLL_GO_BIT_RETRY 20 /* 20 times */
149
150enum actuator_type {
151 ERM,
152 LRA
153};
154
155enum loop_type {
156 CLOSE_LOOP,
157 OPEN_LOOP
158};
159
160struct actuator_data {
161 unsigned char mnActuatorType;
162 unsigned char mnEffectLib;
163 unsigned char mnRatedVoltage;
164 unsigned char mnOverDriveClampVoltage;
165 unsigned char mnERMLib;
166 unsigned char mnLRAFreq;
167};
168
169struct drv2605_waveform {
170 unsigned char mnEffect;
171};
172
173struct drv2605_waveform_sequencer {
174 struct drv2605_waveform msWaveform[DRV2605_SEQUENCER_SIZE];
175};
176
177struct drv2605_autocal_result {
178 int mnFinished;
179 unsigned char mnResult;
180 unsigned char mnCalComp;
181 unsigned char mnCalBemf;
182 unsigned char mnCalGain;
183};
184
185struct drv2605_diag_result {
186 int mnFinished;
187 unsigned char mnResult;
188};
189
190struct drv2605_platform_data {
191 int mnGpioEN;
192 unsigned char mnLoop;
193 struct actuator_data msActuator;
194};
195
196struct drv2605_data {
197 struct drv2605_platform_data msPlatData;
198 struct mutex dev_lock;
199 unsigned char mnDeviceID;
200 struct device *dev;
201 struct regmap *mpRegmap;
202 struct drv2605_waveform_sequencer msWaveformSequencer;
203 unsigned char mnFileCmd;
204 volatile int mnVibratorPlaying;
205 enum dev_mode mnDevMode;
206 enum work_mode mnWorkMode;
207 unsigned char mnRTPStrength;
208 unsigned char mnCurrentReg;
209 struct wake_lock wklock;
210 struct hrtimer timer;
211 struct mutex lock;
212 struct work_struct vibrator_work;
213 struct timed_output_dev to_dev;
214
215 struct drv2605_autocal_result mAutoCalResult;
216 struct drv2605_diag_result mDiagResult;
217
218};
219
220#define DRV2605_MAGIC_NUMBER 'T'
221
222#define DRV2605_WAVSEQ_PLAY _IOWR(DRV2605_MAGIC_NUMBER, 4, unsigned long)
223#define DRV2605_STOP _IOWR(DRV2605_MAGIC_NUMBER, 5, unsigned long)
224#define DRV2605_RUN_DIAGNOSTIC _IOWR(DRV2605_MAGIC_NUMBER, 6, unsigned long)
225#define DRV2605_GET_DIAGRESULT _IOWR(DRV2605_MAGIC_NUMBER, 7, struct drv2605_diag_result *)
226#define DRV2605_RUN_AUTOCAL _IOWR(DRV2605_MAGIC_NUMBER, 8, unsigned long)
227#define DRV2605_GET_CALRESULT _IOWR(DRV2605_MAGIC_NUMBER, 9, struct drv2605_autocal_result *)
228
229#endif
diff --git a/dts.readme b/dts.readme
new file mode 100755
index 0000000..1469bf7
--- /dev/null
+++ b/dts.readme
@@ -0,0 +1,12 @@
1 drv2605@5a {
2 compatible = "ti,drv2605";
3 reg = <0x5a>;
4 ti,enable-gpio = <&msmgpio 13 0>;
5 ti,smart-loop = <0>; /* 0-closeloop, 1-openloop */
6 ti,actuator = <1>; /* 0-ERM, 1-LRA */
7 ti,rated-voltage = <0x53>;
8 ti,odclamp-voltage = <0x9b>;
9 ti,lra-frequency = <175>; /* DON'T Care if ERM */
10 ti,erm-lib = <1>; /* DON'T Care if LRA */
11 status = "ok";
12 }; \ No newline at end of file
diff --git a/include_linux_haptics_drv2605.h b/include_linux_haptics_drv2605.h
deleted file mode 100755
index c6f430d..0000000
--- a/include_linux_haptics_drv2605.h
+++ /dev/null
@@ -1,462 +0,0 @@
1#ifndef __DRV2605_H__
2#define __DRV2605_H__
3/*
4** =============================================================================
5** Copyright (c)2014 Texas Instruments Inc.
6**
7** This program is free software; you can redistribute it and/or
8** modify it under the terms of the GNU General Public License
9** as published by the Free Software Foundation; either version 2
10** of the License, or (at your option) any later version.
11**
12** This program is distributed in the hope that it will be useful,
13** but WITHOUT ANY WARRANTY; without even the implied warranty of
14** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15** GNU General Public License for more details.
16**
17** You should have received a copy of the GNU General Public License
18** along with this program; if not, write to the Free Software
19** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20**
21** File:
22** drv2605.h
23**
24** Description:
25** Header file for drv2605.c
26**
27** =============================================================================
28*/
29
30#include <linux/switch.h>
31#include <linux/earlysuspend.h>
32#include <linux/regmap.h>
33#include <linux/timer.h>
34#include <linux/workqueue.h>
35#include <../../../drivers/staging/android/timed_output.h>
36#include <linux/hrtimer.h>
37#include <linux/wakelock.h>
38#include <linux/mutex.h>
39#include <linux/cdev.h>
40#include <linux/earlysuspend.h>
41
42#define HAPTICS_DEVICE_NAME "drv2605"
43
44#define LIBRARY_A 0x01
45#define LIBRARY_B 0x02
46#define LIBRARY_C 0x03
47#define LIBRARY_D 0x04
48#define LIBRARY_E 0x05
49#define LIBRARY_F 0x06
50
51#define GO_BIT_POLL_INTERVAL 15
52#define STANDBY_WAKE_DELAY 1
53#define WAKE_STANDBY_DELAY 3
54
55/* Commands */
56#define HAPTIC_CMDID_PLAY_SINGLE_EFFECT 0x01
57#define HAPTIC_CMDID_PLAY_EFFECT_SEQUENCE 0x02
58#define HAPTIC_CMDID_PLAY_TIMED_EFFECT 0x03
59#define HAPTIC_CMDID_GET_DEV_ID 0x04
60#define HAPTIC_CMDID_RUN_DIAG 0x05
61#define HAPTIC_CMDID_AUDIOHAPTIC_ENABLE 0x06
62#define HAPTIC_CMDID_AUDIOHAPTIC_DISABLE 0x07
63#define HAPTIC_CMDID_AUDIOHAPTIC_GETSTATUS 0x08
64
65#define HAPTIC_CMDID_REG_WRITE 0x09
66#define HAPTIC_CMDID_REG_READ 0x0a
67#define HAPTIC_CMDID_REG_SETBIT 0x0b
68
69#define HAPTIC_CMDID_PATTERN_RTP 0x0c
70#define HAPTIC_CMDID_RTP_SEQUENCE 0x0d
71#define HAPTIC_CMDID_GET_EFFECT_COUNT 0x10
72#define HAPTIC_CMDID_UPDATE_FIRMWARE 0x11
73#define HAPTIC_CMDID_READ_FIRMWARE 0x12
74#define HAPTIC_CMDID_STOP 0xFF
75
76/*
77** Go
78*/
79#define GO_REG 0x0C
80#define GO_MASK 0x01
81#define GO 0x01
82#define STOP 0x00
83
84/*
85** Status
86*/
87#define STATUS_REG 0x00
88#define STATUS_DEFAULT 0x00
89
90#define DIAG_RESULT_MASK (1 << 3)
91#define AUTO_CAL_PASSED (0 << 3)
92#define AUTO_CAL_FAILED (1 << 3)
93#define DIAG_GOOD (0 << 3)
94#define DIAG_BAD (1 << 3)
95
96#define DEV_ID_MASK (7 << 5)
97
98#define DRV2605_VER_1DOT1 (3 << 5)
99#define DRV2605_VER_1DOT0 (5 << 5)
100#define DRV2604 (4 << 5)
101#define DRV2604L (6 << 5)
102#define DRV2605L (7 << 5)
103
104/*
105** Mode
106*/
107#define MODE_REG 0x01
108#define MODE_STANDBY_MASK 0x40
109#define MODE_STANDBY 0x40
110#define MODE_RESET 0x80
111#define DRV2605_MODE_MASK 0x07
112#define MODE_INTERNAL_TRIGGER 0
113#define MODE_EXTERNAL_TRIGGER_EDGE 1
114#define MODE_EXTERNAL_TRIGGER_LEVEL 2
115#define MODE_PWM_OR_ANALOG_INPUT 3
116#define MODE_AUDIOHAPTIC 4
117#define MODE_REAL_TIME_PLAYBACK 5
118#define MODE_DIAGNOSTICS 6
119#define AUTO_CALIBRATION 7
120
121/*
122** Real Time Playback
123*/
124#define REAL_TIME_PLAYBACK_REG 0x02
125
126/*
127** Library Selection
128*/
129#define LIBRARY_SELECTION_REG 0x03
130#define LIBRARY_SELECTION_DEFAULT 0x00
131#define LIBRARY_SELECTION_HIZ_MASK 0x10
132#define LIBRARY_SELECTION_HIZ_EN 1
133#define LIBRARY_SELECTION_HIZ_DIS 0
134
135/*
136** Waveform Sequencer
137*/
138#define WAVEFORM_SEQUENCER_REG 0x04
139#define WAVEFORM_SEQUENCER_REG2 0x05
140#define WAVEFORM_SEQUENCER_REG3 0x06
141#define WAVEFORM_SEQUENCER_REG4 0x07
142#define WAVEFORM_SEQUENCER_REG5 0x08
143#define WAVEFORM_SEQUENCER_REG6 0x09
144#define WAVEFORM_SEQUENCER_REG7 0x0A
145#define WAVEFORM_SEQUENCER_REG8 0x0B
146#define WAVEFORM_SEQUENCER_MAX 8
147#define WAVEFORM_SEQUENCER_DEFAULT 0x00
148
149/*
150** OverDrive Time Offset
151*/
152#define OVERDRIVE_TIME_OFFSET_REG 0x0D
153
154/*
155** Sustain Time Offset, postive
156*/
157#define SUSTAIN_TIME_OFFSET_POS_REG 0x0E
158
159/*
160** Sustain Time Offset, negative
161*/
162#define SUSTAIN_TIME_OFFSET_NEG_REG 0x0F
163
164/*
165** Brake Time Offset
166*/
167#define BRAKE_TIME_OFFSET_REG 0x10
168
169/*
170** Audio to Haptics Control
171*/
172#define AUDIO_HAPTICS_CONTROL_REG 0x11
173
174#define AUDIO_HAPTICS_RECT_10MS (0 << 2)
175#define AUDIO_HAPTICS_RECT_20MS (1 << 2)
176#define AUDIO_HAPTICS_RECT_30MS (2 << 2)
177#define AUDIO_HAPTICS_RECT_40MS (3 << 2)
178
179#define AUDIO_HAPTICS_FILTER_100HZ 0
180#define AUDIO_HAPTICS_FILTER_125HZ 1
181#define AUDIO_HAPTICS_FILTER_150HZ 2
182#define AUDIO_HAPTICS_FILTER_200HZ 3
183
184/*
185** Audio to Haptics Minimum Input Level
186*/
187#define AUDIO_HAPTICS_MIN_INPUT_REG 0x12
188
189/*
190** Audio to Haptics Maximum Input Level
191*/
192#define AUDIO_HAPTICS_MAX_INPUT_REG 0x13
193
194/*
195** Audio to Haptics Minimum Output Drive
196*/
197#define AUDIO_HAPTICS_MIN_OUTPUT_REG 0x14
198
199/*
200** Audio to Haptics Maximum Output Drive
201*/
202#define AUDIO_HAPTICS_MAX_OUTPUT_REG 0x15
203
204/*
205** Rated Voltage
206*/
207#define RATED_VOLTAGE_REG 0x16
208
209/*
210** Overdrive Clamp Voltage
211*/
212#define OVERDRIVE_CLAMP_VOLTAGE_REG 0x17
213
214/*
215** Auto Calibrationi Compensation Result
216*/
217#define AUTO_CALI_RESULT_REG 0x18
218
219/*
220** Auto Calibration Back-EMF Result
221*/
222#define AUTO_CALI_BACK_EMF_RESULT_REG 0x19
223
224/*
225** Feedback Control
226*/
227#define FEEDBACK_CONTROL_REG 0x1A
228#define FEEDBACK_CONTROL_DEVICE_TYPE_MASK 0x80
229#define FEEDBACK_CONTROL_BEMF_ERM_GAIN0 0 // 0.33x
230#define FEEDBACK_CONTROL_BEMF_ERM_GAIN1 1 // 1.0x
231#define FEEDBACK_CONTROL_BEMF_ERM_GAIN2 2 // 1.8x
232#define FEEDBACK_CONTROL_BEMF_ERM_GAIN3 3 // 4.0x
233
234#define FEEDBACK_CONTROL_BEMF_LRA_GAIN0 0 // 5x
235#define FEEDBACK_CONTROL_BEMF_LRA_GAIN1 1 // 10x
236#define FEEDBACK_CONTROL_BEMF_LRA_GAIN2 2 // 20x
237#define FEEDBACK_CONTROL_BEMF_LRA_GAIN3 3 // 30x
238
239#define LOOP_RESPONSE_SLOW (0 << 2)
240#define LOOP_RESPONSE_MEDIUM (1 << 2) // default
241#define LOOP_RESPONSE_FAST (2 << 2)
242#define LOOP_RESPONSE_VERY_FAST (3 << 2)
243
244#define FB_BRAKE_FACTOR_1X (0 << 4) // 1x
245#define FB_BRAKE_FACTOR_2X (1 << 4) // 2x
246#define FB_BRAKE_FACTOR_3X (2 << 4) // 3x (default)
247#define FB_BRAKE_FACTOR_4X (3 << 4) // 4x
248#define FB_BRAKE_FACTOR_6X (4 << 4) // 6x
249#define FB_BRAKE_FACTOR_8X (5 << 4) // 8x
250#define FB_BRAKE_FACTOR_16X (6 << 4) // 16x
251#define FB_BRAKE_DISABLED (7 << 4)
252
253#define FEEDBACK_CONTROL_MODE_ERM 0 // default
254#define FEEDBACK_CONTROL_MODE_LRA (1 << 7)
255
256/*
257** Control1
258*/
259#define Control1_REG 0x1B
260#define Control1_REG_AC_COUPLE_MASK 0x20
261#define Control1_REG_DRIVE_TIME_MASK 0x1f
262
263#define STARTUP_BOOST_ENABLED (1 << 7)
264#define STARTUP_BOOST_DISABLED (0 << 7) // default
265#define AC_COUPLE_ENABLED (1 << 5)
266#define AC_COUPLE_DISABLED (0 << 5) // default
267
268#define DEFAULT_DRIVE_TIME 0x13
269#define AUDIOHAPTIC_DRIVE_TIME 0x13
270
271/*
272** Control2
273*/
274#define Control2_REG 0x1C
275#define Control2_REG_BIDIR_INPUT_MASK 0x80
276
277#define BIDIR_INPUT_UNIDIRECTIONAL (0<<7)
278#define BIDIR_INPUT_BIDIRECTIONAL (1<<7)
279#define IDISS_TIME_MASK 0x03
280#define IDISS_TIME_VERY_SHORT 0
281#define IDISS_TIME_SHORT 1
282#define IDISS_TIME_MEDIUM 2 // default
283#define IDISS_TIME_LONG 3
284
285#define BLANKING_TIME_MASK 0x0C
286#define BLANKING_TIME_VERY_SHORT (0 << 2)
287#define BLANKING_TIME_SHORT (1 << 2)
288#define BLANKING_TIME_MEDIUM (2 << 2) // default
289#define BLANKING_TIME_VERY_LONG (3 << 2)
290
291#define AUTO_RES_GAIN_MASK 0x30
292#define AUTO_RES_GAIN_VERY_LOW (0 << 4)
293#define AUTO_RES_GAIN_LOW (1 << 4)
294#define AUTO_RES_GAIN_MEDIUM (2 << 4) // default
295#define AUTO_RES_GAIN_HIGH (3 << 4)
296
297#define SOFT_BRAKE_MASK 0x40
298
299#define BIDIR_INPUT_MASK 0x80
300#define UNIDIRECT_INPUT (0 << 7)
301#define BRAKE_STABLIZER (1<<6)
302#define BIDIRECT_INPUT (1 << 7) // default
303
304/*
305** Control3
306*/
307#define Control3_REG 0x1D
308#define Control3_REG_LOOP_MASK 0x21
309#define Control3_REG_PWMANALOG_MASK 0x02
310#define Control3_REG_FORMAT_MASK 0x08
311#define INPUT_PWM (0 << 1) // default
312#define INPUT_ANALOG (1 << 1)
313#define ERM_OpenLoop_Enabled (1 << 5)
314#define ERM_OpenLoop_Disable (0 << 5)
315#define LRA_OpenLoop_Enabled (1 << 0)
316#define LRA_OpenLoop_Disable (0 << 0)
317#define RTP_FORMAT_SIGNED (0 << 3)
318#define RTP_FORMAT_UNSIGNED (1 << 3)
319#define NG_Thresh_DISABLED (0 << 6)
320#define NG_Thresh_1 (1 << 6)
321#define NG_Thresh_2 (2 << 6)
322#define NG_Thresh_3 (3 << 6)
323
324/*
325** Auto Calibration Memory Interface
326*/
327#define AUTOCAL_MEM_INTERFACE_REG 0x1E
328#define AUTOCAL_MEM_INTERFACE_REG_OTP_MASK 0x04
329
330#define AUTOCAL_TIME_150MS (0 << 4)
331#define AUTOCAL_TIME_250MS (1 << 4)
332#define AUTOCAL_TIME_500MS (2 << 4)
333#define AUTOCAL_TIME_1000MS (3 << 4)
334
335#define SILICON_REVISION_REG 0x3B
336#define SILICON_REVISION_MASK 0x07
337
338//reset values
339#define AUDIO_HAPTICS_MIN_INPUT_VOLTAGE 0x19
340#define AUDIO_HAPTICS_MAX_INPUT_VOLTAGE 0xff
341#define AUDIO_HAPTICS_MIN_OUTPUT_VOLTAGE 0x19
342#define AUDIO_HAPTICS_MAX_OUTPUT_VOLTAGE 0xFF
343
344#define MAX_TIMEOUT 10000 /* 10s */
345#define MAX_READ_BYTES 0xff
346
347#define SW_STATE_IDLE 0x00
348#define SW_STATE_AUDIO2HAPTIC 0x01
349#define SW_STATE_SEQUENCE_PLAYBACK 0x02
350#define SW_STATE_RTP_PLAYBACK 0x04
351
352#define DEV_IDLE 0 // default
353#define DEV_STANDBY 1
354#define DEV_READY 2
355
356#define WORK_IDLE 0x00
357#define WORK_AUDIO2HAPTIC 0x05
358#define WORK_RTP 0x06
359#define WORK_CALIBRATION 0x07
360#define WORK_VIBRATOR 0x08
361#define WORK_PATTERN_RTP_ON 0x09
362#define WORK_PATTERN_RTP_OFF 0x0a
363#define WORK_SEQ_RTP_ON 0x0b
364#define WORK_SEQ_RTP_OFF 0x0c
365#define WORK_SEQ_PLAYBACK 0x0d
366
367#define YES 1
368#define NO 0
369
370enum actuator_type {
371 ERM,
372 LRA
373};
374
375enum loop_type {
376 OPEN_LOOP,
377 CLOSE_LOOP
378};
379
380enum RTP_Format {
381 Signed,
382 Unsigned
383};
384
385enum BIDIR_Input {
386 UniDirectional,
387 BiDirectional
388};
389
390struct actuator_data {
391 enum actuator_type device_type;
392 unsigned char g_effect_bank;
393 unsigned char rated_vol;
394 unsigned char over_drive_vol;
395 unsigned char LRAFreq;
396};
397
398struct audio2haptics_data {
399 unsigned char a2h_min_input;
400 unsigned char a2h_max_input;
401 unsigned char a2h_min_output;
402 unsigned char a2h_max_output;
403};
404
405struct drv2605_platform_data {
406 int GpioEnable;
407 int GpioTrigger;
408 enum loop_type loop;
409 enum RTP_Format RTPFormat;
410 enum BIDIR_Input BIDIRInput;
411 struct actuator_data actuator;
412 struct audio2haptics_data a2h;
413};
414
415#define MAX_RTP_SEQ 16
416
417struct RTP_Seq{
418 unsigned short RTPData[MAX_RTP_SEQ]; //RTPTime<<8||RTPAmp
419 int RTPCounts;
420 int RTPindex;
421};
422
423struct drv2605_data {
424 struct drv2605_platform_data PlatData;
425 int device_id;
426
427 struct regmap *regmap;
428
429 struct class* class;
430 struct device* device;
431 dev_t version;
432 struct semaphore sem;
433 struct cdev cdev;
434 struct switch_dev sw_dev;
435 volatile int audio_haptics_enabled;
436 volatile int vibrator_is_playing;
437 char ReadBuff[MAX_READ_BYTES];
438 int ReadLen;
439
440 int vibration_time;
441 int silience_time;
442 char repeat_times;
443 volatile char work_mode;
444 char dev_mode;
445
446 struct RTP_Seq RTPSeq;
447
448 int OTP;
449
450 struct wake_lock wklock;
451 struct hrtimer timer;
452 struct mutex lock;
453 struct work_struct vibrator_work;
454 unsigned char sequence[WAVEFORM_SEQUENCER_MAX];
455 volatile int should_stop;
456 struct timed_output_dev to_dev;
457#ifdef CONFIG_HAS_EARLYSUSPEND
458 struct early_suspend early_suspend;
459#endif
460};
461
462#endif