Reply
Thread Tools
Community Council | Posts: 2,332 | Thanked: 3,580 times | Joined on May 2012 @ Finland
#21
OK, I have bee struggling with the vibration device for some time, as it was extremely annoying why I could not make it work.

I did quite a lot of searching, before it hit home that the device actually needs to be initialized with a set of waveform samples before it is usable. I kind of thought it is enough to write a set of input_event structures to it to make it work, but turns out those events only trigger the internal works to play out a pre-loaded sample on the vibrator device.

There is some user-space utility that initializes the vifrator device with the waveform samples in init phase, and that was the reason I could not tickle it in pre-init phase.

So, I added some debug code to vibra_spi.c, recompiled the module and was actually able to capture the data needed to initialize it. It turns out there are 36 different sample sequences, each 612 bytes long, that need to be fed to the device.

Here is one sample aas seen on kernel log:

Code:
Sep 13 09:27:31 (2012) kernel: [   34.296295] Entered vibra_spi_upload()
Sep 13 09:27:31 (2012) kernel: [   34.296295] einfo->buflen       = 612
Sep 13 09:27:31 (2012) kernel: [   34.296295] einfo->flags        = 8
Sep 13 09:27:31 (2012) kernel: [   34.296295] einfo->remaining_ms = 0
Sep 13 09:27:31 (2012) kernel: [   34.296325] einfo->len_ms       = 6
Sep 13 09:27:31 (2012) kernel: [   34.296325] einfo->buf: 00000000: aa aa aa aa ab aa aa aa 6a 55 55 55 56 55 ad aa
Sep 13 09:27:31 (2012) kernel: [   34.296325] 00000010: 6a 55 ad aa ad 6a 55 ab 5a d5 aa 55 56 ad 5a ad
Sep 13 09:27:31 (2012) kernel: [   34.296356] 00000020: 5a ad 5a ad ad d6 6a b5 5a ab d5 5a d6 6a ad d5
Sep 13 09:27:31 (2012) kernel: [   34.296356] 00000030: 56 6b ad b5 6b ad b5 b6 b6 d6 da 5a ad ad b5 b5
Sep 13 09:27:31 (2012) kernel: [   34.296356] 00000040: 6d 6d 6d 6d ad ad 6d 6d b6 b6 b5 ad 6d 5b db d6
Sep 13 09:27:31 (2012) kernel: [   34.296356] 00000050: db b6 b6 6d b6 b5 6d 5b b6 b5 6d db db b6 6d db
Sep 13 09:27:31 (2012) kernel: [   34.296386] 00000060: 6d db b6 6d b6 6d db b6 6d b7 6d db db 6e db b6
Sep 13 09:27:31 (2012) kernel: [   34.296386] 00000070: b6 6d b7 6d b6 db b6 dd 76 db 76 db b6 db 76 db
Sep 13 09:27:31 (2012) kernel: [   34.296386] 00000080: b6 dd b6 db bb 6d b7 ed db 76 db 6e 6d b7 ed b6
Sep 13 09:27:31 (2012) kernel: [   34.296417] 00000090: b6 db 6e db db 6d b7 ed ed b6 db 76 76 db 6d b7
Sep 13 09:27:31 (2012) kernel: [   34.296417] 000000a0: b7 ed b6 db db 6e db 6d ed b6 dd b6 6d bb 6d b7
Sep 13 09:27:31 (2012) kernel: [   34.296417] 000000b0: 76 db 6e db 76 db 76 db 6e db 76 db 6d db 6d db
Sep 13 09:27:31 (2012) kernel: [   34.296447] 000000c0: db b6 6d b7 b6 6d db b6 6d db b6 ed b6 6d db b6
Sep 13 09:27:31 (2012) kernel: [   34.296447] 000000d0: db b6 6d db db da b6 6d db da b6 6d da b6 b5 6d
Sep 13 09:27:31 (2012) kernel: [   34.296447] 000000e0: b5 6d 6d db db da d6 b6 6d 6b 6b 5b 6d 6d 6d 6d
Sep 13 09:27:31 (2012) kernel: [   34.296447] 000000f0: 6b 6d 6d 6d d6 5a 5b 6b ad ad b5 d6 b5 d6 5a 6b
Sep 13 09:27:31 (2012) kernel: [   34.296478] 00000100: b5 d6 6a ad ad d5 5a ab 56 ab d5 5a aa d5 6a b5
Sep 13 09:27:31 (2012) kernel: [   34.296478] 00000110: ab 55 ab d5 6a d5 aa 55 55 ab 56 b5 5a 55 ab 5a
Sep 13 09:27:31 (2012) kernel: [   34.296478] 00000120: 6a 55 d5 aa 55 55 b5 aa aa aa aa 6a 55 55 55 d5
Sep 13 09:27:31 (2012) kernel: [   34.296508] 00000130: 55 55 55 55 54 55 55 55 aa aa aa aa aa 52 55 55
Sep 13 09:27:31 (2012) kernel: [   34.296508] 00000140: aa 54 55 aa a9 2a 55 a9 52 a5 2a 55 95 2a 55 aa
Sep 13 09:27:31 (2012) kernel: [   34.296508] 00000150: 95 2a 95 2a 52 a9 54 2a a9 54 4a a5 4a a9 94 4a
Sep 13 09:27:31 (2012) kernel: [   34.296539] 00000160: 4a 29 a5 52 29 a5 94 52 94 94 52 4a 29 29 25 a5
Sep 13 09:27:31 (2012) kernel: [   34.296539] 00000170: 4a 4a 4a 49 4a 4a 4a 4a 29 49 49 49 94 a4 24 25
Sep 13 09:27:31 (2012) kernel: [   34.296539] 00000180: 49 49 52 92 4a 92 a4 24 92 92 24 49 49 92 24 49
Sep 13 09:27:31 (2012) kernel: [   34.296539] 00000190: 49 92 24 25 24 49 92 24 49 92 24 89 92 24 92 24
Sep 13 09:27:31 (2012) kernel: [   34.296569] 000001a0: 24 49 24 49 44 92 24 91 48 92 48 92 48 92 48 92
Sep 13 09:27:31 (2012) kernel: [   34.296569] 000001b0: 44 92 44 92 24 91 24 92 12 49 24 89 91 44 92 48
Sep 13 09:27:31 (2012) kernel: [   34.296569] 000001c0: 49 22 89 24 24 91 44 12 92 48 22 89 49 24 91 44
Sep 13 09:27:31 (2012) kernel: [   34.296600] 000001d0: 44 92 48 22 22 89 24 91 92 44 12 49 89 24 91 24
Sep 13 09:27:31 (2012) kernel: [   34.296600] 000001e0: 49 22 49 24 48 12 49 12 49 92 48 92 49 12 49 12
Sep 13 09:27:31 (2012) kernel: [   34.296600] 000001f0: 91 24 49 24 12 49 92 24 49 92 24 49 92 24 49 22
Sep 13 09:27:31 (2012) kernel: [   34.296630] 00000200: 49 92 24 49 49 4a 92 24 29 49 92 24 49 4a 92 24
Sep 13 09:27:31 (2012) kernel: [   34.296630] 00000210: 52 92 a4 24 24 25 49 49 92 92 94 a4 4a 4a 52 52
Sep 13 09:27:31 (2012) kernel: [   34.296630] 00000220: 4a 4a 4a 4a 92 52 52 52 29 a5 a4 94 94 52 4a 49
Sep 13 09:27:31 (2012) kernel: [   34.296661] 00000230: 52 4a 29 a5 94 4a 29 a5 a9 54 4a a9 54 2a 95 4a
Sep 13 09:27:31 (2012) kernel: [   34.296661] 00000240: 4a a5 52 a9 52 a5 4a a5 55 aa 54 a9 2a 55 a9 4a
Sep 13 09:27:31 (2012) kernel: [   34.296661] 00000250: aa 4a 55 a9 aa 4a 55 95 55 55 55 aa aa aa aa 2a
Sep 13 09:27:31 (2012) kernel: [   34.296661] 00000260: aa aa aa aa
A bit of digging produced the culprit; there is something called "meegofeedbackd" that is loading and initializing the sample maps to the vibra_spi driver:

Code:
Sep 13 09:27:31 (2012) meegofeedbackd: Loaded backend plugin "/usr/lib/meegofeedbackd/non-threaded-backends/00-libmeegofeedback-pulseaudio.so"
Sep 13 09:27:31 (2012) meegofeedbackd: Loaded backend plugin "/usr/lib/meegofeedbackd/non-threaded-backends/01-libmeegofeedback-vibra.so"
Sep 13 09:27:31 (2012) meegofeedbackd: MfManager: Lib directory "/usr/lib/meegofeedbackd/threaded-backends" doesn't exist.
Sep 13 09:27:31 (2012) meegofeedbackd: Loaded source plugin "/usr/lib/meegofeedbackd/sources/libmeegofeedback-reactionmap.so"
Sep 13 09:27:31 (2012) meegofeedbackd: Loaded source plugin "/usr/lib/meegofeedbackd/sources/libmeegofeedback-wakeup.so"
There seems to be sources available for the following packages, so I need to dig into the sources to see how the initialization is done. Propably it is via ioctl() to /dev/input/vibra or something like that:
meegofeedbackd_0.10.7-5+0m6.tar
meegofeedback-reactionmaps_0.15.1-3+0m8.tar
 

The Following 3 Users Say Thank You to juiceme For This Useful Post:
Community Council | Posts: 2,332 | Thanked: 3,580 times | Joined on May 2012 @ Finland
#22
Not se straightforward as I first thought...

Even as the sources for meegofeedbackd and reactionmaps are available, the backend part which uploads the sample to the device via ioctl is closed source. Bummer.

But, I do have the samples, as I fished them off the kernel, so I do have several options how to proceed;
  • I could try to fish out what&how the ioctl is used to upload. This is not directly seen in spi_vibra but it goes through the upper SPI layer which makes it a bit obscured.
  • I could make my own /proc/ interface to vibra_spi to load the samples. I like proc stuff better than ioctls anyway in my modules as it is way simpler to tweak from userland
  • I could hard-code the samples in the driver, there is actually no need to upload that stuff as it never changes

What would be the best/easiest way to proceed...?
In the last two options I would propably need to recreate vibra_spi as a new module and make sure it is unloaded after use as not to conflict with the original module when it is loaded and initialized in later boot phase.
Or, I could stub out the initialization function in the module so that later init does not cause anything, and just replace the original module...

Thoughts?
 

The Following User Says Thank You to juiceme For This Useful Post:
coderus's Avatar
Posts: 3,768 | Thanked: 5,635 times | Joined on Nov 2011 @ Russia
#23
i think better to produce hardcoded spi and just use it
__________________
Please Donate for my work: PayPal
Your donations makes my applications better

my twitter @icoderus

[F.A.Q.] List of harmattan terminal warnings and errors (contribute!)

If you like what i do please add recomendation for me in LinkedIn to help me get new job
 

The Following User Says Thank You to coderus For This Useful Post:
Community Council | Posts: 2,332 | Thanked: 3,580 times | Joined on May 2012 @ Finland
#24
I have now studied the spi_vibra driver initialization a bit. It seems that the sample upload is done via the following kind of ioctl call.
This bit uploads 612 bytes of sample data to one effect. (Actually I think it is 306 words but that is identical...)
There are 32 effects that need to be uploaded in total.

Code:
int initialize_samples(int fp, int effect)
{
  struct ff_effect new;

  new.type = FF_PERIODIC;
  new.id = -1;
  new.direction = 0;
  new.u.periodic.waveform = FF_CUSTOM;
  new.u.periodic.period = 6;
  new.u.periodic.magnitude = 0;
  new.u.periodic.offset = 0;
  new.u.periodic.phase = 0;
  new.u.periodic.envelope.attack_length = 0;
  new.u.periodic.envelope.attack_level = 0;
  new.u.periodic.envelope.fade_length = 0;
  new.u.periodic.envelope.fade_level = 0;
  new.u.periodic.custom_len = 306;
  new.u.periodic.custom_data = (void *) initstring[effect];

  if(ioctl(fp, EVIOCSFF, &new) < 0) {
    perror("ioctl");
  }

  return ret;
}
The sample bytestring is stored in initstring[][] table in this example.
The full code and bytestrings can be gotten from my svn server, same place as before.

However, even as this ioctl produces exactly same results in the driver as the closed-source initialization, I stll cannot make the device vibrate. There is some element I am missing here in the process.

Actually it just occured to me, how is the initialization done in nitdroid? The vibra device works there. Is the initialization sequence there on an open source component?
 

The Following User Says Thank You to juiceme For This Useful Post:
coderus's Avatar
Posts: 3,768 | Thanked: 5,635 times | Joined on Nov 2011 @ Russia
#25
i can't remember if nitdroid support vibra.
__________________
Please Donate for my work: PayPal
Your donations makes my applications better

my twitter @icoderus

[F.A.Q.] List of harmattan terminal warnings and errors (contribute!)

If you like what i do please add recomendation for me in LinkedIn to help me get new job
 

The Following 2 Users Say Thank You to coderus For This Useful Post:
Community Council | Posts: 2,332 | Thanked: 3,580 times | Joined on May 2012 @ Finland
#26
Originally Posted by coderus View Post
i can't remember if nitdroid support vibra.
Oh my!
That was my mistake, I just had to actually check it tpo belive it, and it is true, I could not get it to vibrate.
I somehow remembered it did work on nitdroid.
 

The Following User Says Thank You to juiceme For This Useful Post:
Posts: 52 | Thanked: 28 times | Joined on Oct 2011 @ Poland, Tricity
#27
Originally Posted by juiceme View Post
OK, I have bee struggling with the vibration device for some time, as it was extremely annoying why I could not make it work.

I did quite a lot of searching, before it hit home that the device actually needs to be initialized with a set of waveform samples before it is usable. I kind of thought it is enough to write a set of input_event structures to it to make it work, but turns out those events only trigger the internal works to play out a pre-loaded sample on the vibrator device.

[...]
So did I understood this right - you've managed to "play" some predefined vibration on init? If so I would be interested in source or preferably even a working binary :-). I'd like to change my preinit so that phones vibrates when the system is ready for choosing my system.

BTW. Have you tried a to play few low notes to make a tick sound rather then vibration? Or maybe even play some wav?
 

The Following 2 Users Say Thank You to eccenux For This Useful Post:
Posts: 52 | Thanked: 28 times | Joined on Oct 2011 @ Poland, Tricity
#28
So I made some tests and I found out that I would probably need to initialize PulseAudio somehow to play sounds. Or at least when using `/usr/bin/aplay` I get this error:
Code:
ALSA lib pulse.c:229:(pulse_connect) PulseAudio: Unable to connect: Connection refused
But I also noticed that devices in /dev/snd have different rights in preinit and after booted to MeeGo (when booted the group is audio). Do you think it would be wise to change the group and in preinit and try that? Or maybe of more importance - dsp seem to be unavailable and I have no clue how to initialize it.

Oh and BTW - I did try what seemed to be easier to just beep in console. But neither of below work :-(.
Code:
echo -ne '\007'
echo -ne '\007' > /dev/tty
echo -ne '\007' > /dev/console
In preinit there are also many links missing like vibra -> event4 - which might be more interesting for you, if you still want to vibrate.

This is in preinit stage:
Code:
event4          crw-------    1 root     root       13,  68
This is after booting:
Code:
event4          crw-rw----    1 root     input      13,  68 
vibra -> event4 lrwxrwxrwx    1 root     root             6
Maybe there are some internal dependencies to /dev/input/vibra being available? I know this is a long shot, but I've actually seen worse things ;-).
 

The Following User Says Thank You to eccenux For This Useful Post:
Community Council | Posts: 2,332 | Thanked: 3,580 times | Joined on May 2012 @ Finland
#29
Hi eccenux, thanks for the tip.
Actually I have not tried to play sounds, I was so fixed on the idea of getting the vibration device working I did not think about outputting a clicking sound. That would probably work OK for keypress confirmation too.

As for status update on the vibration device initialization, I have not been actively trying to crack that nut for saome time now, as I have been otherwise enganged.
Anyway, as I state in my posting about four weeks ago, I managed to fish out the initialization sequences out from the closed-source library that does the init by building a debug version of vibration device that logs the given sequences.
Turns out there are 32 different samples that are each 306 words long. However, even as I initialize the device with exactly the same data, still I could not make it vibrate, there is something else that is needed.

You can load the source code for the initialization from my svn repository, https://toosa.swagman.org/svn/sillykbd/TRUNK/ The initialization routine and data is in the file "vibra_test.c"

Please test it, and if you find out what is missing/wrong in the initialization I would really like to hear!
 

The Following User Says Thank You to juiceme For This Useful Post:
Posts: 52 | Thanked: 28 times | Joined on Oct 2011 @ Poland, Tricity
#30
Thanks. I've tried to dig around for sound initialization (alsa/pulse), but eventually gave up. There seem to be to much to it.

I poked vibration a bit but didn't had too much luck. I did found hid-twl4030-vibra module which seem to be used in various places, but just loading it didn't work. Maybe some of my findings will help you:
  • There are some *.ivt files on N9 which seem to be files for vibration. Haven't found a way to "play" them.
  • There are some rules for udev that seem to be vibration related in: "/etc/udev/rules.d/92-n770.rules".
  • /sbin/immvibed uses vibrations heavily, but have no idea how to use it even when the MeeGo system is fully loaded. If you'll look in the file you'll notice that there seem to be a dependency on "/dev/input/vibra" which is not available in preinit phase.
  • Also it seems vibrations where made by Kurre from Nokia. Maybe you could contact him and he would be kind enough to help? :-)

Anyway for now I gave up on both (sounds and vibrations). I'm going for a different approach and using image feedback. It almost works as I expect but sometimes I need to rub the screen rather then just hold my finger. Don't know why this happens. Maybe you could have a look (attached tar with all files)?
Attached Files
File Type: tar sillyboot2_touch.tar (150.5 KB, 29 views)
 

The Following User Says Thank You to eccenux For This Useful Post:
Reply

Thread Tools

 
Forum Jump


All times are GMT. The time now is 01:34.