Yan,
May I suggest "Linux Device Drivers" from O'Reilly.
You can read it at http://www.oreilly.com/catalog/linuxdrive3/book/index.csp
That is the third edition, which is 2.6 specific.
Here's the second edition: http://www.xml.com/ldd/chapter/book/index.html
I suspect you're having problems because you're not page aligned.
This is from the above book, and should give you a hint:
/* Remap a not (necessarily) aligned port region */ void *short_remap(unsigned long phys_addr) { /* The code comes mainly from arch/any/mm/ioremap.c */ unsigned long offset, last_addr, size;
last_addr = phys_addr + SHORT_NR_PORTS - 1; offset = phys_addr & ~PAGE_MASK; /* Adjust the begin and end to remap a full page */ phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr) - phys_addr;
return ioremap(phys_addr, size) + offset; }
Rich
On 3/16/06, Yan Seiner <> wrote:
I've started down the rocky path of writing a module for GPIO
irq-driven access....
This is the first time I've tried to write a kernel module, and I'm a
bit stuck...
The following code should spit out the 4 registers of a TSDIO24 card
every time you read major device 253... (You have to compile and load
the module: arm-linux-gcc -D__KERNEL__ -DMODULE
-I/usr/local/src/linux24/include -O -Wall -c -o gpio.o gpio.c )
And in fact it does spit out 4 bytes, which occasionally change in
value. But alas they don't have any connection to what should be in
the registers....
I can't find any docs on ioremap, readb, or readw... So I am flying
blind. If anyone has a bit of time and knows something about kernel
2.4 modules, I would appreciate some advice....
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <asm-arm/io.h>
#define TSDIO24region 0x11e00104
#define TSDIO24length 4
#define TSDIO24ctrl 0x11e00104
#define TSDIO24regA 0x11e00105
#define TSDIO24regB 0x11e00106
#define TSDIO24regC 0x11e00107
// device numbers
// major - 253
// minor:
// 0 - ctrl
// 1 - regA
// 2 - regB
// 3 - regC
#define TSDIO24major 253
static char *mem_virt_addr;
static ssize_t tsdio24_write(struct file *file, const char *buf,
size_t length, loff_t *ppos)
{
printk("<1>in write\n");
return 0;
}
static ssize_t tsdio24_read(struct file *file, char *buf, size_t
length, loff_t *ppos)
{
printk("0x%02x %02x %02x %02x\n",
readb(mem_virt_addr),
readb(mem_virt_addr+1),
readb(mem_virt_addr+2),
readb(mem_virt_addr+3));
return 0;
}
static struct file_operations tsdio24_fops = {
write: tsdio24_write,
read: tsdio24_read
};
int init_TSgpio(void)
{
int result;
printk("<1>Hello world.\n");
if (check_mem_region(TSDIO24region, TSDIO24length))
{
printk("TSgpio: memory already in use\n");
return -EBUSY;
}
request_mem_region(TSDIO24region, TSDIO24length, "TSDIO24gpio");
if( (result = register_chrdev(TSDIO24major, "TSDIO24",
&tsdio24_fops)) < 0)
{
printk(KERN_WARNING "tsdio24: can't get major %d\n",TSDIO24major);
return result;
}
mem_virt_addr = ioremap(TSDIO24region, TSDIO24length);
return 0;
}
void exit_TSgpio(void)
{
iounmap(mem_virt_addr);
unregister_chrdev(TSDIO24major,"TSDIO24");
release_mem_region(TSDIO24region, TSDIO24length);
printk("<1>Goodbye, cruel world.\n");
}
module_init(init_TSgpio);
module_exit(exit_TSgpio);
SPONSORED LINKS
YAHOO! GROUPS LINKS
- Visit your group "ts-7000" on the web.
- To unsubscribe from this group, send an email to:
=Unsubscribe
- Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
-- Rich Wilson
425-337-7129
SPONSORED LINKS
YAHOO! GROUPS LINKS
- Visit your group "ts-7000" on the web.
- To unsubscribe from this group, send an email to:
=Unsubscribe
- Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
|