Initial dump from Sourceforge website

This commit is contained in:
Simon Howard
2023-08-03 23:03:18 -04:00
commit 0b086fc6bc
99 changed files with 2421 additions and 0 deletions

41
dev/adc7843_diff Normal file
View File

@ -0,0 +1,41 @@
89a90
> static struct tpanel_sample old_ts = {0,0,0};
92c93
< int trigger, x, y;
---
> int trigger;
113,114d113
< x = ts.x;
< y = ts.y;
116,120c115,139
< /* Converte to screen coordinates... */
< x = ( ( ts.x - cal->min_x ) * cal->x_res / ( cal->max_x - cal->min_x ) );
< y = ( ( ts.y - cal->min_y ) * cal->y_res / ( cal->max_y - cal->min_y ) );
<
< infilter_send_pointing(PG_TRIGGER_PNTR_STATUS,x,y,ts.state,NULL);
---
> /* if pointer is up, keep the cursor position from when it was up */
> if (!ts.state) {
> ts.x = old_ts.x;
> ts.y = old_ts.y;
> } else {
> /* Converte to screen coordinates... */
> ts.x = ((ts.x - cal->min_x) * cal->x_res / (cal->max_x - cal->min_x));
> ts.y = ((ts.y - cal->min_y) * cal->y_res / (cal->max_y - cal->min_y));
> }
>
> /* if nothing has changed, dont send an event */
> if (ts.state == old_ts.state && ts.x == old_ts.x && ts.y == old_ts.y)
> return;
>
> if (old_ts.state && !ts.state)
> infilter_send_pointing(PG_TRIGGER_UP, ts.x, ts.y, ts.state, NULL);
> else if (!old_ts.state && ts.state)
> infilter_send_pointing(PG_TRIGGER_DOWN, ts.x, ts.y, ts.state, NULL);
>
> if (ts.x != old_ts.x || ts.y != old_ts.y)
> infilter_send_pointing(PG_TRIGGER_MOVE, ts.x, ts.y, ts.state, NULL);
>
> /* save ts for next time */
> old_ts = ts;
>

76
dev/adc_diff Normal file
View File

@ -0,0 +1,76 @@
Index: adc7843.c
===================================================================
RCS file: /cvsroot/pgui/pgserver/input/adc7843.c,v
retrieving revision 1.6
diff -u -r1.6 adc7843.c
--- adc7843.c 3 Jul 2002 22:03:29 -0000 1.6
+++ adc7843.c 6 Nov 2002 00:25:45 -0000
@@ -60,16 +60,16 @@
int adc7843_fd;
-struct tpanel_sample {
- u16 state;
- u16 x;
- u16 y;
-};
-
/******************************************** Implementations */
g_error adc7843_init(void) {
adc7843_fd = open("/dev/tpanel",O_NONBLOCK);
+
+ /* devfs name */
+
+ if (adc7843_fd <= 0)
+ adc7843_fd = open("/dev/misc/adc7843", O_NONBLOCK);
+
if (adc7843_fd <= 0)
return mkerror(PG_ERRT_IO, 74);
@@ -87,9 +87,10 @@
}
int adc7843_fd_activate(int fd) {
- struct tpanel_sample ts;
+ int state;
char buffer[6];
- int trigger, x, y;
+ int trigger;
+ static int x=0, y=0;
if (!cal) {
if (!vid)
@@ -107,17 +108,22 @@
return 1;
/* Convert the bytes to unsigned integers... */
- ts.state = ( ( (buffer[0]) << 8 ) + buffer[1] );
- ts.x = ( ( (buffer[2]) << 8 ) + buffer[3] );
- ts.y = ( ( (buffer[4]) << 8 ) + buffer[5] );
- x = ts.x;
- y = ts.y;
-
- /* Converte to screen coordinates... */
- x = ( ( ts.x - cal->min_x ) * cal->x_res / ( cal->max_x - cal->min_x ) );
- y = ( ( ts.y - cal->min_y ) * cal->y_res / ( cal->max_y - cal->min_y ) );
+ state = ( ( (buffer[0]) << 8 ) + buffer[1] );
+
+ /* save x,y in static variables. when pen up, send the last known
+ coordinates */
+
+ if (state) {
+ x = ( ( (buffer[2]) << 8 ) + buffer[3] );
+ y = ( ( (buffer[4]) << 8 ) + buffer[5] );
+
+ /* Convert to screen coordinates... */
+ x = ( ( x - cal->min_x ) * cal->x_res / ( cal->max_x - cal->min_x ) );
+ y = ( ( y - cal->min_y ) * cal->y_res / ( cal->max_y - cal->min_y ) );
+ }
- infilter_send_pointing(PG_TRIGGER_PNTR_STATUS,x,y,ts.state,NULL);
+ infilter_send_pointing(PG_TRIGGER_PNTR_STATUS,x,y,state,NULL);
+
return 1;
}

166
dev/pdf/battery_info.txt Normal file
View File

@ -0,0 +1,166 @@
The battery level(s) can be monitored using the auxilary channels of the ADC
for the touchscreen. Here are some emails which may be useful:
From: Simon D Howard <sdh300@ecs.soton.ac.uk>
To: Tony Lindgren <tony@atomide.com>
cc: Linux-7110-psion@lists.sourceforge.net
Subject: Re: [Linux-7110-psion] /proc patch
Date: Mon, 29 Apr 2002 18:57:35 +0100 (BST)
On Mon, 29 Apr 2002, Tony Lindgren wrote:
> So sounds like your SSI extra channel code might work on 5mx!
> Can you post it so we can try if you don't have a 5mx?
Well, it wasnt really specific code, I just hacked about with the adc
code. Currently it listens on the first 2 ports (which give the x, y
coordinate). If you change the following lines:
ssi_transmit_data(dev,0xd000);
ssi_transmit_data(dev,0x9000);
to
ssi_transmit_data(dev,0xd000 | 0x2000);
ssi_transmit_data(dev,0x9000 | 0x2000);
it ought to read the other channels (according to the adc datasheet
anyway, it didnt work so it may be that I'm totally wrong). I wrote a
small program to print the output from /dev/tpanel but I dont have it with
me right now - I adapted the picogui tpanel code.
Simon
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-7110-psion
From: "Thilo Hille" <thilo@resourcery.de>
To: "Simon D Howard" <sdh300@ecs.soton.ac.uk>,
"Tony Lindgren" <tony@atomide.com>
Subject: Re: [Linux-7110-psion] /proc patch
Date: Tue, 30 Apr 2002 14:40:02 +0200
gotcha..
> So sounds like your SSI extra channel code might work on 5mx!
> Can you post it so we can try if you don't have a 5mx?
i just tweaked the controlbytes in adc7843.c
ssi_transmit_data(dev,0xa400); //channel 3
ssi_transmit_data(dev,0xe400); //channel 4
and voila shows up the battery state on channel three.
it stays around 2593 when accus inserted and drops down to <20 (needs about
a 3 minutes).
i think there are some capacitors discharging slowly this might be faster
when the external powersupply is disconnected.
how do we get this into an own driver?
Thilo Hille
resourcery GbR.
Habsburgerstr. 11
79104 Freiburg
Tel.: 0761-4567807
Fax.: 0761-4567805
thilo@resourcery.de
From: "Thilo Hille" <thilo@resourcery.de>
To: <linux-7110-psion@lists.sourceforge.net>
Subject: [Linux-7110-psion] power consumtion
Date: Tue, 30 Apr 2002 14:57:01 +0200
i just measured the battery current.
its about 2.74V.
the adc reports about 2594 (maybe rough mV?)
Thilo Hille
resourcery GbR.
Habsburgerstr. 11
79104 Freiburg
Tel.: 0761-4567807
Fax.: 0761-4567805
thilo@resourcery.de
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-7110-psion
From: Simon D Howard <sdh300@ecs.soton.ac.uk>
To: Thilo Hille <thilo@resourcery.de>
cc: linux-7110-psion@lists.sourceforge.net
Subject: Re: [Linux-7110-psion] /proc patch
Date: Tue, 30 Apr 2002 19:23:27 +0100 (BST)
On Tue, 30 Apr 2002, Thilo Hille wrote:
> i just tweaked the controlbytes in adc7843.c
> ssi_transmit_data(dev,0xa400); //channel 3
> ssi_transmit_data(dev,0xe400); //channel 4
> and voila shows up the battery state on channel three.
> it stays around 2593 when accus inserted and drops down to <20 (needs about
> a 3 minutes).
> i think there are some capacitors discharging slowly this might be faster
> when the external powersupply is disconnected.
Good news, this seems to work on my revo too. I found this slightly
surprising as the email tony quoted suggested the battery monitoring was
done differently. When charging, it seems to reach a maximum of around
3950 but drops to around 3500 when its finished. EPOC seems to use
3950-4000 as its "100%" value too - I get similar readings from its
battery monitor.
I also get ~2464 (invariant) from the other channel - presumably the
backup battery.
> how do we get this into an own driver?
"with difficulty" :)
Simon
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-7110-psion
From: "Thilo Hille" <thilo@resourcery.de>
To: "Simon D Howard" <sdh300@ecs.soton.ac.uk>
Cc: <linux-7110-psion@lists.sourceforge.net>
Subject: Re: [Linux-7110-psion] /proc patch
Date: Tue, 30 Apr 2002 20:51:00 +0200
hi simon,
> I also get ~2464 (invariant) from the other channel - presumably the
> backup battery.
hmmm i dont have a backupbattery inserted and ch4 shows up ~4084.
i dont have one at hands for now, but tomorrow i ll try it.
did you try to remove the backup battery while watching the 4th channel?
(hey, its like tv :)
i really forgot about the backupbattery. i removed it 2 month ago and as id
never used epoc since than i never needed it.
greetingz
Thilo Hille
resourcery GbR.
Habsburgerstr. 11
79104 Freiburg
Tel.: 0761-4567807
Fax.: 0761-4567805
thilo@resourcery.de
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-7110-psion

31
dev/pdf/cf-etna.txt Normal file
View File

@ -0,0 +1,31 @@
ETNA CF CLPS7110 Name Description
3509-0169-02 Memory I/O
(C)PSION PLC
A12 R02 NL
9732M3006
Pin 1 <-> Pin 47 D08
Pin 2 <-> Pin 48 D09
Pin 3 <-> Pin 49 D10
Pin 4 <-> Pin 27 D11
Pin 5 <-> Pin 28 D12
Pin 6 <-> Pin 29 D13
Pin 7 <-> Pin 30 D14
Pin 8 <-> Pin 31 D15
Pin 9 <-- Pin 208 CS4 Expansion select 4 (PCMCIA 0)
Pin 10 <-- Pin 1 CS5 Expansion select 5 (PCMCIA 1)
Pin 11 <-- Pin 206 NCS2 ROM select 2 (Etna registers)
Pin 12 GND
Pin 13 VCC
Pin 14 --> Pin 45 BVD2 -SPKR n/a or speaker
Pin 15 --> Pin 45 BVD2 -SPKR n/a or speaker
Pin 16 <-- Pin 24 WP -IOIS16 Write protect or 16-bit I/O
Pin 17 <-- Pin 42 -WAIT Wait
Pin 18 <-- Pin 33 -VS1 Voltage select 1
Pin 19 <-- Pin 40 -VS2 Voltage select 2
Pin 20 <-- Pin 26 -CD1 Card detect (grounded in CF)
Pin 21 Pin 50 GND
Pin 22 <-- Pin 37 RDY/-BSY -IREQ Card ready or interrupt REQ
Pin 23
Pin 100 <-- Pin 25 -CD2 Card detect (grounded in CF)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dev/pdf/ps7110db.pdf Normal file

Binary file not shown.

212
dev/pdf/psion_mails.txt Normal file
View File

@ -0,0 +1,212 @@
These are emails from an employee at Psion who worked on the 5mx and
provide some technical information. Thanks to Tony <tony@atomide.com> for
forwarding me these.
Date: Tue, 08 Aug 2000 20:52:12 +0100
From: Atish Nazir <hashaday@littleworld.freeserve.co.uk>
To: Peter Liniker <pl198@doc.ic.ac.uk>
Subject: Re: [Linux-7110-psion] psion5mx (fwd)
re:
---
> * the memory map
---
be more specific. what would you like to access?
re:
---
> * MMU details, esp. EPOC's MMU usage, so that ArLo can load the kernel
> into memory, initialise FiPaBoL and start it
---
hard one, because i'm not too clued up on that aspect of base. one
solution would be to install yourself as a "PartnerOS" - something EPOC
does have a provision for for the Philips smart phone of years ago.
documentation is very sparse though.
re:
---
> * ROM/serial/CF boot mechanism (latter two netbook only)
---
hehehe boss and i wrote this bit :o) protocol is basically YModem with
a few optional extras - i.e. any terminal program will be okay. the
exact specifics of the S7 client is unknown to me as a contractor at
Enterprise wrote it (a perpetually up beat guy).
re:
---
> * ROM/RAM speeds
---
varies according to machine _and_ when it was built in production
cycle. i.e. early machines have flash and later we switch to mask ROM
(with a small patch flash, should it be needed).
re:
---
> * interrupt handling
---
erm, it works...
re:
---
> * all the device interface specs:
> -- CF slot/card
---
function spec for ETNA - i'll find out, whom you have to speak about
this or whether i can release this (quite possible, but remember to say
thank you).
re:
---
> -- PCMCIA slot/card
---
functional spec for ASIC14 - ask Enterprise.
re:
---
> -- sound in/out, audio codecs
---
5, 5mx and Revo, sound out is identical (same drivers used in fact).
except on Revo, there's a slight pin move (can't remember what however,
it wasn't the buzzline). Revo sounds record is obviously disabled...
S7, go ask Enterprise...
re:
---
> -- screen
---
Eiger and Windermere have similar, but certainly different LCD
controllers on board - you'll have to change you device driver. i can't
give more details, because i don't know any more here - never worked on
that aspect.
re:
---
> -- pointer
---
ADC talks directly to main ASIC via SSP interface (changed on 5mx)
re:
---
> -- serial
---
UARTs integrated on main ASICS. Eiger only had one, Windy has two.
re:
---
> -- irda
---
see the bit about UARTs - same UARTs used for RS232 and talking to
IRDA.
re:
---
> -- power management/monitoring
---
hmm. 5, 5mx have voltmeters (same ADC as pointer). Revo has dedicated
current counter, talks via GPIO to main ASIC with a very slow
asynchronous serial protocol.
re:
---
> -- timers
> * Which of these are the same as series5?
---
same as before.
re:
---
> * Config used for the SA1100 and support.
---
how many ports are going here? the people to contact would be Psion
Enterprise as it's really more their turf.
re:
---
> * "ETNA" specs (this is the main ASIC, AFAIK)
---
no, rubbish. ETNA is a helper ASIC. chip code names: Eiger,
Windermere and SA1100 (affectionately known as Sally), which correspond
to 5, 5mx and Revo, and S7 and Net book.
re:
---
> * We'd also like the ER5 DDK info/headers - enough to compile arlo
> "properly".
---
you'll need the E32 tree, this comes with the OCK and DDK. since i use
the OCK (something only available to licensees of Symbian), i wouldn't
know how to obtain a copy of the DDK from Symbian (other than asking
nicely, but i can't imagine that working when they inevitably ask why
you want it). soz. been speaking to bossman and it looks like you'll
have to become a Symbian licencee / partner - PSION can't help you here
because it will violate our agreement with the collective.
IF YOU'RE INTERESTED:
if one individual is prepared to sign an NDA and many other evil
agreements (IPR etc) we have, i _might_ (not a promise, a lot of red
tape would have to be cleared and i'd have to speak to a lot of people)
be able to provide the full Windermere spec for free.
however if a few people are London based, what may a more attractive
solution, a few members of the systems team could give a short seminar
or something along those lines, answering questions in person, giving
the vital information and so forth...
n.b. both these proposals have to be confirmed with other powers that
be.
--- --- ---
.~. the way of the Sacred Penguin is the path of
/V\ the truly righteous...
// \\/
/( ) hashaday@littleworld.freeserve.co.uk
^`~'^ http://thor.prohosting.com/~hashaday/
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
http://lists.sourceforge.net/mailman/listinfo/linux-7110-psion
---------- Forwarded message ----------
Date: Tue, 08 Aug 2000 18:45:00 +0100
From: Atish Nazir <hashaday@littleworld.freeserve.co.uk>
To: Peter Liniker <pl198@doc.ic.ac.uk>
Subject: Re: [Linux-7110-psion] psion5mx (fwd)
re:
---
> Etna is the S5 ASIC, AFAIK.
---
ETNA (aka ASIC12) is the _helper_ ASIC for Eiger (S5) and Windermere
(5MX). it adds CF capabilities and some other gubbins. basically it
adds more pins to the CPU.
re:
---
> Is the S5mx/7 ASIC called Etna? (Although you may not be able to answer
> this!)
---
the S7 and NetBook uses ASIC14 (aka "that many legged bastard"), which
has nothing really in common with ETNA other than it was designed by the
same guy (and uses same VHDL for the timers, copy and paste is a
wonderful thing). it's also a helper ASIC, the exact specifics i can't
be sure of because Enterprise have done a lot of developmental work on
it...
--- --- ---
.~. the way of the Sacred Penguin is the path of
/V\ the truly righteous...
// \\/
/( ) hashaday@littleworld.freeserve.co.uk
^`~'^ http://thor.prohosting.com/~hashaday/
_______________________________________________
Linux-7110-psion mailing list
Linux-7110-psion@lists.sourceforge.net
http://lists.sourceforge.net/mailman/listinfo/linux-7110-psion

8
dev/pdf/readme.txt Normal file
View File

@ -0,0 +1,8 @@
ps7110db.pdf - 7110 processor data sheet
msm7717_01_02_03.pdf - 7717 CODEC sound chip
sbas090a.pdf - 7843 ADC chip (touchscreen/battery monitor)
psion_mails.txt - Emails from a Psion Employee providing some
technical insight..
battery_info.txt - Results of hacking with the ADC in order to read
the battery level.

BIN
dev/pdf/sbas090a.pdf Normal file

Binary file not shown.

BIN
dev/pdf/thumbquickref.pdf Normal file

Binary file not shown.

360
dev/psionw_sound.c Normal file
View File

@ -0,0 +1,360 @@
/*
Driver for PsionW Sound output
(c) 2002 Simon Howard
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.
*/
/* TODO:
*
* - Microphone support
* - /dev/mixer support
*/
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/sound.h>
#include <linux/soundcard.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/hardware/psionw.h>
#include <asm/arch/irqs.h>
#include <asm/arch/psionw-power.h>
#include "ulaw.h"
/* these ought to be in the hardware headers: */
#define CODOUTEN (1 << 0)
#define CODINEN (1 << 1)
#define SAMPLE_RATE 8000 /* this cant be changed */
static int users;
static struct semaphore users_lock;
extern void enable_irq(unsigned int irq);
extern void disable_irq(unsigned int irq);
static int audio_dev;
/* buffer size */
#define BUFSIZE 128
/* lock for access to writebuf. the interrupt handler does not check
* for this but interrupts are also disabled while we access writebuf
* in write
*/
static struct semaphore writebuf_lock;
/* freelist for buffering data */
static unsigned char writebuf[BUFSIZE];
static int writebuf_head, writebuf_tail, writebuf_size;
/* interrupt routine */
void psionw_sound_isr(unsigned int irq)
{
int i, count;
/* write some more data to the speaker */
count = writebuf_size < 8 ? writebuf_size : 8;
for (i=0; i<count; ++i) {
psionw_writeb(dsp_ulaw[writebuf[writebuf_head]], CODR);
writebuf_head = (writebuf_head + 1) % BUFSIZE;
}
for (; i<8; ++i) {
psionw_writeb(0, CODR);
}
writebuf_size -= count;
/* if we had nothing left, stop interrupts until we
* get more (set in the write function)
*/
if (count == 0)
disable_irq(IRQ_CSINT);
/* clear interrupt */
psionw_writel(1, COEOI);
}
static ssize_t psionw_sound_read(struct file *file, char *buffer,
size_t count, loff_t *ppos)
{
/* insert microphone code here */
return count;
}
static ssize_t psionw_sound_write(struct file *file, const char *buffer,
size_t count, loff_t *ppos)
{
int i, n, ret = 0;
while (count > 0) {
/* check we can fit anything into the buffer */
if (writebuf_size >= BUFSIZE) {
if (file->f_flags & O_NONBLOCK)
break;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
continue;
}
down(&writebuf_lock);
/* disable irq while we do this */
disable_irq(IRQ_CSINT);
/* fit in as much as we can to the write buffer */
if (count > BUFSIZE - writebuf_size)
n = BUFSIZE - writebuf_size;
else
n = count;
/* this is complicated stuff to add to the buffer in blocks
* rather than byte-by-byte, for speed
* we dont want to disable the sound IRQ for too long or we
* get nasty breaks in the sound
*/
if (writebuf_tail >= writebuf_head) {
/* fill in as much as possible at the end */
i = BUFSIZE - writebuf_tail;
if (i >= n) {
/* we can fit them all at the end */
memcpy(writebuf + writebuf_tail, buffer, n);
} else {
/* first part at the end of buffer */
memcpy(writebuf + writebuf_tail, buffer, i);
/* second part at the beginning */
memcpy(writebuf, buffer+i, n-i);
}
} else {
/* just fit in as much as we can */
memcpy(writebuf + writebuf_tail, buffer, n);
}
writebuf_tail = (writebuf_tail + n) % BUFSIZE;
writebuf_size += n;
count -= n;
buffer += n;
ret += n;
/* enable irq again */
enable_irq(IRQ_CSINT);
up(&writebuf_lock);
}
if (file->f_flags & O_NONBLOCK && ret == 0)
return -EAGAIN;
return ret;
}
static int psionw_sound_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
int val;
switch (cmd) {
case OSS_GETVERSION:
return put_user(SOUND_VERSION, (int *)arg);
case SNDCTL_DSP_RESET:
return 0;
case SNDCTL_DSP_SYNC:
/* we cant really do this, but we'll pretend
* we can, to keep programs that use it happy
*/
return 0;
case SNDCTL_DSP_SPEED: /* set sample rate */
/* we cant change it */
if (get_user(val, (int *)arg))
return -EFAULT;
if (val >= 0)
return put_user(SAMPLE_RATE, (int *)arg);
else
return -EFAULT;
case SNDCTL_DSP_STEREO: /* set stereo or mono */
if (get_user(val, (int *)arg))
return -EFAULT;
/* we are stuck in mono mode */
if (val)
printk("psionw_sound: attempt to put in stereo mode (unsupported)\n");
return 0;
case SNDCTL_DSP_GETBLKSIZE:
return put_user(8, (int *)arg); /* 8 byte block size (?) */
case SNDCTL_DSP_GETFMTS:
return put_user(AFMT_U8, (int *)arg);
case SNDCTL_DSP_SETFMT:
return put_user(AFMT_U8, (int *)arg);
case SNDCTL_DSP_CHANNELS: /* set channels */
return put_user(1, (int *) arg);
case SNDCTL_DSP_NONBLOCK:
file->f_flags |= O_NONBLOCK;
}
return -EINVAL;
}
static int psionw_sound_open(struct inode *inode, struct file *file)
{
down(&users_lock);
if (users > 0) {
up(&users_lock);
return -EBUSY;
}
++users;
/* empty list */
writebuf_head = writebuf_tail = writebuf_size = 0;
/* enable codec */
psionw_writeb(psionw_readb(PDDR) | PDDR_AMPEN | PDDR_CDE, PDDR);
psionw_writel(psionw_readl(CONFG) | CODINEN | CODOUTEN, CONFG);
/* enable sound irq */
irq_desc[IRQ_CSINT].mask_ack = psionw_sound_isr;
enable_irq(IRQ_CSINT);
up(&users_lock);
return 0;
}
static int psionw_sound_release(struct inode *inode, struct file *file)
{
down(&users_lock);
--users;
/* disable codec */
psionw_writeb(psionw_readb(PDDR) & ~(PDDR_AMPEN|PDDR_CDE), PDDR);
psionw_writel(psionw_readl(CONFG) & ~(CODINEN|CODOUTEN), CONFG);
/* disable sound irq */
disable_irq(IRQ_CSINT);
up(&users_lock);
return 0;
}
static int psionw_sound_mmap(struct file *file, struct vm_area_struct *vma)
{
return -ENODEV;
}
static struct file_operations sound_ops = {
owner: THIS_MODULE,
llseek: no_llseek,
read: psionw_sound_read,
write: psionw_sound_write,
ioctl: psionw_sound_ioctl,
mmap: psionw_sound_mmap,
open: psionw_sound_open,
release: psionw_sound_release,
};
int __init init_psionw_sound(void)
{
audio_dev = register_sound_dsp(&sound_ops, -1);
if (audio_dev < 0) {
printk(KERN_ERR "psionw_sound: cannot register sound device\n");
return -ENODEV;
}
init_MUTEX(&writebuf_lock);
init_MUTEX(&users_lock);
printk("psionw_sound: initialised sound output\n");
return 0;
}
void __exit cleanup_psionw_sound(void)
{
unregister_sound_dsp(audio_dev);
}
MODULE_DESCRIPTION("psionw sound output driver");
MODULE_AUTHOR("Simon Howard");
MODULE_LICENSE("GPL");
module_init(init_psionw_sound);
module_exit(cleanup_psionw_sound);