linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
@ 2001-06-12 20:58 Alex Deucher
  2001-06-12 22:50 ` egger
  2001-06-12 22:51 ` Linus Torvalds
  0 siblings, 2 replies; 20+ messages in thread
From: Alex Deucher @ 2001-06-12 20:58 UTC (permalink / raw)
  To: torvalds, linux-kernel

As far as I know they have not been integrated into the Xfree tree.  I
believe there were some disagreements about extending the Xv API since
GATOS added some extentions to support the AIW video capture cards.  I
suppose someone could try and submit a patch again and see if they'll
take it.  

Also there is some work on a new XvMC interface that would allow for
extended DVD acceleration.

Alex

--------------------------

On Mon, 11 Jun 2001 egger@suse.de wrote: 
> 
> On 10 Jun, Linus Torvalds wrote: 
> 
> > I've not figured out why the ATI Xv stuff from gatos seems to not have 
> > made it into the XFree86 CVS tree - it works better than much of the 
> > Xv stuff for some other chipsets that _are_ in the CVS tree. 
> > 
> > I imported it into the XFree86 CVS some months ago, it was trivial. I 
> > don't have the patches lying around any more, though. I can try to 
> > re-create them if anybody needs help. 
> 
> Did it look endiansafe to you? The ATI Xv stuff from XFree86 4.1.0 
> produces psychadelic results for me on PPC. 

I have to say that I have absolutely no idea. I only use little-endian 
machines myself (and 99% x86). 

Also, which ATI Xv stuff are you talking about? The ATI Rage128 and ATI 
Radeon Xv code was at least a few months ago completely separate from
the 
ATI Rage code (the first two were in X CVS, while the latter only
existed 
in the gatos version). 

Has the Gatos code (or some other code) maybe been integrated into 4.1.0 
now? I haven't followed X CVS for the last months very closely.. 

                Linus

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 20:58 [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver Alex Deucher
@ 2001-06-12 22:50 ` egger
  2001-06-13 13:05   ` Alex Deucher
  2001-06-12 22:51 ` Linus Torvalds
  1 sibling, 1 reply; 20+ messages in thread
From: egger @ 2001-06-12 22:50 UTC (permalink / raw)
  To: adeucher; +Cc: linux-kernel

On 12 Jun, Alex Deucher wrote:

> Also there is some work on a new XvMC interface that would allow for
> extended DVD acceleration.

 Extended DVD acceleration with Motion-Compensation? How?

Servus,
       Daniel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 20:58 [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver Alex Deucher
  2001-06-12 22:50 ` egger
@ 2001-06-12 22:51 ` Linus Torvalds
  2001-06-13  6:33   ` egger
                     ` (2 more replies)
  1 sibling, 3 replies; 20+ messages in thread
From: Linus Torvalds @ 2001-06-12 22:51 UTC (permalink / raw)
  To: Alex Deucher; +Cc: linux-kernel



On Tue, 12 Jun 2001, Alex Deucher wrote:
>
> As far as I know they have not been integrated into the Xfree tree.  I
> believe there were some disagreements about extending the Xv API since
> GATOS added some extentions to support the AIW video capture cards.  I
> suppose someone could try and submit a patch again and see if they'll
> take it.

I got just the YUV code from Gatos, and a few months ago it took less than
an hour to merge just that part (and most of that was compiling and
testing).

The rest of Gatos is obviously more experimental, but the YUV code looks
quite sane.

> Also there is some work on a new XvMC interface that would allow for
> extended DVD acceleration.

Yes. Although I hope it's going to be XvMPG2 or something - some cards
literally do all of the mpeg2 stuff, not just parts of it, and limiting
yourself to just the motion comp is limiting the protocol quite badly.

		Linus


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 22:51 ` Linus Torvalds
@ 2001-06-13  6:33   ` egger
  2001-06-13 10:24   ` Stelian Pop
  2001-06-13 13:09   ` Alex Deucher
  2 siblings, 0 replies; 20+ messages in thread
From: egger @ 2001-06-13  6:33 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

On 12 Jun, Linus Torvalds wrote:

> Yes. Although I hope it's going to be XvMPG2 or something - some cards
> literally do all of the mpeg2 stuff, not just parts of it, and
> limiting yourself to just the motion comp is limiting the protocol
> quite badly.

 I recompiled a complete X with the extended Xv ATI driver from GATOS
 (aka ati.2). After fixing a bug (well, checking from the presence of
 a BIOS to try to access it anyway doesn't really make sense and will
 crash on any non-i386) I still have the same endianess problems.
 Just to let you know....

Servus,
       Daniel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 22:51 ` Linus Torvalds
  2001-06-13  6:33   ` egger
@ 2001-06-13 10:24   ` Stelian Pop
  2001-06-14 21:36     ` Linus Torvalds
                       ` (2 more replies)
  2001-06-13 13:09   ` Alex Deucher
  2 siblings, 3 replies; 20+ messages in thread
From: Stelian Pop @ 2001-06-13 10:24 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

> I got just the YUV code from Gatos, and a few months ago it took less than
> an hour to merge just that part (and most of that was compiling and
> testing).

Me too. After some days playing with it it seems that the Rage Mobility
Card (from the Vaio Picturebook C1VE <- that's where we started the
discussion):
	- has almost no acceleration in XFree, including the 4.1.0 release
	- has Xv YUV->RGB acceleration in Gatos (but that's all, no direct
	  video input etc).

> The rest of Gatos is obviously more experimental, but the YUV code looks
> quite sane.

Well, not quite... I've had several X lockups while using the YUV 
acceleration code. Let's say one lockup per half an hour.

Even the performances are controversial: with 320x240, I achieve 
great performance with xawtv/meye driver, I can even use the hardware
scaling facilities (well, the xawtv sources need a little hacking for
that), but in 640x480 the framerate achieved with Xv is below the
one I get by converting YUV->RGB in software...

But the main question remains: does the MotionEye camera support
overlay or not ? It could be that it is connected to the feature
connector of the ATI board for doing direct video input/output
(but no X driver recognizes this connector today). The motion jpeg
chip this camera is based on definately has a video output.

Or it could just be the application who gets YUV data from the chip
then send it directly to the video board. Today this works, almost
(because we need a patched X - read gatos - and a patched xawtv - in
order to do scaling).

Stelian.
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 22:50 ` egger
@ 2001-06-13 13:05   ` Alex Deucher
  0 siblings, 0 replies; 20+ messages in thread
From: Alex Deucher @ 2001-06-13 13:05 UTC (permalink / raw)
  To: egger; +Cc: linux-kernel

I'm not sure of the exact specs.  Check out the Xfree CVS.  Or ask on
the xpert@xfree86.org ML.

Alex

egger@suse.de wrote:
> 
> On 12 Jun, Alex Deucher wrote:
> 
> > Also there is some work on a new XvMC interface that would allow for
> > extended DVD acceleration.
> 
>  Extended DVD acceleration with Motion-Compensation? How?
> 
> Servus,
>        Daniel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-12 22:51 ` Linus Torvalds
  2001-06-13  6:33   ` egger
  2001-06-13 10:24   ` Stelian Pop
@ 2001-06-13 13:09   ` Alex Deucher
  2 siblings, 0 replies; 20+ messages in thread
From: Alex Deucher @ 2001-06-13 13:09 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-kernel

I actually heard from one of the xfree developers last night that the
merge of the the YUV stuff at least is in progress.  As I recall I think
XvMC was for general media controls, but I could be wrong, it's been a
while.

Alex

Linus Torvalds wrote:
> 
> On Tue, 12 Jun 2001, Alex Deucher wrote:
> >
> > As far as I know they have not been integrated into the Xfree tree.  I
> > believe there were some disagreements about extending the Xv API since
> > GATOS added some extentions to support the AIW video capture cards.  I
> > suppose someone could try and submit a patch again and see if they'll
> > take it.
> 
> I got just the YUV code from Gatos, and a few months ago it took less than
> an hour to merge just that part (and most of that was compiling and
> testing).
> 
> The rest of Gatos is obviously more experimental, but the YUV code looks
> quite sane.
> 
> > Also there is some work on a new XvMC interface that would allow for
> > extended DVD acceleration.
> 
> Yes. Although I hope it's going to be XvMPG2 or something - some cards
> literally do all of the mpeg2 stuff, not just parts of it, and limiting
> yourself to just the motion comp is limiting the protocol quite badly.
> 
>                 Linus

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-13 10:24   ` Stelian Pop
@ 2001-06-14 21:36     ` Linus Torvalds
  2001-06-15 21:10     ` Stelian Pop
  2001-06-28 19:11     ` volodya
  2 siblings, 0 replies; 20+ messages in thread
From: Linus Torvalds @ 2001-06-14 21:36 UTC (permalink / raw)
  To: linux-kernel

In article <E15A7os-0003e9-00@come.alcove-fr>,
Stelian Pop  <stelian@alcove.fr> wrote:
>
>Well, not quite... I've had several X lockups while using the YUV 
>acceleration code. Let's say one lockup per half an hour.

Strange. I've watched DVD's etc. Maybe it's not the Xv code, but your
camera code?

>Even the performances are controversial: with 320x240, I achieve 
>great performance with xawtv/meye driver, I can even use the hardware
>scaling facilities (well, the xawtv sources need a little hacking for
>that), but in 640x480 the framerate achieved with Xv is below the
>one I get by converting YUV->RGB in software...

There's something wrong with your setup. I watch full-screen DVD's on my
VAIO. It's not really fast enough with just the YUV conversion done in
hardware (it's plenty fast enough if MC and iDCT would be done in HW
too, but ATI doesn't release docs without strict NDA's). But there's no
way DVD's are watchable with sw YUV conversion and scaling.

>But the main question remains: does the MotionEye camera support
>overlay or not ? 

That one I have no clue about at all.

			Linus

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-13 10:24   ` Stelian Pop
  2001-06-14 21:36     ` Linus Torvalds
@ 2001-06-15 21:10     ` Stelian Pop
  2001-06-28 19:11     ` volodya
  2 siblings, 0 replies; 20+ messages in thread
From: Stelian Pop @ 2001-06-15 21:10 UTC (permalink / raw)
  To: linux-kernel

In alcove.lists.linux.kernel, you wrote:

> >Well, not quite... I've had several X lockups while using the YUV 
> >acceleration code. Let's say one lockup per half an hour.
> 
> Strange. I've watched DVD's etc. Maybe it's not the Xv code, but your
> camera code?

It can be, of course. However I never experienced problems when 
using the 'regular' X server, but quite often when using the 
patched server from gatos.

And since the driver delivers YUV data in both cases, I see
no difference (from its point of vue) between the two uses.

> >Even the performances are controversial: with 320x240, I achieve 
> >great performance with xawtv/meye driver, I can even use the hardware
> >scaling facilities (well, the xawtv sources need a little hacking for
> >that), but in 640x480 the framerate achieved with Xv is below the
> >one I get by converting YUV->RGB in software...
> 
> There's something wrong with your setup. I watch full-screen DVD's on my
> VAIO. It's not really fast enough with just the YUV conversion done in
> hardware (it's plenty fast enough if MC and iDCT would be done in HW
> too, but ATI doesn't release docs without strict NDA's). But there's no
> way DVD's are watchable with sw YUV conversion and scaling.

I said that YUV conversion and scaling _do_ work in hardware. Actually,
using a capture size of 320x240 I can use those hardware features
and scale the image to full screen and I get all the 30 fps.

It seems however to work pretty bad in 640x480... but maybe it is
my setup here...

> >But the main question remains: does the MotionEye camera support
> >overlay or not ? 
> 
> That one I have no clue about at all.

Neither do I :-)

Stelian.
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-13 10:24   ` Stelian Pop
  2001-06-14 21:36     ` Linus Torvalds
  2001-06-15 21:10     ` Stelian Pop
@ 2001-06-28 19:11     ` volodya
  2001-06-29  9:29       ` Stelian Pop
  2 siblings, 1 reply; 20+ messages in thread
From: volodya @ 2001-06-28 19:11 UTC (permalink / raw)
  To: Stelian Pop; +Cc: torvalds, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: TEXT/PLAIN; charset=X-UNKNOWN, Size: 3125 bytes --]


Sorry for replying a couple of weeks late - I don't check linux-kernel
that often.

On Wed, 13 Jun 2001, Stelian Pop wrote:

> > I got just the YUV code from Gatos, and a few months ago it took less than
> > an hour to merge just that part (and most of that was compiling and
> > testing).
> 
> Me too. After some days playing with it it seems that the Rage Mobility
> Card (from the Vaio Picturebook C1VE <- that's where we started the
> discussion):
> 	- has almost no acceleration in XFree, including the 4.1.0 release
> 	- has Xv YUV->RGB acceleration in Gatos (but that's all, no direct
> 	  video input etc).

it has, but it is disabled as normally notebooks don't have video in. 
Well, some do but this is a grey area. ATI says there supposed to be a
multimedia table that says if you have a decoder on board - but some
manufacturers don't include it. In this case the driver cannot know
whether the decoder is present and disables the interface to avoid
lockups.

I imagine it is either using ZV port or VIP/MPP connector - I'll be happy
to help you to get it to work, provided you know the part that produces
video stream.

> 
> > The rest of Gatos is obviously more experimental, but the YUV code looks
> > quite sane.
> 
> Well, not quite... I've had several X lockups while using the YUV 
> acceleration code. Let's say one lockup per half an hour.

That's not supposed to happen - let me know what causes it.. what you are
using, etc..

> 
> Even the performances are controversial: with 320x240, I achieve 
> great performance with xawtv/meye driver, I can even use the hardware
> scaling facilities (well, the xawtv sources need a little hacking for
> that), but in 640x480 the framerate achieved with Xv is below the
> one I get by converting YUV->RGB in software...

You have to be careful here - you can't write to the framebuffer without 
waiting for engine to go idle. Otherwise it'll lockup.

> 
> But the main question remains: does the MotionEye camera support
> overlay or not ? It could be that it is connected to the feature
> connector of the ATI board for doing direct video input/output
> (but no X driver recognizes this connector today). The motion jpeg
> chip this camera is based on definately has a video output.

I can help you get this to work.

> 
> Or it could just be the application who gets YUV data from the chip
> then send it directly to the video board. Today this works, almost
> (because we need a patched X - read gatos - and a patched xawtv - in
> order to do scaling).

Try using xv_stream from ati_xv branch on gatos.

                           Vladimir Dergachev

> 
> Stelian.
> -- 
> Stelian Pop <stelian.pop@fr.alcove.com>
> |---------------- Free Software Engineer -----------------|
> | Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
> |------------- Alcôve, liberating software ---------------|
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-28 19:11     ` volodya
@ 2001-06-29  9:29       ` Stelian Pop
  0 siblings, 0 replies; 20+ messages in thread
From: Stelian Pop @ 2001-06-29  9:29 UTC (permalink / raw)
  To: volodya; +Cc: torvalds, linux-kernel

On Thu, Jun 28, 2001 at 03:11:22PM -0400, volodya@mindspring.com wrote:

> I imagine it is either using ZV port or VIP/MPP connector - I'll be happy
> to help you to get it to work, provided you know the part that produces
> video stream.

This part is described in the chip's doc here:
	http://va.samba.org/picturebook/72002_E_.pdf

Look at the page 9 where the connections between the chip and
the video bus are described. The problem is that there are 2 possible
modes (ZV-port or Digital YC), and I'm not sure which one Sony
chose to use...

> > Well, not quite... I've had several X lockups while using the YUV 
> > acceleration code. Let's say one lockup per half an hour.
> 
> That's not supposed to happen - let me know what causes it.. what you are
> using, etc..

The lockups happen upon closing xawtv (used with xv output). Let's
say one time in ten runs... Then the X server is dead, but I can
still log in using the network and do whatever I want. But if I kill
the X server the whole system freezes hard.

> > but in 640x480 the framerate achieved with Xv is below the
> > one I get by converting YUV->RGB in software...
> 
> You have to be careful here - you can't write to the framebuffer without 
> waiting for engine to go idle. Otherwise it'll lockup.

??? That's not me, it's xawtv, through the XV facilities of the 
X server which writes to the framebuffer... Or maybe I don't 
understand the question...

Anyway, I've retested it with the latest ati.2 binaries and how
the 640x480 xv speed seems to have improved (or something in
my configuration changed, of course :-) ).

> > (but no X driver recognizes this connector today). The motion jpeg
> > chip this camera is based on definately has a video output.
> 
> I can help you get this to work.

I'd like to, thanks.

> > Or it could just be the application who gets YUV data from the chip
> > then send it directly to the video board. Today this works, almost
> > (because we need a patched X - read gatos - and a patched xawtv - in
> > order to do scaling).
> 
> Try using xv_stream from ati_xv branch on gatos.

It won't work out of the box either (it uses only v4l read calls and
doesn't support mmap, it assumes a capture size of 352x288 which this
camera does not support etc). But it should be easy to patch it and
make it work with this camera, just like I did with xawtv.

Stelian.

PS: this hasn't much to do with the kernel anymore, I suggest we
take this discussion off list now. I'm not sure neither if Linus
is really interested in getting a copy of this. :-)
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-11  0:13             ` Linus Torvalds
@ 2001-06-11 19:37               ` egger
  0 siblings, 0 replies; 20+ messages in thread
From: egger @ 2001-06-11 19:37 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

On 10 Jun, Linus Torvalds wrote:

> I have to say that I have absolutely no idea. I only use little-endian
> machines myself (and 99% x86).

> Also, which ATI Xv stuff are you talking about?

 I'm talking about original ATI Xv stuff in X 4.1.0 making trouble.
 I'm really ccurious whether they fixed the problem in the GATOS
 driver.

> Has the Gatos code (or some other code) maybe been integrated into 4.1.0
> now? I haven't followed X CVS for the last months very closely..

 Doesn't seem so, at least the linuxvideo people advertise their "ati.2"
 module for 4.1.0 on their website, but only in source or i386 binary.
 :/

Servus,
       Daniel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 23:41           ` egger
@ 2001-06-11  0:13             ` Linus Torvalds
  2001-06-11 19:37               ` egger
  0 siblings, 1 reply; 20+ messages in thread
From: Linus Torvalds @ 2001-06-11  0:13 UTC (permalink / raw)
  To: egger; +Cc: linux-kernel


On Mon, 11 Jun 2001 egger@suse.de wrote:
>
> On 10 Jun, Linus Torvalds wrote:
> 
> > I've not figured out why the ATI Xv stuff from gatos seems to not have
> > made it into the XFree86 CVS tree - it works better than much of the
> > Xv stuff for some other chipsets that _are_ in the CVS tree.
> >  
> > I imported it into the XFree86 CVS some months ago, it was trivial.  I
> > don't have the patches lying around any more, though. I can try to
> > re-create them if anybody needs help.
> 
>  Did it look endiansafe to you? The ATI Xv stuff from XFree86 4.1.0
>  produces psychadelic results for me on PPC.

I have to say that I have absolutely no idea. I only use little-endian
machines myself (and 99% x86).

Also, which ATI Xv stuff are you talking about? The ATI Rage128 and ATI
Radeon Xv code was at least a few months ago completely separate from the
ATI Rage code (the first two were in X CVS, while the latter only existed
in the gatos version). 

Has the Gatos code (or some other code) maybe been integrated into 4.1.0
now? I haven't followed X CVS for the last months very closely..

		Linus


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 19:07         ` Linus Torvalds
@ 2001-06-10 23:41           ` egger
  2001-06-11  0:13             ` Linus Torvalds
  0 siblings, 1 reply; 20+ messages in thread
From: egger @ 2001-06-10 23:41 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel

On 10 Jun, Linus Torvalds wrote:

> I've not figured out why the ATI Xv stuff from gatos seems to not have
> made it into the XFree86 CVS tree - it works better than much of the
> Xv stuff for some other chipsets that _are_ in the CVS tree.
 
> I imported it into the XFree86 CVS some months ago, it was trivial.  I
> don't have the patches lying around any more, though. I can try to
> re-create them if anybody needs help.

 Did it look endiansafe to you? The ATI Xv stuff from XFree86 4.1.0
 produces psychadelic results for me on PPC.
 If it's supposed to work I'd really like to give it a try.

Servus,
       Daniel


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 16:46       ` Stelian Pop
@ 2001-06-10 19:07         ` Linus Torvalds
  2001-06-10 23:41           ` egger
  0 siblings, 1 reply; 20+ messages in thread
From: Linus Torvalds @ 2001-06-10 19:07 UTC (permalink / raw)
  To: linux-kernel

In article <20010610184611.A16660@ontario.alcove-fr>,
Stelian Pop  <stelian.pop@fr.alcove.com> wrote:
>
>> 2.	Using the YUV overlay/expand hardware in the ATI card 
>> 	(see www.gatos.org for X stuff for ATI for this)
>
>:s/www.gatos.org/www.linuxvideo.org/gatos/
>
>I took a quick look on their site but it seems that the
>Rage Mobility P/M card which this laptop has isn't yet supported.

It definitely is - at least if you use the XFree86 CVS tree with just
the ATI video extensions imported from Gatos.  I've used the YUV
hardware for half-accelerated DVD playing ("half-accelerated" only
because the chip can really do MC too, but ATI doesn't document how to
do it, so it only does the YUV conversion). 

I've not figured out why the ATI Xv stuff from gatos seems to not have
made it into the XFree86 CVS tree - it works better than much of the Xv
stuff for some other chipsets that _are_ in the CVS tree. 

I imported it into the XFree86 CVS some months ago, it was trivial.  I
don't have the patches lying around any more, though. I can try to
re-create them if anybody needs help.

		Linus

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 15:58     ` Alan Cox
@ 2001-06-10 16:46       ` Stelian Pop
  2001-06-10 19:07         ` Linus Torvalds
  0 siblings, 1 reply; 20+ messages in thread
From: Stelian Pop @ 2001-06-10 16:46 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

On Sun, Jun 10, 2001 at 04:58:42PM +0100, Alan Cox wrote:

> > Yes. But, even if I know how to program the mchip to output to
> > the video bus, there is something missing to enable overlay
> > (either in the mchip or in the ati video driver).
> 
> It could be using the YUV digital inputs to the ATI chip. 

Most likely yes. 

> It seems however
> also quite likely to me that windows is doing the following
> 
> 1.	Issuing USB transfers which put the data into video ram overlay buffers
> 	(ie the DMA from the USB controller)

:s/USB/PCI/g

The rest seems good to me :-) I even think that the docs we have
are sufficient for this part (programming the mchip dma).

> 2.	Using the YUV overlay/expand hardware in the ATI card 
> 	(see www.gatos.org for X stuff for ATI for this)

:s/www.gatos.org/www.linuxvideo.org/gatos/

I took a quick look on their site but it seems that the
Rage Mobility P/M card which this laptop has isn't yet supported.

Stelian.
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 15:57   ` Stelian Pop
@ 2001-06-10 15:58     ` Alan Cox
  2001-06-10 16:46       ` Stelian Pop
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Cox @ 2001-06-10 15:58 UTC (permalink / raw)
  To: stelian.pop; +Cc: Alan Cox, linux-kernel

> Yes. But, even if I know how to program the mchip to output to
> the video bus, there is something missing to enable overlay
> (either in the mchip or in the ati video driver).

It could be using the YUV digital inputs to the ATI chip. It seems however
also quite likely to me that windows is doing the following

1.	Issuing USB transfers which put the data into video ram overlay buffers
	(ie the DMA from the USB controller)

2.	Using the YUV overlay/expand hardware in the ATI card 
	(see www.gatos.org for X stuff for ATI for this)

> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 14:39 ` Alan Cox
@ 2001-06-10 15:57   ` Stelian Pop
  2001-06-10 15:58     ` Alan Cox
  0 siblings, 1 reply; 20+ messages in thread
From: Stelian Pop @ 2001-06-10 15:57 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

On Sun, Jun 10, 2001 at 03:39:26PM +0100, Alan Cox wrote:

> > The driver does not yet support overlay (no docs... :-( ), but it does =
> > support
> 
> Are you sure the hardware supports overlay ?

Yes. But, even if I know how to program the mchip to output to
the video bus, there is something missing to enable overlay
(either in the mchip or in the ati video driver).

> > grabbing, jpeg snapshots and mjpeg compressed videos (through a private=
> >  API,
> > documented in <file:Documentation/video4linux/meye.txt>).
> 
> We have an API for mjpeg in the buz, I wonder if its possible to make that
> more generic.

I started with that one and abandoned it later, since it is really
targeted to _tv_ capture cards only (the size of capture can be only 
the PAL/NTSC size, and many other little things, like framerate 
fixed to PAL/NTSC mode too etc.)

Maybe video4linux version 2 will be a more useful API for all
cameras / webcams / video capture cards. (almost a carbon copy
of what I say in Documentation/video4linux/meye.txt :-) ).

Stelian.
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
  2001-06-10 13:25 Stelian Pop
@ 2001-06-10 14:39 ` Alan Cox
  2001-06-10 15:57   ` Stelian Pop
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Cox @ 2001-06-10 14:39 UTC (permalink / raw)
  To: stelian.pop; +Cc: linux-kernel, Alan Cox

> The driver does not yet support overlay (no docs... :-( ), but it does =
> support

Are you sure the hardware supports overlay ?

> grabbing, jpeg snapshots and mjpeg compressed videos (through a private=
>  API,
> documented in <file:Documentation/video4linux/meye.txt>).

We have an API for mjpeg in the buz, I wonder if its possible to make that
more generic.


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver
@ 2001-06-10 13:25 Stelian Pop
  2001-06-10 14:39 ` Alan Cox
  0 siblings, 1 reply; 20+ messages in thread
From: Stelian Pop @ 2001-06-10 13:25 UTC (permalink / raw)
  To: linux-kernel; +Cc: Alan Cox

Hi,

This patch (to be applied on top of the previous sonypi patch) adds a new
driver for the Sony Vaio MotionEye camera (the one found in the Picturebook
models).

The driver does not yet support overlay (no docs... :-( ), but it does support
grabbing, jpeg snapshots and mjpeg compressed videos (through a private API,
documented in <file:Documentation/video4linux/meye.txt>).

Until the alcove-labs web site updates, you can download the 'motioneye'
application documented in meye.txt from:
	http://mapage.noos.fr/pop/sonypi
		and
	http://mapage.noos.fr/pop/meye

Stelian.

diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/CREDITS linux-2.4.5-ac12/CREDITS
--- linux-2.4.5-ac12.orig/CREDITS	Sun Jun 10 13:41:47 2001
+++ linux-2.4.5-ac12/CREDITS	Sun Jun 10 14:12:55 2001
@@ -2249,6 +2249,15 @@
 E: ken@halcyon.com
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 
+N: Stelian Pop
+E: stelian.pop@fr.alcove.com
+P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0  D3F7 7185 9E7A EDBB 6147
+D: sonypi, meye drivers, mct_u232 usb serial hacks
+S: Alcôve
+S: 153, bd. Anatole France 
+S: 93200 Saint Denis
+S: France
+
 N: Frederic Potter 
 E: fpotter@cirpack.com
 D: Some PCI kernel support
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/Documentation/Configure.help linux-2.4.5-ac12/Documentation/Configure.help
--- linux-2.4.5-ac12.orig/Documentation/Configure.help	Sun Jun 10 13:41:47 2001
+++ linux-2.4.5-ac12/Documentation/Configure.help	Sun Jun 10 14:23:54 2001
@@ -19279,6 +19279,20 @@
   module called pms.o ( = code which can be inserted in and removed
   from the running kernel whenever you want). If you want to compile
   it as a module, say M here and read <file:Documentation/modules.txt>.
+
+Sony Vaio Picturebook Motion Eye Video for Linux
+CONFIG_VIDEO_MEYE
+  This is the video4linux driver for the Motion Eye camera found
+  in the Vaio Picturebook laptops. Please read the material in
+  <file:Documentation/video4linux/meye.txt> for more information.
+
+  If you say Y or M here, you need to say Y or M to "Sony Programmable
+  I/O Control Device" in the character device section.
+
+  This driver is available as a module called meye.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
 
 IBM's S/390 architecture
 CONFIG_ARCH_S390
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/Documentation/video4linux/meye.txt linux-2.4.5-ac12/Documentation/video4linux/meye.txt
--- linux-2.4.5-ac12.orig/Documentation/video4linux/meye.txt	Thu Jan  1 01:00:00 1970
+++ linux-2.4.5-ac12/Documentation/video4linux/meye.txt	Sun Jun 10 13:56:48 2001
@@ -0,0 +1,102 @@
+Vaio Picturebook Motion Eye Camera Driver Readme
+------------------------------------------------
+	Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+	Copyright (C) 2000 Andrew Tridgell <tridge@samba.org>
+
+This driver enable the use of video4linux compatible applications with the
+Motion Eye camera.
+
+It can do at maximum 30 fps @ 320x240 or 15 fps @ 640x480.
+
+Grabbing is supported in packed YUV colorspace only.
+
+MJPEG hardware grabbing is supported via a private API (see below).
+
+Module options:
+---------------
+
+	gbuffers:	number of capture buffers, default is 2 (32 max)
+
+	gbufsize:	size of each capture buffer, default is 614400
+
+	video_nr:	video device to register (0 = /dev/video0, etc)
+
+Module use:
+-----------
+
+In order to automatically load the meye module on use, you can put those lines
+in your /etc/modules.conf file:
+
+	alias char-major-81 videodev
+	alias char-major-81-0 meye
+	options meye gbuffers=32
+
+Usage:
+------
+
+	xawtv >= 3.49 (<http://bytesex.org/xawtv/>)
+		for display and uncompressed video capture:
+
+			xawtv -c /dev/video0 -geometry 640x480
+				or
+			xawtv -c /dev/video0 -geometry 320x240
+
+	motioneye (<http://www.alcove-labs.org/en/software/meye/>)
+		for getting ppm or jpg snapshots, mjpeg video
+
+Private API:
+------------
+
+	The driver supports frame grabbing with the video4linux API, so
+	all video4linux tools (like xawtv) should work with this driver.
+
+	Besides the video4linux interface, the driver has a private interface
+	for accessing the Motion Eye extended parameters (camera sharpness,
+	agc, video framerate), the shapshot and the MJPEG capture facilities.
+
+	This interface consists of several ioctls (prototypes and structures
+	can be found in include/linux/meye.h):
+
+	MEYEIOC_G_PARAMS
+	MEYEIOC_S_PARAMS
+		Get and set the extended parameters of the motion eye camera.
+		The user should always query the current parameters with
+		MEYEIOC_G_PARAMS, change what he likes and then issue the
+		MEYEIOC_S_PARAMS call (checking for -EINVAL). The extended
+		parameters are described by the meye_params structure.
+
+
+	MEYEIOC_QBUF_CAPT
+		Queue a buffer for capture (the buffers must have been
+		obtained with a VIDIOCGMBUF call and mmap'ed by the
+		application). The argument to MEYEIOC_QBUF_CAPT is the
+		buffer number to queue (or -1 to end capture). The first
+		call to MEYEIOC_QBUF_CAPT starts the streaming capture.
+
+	MEYEIOC_SYNC
+		Takes as an argument the buffer number you want to sync.
+		This ioctl blocks untils the buffer is filled and ready
+		for the application to use. It returns the buffer size.
+
+	MEYEIOC_STILLCAPT
+	MEYEIOC_STILLJCAPT
+		Takes a snapshot in an uncompressed or compressed jpeg format.
+		This ioctl blocks until the snapshot is done and returns (for
+		jpeg snapshot) the size of the image. The image data is 
+		available from the first mmap'ed buffer.
+
+	Look at the 'motioneye' application code for an actual example.
+
+Bugs / Todo:
+------------
+
+	- overlay output is not supported (although the camera is capable of).
+	  	(it should not be too hard to to it, provided we found how...)
+		
+	- mjpeg hardware playback doesn't work (depends on overlay...)
+
+	- rewrite the driver to use some commun video4linux API for snapshot
+	  and mjpeg capture. Unfortunately, video4linux1 does not permit it,
+	  the BUZ API seems to be targeted to TV cards only. The video4linux 2
+	  API may be an option, if it goes into the kernel (maybe 2.5 
+	  material ?).
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/drivers/media/video/Config.in linux-2.4.5-ac12/drivers/media/video/Config.in
--- linux-2.4.5-ac12.orig/drivers/media/video/Config.in	Sun Jun 10 13:41:57 2001
+++ linux-2.4.5-ac12/drivers/media/video/Config.in	Thu Jun  7 15:51:55 2001
@@ -47,5 +47,8 @@
 fi
 dep_tristate '  Zoran ZR36057/36060 Video For Linux' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
 dep_tristate '  Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+  dep_tristate '  Sony Vaio Picturebook Motion Eye Video For Linux' CONFIG_VIDEO_MEYE $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_SONYPI
+fi
 
 endmenu
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/drivers/media/video/Makefile linux-2.4.5-ac12/drivers/media/video/Makefile
--- linux-2.4.5-ac12.orig/drivers/media/video/Makefile	Sun Jun 10 13:41:57 2001
+++ linux-2.4.5-ac12/drivers/media/video/Makefile	Thu Jun  7 15:51:55 2001
@@ -53,6 +53,7 @@
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
+obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
 
 # Extract lists of the multi-part drivers.
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/drivers/media/video/meye.c linux-2.4.5-ac12/drivers/media/video/meye.c
--- linux-2.4.5-ac12.orig/drivers/media/video/meye.c	Thu Jan  1 01:00:00 1970
+++ linux-2.4.5-ac12/drivers/media/video/meye.c	Fri Jun  8 19:53:17 2001
@@ -0,0 +1,1498 @@
+/* 
+ * Motion Eye video4linux driver for Sony Vaio PictureBook
+ *
+ * Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+ *
+ * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
+ *
+ * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
+ *
+ * Some parts borrowed from various video4linux drivers, especially
+ * bttv-driver.c and zoran.c, see original files for credits.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/videodev.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/wrapper.h>
+#include <linux/interrupt.h>
+
+#include "meye.h"
+#include "linux/meye.h"
+
+/* driver structure - only one possible */
+static struct meye meye;
+/* number of grab buffers */
+static unsigned int gbuffers = 2;
+/* size of a grab buffer */
+static unsigned int gbufsize = MEYE_MAX_BUFSIZE;
+/* /dev/videoX registration number */
+static int video_nr = -1;
+
+/****************************************************************************/
+/* Queue routines                                                           */
+/****************************************************************************/
+
+/* Inits the queue */
+static inline void meye_initq(struct meye_queue *queue) {
+	queue->head = queue->tail = 0;
+	queue->len = 0;
+	queue->s_lock = (spinlock_t)SPIN_LOCK_UNLOCKED;
+	init_waitqueue_head(&queue->proc_list);
+}
+
+/* Pulls an element from the queue */
+static inline int meye_pullq(struct meye_queue *queue) {
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&queue->s_lock, flags);
+	if (!queue->len) {
+		spin_unlock_irqrestore(&queue->s_lock, flags);
+		return -1;
+	}
+	result = queue->buf[queue->head];
+	queue->head++;
+	queue->head &= (MEYE_QUEUE_SIZE - 1);
+	queue->len--;
+	spin_unlock_irqrestore(&queue->s_lock, flags);
+	return result;
+}
+
+/* Pushes an element into the queue */
+static inline void meye_pushq(struct meye_queue *queue, int element) {
+	unsigned long flags;
+
+	spin_lock_irqsave(&queue->s_lock, flags);
+	if (queue->len == MEYE_QUEUE_SIZE) {
+		/* remove the first element */
+		queue->head++;
+		queue->head &= (MEYE_QUEUE_SIZE - 1);
+		queue->len--;
+	}
+	queue->buf[queue->tail] = element;
+	queue->tail++;
+	queue->tail &= (MEYE_QUEUE_SIZE - 1);
+	queue->len++;
+
+	spin_unlock_irqrestore(&queue->s_lock, flags);
+}
+
+/* Tests if the queue is empty */
+static inline int meye_emptyq(struct meye_queue *queue, int *elem) {
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&queue->s_lock, flags);
+	result = (queue->len == 0);
+	if (!result && elem)
+		*elem = queue->buf[queue->head];
+	spin_unlock_irqrestore(&queue->s_lock, flags);
+	return result;
+}
+
+/****************************************************************************/
+/* Memory allocation routines (stolen from bttv-driver.c)                   */
+/****************************************************************************/
+
+#define MDEBUG(x)	do {} while (0)
+/* #define MDEBUG(x)	x */
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) {
+        unsigned long ret = 0UL;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+  
+	if (!pgd_none(*pgd)) {
+                pmd = pmd_offset(pgd, adr);
+                if (!pmd_none(*pmd)) {
+                        ptep = pte_offset(pmd, adr);
+                        pte = *ptep;
+                        if(pte_present(pte)) {
+				ret = (unsigned long)page_address(pte_page(pte));
+				ret |= (adr & (PAGE_SIZE - 1));
+				
+			}
+                }
+        }
+        MDEBUG(printk("uv2kva(%lx-->%lx)\n", adr, ret));
+	return ret;
+}
+
+static inline unsigned long uvirt_to_bus(unsigned long adr) {
+        unsigned long kva, ret;
+
+        kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+	ret = virt_to_bus((void *)kva);
+        MDEBUG(printk("uv2b(%lx-->%lx)\n", adr, ret));
+        return ret;
+}
+
+static inline unsigned long kvirt_to_bus(unsigned long adr) {
+        unsigned long va, kva, ret;
+
+        va = VMALLOC_VMADDR(adr);
+        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	ret = virt_to_bus((void *)kva);
+        MDEBUG(printk("kv2b(%lx-->%lx)\n", adr, ret));
+        return ret;
+}
+
+/* Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+static inline unsigned long kvirt_to_pa(unsigned long adr) {
+        unsigned long va, kva, ret;
+
+        va = VMALLOC_VMADDR(adr);
+        kva = uvirt_to_kva(pgd_offset_k(va), va);
+	ret = __pa(kva);
+        MDEBUG(printk("kv2pa(%lx-->%lx)\n", adr, ret));
+        return ret;
+}
+
+static void *rvmalloc(signed long size) {
+	void *mem;
+	unsigned long adr, page;
+
+	mem = vmalloc_32(size);
+	if (mem) {
+		memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+	        adr = (unsigned long)mem;
+		while (size > 0) {
+	                page = kvirt_to_pa(adr);
+			mem_map_reserve(virt_to_page(__va(page)));
+			adr += PAGE_SIZE;
+			size -= PAGE_SIZE;
+		}
+	}
+	return mem;
+}
+
+static void rvfree(void * mem, signed long size) {
+        unsigned long adr, page;
+        
+	if (mem) {
+	        adr = (unsigned long) mem;
+		while (size > 0) {
+	                page = kvirt_to_pa(adr);
+			mem_map_unreserve(virt_to_page(__va(page)));
+			adr += PAGE_SIZE;
+			size -= PAGE_SIZE;
+		}
+		vfree(mem);
+	}
+}
+
+/* return a page table pointing to N pages of locked memory */
+static void *ptable_alloc(int npages, u32 *pt_addr) {
+	int i = 0;
+	void *vmem;
+	u32 ptable[npages+1];
+	signed long size;
+	unsigned long adr;
+
+	size = (npages + 1) * PAGE_SIZE;
+	vmem = rvmalloc(size);
+	if (!vmem)
+		return NULL;
+
+	memset(ptable, 0, sizeof(ptable));
+        adr = (unsigned long)vmem;
+	while (size > 0) {
+		ptable[i++] = virt_to_bus(__va(kvirt_to_pa(adr)));
+		adr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	memcpy(vmem + npages * PAGE_SIZE, ptable, PAGE_SIZE);
+	*pt_addr = ptable[npages];
+
+	return vmem;
+}
+
+static void ptable_free(void *vmem, int npages) {
+	rvfree(vmem, (npages + 1) * PAGE_SIZE);
+}
+
+/****************************************************************************/
+/* JPEG tables at different qualities to load into the VRJ chip             */
+/****************************************************************************/
+
+/* return a set of quantisation tables based on a quality from 1 to 10 */
+static u16 *jpeg_quantisation_tables(int *size, int quality) {
+	static u16 tables0[] = {
+		0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 
+		0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 
+	};
+	static u16 tables1[] = {
+		0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46, 
+		0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 
+		0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 
+		0xffff, 0xffff, 0xffff, 
+	};
+	static u16 tables2[] = {
+		0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23, 
+		0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164, 
+		0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad, 
+		0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff, 
+		0xe6ff, 0xfffd, 0xfff8, 
+		0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876, 
+		0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 
+		0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 
+		0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 
+		0xf8f8, 0xf8f8, 0xfff8, 
+	};
+	static u16 tables3[] = {
+		0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17, 
+		0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042, 
+		0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73, 
+		0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba, 
+		0x99c7, 0xaba8, 0xffa4, 
+		0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e, 
+		0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 
+		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 
+		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 
+		0xa4a4, 0xa4a4, 0xffa4, 
+	};
+	static u16 tables4[] = {
+		0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712, 
+		0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932, 
+		0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556, 
+		0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c, 
+		0x7396, 0x817e, 0xff7c, 
+		0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b, 
+		0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 
+		0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 
+		0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 
+		0x7c7c, 0x7c7c, 0xff7c, 
+	};
+	static u16 tables5[] = {
+		0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e, 
+		0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28, 
+		0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745, 
+		0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470, 
+		0x5c78, 0x6765, 0xff63, 
+		0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f, 
+		0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 
+		0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 
+		0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 
+		0x6363, 0x6363, 0xff63, 
+	};
+	static u16 tables6[] = {
+		0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b, 
+		0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20, 
+		0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37, 
+		0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a, 
+		0x4a60, 0x5251, 0xff4f, 
+		0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26, 
+		0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 
+		0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 
+		0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 
+		0x4f4f, 0x4f4f, 0xff4f, 
+	};
+	static u16 tables7[] = {
+		0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08, 
+		0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318, 
+		0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129, 
+		0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43, 
+		0x3748, 0x3e3d, 0xff3b, 
+		0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c, 
+		0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 
+		0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 
+		0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 
+		0x3b3b, 0x3b3b, 0xff3b, 
+	};
+	static u16 tables8[] = {
+		0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706, 
+		0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710, 
+		0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c, 
+		0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d, 
+		0x2530, 0x2928, 0xff28, 
+		0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813, 
+		0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 
+		0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 
+		0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 
+		0x2828, 0x2828, 0xff28, 
+	};
+	static u16 tables9[] = {
+		0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403, 
+		0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08, 
+		0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e, 
+		0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416, 
+		0x1218, 0x1514, 0xff14, 
+		0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409, 
+		0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 
+		0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 
+		0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 
+		0x1414, 0x1414, 0xff14, 
+	};
+	static u16 tables10[] = {
+		0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0xff01, 
+		0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0101, 0x0101, 0xff01, 
+	};
+
+	switch (quality) {
+	case 0:
+		*size = sizeof(tables0);
+		return tables0;
+	case 1:
+		*size = sizeof(tables1);
+		return tables1;
+	case 2:
+		*size = sizeof(tables2);
+		return tables2;
+	case 3:
+		*size = sizeof(tables3);
+		return tables3;
+	case 4:
+		*size = sizeof(tables4);
+		return tables4;
+	case 5:
+		*size = sizeof(tables5);
+		return tables5;
+	case 6:
+		*size = sizeof(tables6);
+		return tables6;
+	case 7:
+		*size = sizeof(tables7);
+		return tables7;
+	case 8:
+		*size = sizeof(tables8);
+		return tables8;
+	case 9:
+		*size = sizeof(tables9);
+		return tables9;
+	case 10:
+		*size = sizeof(tables10);
+		return tables10;
+	default:
+		printk(KERN_WARNING "meye: invalid quality level %d - using 8\n", quality);
+		*size = sizeof(tables8);
+		return tables8;
+	}
+	return NULL;
+}
+
+/* return a generic set of huffman tables */
+static u16 *jpeg_huffman_tables(int *size) {
+	static u16 tables[] = {
+		0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405, 
+		0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131, 
+		0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142, 
+		0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918, 
+		0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443, 
+		0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463, 
+		0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483, 
+		0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A, 
+		0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8, 
+		0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6, 
+		0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2, 
+		0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, 
+		0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405, 
+		0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206, 
+		0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1, 
+		0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125, 
+		0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A, 
+		0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A, 
+		0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A, 
+		0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 
+		0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 
+		0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 
+		0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2, 
+		0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, 
+		0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000, 
+		0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, 
+		0xFF0B, 
+		0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101, 
+		0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, 
+		0xFF0B
+	};
+
+	*size = sizeof(tables);
+	return tables;
+}
+
+/****************************************************************************/
+/* MCHIP low-level functions                                                */
+/****************************************************************************/
+
+/* waits for the specified miliseconds */
+static inline void wait_ms(unsigned int ms) {
+	if (!in_interrupt()) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1 + ms * HZ / 1000);
+	}
+	else
+		mdelay(ms);
+}
+
+/* returns the horizontal capture size */
+static inline int mchip_hsize(void) {
+	return meye.params.subsample ? 320 : 640;
+}
+
+/* returns the vertical capture size */
+static inline int mchip_vsize(void) {
+	return meye.params.subsample ? 240 : 480;
+}
+
+/* waits for a register to be available */
+static void mchip_sync(int reg) {
+	u32 status;
+	int i;
+
+	if (reg == MCHIP_MM_FIFO_DATA) {
+		for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
+			status = readl(meye.mchip_mmregs + MCHIP_MM_FIFO_STATUS);
+			if (!(status & MCHIP_MM_FIFO_WAIT)) {
+				printk(KERN_WARNING "meye: fifo not ready\n");
+				return;
+			}
+			if (status & MCHIP_MM_FIFO_READY)
+				return;
+			udelay(1);
+		}
+	}
+	else if (reg > 0x80) {
+		u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY
+			                 : MCHIP_HIC_STATUS_VRJ_RDY;
+		for (i = 0; i < MCHIP_REG_TIMEOUT; i++) {
+			status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS);
+			if (status & mask)
+				return;
+			udelay(1);
+		}
+	}
+	else
+		return;
+	printk(KERN_WARNING "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n", reg, status);
+}
+
+/* sets a value into the register */
+static inline void mchip_set(int reg, u32 v) {
+	mchip_sync(reg);
+	writel(v, meye.mchip_mmregs + reg);
+}
+
+/* get the register value */
+static inline u32 mchip_read(int reg) {
+	mchip_sync(reg);
+	return readl(meye.mchip_mmregs + reg);
+}
+
+/* wait for a register to become a particular value */
+static inline int mchip_delay(u32 reg, u32 v) {
+	int n = 10;
+	while (--n && mchip_read(reg) != v) 
+		udelay(1);
+	return n;
+}
+
+/* setup subsampling */
+static void mchip_subsample(void) {
+	mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample);
+	mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize());
+	mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize());
+	mchip_set(MCHIP_MCC_B_XRANGE, mchip_hsize());
+	mchip_set(MCHIP_MCC_B_YRANGE, mchip_vsize());
+	mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
+}
+
+/* set the framerate into the mchip */
+static void mchip_set_framerate(void) {
+	mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate);
+}
+
+/* load some huffman and quantisation tables into the VRJ chip ready
+   for JPEG compression */
+static void mchip_load_tables(void) {
+	int i;
+	int size;
+	u16 *tables;
+
+	tables = jpeg_huffman_tables(&size);
+	for (i = 0; i < size / 2; i++)
+		writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
+
+	tables = jpeg_quantisation_tables(&size, meye.params.quality);
+	for (i = 0; i < size / 2; i++)
+		writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA);
+}
+
+/* setup the VRJ parameters in the chip */
+static void mchip_vrj_setup(u8 mode) {
+
+	mchip_set(MCHIP_VRJ_BUS_MODE, 5);
+	mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f);
+	mchip_set(MCHIP_VRJ_PDAT_USE, 1);
+	mchip_set(MCHIP_VRJ_IRQ_FLAG, 0xa0);
+	mchip_set(MCHIP_VRJ_MODE_SPECIFY, mode);
+	mchip_set(MCHIP_VRJ_NUM_LINES, mchip_vsize());
+	mchip_set(MCHIP_VRJ_NUM_PIXELS, mchip_hsize());
+	mchip_set(MCHIP_VRJ_NUM_COMPONENTS, 0x1b);
+	mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_LO, 0xFFFF);
+	mchip_set(MCHIP_VRJ_LIMIT_COMPRESSED_HI, 0xFFFF);
+	mchip_set(MCHIP_VRJ_COMP_DATA_FORMAT, 0xC);
+	mchip_set(MCHIP_VRJ_RESTART_INTERVAL, 0);
+	mchip_set(MCHIP_VRJ_SOF1, 0x601);
+	mchip_set(MCHIP_VRJ_SOF2, 0x1502);
+	mchip_set(MCHIP_VRJ_SOF3, 0x1503);
+	mchip_set(MCHIP_VRJ_SOF4, 0x1596);
+	mchip_set(MCHIP_VRJ_SOS,  0x0ed0);
+
+	mchip_load_tables();
+}
+
+/* setup for DMA transfers - also zeros the framebuffer */
+static int mchip_dma_alloc(void) {
+	if (!meye.mchip_fbuffer) {
+		meye.mchip_fbuffer = ptable_alloc(MCHIP_NB_PAGES, 
+				                  &meye.mchip_ptaddr);
+		if (!meye.mchip_fbuffer)
+			return -1;
+	}
+	return 0;
+}
+
+/* frees the DMA buffer */
+static void mchip_dma_free(void) {
+	if (meye.mchip_fbuffer) {
+		ptable_free(meye.mchip_fbuffer, MCHIP_NB_PAGES);
+		meye.mchip_fbuffer = 0;
+		meye.mchip_ptaddr = 0;
+	}
+}
+
+/* sets the DMA parameters into the chip */
+static void mchip_dma_setup(void) {
+	int i;
+
+	mchip_set(MCHIP_MM_PT_ADDR, meye.mchip_ptaddr);
+	for (i = 0; i < 4; i++)
+		mchip_set(MCHIP_MM_FIR(i), 0);
+	meye.mchip_fnum = 0;
+}
+
+/* stop any existing HIC action and wait for any dma to complete then
+   reset the dma engine */
+static void mchip_hic_stop(void) {
+	int i = 0;
+
+	meye.mchip_mode = MCHIP_HIC_MODE_NOOP;
+	if (!(mchip_read(MCHIP_HIC_STATUS) & MCHIP_HIC_STATUS_BUSY)) 
+		return;
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
+	mchip_delay(MCHIP_HIC_CMD, 0);
+	while (!mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) {
+		/*  resetting HIC */
+		mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP);
+		mchip_delay(MCHIP_HIC_CMD, 0);
+		mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET);
+		wait_ms(250);
+		if (i++ > 20) {
+			printk(KERN_ERR "meye: resetting HIC hanged!\n");
+			break;
+		}
+	}
+	wait_ms(100);
+}
+
+/****************************************************************************/
+/* MCHIP frame processing functions                                         */
+/****************************************************************************/
+
+/* get the next ready frame from the dma engine */
+static u32 mchip_get_frame(void) {
+	u32 v;
+	
+	v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum));
+	return v;
+}
+
+/* frees the current frame from the dma engine */
+static void mchip_free_frame(void) {
+	mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0);
+	meye.mchip_fnum++;
+	meye.mchip_fnum %= 4;
+}
+
+
+/* read one frame from the framebuffer assuming it was captured using
+   a uncompressed transfer */
+static void  mchip_cont_read_frame(u32 v, u8 *buf, int size) {
+	int pt_id;
+	int avail;
+
+	pt_id = (v >> 17) & 0x3FF;
+	avail = MCHIP_NB_PAGES - pt_id;
+
+	if (size > avail*PAGE_SIZE) {
+		memcpy(buf, meye.mchip_fbuffer + pt_id * PAGE_SIZE, 
+		       avail * PAGE_SIZE);
+		memcpy(buf +avail * PAGE_SIZE, meye.mchip_fbuffer,
+		       size - avail * PAGE_SIZE);
+	}
+	else
+		memcpy(buf, meye.mchip_fbuffer + pt_id * PAGE_SIZE, size);
+}
+
+/* read a compressed frame from the framebuffer */
+static int mchip_comp_read_frame(u32 v, u8 *buf, int size) {
+	int pt_start, pt_end, trailer;
+	int fsize, fsize2;
+	int i;
+
+	pt_start = (v >> 19) & 0xFF;
+	pt_end = (v >> 11) & 0xFF;
+	trailer = (v >> 1) & 0x3FF;
+
+	if (pt_end < pt_start) {
+		fsize = (MCHIP_NB_PAGES_MJPEG - pt_start) * PAGE_SIZE;
+		fsize2 = pt_end * PAGE_SIZE + trailer * 4;
+		if (fsize + fsize2 > size) {
+			printk(KERN_WARNING "meye: oversized compressed frame %d %d\n", 
+			       fsize, fsize2);
+			return -1;
+		} else {
+			memcpy(buf, meye.mchip_fbuffer + pt_start * PAGE_SIZE, 
+			       fsize);
+			memcpy(buf + fsize, meye.mchip_fbuffer, fsize2); 
+			fsize += fsize2;
+		}
+	} else {
+		fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4;
+		if (fsize > size) {
+			printk(KERN_WARNING "meye: oversized compressed frame %d\n", 
+			       fsize);
+			return -1;
+		} else
+			memcpy(buf, meye.mchip_fbuffer + pt_start * PAGE_SIZE, 
+			       fsize);
+	}
+
+
+#ifdef MEYE_JPEG_CORRECTION
+
+	/* Some mchip generated jpeg frames are incorrect. In most
+	 * (all ?) of those cases, the final EOI (0xff 0xd9) marker 
+	 * is not present at the end of the frame.
+	 *
+	 * Since adding the final marker is not enough to restore
+	 * the jpeg integrity, we drop the frame.
+	 */
+
+	for (i = fsize - 1; i > 0 && buf[i] == 0xff; i--) ;
+
+	if (i < 2 || buf[i - 1] != 0xff || buf[i] != 0xd9)
+		return -1;
+
+#endif
+
+	return fsize;
+}
+
+/* take a picture into SDRAM */
+static void mchip_take_picture(void) {
+	int i;
+	
+	mchip_hic_stop();
+	mchip_subsample();
+	mchip_dma_setup();
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_CAP);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+
+	mchip_delay(MCHIP_HIC_CMD, 0);
+
+	for (i = 0; i < 100; ++i) {
+		if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
+			break;
+		wait_ms(1);
+	}
+}
+
+/* dma a previously taken picture into a buffer */
+static void mchip_get_picture(u8 *buf, int bufsize) {
+	u32 v;
+	int i;
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_OUT);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+
+	mchip_delay(MCHIP_HIC_CMD, 0);
+	for (i = 0; i < 100; ++i) {
+		if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
+			break;
+		wait_ms(1);
+	}
+	for (i = 0; i < 4 ; ++i) {
+		v = mchip_get_frame();
+		if (v & MCHIP_MM_FIR_RDY) {
+			mchip_cont_read_frame(v, buf, bufsize);
+			break;
+		}
+		mchip_free_frame();
+	}
+}
+
+/* start continuous dma capture */
+static void mchip_continuous_start(void) {
+	mchip_hic_stop();
+	mchip_subsample();
+	mchip_set_framerate();
+	mchip_dma_setup();
+
+	meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT;
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_OUT);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+
+	mchip_delay(MCHIP_HIC_CMD, 0);
+}
+
+/* compress one frame into a buffer */
+static int mchip_compress_frame(u8 *buf, int bufsize) {
+	u32 v;
+	int len = -1, i;
+
+	mchip_vrj_setup(0x3f);
+	udelay(50);
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+	
+	mchip_delay(MCHIP_HIC_CMD, 0);
+	for (i = 0; i < 100; ++i) {
+		if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE))
+			break;
+		wait_ms(1);
+	}
+
+	for (i = 0; i < 4 ; ++i) {
+		v = mchip_get_frame();
+		if (v & MCHIP_MM_FIR_RDY) {
+			len = mchip_comp_read_frame(v, buf, bufsize);
+			break;
+		}
+		mchip_free_frame();
+	}
+	return len;
+}
+
+#if 0
+/* uncompress one image into a buffer */
+static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) {
+	mchip_vrj_setup(0x3f);
+	udelay(50);
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+	
+	mchip_delay(MCHIP_HIC_CMD, 0);
+
+	return mchip_comp_read_frame(buf, bufsize);
+}
+#endif
+
+/* start continuous compressed capture */
+static void mchip_cont_compression_start(void) {
+	mchip_hic_stop();
+	mchip_vrj_setup(0x3f);
+	mchip_subsample();
+	mchip_set_framerate();
+	mchip_dma_setup();
+
+	meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP;
+
+	mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_CONT_COMP);
+	mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START);
+
+	mchip_delay(MCHIP_HIC_CMD, 0);
+}
+
+/****************************************************************************/
+/* Interrupt handling                                                       */
+/****************************************************************************/
+
+static void meye_irq(int irq, void *dev_id, struct pt_regs *regs) {
+	u32 v;
+	int reqnr;
+	v = mchip_read(MCHIP_MM_INTA);
+
+	while (1) {
+		v = mchip_get_frame();
+		if (!(v & MCHIP_MM_FIR_RDY))
+			goto out;
+		switch (meye.mchip_mode) {
+
+		case MCHIP_HIC_MODE_CONT_OUT:
+			if (!meye_emptyq(&meye.grabq, NULL)) {
+				int nr = meye_pullq(&meye.grabq);
+				mchip_cont_read_frame(
+					v, 
+					meye.grab_fbuffer + gbufsize * nr,
+					mchip_hsize() * mchip_vsize() * 2);
+				meye.grab_buffer[nr].state = MEYE_BUF_DONE;
+				wake_up_interruptible(&meye.grabq.proc_list);
+			}
+			break;
+
+		case MCHIP_HIC_MODE_CONT_COMP:
+			if (!meye_emptyq(&meye.grabq, &reqnr)) {
+				int size;
+				size = mchip_comp_read_frame(
+					v,
+					meye.grab_fbuffer + gbufsize * reqnr,
+					gbufsize);
+				if (size == -1)
+					break;
+				reqnr = meye_pullq(&meye.grabq);
+				meye.grab_buffer[reqnr].size = size;
+				meye.grab_buffer[reqnr].state = MEYE_BUF_DONE;
+				wake_up_interruptible(&meye.grabq.proc_list);
+			}
+			break;
+
+		default:
+			/* do not free frame, since it can be a snap */
+			goto out;
+		} /* switch */
+
+		mchip_free_frame();
+	}
+out:
+}
+
+/****************************************************************************/
+/* video4linux integration                                                  */
+/****************************************************************************/
+
+static int meye_open(struct video_device *dev, int flags) {
+	int i;
+
+	down(&meye.lock);
+	if (meye.open_count) {
+		up(&meye.lock);
+		return -EBUSY;
+	}
+	meye.open_count++;
+	if (mchip_dma_alloc()) {
+		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
+		up(&meye.lock);
+		return -ENOBUFS;
+	}
+	mchip_hic_stop();
+	meye_initq(&meye.grabq);
+	for (i = 0; i < MEYE_MAX_BUFNBRS; i++)
+		meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
+	up(&meye.lock);
+	return 0;
+}
+
+static void meye_close(struct video_device *dev) {
+	down(&meye.lock);
+	meye.open_count--;
+	mchip_hic_stop();
+	up(&meye.lock);
+}
+
+static int meye_ioctl(struct video_device *dev, unsigned int cmd, void *arg) {
+
+	switch (cmd) {
+
+	case VIDIOCGCAP: {
+		struct video_capability b;
+		strcpy(b.name,meye.video_dev.name);
+		b.type = VID_TYPE_CAPTURE;
+		b.channels = 1;
+		b.audios = 0;
+		b.maxwidth = 640;
+		b.maxheight = 480;
+		b.minwidth = 320;
+		b.minheight = 240;
+		if(copy_to_user(arg,&b,sizeof(b)))
+			return -EFAULT;
+		break;
+	}
+
+	case VIDIOCGCHAN: {
+		struct video_channel v;
+		if(copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+		v.flags = 0;
+		v.tuners = 0;
+		v.type = VIDEO_TYPE_CAMERA;
+		if (v.channel != 0)
+			return -EINVAL;
+		strcpy(v.name,"Camera");
+		if(copy_to_user(arg,&v,sizeof(v)))
+			return -EFAULT;
+		break;
+	}
+
+	case VIDIOCSCHAN: {
+		struct video_channel v;
+		if(copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+		if (v.channel != 0)
+			return -EINVAL;
+		break;
+	}
+
+	case VIDIOCGPICT: {
+		struct video_picture p = meye.picture;
+		if(copy_to_user(arg, &p, sizeof(p)))
+			return -EFAULT;
+		break;
+	}
+
+	case VIDIOCSPICT: {
+		struct video_picture p;
+		if(copy_from_user(&p, arg,sizeof(p)))
+			return -EFAULT;
+		if (p.depth != 2)
+			return -EINVAL;
+		if (p.palette != VIDEO_PALETTE_YUV422)
+			return -EINVAL;
+		down(&meye.lock);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 
+				      p.brightness >> 10);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 
+				      p.hue >> 10);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 
+				      p.colour >> 10);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 
+				      p.contrast >> 10);
+		memcpy(&meye.picture, &p, sizeof(p));
+		up(&meye.lock);
+		break;
+	}
+
+	case VIDIOCSYNC: {
+		int i;
+		DECLARE_WAITQUEUE(wait, current);
+
+		if(copy_from_user((void *)&i,arg,sizeof(int)))
+			return -EFAULT;
+		if (i < 0 || i >= gbuffers)
+			return -EINVAL;
+
+		switch (meye.grab_buffer[i].state) {
+
+		case MEYE_BUF_UNUSED:
+			return -EINVAL;
+		case MEYE_BUF_USING:
+			add_wait_queue(&meye.grabq.proc_list, &wait);
+			current->state = TASK_INTERRUPTIBLE;
+			while (meye.grab_buffer[i].state == MEYE_BUF_USING) {
+				schedule();
+				if(signal_pending(current)) {
+					remove_wait_queue(&meye.grabq.proc_list, &wait);
+					current->state = TASK_RUNNING;
+					return -EINTR;
+				}
+			}
+			remove_wait_queue(&meye.grabq.proc_list, &wait);
+			current->state = TASK_RUNNING;
+			/* fall through */
+		case MEYE_BUF_DONE:
+			meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
+		}
+		break;
+	}
+
+	case VIDIOCMCAPTURE: {
+		struct video_mmap vm;
+		int restart = 0;
+
+		if(copy_from_user((void *) &vm, (void *) arg, sizeof(vm)))
+			return -EFAULT;
+		if (vm.frame >= gbuffers || vm.frame < 0)
+			return -EINVAL;
+		if (vm.format != VIDEO_PALETTE_YUV422)
+			return -EINVAL;
+		if (vm.height * vm.width * 2 > gbufsize)
+			return -EINVAL;
+		if (!meye.grab_fbuffer)
+			return -EINVAL;
+		if (meye.grab_buffer[vm.frame].state != MEYE_BUF_UNUSED)
+			return -EBUSY;
+
+		down(&meye.lock);
+		if (vm.width == 640 && vm.height == 480) {
+			if (meye.params.subsample) {
+				meye.params.subsample = 0;
+				restart = 1;
+			}
+		}
+		else if (vm.width == 320 && vm.height == 240) {
+			if (!meye.params.subsample) {
+				meye.params.subsample = 1;
+				restart = 1;
+			}
+		}
+		else {
+			up(&meye.lock);
+			return -EINVAL;
+		}
+
+		if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT)
+			mchip_continuous_start();
+		meye.grab_buffer[vm.frame].state = MEYE_BUF_USING;
+		meye_pushq(&meye.grabq, vm.frame);
+		up(&meye.lock);
+		break;
+	}
+
+	case VIDIOCGMBUF: {
+		struct video_mbuf vm;
+		int i;
+
+		memset(&vm, 0 , sizeof(vm));
+		vm.size = gbufsize * gbuffers;
+		vm.frames = gbuffers;
+		for (i = 0; i < gbuffers; i++)
+			vm.offsets[i] = i * gbufsize;
+		if(copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
+			return -EFAULT;
+		break;
+	}
+
+	case MEYEIOC_G_PARAMS: {
+		if (copy_to_user(arg, &meye.params, sizeof(meye.params)))
+			return -EFAULT;
+		break;
+	}
+
+	case MEYEIOC_S_PARAMS: {
+		struct meye_params jp;
+		if (copy_from_user(&jp, arg, sizeof(jp)))
+			return -EFAULT;
+		if (jp.subsample > 1)
+			return -EINVAL;
+		if (jp.quality > 10)
+			return -EINVAL;
+		if (jp.sharpness > 63 || jp.agc > 63 || jp.picture > 63)
+			return -EINVAL;
+		if (jp.framerate > 31)
+			return -EINVAL;
+		down(&meye.lock);
+		if (meye.params.subsample != jp.subsample ||
+		    meye.params.quality != jp.quality)
+			mchip_hic_stop();	/* need restart */
+		memcpy(&meye.params, &jp, sizeof(jp));
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS,
+				      meye.params.sharpness);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC,
+				      meye.params.agc);
+		sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE,
+				      meye.params.picture);
+		up(&meye.lock);
+		break;
+	}
+
+	case MEYEIOC_QBUF_CAPT: {
+		int nb;
+
+		if (copy_from_user((void *) &nb, (void *) arg, sizeof(int)))
+			return -EFAULT;
+
+		if (!meye.grab_fbuffer) 
+			return -EINVAL;
+		if (nb >= gbuffers)
+			return -EINVAL;
+		if (nb < 0) {
+			/* stop capture */
+			mchip_hic_stop();
+			return 0;
+		}
+		if (meye.grab_buffer[nb].state != MEYE_BUF_UNUSED)
+			return -EBUSY;
+		down(&meye.lock);
+		if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP)
+			mchip_cont_compression_start();
+		meye.grab_buffer[nb].state = MEYE_BUF_USING;
+		meye_pushq(&meye.grabq, nb);
+		up(&meye.lock);
+		break;
+	}
+
+	case MEYEIOC_SYNC: {
+		int i;
+		DECLARE_WAITQUEUE(wait, current);
+
+		if(copy_from_user((void *)&i,arg,sizeof(int)))
+			return -EFAULT;
+		if (i < 0 || i >= gbuffers)
+			return -EINVAL;
+
+		switch (meye.grab_buffer[i].state) {
+
+		case MEYE_BUF_UNUSED:
+			return -EINVAL;
+		case MEYE_BUF_USING:
+			add_wait_queue(&meye.grabq.proc_list, &wait);
+			current->state = TASK_INTERRUPTIBLE;
+			while (meye.grab_buffer[i].state == MEYE_BUF_USING) {
+				schedule();
+				if(signal_pending(current)) {
+					remove_wait_queue(&meye.grabq.proc_list, &wait);
+					current->state = TASK_RUNNING;
+					return -EINTR;
+				}
+			}
+			remove_wait_queue(&meye.grabq.proc_list, &wait);
+			current->state = TASK_RUNNING;
+			/* fall through */
+		case MEYE_BUF_DONE:
+			meye.grab_buffer[i].state = MEYE_BUF_UNUSED;
+		}
+		i = meye.grab_buffer[i].size;
+		if (copy_to_user(arg, (void *)&i, sizeof(int)))
+			return -EFAULT;
+		break;
+	}
+
+	case MEYEIOC_STILLCAPT: {
+
+		if (!meye.grab_fbuffer) 
+			return -EINVAL;
+		if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
+			return -EBUSY;
+		down(&meye.lock);
+		meye.grab_buffer[0].state = MEYE_BUF_USING;
+		mchip_take_picture();
+		mchip_get_picture(
+			meye.grab_fbuffer,
+			mchip_hsize() * mchip_vsize() * 2);
+		meye.grab_buffer[0].state = MEYE_BUF_DONE;
+		up(&meye.lock);
+		break;
+	}
+
+	case MEYEIOC_STILLJCAPT: {
+		int len = -1;
+
+		if (!meye.grab_fbuffer) 
+			return -EINVAL;
+		if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED)
+			return -EBUSY;
+		down(&meye.lock);
+		meye.grab_buffer[0].state = MEYE_BUF_USING;
+		while (len == -1) {
+			mchip_take_picture();
+			len = mchip_compress_frame(meye.grab_fbuffer, gbufsize);
+		}
+		meye.grab_buffer[0].state = MEYE_BUF_DONE;
+		up(&meye.lock);
+		if (copy_to_user(arg, (void *)&len, sizeof(int)))
+			return -EFAULT;
+		break;
+	}
+
+	default:
+		return -ENOIOCTLCMD;
+		
+	} /* switch */
+
+	return 0;
+}
+
+static int meye_mmap(struct video_device *dev, const char *adr, 
+		     unsigned long size) {
+	unsigned long start=(unsigned long) adr;
+	unsigned long page,pos;
+
+	down(&meye.lock);
+	if (size > gbuffers * gbufsize) {
+		up(&meye.lock);
+		return -EINVAL;
+	}
+	if (!meye.grab_fbuffer) {
+		/* lazy allocation */
+		meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize);
+		if (!meye.grab_fbuffer) {
+			printk(KERN_ERR "meye: v4l framebuffer allocation failed\n");
+			up(&meye.lock);
+			return -ENOMEM;
+		}
+	}
+	pos = (unsigned long)meye.grab_fbuffer;
+
+	while (size > 0) {
+		page = kvirt_to_pa(pos);
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
+			up(&meye.lock);
+			return -EAGAIN;
+		}
+		start += PAGE_SIZE;
+		pos += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	up(&meye.lock);
+	return 0;
+}
+
+static struct video_device meye_template = {
+	owner:		THIS_MODULE,
+	name:		"meye",
+	type:		VID_TYPE_CAPTURE,
+	hardware:	VID_HARDWARE_MEYE,
+	open:		meye_open,
+	close:		meye_close,
+	ioctl:		meye_ioctl,
+	mmap:		meye_mmap,
+};
+
+static int __devinit meye_probe(struct pci_dev *pcidev, 
+		                const struct pci_device_id *ent) {
+	int ret;
+	unsigned long mchip_adr;
+	u8 revision;
+
+	if (meye.mchip_dev != NULL) {
+		printk(KERN_ERR "meye: only one device allowed!\n");
+		ret = -EBUSY;
+		goto out1;
+	}
+
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1);
+
+	meye.mchip_dev = pcidev;
+	meye.mchip_irq = pcidev->irq;
+	memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));
+
+	if (mchip_dma_alloc()) {
+		printk(KERN_ERR "meye: mchip framebuffer allocation failed\n");
+		ret = -ENOMEM;
+		goto out2;
+	}
+
+	if ((ret = pci_enable_device(meye.mchip_dev))) {
+		printk(KERN_ERR "meye: pci_enable_device failed\n");
+		goto out3;
+	}
+
+	mchip_adr = pci_resource_start(meye.mchip_dev,0);
+	if (!mchip_adr) {
+		printk(KERN_ERR "meye: mchip has no device base address\n");
+		ret = -EIO;
+		goto out4;
+	}
+	if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0),
+			        pci_resource_len(meye.mchip_dev, 0),
+				"meye")) {
+		ret = -EIO;
+		printk(KERN_ERR "meye: request_mem_region failed\n");
+		goto out4;
+	}
+
+	pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision);
+
+	pci_set_master(meye.mchip_dev);
+
+	pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8);
+	pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64);
+
+	if ((ret = request_irq(meye.mchip_irq, meye_irq, 
+			       SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) {
+		printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret);
+		goto out5;
+	}
+
+	meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS);
+	if (!meye.mchip_mmregs) {
+		printk(KERN_ERR "meye: ioremap failed\n");
+		ret = -EIO;
+		goto out6;
+	}
+	
+	/* Ask the camera to perform a soft reset. */
+	pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1);
+
+	mchip_delay(MCHIP_HIC_CMD, 0);
+	mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE);
+
+	wait_ms(1);
+	mchip_set(MCHIP_VRJ_SOFT_RESET, 1);
+
+	wait_ms(1);
+	mchip_set(MCHIP_MM_PCI_MODE, 5);
+
+	wait_ms(1);
+	mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK);
+
+	if (video_register_device(&meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
+
+		printk(KERN_ERR "meye: video_register_device failed\n");
+		ret = -EIO;
+		goto out7;
+	}
+	
+	printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n",
+	       MEYE_DRIVER_MAJORVERSION,
+	       MEYE_DRIVER_MINORVERSION);
+	printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n", 
+		revision, mchip_adr, meye.mchip_irq);
+
+	/* init all fields */
+	init_MUTEX(&meye.lock);
+
+	meye.picture.depth = 2;
+	meye.picture.palette = VIDEO_PALETTE_YUV422;
+	meye.picture.brightness = 32 << 10;
+	meye.picture.hue = 32 << 10;
+	meye.picture.colour = 32 << 10;
+	meye.picture.contrast = 32 << 10;
+	meye.picture.whiteness = 0;
+	meye.params.subsample = 0;
+	meye.params.quality = 7;
+	meye.params.sharpness = 32;
+	meye.params.agc = 48;
+	meye.params.picture = 0;
+	meye.params.framerate = 0;
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, 32);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERASHARPNESS, 32);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0);
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48);
+
+	return 0;
+out7:
+	iounmap(meye.mchip_mmregs);
+out6:
+	free_irq(meye.mchip_irq, meye_irq);
+out5:
+	release_mem_region(pci_resource_start(meye.mchip_dev, 0),
+			   pci_resource_len(meye.mchip_dev, 0));
+out4:
+	pci_disable_device(meye.mchip_dev);
+out3:
+	mchip_dma_free();
+out2:
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
+out1:
+	return ret;
+}
+
+static void __devexit meye_remove(struct pci_dev *pcidev) {
+
+	video_unregister_device(&meye.video_dev);
+
+	mchip_hic_stop();
+
+	/* disable interrupts */
+	mchip_set(MCHIP_MM_INTA, 0x0);
+
+	free_irq(meye.mchip_irq, meye_irq);
+
+
+	iounmap(meye.mchip_mmregs);
+
+	release_mem_region(pci_resource_start(meye.mchip_dev, 0),
+			   pci_resource_len(meye.mchip_dev, 0));
+
+	pci_disable_device(meye.mchip_dev);
+
+	mchip_dma_free();
+
+	if (meye.grab_fbuffer)
+		rvfree(meye.grab_fbuffer, gbuffers*gbufsize);
+
+	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0);
+
+	printk(KERN_INFO "meye: removed\n");
+}
+
+static struct pci_device_id meye_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, 
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pci, meye_pci_tbl);
+
+static struct pci_driver meye_driver = {
+	name:		"meye",
+	id_table:	meye_pci_tbl,
+	probe:		meye_probe,
+	remove:		meye_remove,
+};
+
+static int __init meye_init_module(void) {
+	if (gbuffers < 2)
+		gbuffers = 2;
+	if (gbuffers > MEYE_MAX_BUFNBRS)
+		gbuffers = MEYE_MAX_BUFNBRS;
+	if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE)
+		gbufsize = MEYE_MAX_BUFSIZE;
+	printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) for capture\n",
+	       gbuffers, gbufsize/1024, gbuffers*gbufsize/1024);
+	return pci_module_init(&meye_driver);
+}
+
+static void __exit meye_cleanup_module(void) {
+	pci_unregister_driver(&meye_driver);
+}
+
+MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");
+MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
+
+MODULE_PARM(gbuffers,"i");
+MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)");
+MODULE_PARM(gbufsize,"i");
+MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 614400");
+MODULE_PARM(video_nr,"i");
+MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)");
+
+/* Module entry points */
+module_init(meye_init_module);
+module_exit(meye_cleanup_module);
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/drivers/media/video/meye.h linux-2.4.5-ac12/drivers/media/video/meye.h
--- linux-2.4.5-ac12.orig/drivers/media/video/meye.h	Thu Jan  1 01:00:00 1970
+++ linux-2.4.5-ac12/drivers/media/video/meye.h	Sun Jun 10 14:20:34 2001
@@ -0,0 +1,313 @@
+/* 
+ * Motion Eye video4linux driver for Sony Vaio PictureBook
+ *
+ * Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+ *
+ * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
+ *
+ * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
+ * 
+ * Some parts borrowed from various video4linux drivers, especially
+ * bttv-driver.c and zoran.c, see original files for credits.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MEYE_PRIV_H_
+#define _MEYE_PRIV_H_
+
+#define MEYE_DRIVER_MAJORVERSION	1
+#define MEYE_DRIVER_MINORVERSION	0
+
+/****************************************************************************/
+/* Motion JPEG chip registers                                               */
+/****************************************************************************/
+
+/* Motion JPEG chip PCI configuration registers */
+#define MCHIP_PCI_POWER_CSR		0x54
+#define MCHIP_PCI_MCORE_STATUS		0x60	/* see HIC_STATUS   */
+#define MCHIP_PCI_HOSTUSEREQ_SET	0x64
+#define MCHIP_PCI_HOSTUSEREQ_CLR	0x68
+#define MCHIP_PCI_LOWPOWER_SET		0x6c
+#define MCHIP_PCI_LOWPOWER_CLR		0x70
+#define MCHIP_PCI_SOFTRESET_SET		0x74
+
+/* Motion JPEG chip memory mapped registers */
+#define MCHIP_MM_REGS			0x200		/* 512 bytes        */
+#define MCHIP_REG_TIMEOUT		1000		/* reg access, ~us  */
+#define MCHIP_MCC_VRJ_TIMEOUT		1000		/* MCC & VRJ access */
+
+#define MCHIP_MM_PCI_MODE		0x00		/* PCI access mode */
+#define MCHIP_MM_PCI_MODE_RETRY		0x00000001	/* retry mode */
+#define MCHIP_MM_PCI_MODE_MASTER	0x00000002	/* master access */
+#define MCHIP_MM_PCI_MODE_READ_LINE	0x00000004	/* read line */
+
+#define MCHIP_MM_INTA			0x04		/* Int status/mask */
+#define MCHIP_MM_INTA_MCC		0x00000001	/* MCC interrupt */
+#define MCHIP_MM_INTA_VRJ		0x00000002	/* VRJ interrupt */
+#define MCHIP_MM_INTA_HIC_1		0x00000004	/* one frame done */
+#define MCHIP_MM_INTA_HIC_1_MASK	0x00000400	/* 1: enable */
+#define MCHIP_MM_INTA_HIC_END		0x00000008	/* all frames done */
+#define MCHIP_MM_INTA_HIC_END_MASK	0x00000800
+#define MCHIP_MM_INTA_JPEG		0x00000010	/* decompress. error */
+#define MCHIP_MM_INTA_JPEG_MASK		0x00001000
+#define MCHIP_MM_INTA_CAPTURE		0x00000020	/* capture end */
+#define MCHIP_MM_INTA_PCI_ERR		0x00000040	/* PCI error */
+#define MCHIP_MM_INTA_PCI_ERR_MASK	0x00004000
+
+#define MCHIP_MM_PT_ADDR		0x08		/* page table address */
+							/* n*4kB */
+#define MCHIP_NB_PAGES			1024		/* pages for display */
+#define MCHIP_NB_PAGES_MJPEG		256		/* pages for mjpeg */
+
+#define MCHIP_MM_FIR(n)			(0x0c+(n)*4)	/* Frame info 0-3 */
+#define MCHIP_MM_FIR_RDY		0x00000001	/* frame ready */
+#define MCHIP_MM_FIR_FAILFR_MASK	0xf8000000	/* # of failed frames */
+#define MCHIP_MM_FIR_FAILFR_SHIFT	27
+
+	/* continuous comp/decomp mode */
+#define MCHIP_MM_FIR_C_ENDL_MASK	0x000007fe	/* end DW [10] */
+#define MCHIP_MM_FIR_C_ENDL_SHIFT	1
+#define MCHIP_MM_FIR_C_ENDP_MASK	0x0007f800	/* end page [8] */
+#define MCHIP_MM_FIR_C_ENDP_SHIFT	11
+#define MCHIP_MM_FIR_C_STARTP_MASK	0x07f80000	/* start page [8] */
+#define MCHIP_MM_FIR_C_STARTP_SHIFT	19
+
+	/* continuous picture output mode */
+#define MCHIP_MM_FIR_O_STARTP_MASK	0x7ffe0000	/* start page [10] */
+#define MCHIP_MM_FIR_O_STARTP_SHIFT	17
+
+#define MCHIP_MM_FIFO_DATA		0x1c		/* PCI TGT FIFO data */
+#define MCHIP_MM_FIFO_STATUS		0x20		/* PCI TGT FIFO stat */
+#define MCHIP_MM_FIFO_MASK		0x00000003
+#define MCHIP_MM_FIFO_WAIT_OR_READY	0x00000002      /* Bits common to WAIT & READY*/
+#define MCHIP_MM_FIFO_IDLE		0x0		/* HIC idle */
+#define MCHIP_MM_FIFO_IDLE1		0x1		/* idem ??? */
+#define	MCHIP_MM_FIFO_WAIT		0x2		/* wait request */
+#define MCHIP_MM_FIFO_READY		0x3		/* data ready */
+
+#define MCHIP_HIC_HOST_USEREQ		0x40		/* host uses MCORE */
+
+#define MCHIP_HIC_TP_BUSY		0x44		/* taking picture */
+
+#define MCHIP_HIC_PIC_SAVED		0x48		/* pic in SDRAM */
+
+#define MCHIP_HIC_LOWPOWER		0x4c		/* clock stopped */
+
+#define MCHIP_HIC_CTL			0x50		/* HIC control */
+#define MCHIP_HIC_CTL_SOFT_RESET	0x00000001	/* MCORE reset */
+#define MCHIP_HIC_CTL_MCORE_RDY		0x00000002	/* MCORE ready */
+
+#define MCHIP_HIC_CMD			0x54		/* HIC command */
+#define MCHIP_HIC_CMD_BITS		0x00000003      /* cmd width=[1:0]*/
+#define MCHIP_HIC_CMD_NOOP		0x0
+#define MCHIP_HIC_CMD_START		0x1
+#define MCHIP_HIC_CMD_STOP		0x2
+
+#define MCHIP_HIC_MODE			0x58
+#define MCHIP_HIC_MODE_NOOP		0x0
+#define MCHIP_HIC_MODE_STILL_CAP	0x1		/* still pic capt */
+#define MCHIP_HIC_MODE_DISPLAY		0x2		/* display */
+#define MCHIP_HIC_MODE_STILL_COMP	0x3		/* still pic comp. */
+#define MCHIP_HIC_MODE_STILL_DECOMP	0x4		/* still pic decomp. */
+#define MCHIP_HIC_MODE_CONT_COMP	0x5		/* cont capt+comp */
+#define MCHIP_HIC_MODE_CONT_DECOMP	0x6		/* cont decomp+disp */
+#define MCHIP_HIC_MODE_STILL_OUT	0x7		/* still pic output */
+#define MCHIP_HIC_MODE_CONT_OUT		0x8		/* cont output */
+
+#define MCHIP_HIC_STATUS		0x5c
+#define MCHIP_HIC_STATUS_MCC_RDY	0x00000001	/* MCC reg acc ok */
+#define MCHIP_HIC_STATUS_VRJ_RDY	0x00000002	/* VRJ reg acc ok */
+#define MCHIP_HIC_STATUS_IDLE           0x00000003
+#define MCHIP_HIC_STATUS_CAPDIS		0x00000004	/* cap/disp in prog */
+#define MCHIP_HIC_STATUS_COMPDEC	0x00000008	/* (de)comp in prog */
+#define MCHIP_HIC_STATUS_BUSY		0x00000010	/* HIC busy */
+
+#define MCHIP_HIC_S_RATE		0x60		/* MJPEG # frames */
+
+#define MCHIP_HIC_PCI_VFMT		0x64		/* video format */
+#define MCHIP_HIC_PCI_VFMT_YVYU		0x00000001	/* 0: V Y' U Y */
+							/* 1: Y' V Y U */
+
+#define MCHIP_MCC_CMD			0x80		/* MCC commands */
+#define MCHIP_MCC_CMD_INITIAL		0x0		/* idle ? */
+#define MCHIP_MCC_CMD_IIC_START_SET	0x1
+#define MCHIP_MCC_CMD_IIC_END_SET	0x2
+#define MCHIP_MCC_CMD_FM_WRITE		0x3		/* frame memory */
+#define MCHIP_MCC_CMD_FM_READ		0x4
+#define MCHIP_MCC_CMD_FM_STOP		0x5
+#define MCHIP_MCC_CMD_CAPTURE		0x6
+#define MCHIP_MCC_CMD_DISPLAY		0x7
+#define MCHIP_MCC_CMD_END_DISP		0x8
+#define MCHIP_MCC_CMD_STILL_COMP	0x9
+#define MCHIP_MCC_CMD_STILL_DECOMP	0xa
+#define MCHIP_MCC_CMD_STILL_OUTPUT	0xb
+#define MCHIP_MCC_CMD_CONT_OUTPUT	0xc
+#define MCHIP_MCC_CMD_CONT_COMP		0xd
+#define MCHIP_MCC_CMD_CONT_DECOMP	0xe
+#define MCHIP_MCC_CMD_RESET		0xf		/* MCC reset */
+
+#define MCHIP_MCC_IIC_WR		0x84
+
+#define MCHIP_MCC_MCC_WR		0x88
+
+#define MCHIP_MCC_MCC_RD		0x8c
+
+#define MCHIP_MCC_STATUS		0x90
+#define MCHIP_MCC_STATUS_CAPT		0x00000001	/* capturing */
+#define MCHIP_MCC_STATUS_DISP		0x00000002	/* displaying */
+#define MCHIP_MCC_STATUS_COMP		0x00000004	/* compressing */
+#define MCHIP_MCC_STATUS_DECOMP		0x00000008	/* decompressing */
+#define MCHIP_MCC_STATUS_MCC_WR		0x00000010	/* register ready */
+#define MCHIP_MCC_STATUS_MCC_RD		0x00000020	/* register ready */
+#define MCHIP_MCC_STATUS_IIC_WR		0x00000040	/* register ready */
+#define MCHIP_MCC_STATUS_OUTPUT		0x00000080	/* output in prog */
+
+#define MCHIP_MCC_SIG_POLARITY		0x94
+#define MCHIP_MCC_SIG_POL_VS_H		0x00000001	/* VS active-high */
+#define MCHIP_MCC_SIG_POL_HS_H		0x00000002	/* HS active-high */
+#define MCHIP_MCC_SIG_POL_DOE_H		0x00000004	/* DOE active-high */
+
+#define MCHIP_MCC_IRQ			0x98
+#define MCHIP_MCC_IRQ_CAPDIS_STRT	0x00000001	/* cap/disp started */
+#define MCHIP_MCC_IRQ_CAPDIS_STRT_MASK	0x00000010
+#define MCHIP_MCC_IRQ_CAPDIS_END	0x00000002	/* cap/disp ended */
+#define MCHIP_MCC_IRQ_CAPDIS_END_MASK	0x00000020
+#define MCHIP_MCC_IRQ_COMPDEC_STRT	0x00000004	/* (de)comp started */
+#define MCHIP_MCC_IRQ_COMPDEC_STRT_MASK	0x00000040
+#define MCHIP_MCC_IRQ_COMPDEC_END	0x00000008	/* (de)comp ended */
+#define MCHIP_MCC_IRQ_COMPDEC_END_MASK	0x00000080
+
+#define MCHIP_MCC_HSTART		0x9c		/* video in */
+#define MCHIP_MCC_VSTART		0xa0
+#define MCHIP_MCC_HCOUNT		0xa4
+#define MCHIP_MCC_VCOUNT		0xa8
+#define MCHIP_MCC_R_XBASE		0xac		/* capt/disp */
+#define MCHIP_MCC_R_YBASE		0xb0
+#define MCHIP_MCC_R_XRANGE		0xb4
+#define MCHIP_MCC_R_YRANGE		0xb8
+#define MCHIP_MCC_B_XBASE		0xbc		/* comp/decomp */
+#define MCHIP_MCC_B_YBASE		0xc0
+#define MCHIP_MCC_B_XRANGE		0xc4
+#define MCHIP_MCC_B_YRANGE		0xc8
+
+#define MCHIP_MCC_R_SAMPLING		0xcc		/* 1: 1:4 */
+
+#define MCHIP_VRJ_CMD			0x100		/* VRJ commands */
+
+/* VRJ registers (see table 12.2.4) */
+#define MCHIP_VRJ_COMPRESSED_DATA	0x1b0
+#define MCHIP_VRJ_PIXEL_DATA		0x1b8
+
+#define MCHIP_VRJ_BUS_MODE		0x100
+#define MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL	0x108
+#define MCHIP_VRJ_PDAT_USE		0x110
+#define MCHIP_VRJ_MODE_SPECIFY		0x118
+#define MCHIP_VRJ_LIMIT_COMPRESSED_LO	0x120
+#define MCHIP_VRJ_LIMIT_COMPRESSED_HI	0x124
+#define MCHIP_VRJ_COMP_DATA_FORMAT	0x128
+#define MCHIP_VRJ_TABLE_DATA		0x140
+#define MCHIP_VRJ_RESTART_INTERVAL	0x148
+#define MCHIP_VRJ_NUM_LINES		0x150
+#define MCHIP_VRJ_NUM_PIXELS		0x158
+#define MCHIP_VRJ_NUM_COMPONENTS	0x160
+#define MCHIP_VRJ_SOF1			0x168
+#define MCHIP_VRJ_SOF2			0x170
+#define MCHIP_VRJ_SOF3			0x178
+#define MCHIP_VRJ_SOF4			0x180
+#define MCHIP_VRJ_SOS			0x188
+#define MCHIP_VRJ_SOFT_RESET		0x190
+
+#define MCHIP_VRJ_STATUS		0x1c0
+#define MCHIP_VRJ_STATUS_BUSY		0x00001
+#define MCHIP_VRJ_STATUS_COMP_ACCESS	0x00002
+#define MCHIP_VRJ_STATUS_PIXEL_ACCESS	0x00004
+#define MCHIP_VRJ_STATUS_ERROR		0x00008
+
+#define MCHIP_VRJ_IRQ_FLAG		0x1c8
+#define MCHIP_VRJ_ERROR_REPORT		0x1d8
+
+#define MCHIP_VRJ_START_COMMAND		0x1a0
+
+/****************************************************************************/
+/* Driver definitions.                                                      */
+/****************************************************************************/
+
+/* Sony Programmable I/O Controller for accessing the camera commands */
+#include <linux/sonypi.h>
+
+/* private API definitions */
+#include <linux/meye.h>
+
+/* Enable jpg software correction */
+#define MEYE_JPEG_CORRECTION	1
+
+/* Maximum size of a buffer */
+#define MEYE_MAX_BUFSIZE	614400	/* 640 * 480 * 2 */
+
+/* Maximum number of buffers */
+#define MEYE_MAX_BUFNBRS	32
+
+/* State of a buffer */
+#define MEYE_BUF_UNUSED	0	/* not used */
+#define MEYE_BUF_USING	1	/* currently grabbing / playing */
+#define MEYE_BUF_DONE	2	/* done */
+
+/* grab buffer */
+struct meye_grab_buffer {
+	int state;			/* state of buffer */
+	unsigned long size;		/* size of jpg frame */
+};
+
+/* queues containing the buffer indices */
+#define MEYE_QUEUE_SIZE	MEYE_MAX_BUFNBRS
+struct meye_queue {
+	unsigned int head;		/* queue head */
+	unsigned int tail;		/* queue tail */
+	unsigned int len;		/* queue length */
+	spinlock_t s_lock;		/* spinlock protecting the queue */
+	wait_queue_head_t proc_list;	/* wait queue */
+	int buf[MEYE_QUEUE_SIZE];	/* queue contents */
+};
+
+/* Motion Eye device structure */
+struct meye {
+
+	/* mchip related */
+	struct pci_dev *mchip_dev;	/* pci device */
+	u8 mchip_irq;			/* irq */
+	u8 mchip_mode;			/* actual mchip mode: HIC_MODE... */
+	u8 mchip_fnum;			/* current mchip frame number */
+
+	unsigned char *mchip_mmregs;	/* mchip: memory mapped registers */
+	unsigned char *mchip_fbuffer;	/* mchip: framebuffer */
+	u32 mchip_ptaddr;		/* mchip: pointer to framebuffer */
+
+	unsigned char *grab_fbuffer;	/* capture framebuffer */
+					/* list of buffers */
+	struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS];
+
+	/* other */
+	unsigned int open_count;	/* open() count */
+	struct semaphore lock;		/* semaphore for open/mmap... */
+
+	struct meye_queue grabq;	/* queue for buffers to be grabbed */
+
+	struct video_device video_dev;	/* video device parameters */
+	struct video_picture picture;	/* video picture parameters */
+	struct meye_params params;	/* additional parameters */
+};
+
+#endif
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/include/linux/meye.h linux-2.4.5-ac12/include/linux/meye.h
--- linux-2.4.5-ac12.orig/include/linux/meye.h	Thu Jan  1 01:00:00 1970
+++ linux-2.4.5-ac12/include/linux/meye.h	Thu Jun  7 15:48:57 2001
@@ -0,0 +1,57 @@
+/* 
+ * Motion Eye video4linux driver for Sony Vaio PictureBook
+ *
+ * Copyright (C) 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alcôve
+ *
+ * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
+ *
+ * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras.
+ * 
+ * Some parts borrowed from various video4linux drivers, especially
+ * bttv-driver.c and zoran.c, see original files for credits.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MEYE_H_
+#define _MEYE_H_
+
+/****************************************************************************/
+/* Private API for handling mjpeg capture / playback.                       */
+/****************************************************************************/
+
+struct meye_params {
+	unsigned char subsample;
+	unsigned char quality;
+	unsigned char sharpness;
+	unsigned char agc;
+	unsigned char picture;
+	unsigned char framerate;
+};
+
+/* query the extended parameters */
+#define MEYEIOC_G_PARAMS	_IOR ('v', BASE_VIDIOCPRIVATE+0, struct meye_params)
+/* set the extended parameters */
+#define MEYEIOC_S_PARAMS	_IOW ('v', BASE_VIDIOCPRIVATE+1, struct meye_params)
+/* queue a buffer for mjpeg capture */
+#define MEYEIOC_QBUF_CAPT	_IOW ('v', BASE_VIDIOCPRIVATE+2, int)
+/* sync a previously queued mjpeg buffer */
+#define MEYEIOC_SYNC		_IOWR('v', BASE_VIDIOCPRIVATE+3, int)
+/* get a still uncompressed snapshot */
+#define MEYEIOC_STILLCAPT	_IO  ('v', BASE_VIDIOCPRIVATE+4)
+/* get a jpeg compressed snapshot */
+#define MEYEIOC_STILLJCAPT	_IOR ('v', BASE_VIDIOCPRIVATE+5, int)
+
+#endif
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/include/linux/pci_ids.h linux-2.4.5-ac12/include/linux/pci_ids.h
--- linux-2.4.5-ac12.orig/include/linux/pci_ids.h	Sun Jun 10 13:42:18 2001
+++ linux-2.4.5-ac12/include/linux/pci_ids.h	Sun Jun 10 13:49:19 2001
@@ -1304,6 +1304,9 @@
 #define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2	0x0108
 #define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS	0x0109
 
+#define PCI_VENDOR_ID_KAWASAKI		0x136b
+#define PCI_DEVICE_ID_MCHIP_KL5A72002	0xff01
+
 #define PCI_VENDOR_ID_LMC		0x1376
 #define PCI_DEVICE_ID_LMC_HSSI		0x0003
 #define PCI_DEVICE_ID_LMC_DS3		0x0004
diff -uNr --exclude-from=dontdiff linux-2.4.5-ac12.orig/include/linux/videodev.h linux-2.4.5-ac12/include/linux/videodev.h
--- linux-2.4.5-ac12.orig/include/linux/videodev.h	Sun Jun 10 13:41:25 2001
+++ linux-2.4.5-ac12/include/linux/videodev.h	Sun Jun 10 14:20:32 2001
@@ -375,6 +375,7 @@
 #define VID_HARDWARE_W9966	29
 #define VID_HARDWARE_SE401	30	/* SE401 USB webcams */
 #define VID_HARDWARE_PWC	31	/* Philips webcams */
+#define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
 
 /*
  *	Initialiser list

-- 
Stelian Pop <stelian.pop@fr.alcove.com>
|---------------- Free Software Engineer -----------------|
| Alcôve - http://www.alcove.com - Tel: +33 1 49 22 68 00 |
|------------- Alcôve, liberating software ---------------|

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2001-06-29  9:30 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-12 20:58 [PATCH 2.4.5-ac12] New Sony Vaio Motion Eye camera driver Alex Deucher
2001-06-12 22:50 ` egger
2001-06-13 13:05   ` Alex Deucher
2001-06-12 22:51 ` Linus Torvalds
2001-06-13  6:33   ` egger
2001-06-13 10:24   ` Stelian Pop
2001-06-14 21:36     ` Linus Torvalds
2001-06-15 21:10     ` Stelian Pop
2001-06-28 19:11     ` volodya
2001-06-29  9:29       ` Stelian Pop
2001-06-13 13:09   ` Alex Deucher
  -- strict thread matches above, loose matches on Subject: below --
2001-06-10 13:25 Stelian Pop
2001-06-10 14:39 ` Alan Cox
2001-06-10 15:57   ` Stelian Pop
2001-06-10 15:58     ` Alan Cox
2001-06-10 16:46       ` Stelian Pop
2001-06-10 19:07         ` Linus Torvalds
2001-06-10 23:41           ` egger
2001-06-11  0:13             ` Linus Torvalds
2001-06-11 19:37               ` egger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).