1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * iohelper.h 4*4882a593Smuzhiyun * helper for define functions to access ISDN hardware 5*4882a593Smuzhiyun * supported are memory mapped IO 6*4882a593Smuzhiyun * indirect port IO (one port for address, one for data) 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Author Karsten Keil <keil@isdn4linux.de> 9*4882a593Smuzhiyun * 10*4882a593Smuzhiyun * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun 13*4882a593Smuzhiyun #ifndef _IOHELPER_H 14*4882a593Smuzhiyun #define _IOHELPER_H 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun typedef u8 (read_reg_func)(void *hwp, u8 offset); 17*4882a593Smuzhiyun typedef void (write_reg_func)(void *hwp, u8 offset, u8 value); 18*4882a593Smuzhiyun typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size); 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun struct _ioport { 21*4882a593Smuzhiyun u32 port; 22*4882a593Smuzhiyun u32 ale; 23*4882a593Smuzhiyun }; 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #define IOFUNC_IO(name, hws, ap) \ 26*4882a593Smuzhiyun static u8 Read##name##_IO(void *p, u8 off) { \ 27*4882a593Smuzhiyun struct hws *hw = p; \ 28*4882a593Smuzhiyun return inb(hw->ap.port + off); \ 29*4882a593Smuzhiyun } \ 30*4882a593Smuzhiyun static void Write##name##_IO(void *p, u8 off, u8 val) { \ 31*4882a593Smuzhiyun struct hws *hw = p; \ 32*4882a593Smuzhiyun outb(val, hw->ap.port + off); \ 33*4882a593Smuzhiyun } \ 34*4882a593Smuzhiyun static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ 35*4882a593Smuzhiyun struct hws *hw = p; \ 36*4882a593Smuzhiyun insb(hw->ap.port + off, dp, size); \ 37*4882a593Smuzhiyun } \ 38*4882a593Smuzhiyun static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ 39*4882a593Smuzhiyun struct hws *hw = p; \ 40*4882a593Smuzhiyun outsb(hw->ap.port + off, dp, size); \ 41*4882a593Smuzhiyun } 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #define IOFUNC_IND(name, hws, ap) \ 44*4882a593Smuzhiyun static u8 Read##name##_IND(void *p, u8 off) { \ 45*4882a593Smuzhiyun struct hws *hw = p; \ 46*4882a593Smuzhiyun outb(off, hw->ap.ale); \ 47*4882a593Smuzhiyun return inb(hw->ap.port); \ 48*4882a593Smuzhiyun } \ 49*4882a593Smuzhiyun static void Write##name##_IND(void *p, u8 off, u8 val) { \ 50*4882a593Smuzhiyun struct hws *hw = p; \ 51*4882a593Smuzhiyun outb(off, hw->ap.ale); \ 52*4882a593Smuzhiyun outb(val, hw->ap.port); \ 53*4882a593Smuzhiyun } \ 54*4882a593Smuzhiyun static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ 55*4882a593Smuzhiyun struct hws *hw = p; \ 56*4882a593Smuzhiyun outb(off, hw->ap.ale); \ 57*4882a593Smuzhiyun insb(hw->ap.port, dp, size); \ 58*4882a593Smuzhiyun } \ 59*4882a593Smuzhiyun static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ 60*4882a593Smuzhiyun struct hws *hw = p; \ 61*4882a593Smuzhiyun outb(off, hw->ap.ale); \ 62*4882a593Smuzhiyun outsb(hw->ap.port, dp, size); \ 63*4882a593Smuzhiyun } 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define IOFUNC_MEMIO(name, hws, typ, adr) \ 66*4882a593Smuzhiyun static u8 Read##name##_MIO(void *p, u8 off) { \ 67*4882a593Smuzhiyun struct hws *hw = p; \ 68*4882a593Smuzhiyun return readb(((typ *)hw->adr) + off); \ 69*4882a593Smuzhiyun } \ 70*4882a593Smuzhiyun static void Write##name##_MIO(void *p, u8 off, u8 val) { \ 71*4882a593Smuzhiyun struct hws *hw = p; \ 72*4882a593Smuzhiyun writeb(val, ((typ *)hw->adr) + off); \ 73*4882a593Smuzhiyun } \ 74*4882a593Smuzhiyun static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ 75*4882a593Smuzhiyun struct hws *hw = p; \ 76*4882a593Smuzhiyun while (size--) \ 77*4882a593Smuzhiyun *dp++ = readb(((typ *)hw->adr) + off); \ 78*4882a593Smuzhiyun } \ 79*4882a593Smuzhiyun static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ 80*4882a593Smuzhiyun struct hws *hw = p; \ 81*4882a593Smuzhiyun while (size--) \ 82*4882a593Smuzhiyun writeb(*dp++, ((typ *)hw->adr) + off); \ 83*4882a593Smuzhiyun } 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun #define ASSIGN_FUNC(typ, name, dest) do { \ 86*4882a593Smuzhiyun dest.read_reg = &Read##name##_##typ; \ 87*4882a593Smuzhiyun dest.write_reg = &Write##name##_##typ; \ 88*4882a593Smuzhiyun dest.read_fifo = &ReadFiFo##name##_##typ; \ 89*4882a593Smuzhiyun dest.write_fifo = &WriteFiFo##name##_##typ; \ 90*4882a593Smuzhiyun } while (0) 91*4882a593Smuzhiyun #define ASSIGN_FUNC_IPAC(typ, target) do { \ 92*4882a593Smuzhiyun ASSIGN_FUNC(typ, ISAC, target.isac); \ 93*4882a593Smuzhiyun ASSIGN_FUNC(typ, IPAC, target); \ 94*4882a593Smuzhiyun } while (0) 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun #endif 97