linux/arch/m32r/platforms/opsput/io.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/m32r/platforms/opsput/io.c
   3 *
   4 *  Typical I/O routines for OPSPUT board.
   5 *
   6 *  Copyright (c) 2001-2005  Hiroyuki Kondo, Hirokazu Takata,
   7 *                           Hitoshi Yamamoto, Takeo Takahashi
   8 *
   9 *  This file is subject to the terms and conditions of the GNU General
  10 *  Public License.  See the file "COPYING" in the main directory of this
  11 *  archive for more details.
  12 */
  13
  14#include <asm/m32r.h>
  15#include <asm/page.h>
  16#include <asm/io.h>
  17#include <asm/byteorder.h>
  18
  19#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
  20#include <linux/types.h>
  21
  22#define M32R_PCC_IOMAP_SIZE 0x1000
  23
  24#define M32R_PCC_IOSTART0 0x1000
  25#define M32R_PCC_IOEND0   (M32R_PCC_IOSTART0 + M32R_PCC_IOMAP_SIZE - 1)
  26
  27extern void pcc_ioread_byte(int, unsigned long, void *, size_t, size_t, int);
  28extern void pcc_ioread_word(int, unsigned long, void *, size_t, size_t, int);
  29extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int);
  30extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int);
  31#endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */
  32
  33#define PORT2ADDR(port)         _port2addr(port)
  34#define PORT2ADDR_USB(port)     _port2addr_usb(port)
  35
  36static inline void *_port2addr(unsigned long port)
  37{
  38        return (void *)(port | NONCACHE_OFFSET);
  39}
  40
  41#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
  42static inline void *__port2addr_ata(unsigned long port)
  43{
  44        static int      dummy_reg;
  45
  46        switch (port) {
  47        case 0x1f0:     return (void *)(0x0c002000 | NONCACHE_OFFSET);
  48        case 0x1f1:     return (void *)(0x0c012800 | NONCACHE_OFFSET);
  49        case 0x1f2:     return (void *)(0x0c012002 | NONCACHE_OFFSET);
  50        case 0x1f3:     return (void *)(0x0c012802 | NONCACHE_OFFSET);
  51        case 0x1f4:     return (void *)(0x0c012004 | NONCACHE_OFFSET);
  52        case 0x1f5:     return (void *)(0x0c012804 | NONCACHE_OFFSET);
  53        case 0x1f6:     return (void *)(0x0c012006 | NONCACHE_OFFSET);
  54        case 0x1f7:     return (void *)(0x0c012806 | NONCACHE_OFFSET);
  55        case 0x3f6:     return (void *)(0x0c01200e | NONCACHE_OFFSET);
  56        default:        return (void *)&dummy_reg;
  57        }
  58}
  59#endif
  60
  61/*
  62 * OPSPUT-LAN is located in the extended bus space
  63 * from 0x10000000 to 0x13ffffff on physical address.
  64 * The base address of LAN controller(LAN91C111) is 0x300.
  65 */
  66#define LAN_IOSTART     (0x300 | NONCACHE_OFFSET)
  67#define LAN_IOEND       (0x320 | NONCACHE_OFFSET)
  68static inline void *_port2addr_ne(unsigned long port)
  69{
  70        return (void *)(port + 0x10000000);
  71}
  72static inline void *_port2addr_usb(unsigned long port)
  73{
  74        return (void *)((port & 0x0f) + NONCACHE_OFFSET + 0x10303000);
  75}
  76
  77static inline void delay(void)
  78{
  79        __asm__ __volatile__ ("push r0; \n\t pop r0;" : : :"memory");
  80}
  81
  82/*
  83 * NIC I/O function
  84 */
  85
  86#define PORT2ADDR_NE(port)  _port2addr_ne(port)
  87
  88static inline unsigned char _ne_inb(void *portp)
  89{
  90        return *(volatile unsigned char *)portp;
  91}
  92
  93static inline unsigned short _ne_inw(void *portp)
  94{
  95        return (unsigned short)le16_to_cpu(*(volatile unsigned short *)portp);
  96}
  97
  98static inline void _ne_insb(void *portp, void *addr, unsigned long count)
  99{
 100        unsigned char *buf = (unsigned char *)addr;
 101
 102        while (count--)
 103                *buf++ = _ne_inb(portp);
 104}
 105
 106static inline void _ne_outb(unsigned char b, void *portp)
 107{
 108        *(volatile unsigned char *)portp = b;
 109}
 110
 111static inline void _ne_outw(unsigned short w, void *portp)
 112{
 113        *(volatile unsigned short *)portp = cpu_to_le16(w);
 114}
 115
 116unsigned char _inb(unsigned long port)
 117{
 118        if (port >= LAN_IOSTART && port < LAN_IOEND)
 119                return _ne_inb(PORT2ADDR_NE(port));
 120
 121#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 122        else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 123                return *(volatile unsigned char *)__port2addr_ata(port);
 124        }
 125#endif
 126#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 127        else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 128                unsigned char b;
 129                pcc_ioread_byte(0, port, &b, sizeof(b), 1, 0);
 130                return b;
 131        } else
 132#endif
 133
 134        return *(volatile unsigned char *)PORT2ADDR(port);
 135}
 136
 137unsigned short _inw(unsigned long port)
 138{
 139        if (port >= LAN_IOSTART && port < LAN_IOEND)
 140                return _ne_inw(PORT2ADDR_NE(port));
 141#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 142        else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 143                return *(volatile unsigned short *)__port2addr_ata(port);
 144        }
 145#endif
 146#if defined(CONFIG_USB)
 147        else if(port >= 0x340 && port < 0x3a0)
 148                return *(volatile unsigned short *)PORT2ADDR_USB(port);
 149#endif
 150#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 151        else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 152                unsigned short w;
 153                pcc_ioread_word(0, port, &w, sizeof(w), 1, 0);
 154                return w;
 155        } else
 156#endif
 157        return *(volatile unsigned short *)PORT2ADDR(port);
 158}
 159
 160unsigned long _inl(unsigned long port)
 161{
 162#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 163        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 164                unsigned long l;
 165                pcc_ioread_word(0, port, &l, sizeof(l), 1, 0);
 166                return l;
 167        } else
 168#endif
 169        return *(volatile unsigned long *)PORT2ADDR(port);
 170}
 171
 172unsigned char _inb_p(unsigned long port)
 173{
 174        unsigned char v = _inb(port);
 175        delay();
 176        return (v);
 177}
 178
 179unsigned short _inw_p(unsigned long port)
 180{
 181        unsigned short v = _inw(port);
 182        delay();
 183        return (v);
 184}
 185
 186unsigned long _inl_p(unsigned long port)
 187{
 188        unsigned long v = _inl(port);
 189        delay();
 190        return (v);
 191}
 192
 193void _outb(unsigned char b, unsigned long port)
 194{
 195        if (port >= LAN_IOSTART && port < LAN_IOEND)
 196                _ne_outb(b, PORT2ADDR_NE(port));
 197        else
 198#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 199        if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 200                *(volatile unsigned char *)__port2addr_ata(port) = b;
 201        } else
 202#endif
 203#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 204        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 205                pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0);
 206        } else
 207#endif
 208                *(volatile unsigned char *)PORT2ADDR(port) = b;
 209}
 210
 211void _outw(unsigned short w, unsigned long port)
 212{
 213        if (port >= LAN_IOSTART && port < LAN_IOEND)
 214                _ne_outw(w, PORT2ADDR_NE(port));
 215        else
 216#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 217        if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 218                *(volatile unsigned short *)__port2addr_ata(port) = w;
 219        } else
 220#endif
 221#if defined(CONFIG_USB)
 222        if(port >= 0x340 && port < 0x3a0)
 223                *(volatile unsigned short *)PORT2ADDR_USB(port) = w;
 224        else
 225#endif
 226#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 227        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 228                pcc_iowrite_word(0, port, &w, sizeof(w), 1, 0);
 229        } else
 230#endif
 231                *(volatile unsigned short *)PORT2ADDR(port) = w;
 232}
 233
 234void _outl(unsigned long l, unsigned long port)
 235{
 236#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 237        if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 238                pcc_iowrite_word(0, port, &l, sizeof(l), 1, 0);
 239        } else
 240#endif
 241        *(volatile unsigned long *)PORT2ADDR(port) = l;
 242}
 243
 244void _outb_p(unsigned char b, unsigned long port)
 245{
 246        _outb(b, port);
 247        delay();
 248}
 249
 250void _outw_p(unsigned short w, unsigned long port)
 251{
 252        _outw(w, port);
 253        delay();
 254}
 255
 256void _outl_p(unsigned long l, unsigned long port)
 257{
 258        _outl(l, port);
 259        delay();
 260}
 261
 262void _insb(unsigned int port, void *addr, unsigned long count)
 263{
 264        if (port >= LAN_IOSTART && port < LAN_IOEND)
 265                _ne_insb(PORT2ADDR_NE(port), addr, count);
 266#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 267        else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 268                unsigned char *buf = addr;
 269                unsigned char *portp = __port2addr_ata(port);
 270                while (count--)
 271                        *buf++ = *(volatile unsigned char *)portp;
 272        }
 273#endif
 274#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 275        else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 276                pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char),
 277                                count, 1);
 278        }
 279#endif
 280        else {
 281                unsigned char *buf = addr;
 282                unsigned char *portp = PORT2ADDR(port);
 283                while (count--)
 284                        *buf++ = *(volatile unsigned char *)portp;
 285        }
 286}
 287
 288void _insw(unsigned int port, void *addr, unsigned long count)
 289{
 290        unsigned short *buf = addr;
 291        unsigned short *portp;
 292
 293        if (port >= LAN_IOSTART && port < LAN_IOEND) {
 294                /*
 295                 * This portion is only used by smc91111.c to read data
 296                 * from the DATA_REG. Do not swap the data.
 297                 */
 298                portp = PORT2ADDR_NE(port);
 299                while (count--)
 300                        *buf++ = *(volatile unsigned short *)portp;
 301#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 302        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 303                pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short),
 304                                count, 1);
 305#endif
 306#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 307        } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 308                portp = __port2addr_ata(port);
 309                while (count--)
 310                        *buf++ = *(volatile unsigned short *)portp;
 311#endif
 312        } else {
 313                portp = PORT2ADDR(port);
 314                while (count--)
 315                        *buf++ = *(volatile unsigned short *)portp;
 316        }
 317}
 318
 319void _insl(unsigned int port, void *addr, unsigned long count)
 320{
 321        unsigned long *buf = addr;
 322        unsigned long *portp;
 323
 324        portp = PORT2ADDR(port);
 325        while (count--)
 326                *buf++ = *(volatile unsigned long *)portp;
 327}
 328
 329void _outsb(unsigned int port, const void *addr, unsigned long count)
 330{
 331        const unsigned char *buf = addr;
 332        unsigned char *portp;
 333
 334        if (port >= LAN_IOSTART && port < LAN_IOEND) {
 335                portp = PORT2ADDR_NE(port);
 336                while (count--)
 337                        _ne_outb(*buf++, portp);
 338#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 339        } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 340                portp = __port2addr_ata(port);
 341                while (count--)
 342                        *(volatile unsigned char *)portp = *buf++;
 343#endif
 344#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 345        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 346                pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char),
 347                                 count, 1);
 348#endif
 349        } else {
 350                portp = PORT2ADDR(port);
 351                while (count--)
 352                        *(volatile unsigned char *)portp = *buf++;
 353        }
 354}
 355
 356void _outsw(unsigned int port, const void *addr, unsigned long count)
 357{
 358        const unsigned short *buf = addr;
 359        unsigned short *portp;
 360
 361        if (port >= LAN_IOSTART && port < LAN_IOEND) {
 362                /*
 363                 * This portion is only used by smc91111.c to write data
 364                 * into the DATA_REG. Do not swap the data.
 365                 */
 366                portp = PORT2ADDR_NE(port);
 367                while (count--)
 368                        *(volatile unsigned short *)portp = *buf++;
 369#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 370        } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) {
 371                portp = __port2addr_ata(port);
 372                while (count--)
 373                        *(volatile unsigned short *)portp = *buf++;
 374#endif
 375#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC)
 376        } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) {
 377                pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short),
 378                                 count, 1);
 379#endif
 380        } else {
 381                portp = PORT2ADDR(port);
 382                while (count--)
 383                        *(volatile unsigned short *)portp = *buf++;
 384        }
 385}
 386
 387void _outsl(unsigned int port, const void *addr, unsigned long count)
 388{
 389        const unsigned long *buf = addr;
 390        unsigned char *portp;
 391
 392        portp = PORT2ADDR(port);
 393        while (count--)
 394                *(volatile unsigned long *)portp = *buf++;
 395}
 396