18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * iohelper.h 48c2ecf20Sopenharmony_ci * helper for define functions to access ISDN hardware 58c2ecf20Sopenharmony_ci * supported are memory mapped IO 68c2ecf20Sopenharmony_ci * indirect port IO (one port for address, one for data) 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Author Karsten Keil <keil@isdn4linux.de> 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Copyright 2009 by Karsten Keil <keil@isdn4linux.de> 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef _IOHELPER_H 148c2ecf20Sopenharmony_ci#define _IOHELPER_H 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_citypedef u8 (read_reg_func)(void *hwp, u8 offset); 178c2ecf20Sopenharmony_ci typedef void (write_reg_func)(void *hwp, u8 offset, u8 value); 188c2ecf20Sopenharmony_ci typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size); 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci struct _ioport { 218c2ecf20Sopenharmony_ci u32 port; 228c2ecf20Sopenharmony_ci u32 ale; 238c2ecf20Sopenharmony_ci }; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define IOFUNC_IO(name, hws, ap) \ 268c2ecf20Sopenharmony_ci static u8 Read##name##_IO(void *p, u8 off) { \ 278c2ecf20Sopenharmony_ci struct hws *hw = p; \ 288c2ecf20Sopenharmony_ci return inb(hw->ap.port + off); \ 298c2ecf20Sopenharmony_ci } \ 308c2ecf20Sopenharmony_ci static void Write##name##_IO(void *p, u8 off, u8 val) { \ 318c2ecf20Sopenharmony_ci struct hws *hw = p; \ 328c2ecf20Sopenharmony_ci outb(val, hw->ap.port + off); \ 338c2ecf20Sopenharmony_ci } \ 348c2ecf20Sopenharmony_ci static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ 358c2ecf20Sopenharmony_ci struct hws *hw = p; \ 368c2ecf20Sopenharmony_ci insb(hw->ap.port + off, dp, size); \ 378c2ecf20Sopenharmony_ci } \ 388c2ecf20Sopenharmony_ci static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) { \ 398c2ecf20Sopenharmony_ci struct hws *hw = p; \ 408c2ecf20Sopenharmony_ci outsb(hw->ap.port + off, dp, size); \ 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define IOFUNC_IND(name, hws, ap) \ 448c2ecf20Sopenharmony_ci static u8 Read##name##_IND(void *p, u8 off) { \ 458c2ecf20Sopenharmony_ci struct hws *hw = p; \ 468c2ecf20Sopenharmony_ci outb(off, hw->ap.ale); \ 478c2ecf20Sopenharmony_ci return inb(hw->ap.port); \ 488c2ecf20Sopenharmony_ci } \ 498c2ecf20Sopenharmony_ci static void Write##name##_IND(void *p, u8 off, u8 val) { \ 508c2ecf20Sopenharmony_ci struct hws *hw = p; \ 518c2ecf20Sopenharmony_ci outb(off, hw->ap.ale); \ 528c2ecf20Sopenharmony_ci outb(val, hw->ap.port); \ 538c2ecf20Sopenharmony_ci } \ 548c2ecf20Sopenharmony_ci static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ 558c2ecf20Sopenharmony_ci struct hws *hw = p; \ 568c2ecf20Sopenharmony_ci outb(off, hw->ap.ale); \ 578c2ecf20Sopenharmony_ci insb(hw->ap.port, dp, size); \ 588c2ecf20Sopenharmony_ci } \ 598c2ecf20Sopenharmony_ci static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) { \ 608c2ecf20Sopenharmony_ci struct hws *hw = p; \ 618c2ecf20Sopenharmony_ci outb(off, hw->ap.ale); \ 628c2ecf20Sopenharmony_ci outsb(hw->ap.port, dp, size); \ 638c2ecf20Sopenharmony_ci } 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci#define IOFUNC_MEMIO(name, hws, typ, adr) \ 668c2ecf20Sopenharmony_ci static u8 Read##name##_MIO(void *p, u8 off) { \ 678c2ecf20Sopenharmony_ci struct hws *hw = p; \ 688c2ecf20Sopenharmony_ci return readb(((typ *)hw->adr) + off); \ 698c2ecf20Sopenharmony_ci } \ 708c2ecf20Sopenharmony_ci static void Write##name##_MIO(void *p, u8 off, u8 val) { \ 718c2ecf20Sopenharmony_ci struct hws *hw = p; \ 728c2ecf20Sopenharmony_ci writeb(val, ((typ *)hw->adr) + off); \ 738c2ecf20Sopenharmony_ci } \ 748c2ecf20Sopenharmony_ci static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ 758c2ecf20Sopenharmony_ci struct hws *hw = p; \ 768c2ecf20Sopenharmony_ci while (size--) \ 778c2ecf20Sopenharmony_ci *dp++ = readb(((typ *)hw->adr) + off); \ 788c2ecf20Sopenharmony_ci } \ 798c2ecf20Sopenharmony_ci static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) { \ 808c2ecf20Sopenharmony_ci struct hws *hw = p; \ 818c2ecf20Sopenharmony_ci while (size--) \ 828c2ecf20Sopenharmony_ci writeb(*dp++, ((typ *)hw->adr) + off); \ 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#define ASSIGN_FUNC(typ, name, dest) do { \ 868c2ecf20Sopenharmony_ci dest.read_reg = &Read##name##_##typ; \ 878c2ecf20Sopenharmony_ci dest.write_reg = &Write##name##_##typ; \ 888c2ecf20Sopenharmony_ci dest.read_fifo = &ReadFiFo##name##_##typ; \ 898c2ecf20Sopenharmony_ci dest.write_fifo = &WriteFiFo##name##_##typ; \ 908c2ecf20Sopenharmony_ci } while (0) 918c2ecf20Sopenharmony_ci#define ASSIGN_FUNC_IPAC(typ, target) do { \ 928c2ecf20Sopenharmony_ci ASSIGN_FUNC(typ, ISAC, target.isac); \ 938c2ecf20Sopenharmony_ci ASSIGN_FUNC(typ, IPAC, target); \ 948c2ecf20Sopenharmony_ci } while (0) 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#endif 97