freemangordon | fine | 00:01 |
---|---|---|
*** xes has joined #maemo-ssu | 00:03 | |
freemangordon | Pali: now we only need to make it work :D | 00:03 |
Pali | yes :-) | 00:03 |
freemangordon | DocScrutinizer05: iiuc the idea behind DT is that you don;t need to describe clock frequencies in DT | 00:03 |
freemangordon | you only tell the kernel which clock is your driver using | 00:04 |
freemangordon | which is not that bad idea imo | 00:04 |
freemangordon | and there *are* mul/div tables in the clock framework | 00:05 |
freemangordon | Pali: hmm, how familiar are you with the clock framework? | 00:06 |
freemangordon | I wonder how to deal with that wrong frequency: | 00:06 |
freemangordon | 1. reparent cam_mclk on 3430 | 00:07 |
freemangordon | 2. add a divider by 2 | 00:07 |
Pali | freemangordon: I do not know clock framework very good... | 00:07 |
freemangordon | both will work, but I really don;t know if there are real dividers, clocks etc behind those names or some of them are real and some virtual | 00:08 |
freemangordon | Pali: me either, I am trying to figure out what lays bahind it | 00:08 |
freemangordon | *neither | 00:08 |
*** dos1 has quit IRC | 02:07 | |
*** dos1 has joined #maemo-ssu | 02:07 | |
*** dos1 has quit IRC | 02:08 | |
*** xes has quit IRC | 02:24 | |
*** jonwil has joined #maemo-ssu | 02:35 | |
jonwil | hi | 02:36 |
*** dos1 has joined #maemo-ssu | 02:38 | |
*** Pali has quit IRC | 03:06 | |
*** freemangordon has quit IRC | 03:50 | |
*** freemangordon has joined #maemo-ssu | 03:51 | |
*** M4rtinK has quit IRC | 04:11 | |
*** LauRoman has joined #maemo-ssu | 04:28 | |
*** nox- has quit IRC | 04:36 | |
*** dos1 has quit IRC | 04:47 | |
*** Martix_ has quit IRC | 04:49 | |
*** LauRoman has quit IRC | 05:16 | |
*** amiconn has quit IRC | 05:56 | |
*** amiconn_ has joined #maemo-ssu | 05:56 | |
*** amiconn_ is now known as amiconn | 05:56 | |
*** jonwil has quit IRC | 06:57 | |
*** M13 has joined #maemo-ssu | 07:10 | |
*** Vlad_on_the_road has joined #maemo-ssu | 08:38 | |
*** Vlad_on_the_road has quit IRC | 08:54 | |
*** jonwil has joined #maemo-ssu | 09:11 | |
freemangordon | sailus: seems like cam_mclk clock propagation is FUBAR :( , see http://pastebin.com/m6KPax2R | 09:14 |
freemangordon | I put printks in isp_xclk_XXX functions | 09:17 |
freemangordon | sailus: this is the clock tree after all ^^^ : | 09:19 |
freemangordon | dpll4_ck 2 3 432000000 | 09:19 |
freemangordon | dpll4_m6_ck 0 0 144000000 | 09:19 |
freemangordon | dpll4_m6x2_ck 0 0 288000000 | 09:19 |
freemangordon | emu_per_alwon_ck 0 0 288000000 | 09:19 |
freemangordon | dpll4_m5_ck 0 0 86400000 | 09:19 |
freemangordon | dpll4_m5x2_ck 0 0 172800000 | 09:19 |
freemangordon | cam_mclk 0 0 172800000 | 09:19 |
freemangordon | cam_xclkb 0 0 10800000 | 09:19 |
freemangordon | cam_xclka 0 0 5760000 | 09:19 |
*** discopig has joined #maemo-ssu | 09:41 | |
*** discopig is now known as Guest41595 | 09:41 | |
*** Guest41595 has quit IRC | 09:46 | |
*** Guest41595 has joined #maemo-ssu | 09:46 | |
*** Guest41595 is now known as bromide | 09:46 | |
*** Martix_ has joined #maemo-ssu | 10:33 | |
*** amizraa has quit IRC | 10:46 | |
*** amizraa has joined #maemo-ssu | 10:51 | |
*** Martix_ has quit IRC | 11:13 | |
*** Martix_ has joined #maemo-ssu | 11:29 | |
DocScrutinizer05 | freemangordon: http://talk.maemo.org/showpost.php?p=1375221&postcount=44 | 11:36 |
DocScrutinizer05 | jonwil: ^^^ | 11:37 |
freemangordon | great news | 11:37 |
freemangordon | I guess those missing plugins can be easily REed | 11:37 |
*** Martix_ has quit IRC | 11:37 | |
DocScrutinizer05 | :nod: | 11:38 |
jonwil | if someone can get me binaries that work, that would be nice :) | 11:38 |
*** Pali has joined #maemo-ssu | 11:38 | |
jonwil | since my compile box is down for the count | 11:38 |
DocScrutinizer05 | huh? | 11:38 |
jonwil | for reasons I haven't had the time to check | 11:38 |
DocScrutinizer05 | aaah | 11:38 |
jonwil | i.e. I want binaries matching whatever nicolai has been testing | 11:39 |
jonwil | so I can play with them myself | 11:39 |
DocScrutinizer05 | so... ask nicolai ;-) | 11:39 |
* DocScrutinizer05 feels like Cpt Obvious | 11:39 | |
jonwil | post made :) | 11:40 |
DocScrutinizer05 | :-)) | 11:40 |
freemangordon | hmm, what about the sources? | 11:41 |
DocScrutinizer05 | I hope you feel less bored than you did a week or so ago :) | 11:41 |
freemangordon | jonwil: ^^^ :P | 11:41 |
DocScrutinizer05 | jonwil: and btw, awesome job you're doing! | 11:42 |
freemangordon | Pali: seems there is a nsasty bug in the clock framework :( | 11:43 |
freemangordon | Pali: see http://lxr.free-electrons.com/source/drivers/clk/clk.c#L1196 , what it is suppose to do in relation with CLK_SET_RATE_PARENT flag | 11:46 |
jonwil | I think what I might do next is to try and match code modules in pulseaudio-module-nokia-voice to the open code and blobs in the first pushes of pulseaudio-modules-meego (using function names from both) and see what that tells me about whats open and whats closed | 11:51 |
jonwil | It might well be that the answer for pulseaudio-module-nokia-voice is to simply take the code we have (from meego/harmattan) and the binaries we have and use both to figure out how to make the code we have right for Fremantle | 12:00 |
DocScrutinizer05 | :nod: | 12:02 |
DocScrutinizer05 | though... they (Nok) may have realized that they don't need their own nifty AGC algo since there are abundance of them in several free libs and toolkits, and thus the binaries might massively differ though functionally identical | 12:05 |
*** Mihanizat0r has joined #maemo-ssu | 12:09 | |
jonwil | I am planning to compare the oldest code drop (back when the code consisted of a set of code and then a binary pulseaudio-modules-nokia package containing module-nokia-algorithms.so, module-nokia-algorithms-agc.so, module-nokia-audiots.so, libnokia-common.so and module-nokia-parameters.so) | 12:12 |
jonwil | so I plan to figure out for all the bits in Fremantle pulseaudio-module-nokia-voice, which bits ended up in open code, which bits ended up in those blobs I just mentioned and which ones dont match anything I can find | 12:13 |
*** M13 has quit IRC | 12:13 | |
* DocScrutinizer05 can't help reading xxidiots instead of audiots | 12:13 | |
DocScrutinizer05 | ooh wait, i migth have a paper for you I dunno if it could help understand what that *-*-*-voice does | 12:16 |
jonwil | ok, maybe it will | 12:17 |
DocScrutinizer05 | http://linuxplumbersconf.org/2009/slides/Jyri-Sarha-audio_miniconf_slides.pdf | 12:17 |
jonwil | Ooh, "acoustic echo cancellation" sounds important | 12:20 |
jonwil | need to keep an eye out for indications of modules or functions that are doing that | 12:20 |
jonwil | also mentions "Speex SRC and Nokia proprietary algorithms" | 12:21 |
jonwil | The diagram on page 15 looks interesting | 12:22 |
jonwil | Although it doesn't appear that useful as its just a theoretical overview and doesn't contain details | 12:23 |
Pali | ~seen _nicolai_ | 12:28 |
infobot | _nicolai_ <~nicolai@pop8-1810.catv.wtnet.de> was last seen on IRC in channel #maemo, 68d 15h 23m 24s ago, saying: 'merlin1991, please do so. It is for my "ledpulse" package. maemo package interface says: "old version cleaned ..." every 4 hourse. The newest version to import is ledpulse 0.3'. | 12:28 |
*** zomack has joined #maemo-ssu | 12:33 | |
*** freemangordon has quit IRC | 12:37 | |
*** freemangordon has joined #maemo-ssu | 12:37 | |
*** zomack has quit IRC | 12:54 | |
*** bromide has quit IRC | 12:56 | |
*** bromide has joined #maemo-ssu | 12:57 | |
*** bromide is now known as Guest23041 | 12:57 | |
*** Guest23041 is now known as discopig | 13:06 | |
*** discopig has joined #maemo-ssu | 13:06 | |
*** freemangordon has quit IRC | 13:14 | |
*** freemangordon has joined #maemo-ssu | 13:14 | |
*** freemangordon has quit IRC | 13:41 | |
*** freemangordon has joined #maemo-ssu | 13:41 | |
*** amizraa has quit IRC | 13:50 | |
freemangordon | /join ##fptf-private | 13:51 |
DocScrutinizer05 | tz | 13:53 |
freemangordon | ~tz | 14:00 |
infobot | i heard tz is defined in /etc/default/rcS to fix that annoying warning message output by hwclockfirst.sh if your /usr is not on the root filesystem | 14:00 |
freemangordon | sailus: ping | 14:02 |
*** amizraa has joined #maemo-ssu | 14:09 | |
DocScrutinizer05 | ~factinfo tz | 14:21 |
infobot | tz -- created by bdarrow <bdarrow@ool-182d933c.dyn.optonline.net> at Tue Oct 23 18:42:51 2001 (4348 days); it has been requested 4 times, last by freemangordon, 20m 29s ago. | 14:21 |
DocScrutinizer05 | thought as much | 14:21 |
DocScrutinizer05 | ~forget tz | 14:21 |
infobot | i forgot tz, DocScrutinizer05 | 14:21 |
kerio | 2001? woah | 14:30 |
kerio | did the internet even exist then | 14:30 |
kerio | that must've been like carrier pigeons | 14:30 |
*** ceteigrek has joined #maemo-ssu | 14:36 | |
DocScrutinizer05 | 2001? I had DSL | 14:36 |
kerio | carrier pigeons i said | 14:36 |
DocScrutinizer05 | and a cheesy P-II-300 | 14:37 |
DocScrutinizer05 | with 256MB | 14:38 |
DocScrutinizer05 | but with *SCSI* ;-P | 14:38 |
kerio | i think i had dial-up in 2001 | 14:38 |
DocScrutinizer05 | nah, ISDN in 2000 | 14:39 |
DocScrutinizer05 | which cost me an arm and a leg when one time I forgot to tear down the connection for a week or so | 14:40 |
DocScrutinizer05 | been like 19ct/min back when | 14:41 |
*** arcean has joined #maemo-ssu | 14:46 | |
sailus | freemangordon: pong | 14:53 |
* ShadowJK had a P3-733 and a compaq prosignia (486 *overdrive*, 24M ram) | 14:54 | |
freemangordon | sailus: hi, someone is changing cam_mclk rate evry now and then http://pastebin.com/m6KPax2R | 14:54 |
freemangordon | sailus: I even made a version with stack_dump() called, but it shows noting interesting :) | 14:55 |
sailus | :-P | 14:55 |
sailus | I think the highest operating point used to be selected when the ISP was in use. | 14:56 |
sailus | I'm not sure whether that's being done any longer. | 14:56 |
sailus | But I have to say I haven't had this issue with the mainline kernel. | 14:56 |
sailus | Well, with N950. | 14:56 |
freemangordon | see - isp_xclk_set_rate:257 rate(5760000) divider(30) | 14:56 |
freemangordon | so actually it sets the correct frequency :D | 14:57 |
freemangordon | well, not correct , but requested | 14:57 |
freemangordon | sailus: which mainline version? | 14:57 |
freemangordon | because there are some changes in 3.10 compared to 3.6 for example | 14:58 |
freemangordon | esp in the way how are rate changes propagated and usage of CLK_SET_RATE_PARENT flag | 14:59 |
sailus | freemangordon: I tried linux-media tree yesterday (with a few patches from Aaro Koskinen). | 15:00 |
sailus | I guess the patches are in linux-omap already. | 15:00 |
freemangordon | which patches? | 15:02 |
sailus | Also apparently others than him. | 15:03 |
sailus | usb: musb: fix resource passed from glue layer to musb | 15:03 |
sailus | ARM: OMAP: rx51: change musb mode to OTG | 15:03 |
freemangordon | well, those should not matter in this case | 15:03 |
freemangordon | sailus: hmm, I thinks this code has never been tested on 3430 | 15:04 |
*** ceteigrek has left #maemo-ssu | 15:05 | |
sailus | Perhaps so. | 15:06 |
sailus | I guess it should boot on N900 as well but I haven't tried it out. | 15:06 |
freemangordon | by *this* code I mean omap3isp | 15:06 |
freemangordon | sailus: anyway, what is your advice? Should I try to fix that by recalculating the divisor every time a rate change happens? | 15:07 |
freemangordon | xclka/b divisor that is | 15:07 |
freemangordon | bwt aiui it is this http://git.kernel.org/cgit/linux/kernel/git/tmlind/linux-omap.git/commit/drivers/media/platform/omap3isp?id=6d1aa02f10497b138e01ebe6eafabd6071729334 patch that brings the problem | 15:09 |
freemangordon | or maybe not | 15:09 |
sailus | I think the rate change must not be allowed. | 15:09 |
sailus | That may crash the sensor as it's certainly not expected. | 15:10 |
freemangordon | hmm, maybe I can just lock dpll | 15:10 |
sailus | I think there's a way to register a notifier to prevent it. | 15:10 |
sailus | Or something. | 15:10 |
freemangordon | on cam_mclk? | 15:10 |
freemangordon | hmm, no, on xclka/b | 15:11 |
sailus | Ack. | 15:12 |
*** ceteigrek has joined #maemo-ssu | 15:12 | |
sailus | I think the smia driver would need to do that. | 15:12 |
freemangordon | :nod: | 15:12 |
freemangordon | will try to implement that | 15:12 |
*** ceteigrek has left #maemo-ssu | 15:12 | |
sailus | I actually haven't seen a situation before that someone would like to change the *same* clock so this hasn't been needed. | 15:13 |
freemangordon | I guess this results from CLK_SET_RATE_PARENT flag on mclk and parents | 15:13 |
freemangordon | as the rate changes are is propagated back and forth | 15:14 |
sailus | clk_notifier_register() | 15:14 |
freemangordon | amybe a bug in the clock framework, dunno | 15:14 |
freemangordon | yeah, was reading the code :) | 15:14 |
jonwil | the closest I want to get to kernel coding is rebuilding my Gentoo kernel when it needs it :P | 15:15 |
sailus | And return NOTIFY_BAD. | 15:15 |
sailus | I mean NOTIFY_BAD if the sensor is powered. | 15:15 |
sailus | Or... the clock is enabled. :-) | 15:16 |
freemangordon | yep | 15:16 |
freemangordon | hmm, and rate != old_rate | 15:16 |
freemangordon | sailus: maybe I should set the rate in power_on too | 15:21 |
freemangordon | and set notifier from there (and unset it on power_off) | 15:22 |
sailus | Isn't that already being done? | 15:27 |
sailus | There have been relatively recent changes to clock handling in the smiapp driver. | 15:27 |
freemangordon | setting the rate in power_on? | 15:27 |
freemangordon | hmm, nooo :) | 15:27 |
freemangordon | at least in our tree, lemme check upstream | 15:28 |
sailus | Apparently not. | 15:28 |
sailus | http://git.linuxtv.org/sailus/media_tree.git/commitdiff/a0c7bf81a5a8a3f817fc03c60a9807270e4bf4da | 15:28 |
freemangordon | sailus: not implemented in mainline? | 15:28 |
sailus | Just that they're correctly prepared before enabling. | 15:28 |
freemangordon | :nod: | 15:29 |
sailus | But the rate is already set there. | 15:30 |
sailus | I think you'd only need to register the notifier. | 15:30 |
freemangordon | someone changes it | 15:30 |
freemangordon | seed the log ^^^ | 15:30 |
freemangordon | *see | 15:30 |
sailus | Because they can? :-P | 15:31 |
freemangordon | also, platform_dtata set_xclk is called in power on | 15:31 |
freemangordon | (if not NULL) | 15:31 |
freemangordon | which will lead in clock being set in case we don;t use clock framework | 15:31 |
sailus | Yes. | 15:32 |
sailus | And don't you use the clock framework? | 15:32 |
freemangordon | sure | 15:32 |
freemangordon | my point is - if we *don't* use it, the clock will be set | 15:32 |
freemangordon | shit, I can't pass data to notifier function :( | 15:35 |
freemangordon | wtf is with those guys | 15:35 |
*** ceteigrek has joined #maemo-ssu | 15:35 | |
freemangordon | oh, I already have it in some clk_notifier_data | 15:36 |
*** ceteigrek has left #maemo-ssu | 15:38 | |
*** ceteigrek has joined #maemo-ssu | 15:38 | |
*** ceteigrek has left #maemo-ssu | 15:45 | |
*** dos1 has joined #maemo-ssu | 16:14 | |
*** LauRoman has joined #maemo-ssu | 16:16 | |
*** oldtopman has joined #maemo-ssu | 16:17 | |
*** freemangordon has quit IRC | 16:31 | |
*** freemangordon has joined #maemo-ssu | 16:36 | |
*** Mihanizat0r has quit IRC | 16:39 | |
*** freemangordon has quit IRC | 16:39 | |
*** freemangordon has joined #maemo-ssu | 16:39 | |
*** arcean_ has joined #maemo-ssu | 16:43 | |
*** arcean has quit IRC | 16:46 | |
*** ceteigrek has joined #maemo-ssu | 17:00 | |
*** Martix_ has joined #maemo-ssu | 17:04 | |
*** ceteigrek has left #maemo-ssu | 17:08 | |
*** arcean_ has quit IRC | 17:15 | |
*** Sicelo has quit IRC | 17:17 | |
*** Sicelo has joined #maemo-ssu | 17:20 | |
*** Martix_ has quit IRC | 17:24 | |
freemangordon | sailus: clk notifier in ISP, the result: http://pastebin.com/yQ1yH2wN :( | 17:36 |
freemangordon | the divider etc seems just fine | 17:36 |
freemangordon | but maybe ISP doesn't run at all | 17:36 |
freemangordon | sailus: see that "omap3isp omap3isp: CCDC stop timeout!" after I stopped yavta | 17:37 |
*** Martix_ has joined #maemo-ssu | 17:50 | |
*** sunny_s has joined #maemo-ssu | 18:00 | |
sailus | freemangordon: That suggests there could be a problem with the configuration. | 18:01 |
sailus | The CCDC will only stop after it has processed a full frame. | 18:01 |
freemangordon | yep, I am checking MUX | 18:01 |
freemangordon | seems like it is wrong | 18:01 |
sailus | Does your sensor configuration have the correct CCP2 bus in it? | 18:01 |
freemangordon | hmm, isn't CSI used? | 18:02 |
sailus | It's the same. :-) | 18:03 |
freemangordon | ok :) | 18:03 |
sailus | CSI-2 is different. | 18:03 |
freemangordon | well, MUX was set wrongly | 18:03 |
freemangordon | I will check all the needed gpios and will retry | 18:04 |
sailus | :-) | 18:04 |
sailus | Your .interface should be ISP_INTERFACE_CCP2B_PHY1. | 18:07 |
sailus | And the signalling mode is SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK. | 18:07 |
freemangordon | .csi_signalling_mode= SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK, | 18:08 |
sailus | Good. | 18:11 |
sailus | Any luck with changed gpio configuration? | 18:11 |
freemangordon | I am trying to grok what PULLUDENABLE1 is supposed to mean | 18:12 |
sailus | Doesn't say anything to me. :-P | 18:13 |
sailus | Pinmux? | 18:13 |
freemangordon | yep | 18:13 |
freemangordon | I suspect this is input with pulldown :) | 18:13 |
freemangordon | should be OMAP_PIN_INPUT_PULLDOWN, going to test | 18:15 |
freemangordon | sailus: don;t help :( | 18:27 |
*** NIN101 has joined #maemo-ssu | 18:30 | |
*** mkaindl has joined #maemo-ssu | 18:31 | |
sailus | :-P | 18:33 |
sailus | freemangordon: Do you get any interrupts now? | 18:33 |
sailus | If you have a patch for the clock notifier we could still see if we could upstream it. | 18:34 |
freemangordon | sailus: I am not sure this patch is really needed | 18:38 |
freemangordon | sailus: 40: 0 INTC OMAP3 ISP | 18:38 |
freemangordon | still no interrupts | 18:38 |
freemangordon | sailus: do I have to have cameras as consumers of VCSI/vaux2? | 18:53 |
Pali | ~seen _nicolai_ | 19:30 |
infobot | _nicolai_ <~nicolai@pop8-1810.catv.wtnet.de> was last seen on IRC in channel #maemo, 68d 22h 24m 58s ago, saying: 'merlin1991, please do so. It is for my "ledpulse" package. maemo package interface says: "old version cleaned ..." every 4 hourse. The newest version to import is ledpulse 0.3'. | 19:30 |
sailus | :-P | 19:42 |
sailus | freemangordon: I think yes. If that was the regulator which used to be there, then so it be. | 19:42 |
freemangordon | sailus: it is not that, ISP is consumer of VCSI | 19:43 |
freemangordon | and it is powered when needed | 19:43 |
*** M4rtinK has joined #maemo-ssu | 19:49 | |
sailus | Back later. | 19:51 |
freemangordon | I hope with a solution :P | 19:51 |
*** Vlad_on_the_road has joined #maemo-ssu | 20:25 | |
*** Martix_ has quit IRC | 20:49 | |
*** discopig has quit IRC | 20:59 | |
*** discopig has joined #maemo-ssu | 20:59 | |
*** discopig is now known as Guest84526 | 21:00 | |
*** Guest84526 has quit IRC | 21:01 | |
*** Guest84526 has joined #maemo-ssu | 21:01 | |
*** Guest84526 is now known as piscodig | 21:01 | |
*** amizraa has quit IRC | 21:04 | |
*** amizraa has joined #maemo-ssu | 21:06 | |
*** Vlad_on_the_road has quit IRC | 21:06 | |
*** xes has joined #maemo-ssu | 21:09 | |
*** arcean_ has joined #maemo-ssu | 21:36 | |
*** _rd has joined #maemo-ssu | 21:38 | |
*** xes_ has joined #maemo-ssu | 21:42 | |
*** xes has quit IRC | 21:44 | |
*** jonwil has quit IRC | 21:45 | |
*** BCMM has joined #maemo-ssu | 21:50 | |
*** _nicolai_ has joined #maemo-ssu | 21:58 | |
_nicolai_ | hi | 22:00 |
sailus | freemangordon: The ISP does need a few regulators. | 22:01 |
sailus | It works on 3630, so I assume that should be in order. | 22:01 |
sailus | The sensors require actually a few different ones but only one is controlled by the driver. | 22:01 |
*** dos1 has quit IRC | 22:04 | |
*** dos1 has joined #maemo-ssu | 22:04 | |
Pali | _nicolai_: hi | 22:06 |
*** piscodig has quit IRC | 22:17 | |
*** _rd has quit IRC | 22:19 | |
*** _rd has joined #maemo-ssu | 22:26 | |
*** xes_ has quit IRC | 22:48 | |
*** xes has joined #maemo-ssu | 22:48 | |
*** arcean_ has quit IRC | 22:50 | |
*** mkaindl has left #maemo-ssu | 22:55 | |
*** mkaindl has joined #maemo-ssu | 22:56 | |
sailus | freemangordon: Here the cameras both use vaux4. | 22:59 |
sailus | Where did vaux2 come from? | 22:59 |
sailus | http://git.linuxtv.org/sailus/media_tree.git/commitdiff/e4d76d27873a7a5edfb470a25ea5218061050873 | 23:01 |
*** discopig has joined #maemo-ssu | 23:05 | |
*** discopig is now known as Guest24737 | 23:06 | |
*** Guest24737 is now known as piscodig | 23:15 | |
*** piscodig has joined #maemo-ssu | 23:15 | |
*** mkaindl has left #maemo-ssu | 23:34 | |
*** _rd has quit IRC | 23:44 |
Generated by irclog2html.py 2.15.1 by Marius Gedminas - find it at mg.pov.lt!