OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [input/] [ff-memless.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  Force feedback support for memoryless devices
3
 *
4
 *  Copyright (c) 2006 Anssi Hannula <anssi.hannula@gmail.com>
5
 *  Copyright (c) 2006 Dmitry Torokhov <dtor@mail.ru>
6
 */
7
 
8
/*
9
 * This program is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
 */
23
 
24
/* #define DEBUG */
25
 
26
#define debug(format, arg...) pr_debug("ff-memless: " format "\n", ## arg)
27
 
28
#include <linux/input.h>
29
#include <linux/module.h>
30
#include <linux/mutex.h>
31
#include <linux/spinlock.h>
32
#include <linux/jiffies.h>
33
 
34
#include "fixp-arith.h"
35
 
36
MODULE_LICENSE("GPL");
37
MODULE_AUTHOR("Anssi Hannula <anssi.hannula@gmail.com>");
38
MODULE_DESCRIPTION("Force feedback support for memoryless devices");
39
 
40
/* Number of effects handled with memoryless devices */
41
#define FF_MEMLESS_EFFECTS      16
42
 
43
/* Envelope update interval in ms */
44
#define FF_ENVELOPE_INTERVAL    50
45
 
46
#define FF_EFFECT_STARTED       0
47
#define FF_EFFECT_PLAYING       1
48
#define FF_EFFECT_ABORTING      2
49
 
50
struct ml_effect_state {
51
        struct ff_effect *effect;
52
        unsigned long flags;    /* effect state (STARTED, PLAYING, etc) */
53
        int count;              /* loop count of the effect */
54
        unsigned long play_at;  /* start time */
55
        unsigned long stop_at;  /* stop time */
56
        unsigned long adj_at;   /* last time the effect was sent */
57
};
58
 
59
struct ml_device {
60
        void *private;
61
        struct ml_effect_state states[FF_MEMLESS_EFFECTS];
62
        int gain;
63
        struct timer_list timer;
64
        spinlock_t timer_lock;
65
        struct input_dev *dev;
66
 
67
        int (*play_effect)(struct input_dev *dev, void *data,
68
                           struct ff_effect *effect);
69
};
70
 
71
static const struct ff_envelope *get_envelope(const struct ff_effect *effect)
72
{
73
        static const struct ff_envelope empty_envelope;
74
 
75
        switch (effect->type) {
76
                case FF_PERIODIC:
77
                        return &effect->u.periodic.envelope;
78
                case FF_CONSTANT:
79
                        return &effect->u.constant.envelope;
80
                default:
81
                        return &empty_envelope;
82
        }
83
}
84
 
85
/*
86
 * Check for the next time envelope requires an update on memoryless devices
87
 */
88
static unsigned long calculate_next_time(struct ml_effect_state *state)
89
{
90
        const struct ff_envelope *envelope = get_envelope(state->effect);
91
        unsigned long attack_stop, fade_start, next_fade;
92
 
93
        if (envelope->attack_length) {
94
                attack_stop = state->play_at +
95
                        msecs_to_jiffies(envelope->attack_length);
96
                if (time_before(state->adj_at, attack_stop))
97
                        return state->adj_at +
98
                                        msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
99
        }
100
 
101
        if (state->effect->replay.length) {
102
                if (envelope->fade_length) {
103
                        /* check when fading should start */
104
                        fade_start = state->stop_at -
105
                                        msecs_to_jiffies(envelope->fade_length);
106
 
107
                        if (time_before(state->adj_at, fade_start))
108
                                return fade_start;
109
 
110
                        /* already fading, advance to next checkpoint */
111
                        next_fade = state->adj_at +
112
                                        msecs_to_jiffies(FF_ENVELOPE_INTERVAL);
113
                        if (time_before(next_fade, state->stop_at))
114
                                return next_fade;
115
                }
116
 
117
                return state->stop_at;
118
        }
119
 
120
        return state->play_at;
121
}
122
 
123
static void ml_schedule_timer(struct ml_device *ml)
124
{
125
        struct ml_effect_state *state;
126
        unsigned long now = jiffies;
127
        unsigned long earliest = 0;
128
        unsigned long next_at;
129
        int events = 0;
130
        int i;
131
 
132
        debug("calculating next timer");
133
 
134
        for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
135
 
136
                state = &ml->states[i];
137
 
138
                if (!test_bit(FF_EFFECT_STARTED, &state->flags))
139
                        continue;
140
 
141
                if (test_bit(FF_EFFECT_PLAYING, &state->flags))
142
                        next_at = calculate_next_time(state);
143
                else
144
                        next_at = state->play_at;
145
 
146
                if (time_before_eq(now, next_at) &&
147
                    (++events == 1 || time_before(next_at, earliest)))
148
                        earliest = next_at;
149
        }
150
 
151
        if (!events) {
152
                debug("no actions");
153
                del_timer(&ml->timer);
154
        } else {
155
                debug("timer set");
156
                mod_timer(&ml->timer, earliest);
157
        }
158
}
159
 
160
/*
161
 * Apply an envelope to a value
162
 */
163
static int apply_envelope(struct ml_effect_state *state, int value,
164
                          struct ff_envelope *envelope)
165
{
166
        struct ff_effect *effect = state->effect;
167
        unsigned long now = jiffies;
168
        int time_from_level;
169
        int time_of_envelope;
170
        int envelope_level;
171
        int difference;
172
 
173
        if (envelope->attack_length &&
174
            time_before(now,
175
                        state->play_at + msecs_to_jiffies(envelope->attack_length))) {
176
                debug("value = 0x%x, attack_level = 0x%x", value,
177
                      envelope->attack_level);
178
                time_from_level = jiffies_to_msecs(now - state->play_at);
179
                time_of_envelope = envelope->attack_length;
180
                envelope_level = min_t(__s16, envelope->attack_level, 0x7fff);
181
 
182
        } else if (envelope->fade_length && effect->replay.length &&
183
                   time_after(now,
184
                              state->stop_at - msecs_to_jiffies(envelope->fade_length)) &&
185
                   time_before(now, state->stop_at)) {
186
                time_from_level = jiffies_to_msecs(state->stop_at - now);
187
                time_of_envelope = envelope->fade_length;
188
                envelope_level = min_t(__s16, envelope->fade_level, 0x7fff);
189
        } else
190
                return value;
191
 
192
        difference = abs(value) - envelope_level;
193
 
194
        debug("difference = %d", difference);
195
        debug("time_from_level = 0x%x", time_from_level);
196
        debug("time_of_envelope = 0x%x", time_of_envelope);
197
 
198
        difference = difference * time_from_level / time_of_envelope;
199
 
200
        debug("difference = %d", difference);
201
 
202
        return value < 0 ?
203
                -(difference + envelope_level) : (difference + envelope_level);
204
}
205
 
206
/*
207
 * Return the type the effect has to be converted into (memless devices)
208
 */
209
static int get_compatible_type(struct ff_device *ff, int effect_type)
210
{
211
 
212
        if (test_bit(effect_type, ff->ffbit))
213
                return effect_type;
214
 
215
        if (effect_type == FF_PERIODIC && test_bit(FF_RUMBLE, ff->ffbit))
216
                return FF_RUMBLE;
217
 
218
        printk(KERN_ERR
219
               "ff-memless: invalid type in get_compatible_type()\n");
220
 
221
        return 0;
222
}
223
 
224
/*
225
 * Combine two effects and apply gain.
226
 */
227
static void ml_combine_effects(struct ff_effect *effect,
228
                               struct ml_effect_state *state,
229
                               int gain)
230
{
231
        struct ff_effect *new = state->effect;
232
        unsigned int strong, weak, i;
233
        int x, y;
234
        fixp_t level;
235
 
236
        switch (new->type) {
237
        case FF_CONSTANT:
238
                i = new->direction * 360 / 0xffff;
239
                level = fixp_new16(apply_envelope(state,
240
                                        new->u.constant.level,
241
                                        &new->u.constant.envelope));
242
                x = fixp_mult(fixp_sin(i), level) * gain / 0xffff;
243
                y = fixp_mult(-fixp_cos(i), level) * gain / 0xffff;
244
                /*
245
                 * here we abuse ff_ramp to hold x and y of constant force
246
                 * If in future any driver wants something else than x and y
247
                 * in s8, this should be changed to something more generic
248
                 */
249
                effect->u.ramp.start_level =
250
                        max(min(effect->u.ramp.start_level + x, 0x7f), -0x80);
251
                effect->u.ramp.end_level =
252
                        max(min(effect->u.ramp.end_level + y, 0x7f), -0x80);
253
                break;
254
 
255
        case FF_RUMBLE:
256
                strong = new->u.rumble.strong_magnitude * gain / 0xffff;
257
                weak = new->u.rumble.weak_magnitude * gain / 0xffff;
258
                effect->u.rumble.strong_magnitude =
259
                        min(strong + effect->u.rumble.strong_magnitude,
260
                            0xffffU);
261
                effect->u.rumble.weak_magnitude =
262
                        min(weak + effect->u.rumble.weak_magnitude, 0xffffU);
263
                break;
264
 
265
        case FF_PERIODIC:
266
                i = apply_envelope(state, abs(new->u.periodic.magnitude),
267
                                   &new->u.periodic.envelope);
268
 
269
                /* here we also scale it 0x7fff => 0xffff */
270
                i = i * gain / 0x7fff;
271
 
272
                effect->u.rumble.strong_magnitude =
273
                        min(i + effect->u.rumble.strong_magnitude, 0xffffU);
274
                effect->u.rumble.weak_magnitude =
275
                        min(i + effect->u.rumble.weak_magnitude, 0xffffU);
276
                break;
277
 
278
        default:
279
                printk(KERN_ERR "ff-memless: invalid type in ml_combine_effects()\n");
280
                break;
281
        }
282
 
283
}
284
 
285
 
286
/*
287
 * Because memoryless devices have only one effect per effect type active
288
 * at one time we have to combine multiple effects into one
289
 */
290
static int ml_get_combo_effect(struct ml_device *ml,
291
                               unsigned long *effect_handled,
292
                               struct ff_effect *combo_effect)
293
{
294
        struct ff_effect *effect;
295
        struct ml_effect_state *state;
296
        int effect_type;
297
        int i;
298
 
299
        memset(combo_effect, 0, sizeof(struct ff_effect));
300
 
301
        for (i = 0; i < FF_MEMLESS_EFFECTS; i++) {
302
                if (__test_and_set_bit(i, effect_handled))
303
                        continue;
304
 
305
                state = &ml->states[i];
306
                effect = state->effect;
307
 
308
                if (!test_bit(FF_EFFECT_STARTED, &state->flags))
309
                        continue;
310
 
311
                if (time_before(jiffies, state->play_at))
312
                        continue;
313
 
314
                /*
315
                 * here we have started effects that are either
316
                 * currently playing (and may need be aborted)
317
                 * or need to start playing.
318
                 */
319
                effect_type = get_compatible_type(ml->dev->ff, effect->type);
320
                if (combo_effect->type != effect_type) {
321
                        if (combo_effect->type != 0) {
322
                                __clear_bit(i, effect_handled);
323
                                continue;
324
                        }
325
                        combo_effect->type = effect_type;
326
                }
327
 
328
                if (__test_and_clear_bit(FF_EFFECT_ABORTING, &state->flags)) {
329
                        __clear_bit(FF_EFFECT_PLAYING, &state->flags);
330
                        __clear_bit(FF_EFFECT_STARTED, &state->flags);
331
                } else if (effect->replay.length &&
332
                           time_after_eq(jiffies, state->stop_at)) {
333
 
334
                        __clear_bit(FF_EFFECT_PLAYING, &state->flags);
335
 
336
                        if (--state->count <= 0) {
337
                                __clear_bit(FF_EFFECT_STARTED, &state->flags);
338
                        } else {
339
                                state->play_at = jiffies +
340
                                        msecs_to_jiffies(effect->replay.delay);
341
                                state->stop_at = state->play_at +
342
                                        msecs_to_jiffies(effect->replay.length);
343
                        }
344
                } else {
345
                        __set_bit(FF_EFFECT_PLAYING, &state->flags);
346
                        state->adj_at = jiffies;
347
                        ml_combine_effects(combo_effect, state, ml->gain);
348
                }
349
        }
350
 
351
        return combo_effect->type != 0;
352
}
353
 
354
static void ml_play_effects(struct ml_device *ml)
355
{
356
        struct ff_effect effect;
357
        DECLARE_BITMAP(handled_bm, FF_MEMLESS_EFFECTS);
358
 
359
        memset(handled_bm, 0, sizeof(handled_bm));
360
 
361
        while (ml_get_combo_effect(ml, handled_bm, &effect))
362
                ml->play_effect(ml->dev, ml->private, &effect);
363
 
364
        ml_schedule_timer(ml);
365
}
366
 
367
static void ml_effect_timer(unsigned long timer_data)
368
{
369
        struct input_dev *dev = (struct input_dev *)timer_data;
370
        struct ml_device *ml = dev->ff->private;
371
 
372
        debug("timer: updating effects");
373
 
374
        spin_lock(&ml->timer_lock);
375
        ml_play_effects(ml);
376
        spin_unlock(&ml->timer_lock);
377
}
378
 
379
static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
380
{
381
        struct ml_device *ml = dev->ff->private;
382
        int i;
383
 
384
        spin_lock_bh(&ml->timer_lock);
385
 
386
        ml->gain = gain;
387
 
388
        for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
389
                __clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
390
 
391
        ml_play_effects(ml);
392
 
393
        spin_unlock_bh(&ml->timer_lock);
394
}
395
 
396
static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
397
{
398
        struct ml_device *ml = dev->ff->private;
399
        struct ml_effect_state *state = &ml->states[effect_id];
400
 
401
        spin_lock_bh(&ml->timer_lock);
402
 
403
        if (value > 0) {
404
                debug("initiated play");
405
 
406
                __set_bit(FF_EFFECT_STARTED, &state->flags);
407
                state->count = value;
408
                state->play_at = jiffies +
409
                                 msecs_to_jiffies(state->effect->replay.delay);
410
                state->stop_at = state->play_at +
411
                                 msecs_to_jiffies(state->effect->replay.length);
412
                state->adj_at = state->play_at;
413
 
414
                ml_schedule_timer(ml);
415
 
416
        } else {
417
                debug("initiated stop");
418
 
419
                if (test_bit(FF_EFFECT_PLAYING, &state->flags))
420
                        __set_bit(FF_EFFECT_ABORTING, &state->flags);
421
                else
422
                        __clear_bit(FF_EFFECT_STARTED, &state->flags);
423
 
424
                ml_play_effects(ml);
425
        }
426
 
427
        spin_unlock_bh(&ml->timer_lock);
428
 
429
        return 0;
430
}
431
 
432
static int ml_ff_upload(struct input_dev *dev,
433
                        struct ff_effect *effect, struct ff_effect *old)
434
{
435
        struct ml_device *ml = dev->ff->private;
436
        struct ml_effect_state *state = &ml->states[effect->id];
437
 
438
        spin_lock_bh(&ml->timer_lock);
439
 
440
        if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
441
                __clear_bit(FF_EFFECT_PLAYING, &state->flags);
442
                state->play_at = jiffies +
443
                                 msecs_to_jiffies(state->effect->replay.delay);
444
                state->stop_at = state->play_at +
445
                                 msecs_to_jiffies(state->effect->replay.length);
446
                state->adj_at = state->play_at;
447
                ml_schedule_timer(ml);
448
        }
449
 
450
        spin_unlock_bh(&ml->timer_lock);
451
 
452
        return 0;
453
}
454
 
455
static void ml_ff_destroy(struct ff_device *ff)
456
{
457
        struct ml_device *ml = ff->private;
458
 
459
        kfree(ml->private);
460
}
461
 
462
/**
463
 * input_ff_create_memless() - create memoryless force-feedback device
464
 * @dev: input device supporting force-feedback
465
 * @data: driver-specific data to be passed into @play_effect
466
 * @play_effect: driver-specific method for playing FF effect
467
 */
468
int input_ff_create_memless(struct input_dev *dev, void *data,
469
                int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
470
{
471
        struct ml_device *ml;
472
        struct ff_device *ff;
473
        int error;
474
        int i;
475
 
476
        ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL);
477
        if (!ml)
478
                return -ENOMEM;
479
 
480
        ml->dev = dev;
481
        ml->private = data;
482
        ml->play_effect = play_effect;
483
        ml->gain = 0xffff;
484
        spin_lock_init(&ml->timer_lock);
485
        setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
486
 
487
        set_bit(FF_GAIN, dev->ffbit);
488
 
489
        error = input_ff_create(dev, FF_MEMLESS_EFFECTS);
490
        if (error) {
491
                kfree(ml);
492
                return error;
493
        }
494
 
495
        ff = dev->ff;
496
        ff->private = ml;
497
        ff->upload = ml_ff_upload;
498
        ff->playback = ml_ff_playback;
499
        ff->set_gain = ml_ff_set_gain;
500
        ff->destroy = ml_ff_destroy;
501
 
502
        /* we can emulate periodic effects with RUMBLE */
503
        if (test_bit(FF_RUMBLE, ff->ffbit)) {
504
                set_bit(FF_PERIODIC, dev->ffbit);
505
                set_bit(FF_SINE, dev->ffbit);
506
                set_bit(FF_TRIANGLE, dev->ffbit);
507
                set_bit(FF_SQUARE, dev->ffbit);
508
        }
509
 
510
        for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
511
                ml->states[i].effect = &ff->effects[i];
512
 
513
        return 0;
514
}
515
EXPORT_SYMBOL_GPL(input_ff_create_memless);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.