1/* 2 * arch/sh/boards/renesas/edosk7705/io.c 3 * 4 * Copyright (C) 2001 Ian da Silva, Jeremy Siegel 5 * Based largely on io_se.c. 6 * 7 * I/O routines for Hitachi EDOSK7705 board. 8 * 9 */ 10 11#include <linux/kernel.h> 12#include <linux/types.h> 13#include <asm/io.h> 14#include <asm/edosk7705/io.h> 15#include <asm/addrspace.h> 16 17#define SMC_IOADDR 0xA2000000 18 19#define maybebadio(name,port) \ 20 printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ 21 #name, (port), (__u32) __builtin_return_address(0)) 22 23/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */ 24unsigned long sh_edosk7705_isa_port2addr(unsigned long port) 25{ 26 if (port >= 0x300 && port < 0x320) { 27 /* SMC91C96 registers are 4 byte aligned rather than the 28 * usual 2 byte! 29 */ 30 return SMC_IOADDR + ( (port - 0x300) * 2); 31 } 32 33 maybebadio(sh_edosk7705_isa_port2addr, port); 34 return port; 35} 36 37/* Trying to read / write bytes on odd-byte boundaries to the Ethernet 38 * registers causes problems. So we bit-shift the value and read / write 39 * in 2 byte chunks. Setting the low byte to 0 does not cause problems 40 * now as odd byte writes are only made on the bit mask / interrupt 41 * register. This may not be the case in future Mar-2003 SJD 42 */ 43unsigned char sh_edosk7705_inb(unsigned long port) 44{ 45 if (port >= 0x300 && port < 0x320 && port & 0x01) { 46 return (volatile unsigned char)(generic_inw(port -1) >> 8); 47 } 48 return *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port); 49} 50 51unsigned int sh_edosk7705_inl(unsigned long port) 52{ 53 return *(volatile unsigned long *)port; 54} 55 56void sh_edosk7705_outb(unsigned char value, unsigned long port) 57{ 58 if (port >= 0x300 && port < 0x320 && port & 0x01) { 59 generic_outw(((unsigned short)value << 8), port -1); 60 return; 61 } 62 *(volatile unsigned char *)sh_edosk7705_isa_port2addr(port) = value; 63} 64 65void sh_edosk7705_outl(unsigned int value, unsigned long port) 66{ 67 *(volatile unsigned long *)port = value; 68} 69 70void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count) 71{ 72 unsigned char *p = addr; 73 while (count--) *p++ = sh_edosk7705_inb(port); 74} 75 76void sh_edosk7705_insl(unsigned long port, void *addr, unsigned long count) 77{ 78 unsigned long *p = (unsigned long*)addr; 79 while (count--) 80 *p++ = *(volatile unsigned long *)port; 81} 82 83void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count) 84{ 85 unsigned char *p = (unsigned char*)addr; 86 while (count--) sh_edosk7705_outb(*p++, port); 87} 88 89void sh_edosk7705_outsl(unsigned long port, const void *addr, unsigned long count) 90{ 91 unsigned long *p = (unsigned long*)addr; 92 while (count--) sh_edosk7705_outl(*p++, port); 93} 94