EmbeddedRelated.com
Forums

How to map physical address of cs8900a under linux device driver?

Started by Aimingoo May 23, 2006
As we all know that the standard linux kernel does not allow us to access
physical address of devices, so the physical address must be converted to
virtual address before any IO operation. In my disign, the cs8900a is
configured for IO mode, its bus physical address is 0x1001_0000, and its
default IO base address is 0x300.
Now, problem is, how can I get the virtual address of the cs8900a under my
device driver?
The code below can't work correctly.
static unsigned int virt_base;
		
		{
			if(check_mem_region(0x10010300, 0x10)){
				printk(KERN_INFO "CS8900A: memory already in use\n");
			} else 
				request_mem_region(0x10010300, 0x10, "CS8900A");
		}
		virt_base = (unsigned int)ioremap(0x10010300, 0x10); // 16 bytes
                // get signature
		writew(0x0000, virt_base+0x0a);
		mdelay(100);
		printk(KERN_INFO "CS8900A :  0x%lx\n", readw(virt_base+0x0c));


I appreciate anyone who help this.

What processor architecture?
You may have to play with some page bits/properties

Aimingoo wrote:
> As we all know that the standard linux kernel does not allow us to access > physical address of devices, so the physical address must be converted to > virtual address before any IO operation. In my disign, the cs8900a is > configured for IO mode, its bus physical address is 0x1001_0000, and its > default IO base address is 0x300. > Now, problem is, how can I get the virtual address of the cs8900a under my
Hi Aimingoo.

> As we all know that the standard linux kernel does not allow us to access > physical address of devices, so the physical address must be converted to > virtual address before any IO operation.
Only if it's memory mapped I/O. True I/O, accesses through I/O rather than memory instructions (or routines like inb, outb) doesn't require a virtual address.
> In my disign, the cs8900a is > configured for IO mode, its bus physical address is 0x1001_0000, and its > default IO base address is 0x300. > > <snip> > > virt_base = (unsigned int)ioremap(0x10010300, 0x10); // 16 bytes
ioremap() is only used if the device is in memory mapped I/O. You mention using the device in IO mode, so just use the raw address with inb(), outb() and the like. Also, you might want to check the address you've mentioned. 0x1001_0000 looks like a memory rather than an I/O address. Oh and watch out with the out() routines -- the order of the parameters is backwards in Linux compared to other systems I've worked on (mostly Unix). Regards, Steve ------------------------------------------------------------------------ Steve Schefter phone: +1 705 725 9999 x26 The Software Group Limited fax: +1 705 725 9666 642 Welham Road, Barrie, Ontario CANADA L4N 9A1 Web: www.wanware.com