18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * ds.h -- 16-bit PCMCIA core support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * The initial developer of the original code is David A. Hinds 68c2ecf20Sopenharmony_ci * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 78c2ecf20Sopenharmony_ci * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * (C) 1999 David A. Hinds 108c2ecf20Sopenharmony_ci * (C) 2003 - 2008 Dominik Brodowski 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#ifndef _LINUX_DS_H 148c2ecf20Sopenharmony_ci#define _LINUX_DS_H 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 178c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h> 188c2ecf20Sopenharmony_ci#endif 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#include <pcmcia/device_id.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 238c2ecf20Sopenharmony_ci#include <linux/device.h> 248c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 258c2ecf20Sopenharmony_ci#include <pcmcia/ss.h> 268c2ecf20Sopenharmony_ci#include <linux/atomic.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus 318c2ecf20Sopenharmony_ci * a.k.a. PCI drivers 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_cistruct pcmcia_socket; 348c2ecf20Sopenharmony_cistruct pcmcia_device; 358c2ecf20Sopenharmony_cistruct config_t; 368c2ecf20Sopenharmony_cistruct net_device; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* dynamic device IDs for PCMCIA device drivers. See 398c2ecf20Sopenharmony_ci * Documentation/pcmcia/driver.rst for details. 408c2ecf20Sopenharmony_ci*/ 418c2ecf20Sopenharmony_cistruct pcmcia_dynids { 428c2ecf20Sopenharmony_ci struct mutex lock; 438c2ecf20Sopenharmony_ci struct list_head list; 448c2ecf20Sopenharmony_ci}; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistruct pcmcia_driver { 478c2ecf20Sopenharmony_ci const char *name; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci int (*probe) (struct pcmcia_device *dev); 508c2ecf20Sopenharmony_ci void (*remove) (struct pcmcia_device *dev); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci int (*suspend) (struct pcmcia_device *dev); 538c2ecf20Sopenharmony_ci int (*resume) (struct pcmcia_device *dev); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci struct module *owner; 568c2ecf20Sopenharmony_ci const struct pcmcia_device_id *id_table; 578c2ecf20Sopenharmony_ci struct device_driver drv; 588c2ecf20Sopenharmony_ci struct pcmcia_dynids dynids; 598c2ecf20Sopenharmony_ci}; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* driver registration */ 628c2ecf20Sopenharmony_ciint pcmcia_register_driver(struct pcmcia_driver *driver); 638c2ecf20Sopenharmony_civoid pcmcia_unregister_driver(struct pcmcia_driver *driver); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/** 668c2ecf20Sopenharmony_ci * module_pcmcia_driver() - Helper macro for registering a pcmcia driver 678c2ecf20Sopenharmony_ci * @__pcmcia_driver: pcmcia_driver struct 688c2ecf20Sopenharmony_ci * 698c2ecf20Sopenharmony_ci * Helper macro for pcmcia drivers which do not do anything special in module 708c2ecf20Sopenharmony_ci * init/exit. This eliminates a lot of boilerplate. Each module may only use 718c2ecf20Sopenharmony_ci * this macro once, and calling it replaces module_init() and module_exit(). 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci#define module_pcmcia_driver(__pcmcia_driver) \ 748c2ecf20Sopenharmony_ci module_driver(__pcmcia_driver, pcmcia_register_driver, \ 758c2ecf20Sopenharmony_ci pcmcia_unregister_driver) 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci/* for struct resource * array embedded in struct pcmcia_device */ 788c2ecf20Sopenharmony_cienum { 798c2ecf20Sopenharmony_ci PCMCIA_IOPORT_0, 808c2ecf20Sopenharmony_ci PCMCIA_IOPORT_1, 818c2ecf20Sopenharmony_ci PCMCIA_IOMEM_0, 828c2ecf20Sopenharmony_ci PCMCIA_IOMEM_1, 838c2ecf20Sopenharmony_ci PCMCIA_IOMEM_2, 848c2ecf20Sopenharmony_ci PCMCIA_IOMEM_3, 858c2ecf20Sopenharmony_ci PCMCIA_NUM_RESOURCES, 868c2ecf20Sopenharmony_ci}; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_cistruct pcmcia_device { 898c2ecf20Sopenharmony_ci /* the socket and the device_no [for multifunction devices] 908c2ecf20Sopenharmony_ci uniquely define a pcmcia_device */ 918c2ecf20Sopenharmony_ci struct pcmcia_socket *socket; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci char *devname; 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci u8 device_no; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* the hardware "function" device; certain subdevices can 988c2ecf20Sopenharmony_ci * share one hardware "function" device. */ 998c2ecf20Sopenharmony_ci u8 func; 1008c2ecf20Sopenharmony_ci struct config_t *function_config; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci struct list_head socket_device_list; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* device setup */ 1058c2ecf20Sopenharmony_ci unsigned int irq; 1068c2ecf20Sopenharmony_ci struct resource *resource[PCMCIA_NUM_RESOURCES]; 1078c2ecf20Sopenharmony_ci resource_size_t card_addr; /* for the 1st IOMEM resource */ 1088c2ecf20Sopenharmony_ci unsigned int vpp; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci unsigned int config_flags; /* CONF_ENABLE_ flags below */ 1118c2ecf20Sopenharmony_ci unsigned int config_base; 1128c2ecf20Sopenharmony_ci unsigned int config_index; 1138c2ecf20Sopenharmony_ci unsigned int config_regs; /* PRESENT_ flags below */ 1148c2ecf20Sopenharmony_ci unsigned int io_lines; /* number of I/O lines */ 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* Is the device suspended? */ 1178c2ecf20Sopenharmony_ci u16 suspended:1; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* Flags whether io, irq, win configurations were 1208c2ecf20Sopenharmony_ci * requested, and whether the configuration is "locked" */ 1218c2ecf20Sopenharmony_ci u16 _irq:1; 1228c2ecf20Sopenharmony_ci u16 _io:1; 1238c2ecf20Sopenharmony_ci u16 _win:4; 1248c2ecf20Sopenharmony_ci u16 _locked:1; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* Flag whether a "fuzzy" func_id based match is 1278c2ecf20Sopenharmony_ci * allowed. */ 1288c2ecf20Sopenharmony_ci u16 allow_func_id_match:1; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* information about this device */ 1318c2ecf20Sopenharmony_ci u16 has_manf_id:1; 1328c2ecf20Sopenharmony_ci u16 has_card_id:1; 1338c2ecf20Sopenharmony_ci u16 has_func_id:1; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci u16 reserved:4; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci u8 func_id; 1388c2ecf20Sopenharmony_ci u16 manf_id; 1398c2ecf20Sopenharmony_ci u16 card_id; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci char *prod_id[4]; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci u64 dma_mask; 1448c2ecf20Sopenharmony_ci struct device dev; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci /* data private to drivers */ 1478c2ecf20Sopenharmony_ci void *priv; 1488c2ecf20Sopenharmony_ci unsigned int open; 1498c2ecf20Sopenharmony_ci}; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev) 1528c2ecf20Sopenharmony_ci#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv) 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/* 1568c2ecf20Sopenharmony_ci * CIS access. 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci * Please use the following functions to access CIS tuples: 1598c2ecf20Sopenharmony_ci * - pcmcia_get_tuple() 1608c2ecf20Sopenharmony_ci * - pcmcia_loop_tuple() 1618c2ecf20Sopenharmony_ci * - pcmcia_get_mac_from_cis() 1628c2ecf20Sopenharmony_ci * 1638c2ecf20Sopenharmony_ci * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface 1648c2ecf20Sopenharmony_ci * might change in future. 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/* get the very first CIS entry of type @code. Note that buf is pointer 1688c2ecf20Sopenharmony_ci * to u8 *buf; and that you need to kfree(buf) afterwards. */ 1698c2ecf20Sopenharmony_cisize_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, 1708c2ecf20Sopenharmony_ci u8 **buf); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci/* loop over CIS entries */ 1738c2ecf20Sopenharmony_ciint pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, 1748c2ecf20Sopenharmony_ci int (*loop_tuple) (struct pcmcia_device *p_dev, 1758c2ecf20Sopenharmony_ci tuple_t *tuple, 1768c2ecf20Sopenharmony_ci void *priv_data), 1778c2ecf20Sopenharmony_ci void *priv_data); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci/* get the MAC address from CISTPL_FUNCE */ 1808c2ecf20Sopenharmony_ciint pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, 1818c2ecf20Sopenharmony_ci struct net_device *dev); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* parse a tuple_t */ 1858c2ecf20Sopenharmony_ciint pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci/* loop CIS entries for valid configuration */ 1888c2ecf20Sopenharmony_ciint pcmcia_loop_config(struct pcmcia_device *p_dev, 1898c2ecf20Sopenharmony_ci int (*conf_check) (struct pcmcia_device *p_dev, 1908c2ecf20Sopenharmony_ci void *priv_data), 1918c2ecf20Sopenharmony_ci void *priv_data); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci/* is the device still there? */ 1948c2ecf20Sopenharmony_cistruct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci/* low-level interface reset */ 1978c2ecf20Sopenharmony_ciint pcmcia_reset_card(struct pcmcia_socket *skt); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/* CIS config */ 2008c2ecf20Sopenharmony_ciint pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val); 2018c2ecf20Sopenharmony_ciint pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val); 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci/* device configuration */ 2048c2ecf20Sopenharmony_ciint pcmcia_request_io(struct pcmcia_device *p_dev); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ciint __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, 2078c2ecf20Sopenharmony_ci irq_handler_t handler); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ciint pcmcia_enable_device(struct pcmcia_device *p_dev); 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ciint pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res, 2128c2ecf20Sopenharmony_ci unsigned int speed); 2138c2ecf20Sopenharmony_ciint pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res); 2148c2ecf20Sopenharmony_ciint pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res, 2158c2ecf20Sopenharmony_ci unsigned int offset); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ciint pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp); 2188c2ecf20Sopenharmony_ciint pcmcia_fixup_iowidth(struct pcmcia_device *p_dev); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_civoid pcmcia_disable_device(struct pcmcia_device *p_dev); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/* IO ports */ 2238c2ecf20Sopenharmony_ci#define IO_DATA_PATH_WIDTH 0x18 2248c2ecf20Sopenharmony_ci#define IO_DATA_PATH_WIDTH_8 0x00 2258c2ecf20Sopenharmony_ci#define IO_DATA_PATH_WIDTH_16 0x08 2268c2ecf20Sopenharmony_ci#define IO_DATA_PATH_WIDTH_AUTO 0x10 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci/* IO memory */ 2298c2ecf20Sopenharmony_ci#define WIN_MEMORY_TYPE_CM 0x00 /* default */ 2308c2ecf20Sopenharmony_ci#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */ 2318c2ecf20Sopenharmony_ci#define WIN_DATA_WIDTH_8 0x00 /* default */ 2328c2ecf20Sopenharmony_ci#define WIN_DATA_WIDTH_16 0x02 /* MAP_16BIT */ 2338c2ecf20Sopenharmony_ci#define WIN_ENABLE 0x01 /* MAP_ACTIVE */ 2348c2ecf20Sopenharmony_ci#define WIN_USE_WAIT 0x40 /* MAP_USE_WAIT */ 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci#define WIN_FLAGS_MAP 0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE | 2378c2ecf20Sopenharmony_ci MAP_USE_WAIT */ 2388c2ecf20Sopenharmony_ci#define WIN_FLAGS_REQ 0x1c /* mapping to socket->win[i]: 2398c2ecf20Sopenharmony_ci 0x04 -> 0 2408c2ecf20Sopenharmony_ci 0x08 -> 1 2418c2ecf20Sopenharmony_ci 0x0c -> 2 2428c2ecf20Sopenharmony_ci 0x10 -> 3 */ 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci/* config_reg{ister}s present for this PCMCIA device */ 2458c2ecf20Sopenharmony_ci#define PRESENT_OPTION 0x001 2468c2ecf20Sopenharmony_ci#define PRESENT_STATUS 0x002 2478c2ecf20Sopenharmony_ci#define PRESENT_PIN_REPLACE 0x004 2488c2ecf20Sopenharmony_ci#define PRESENT_COPY 0x008 2498c2ecf20Sopenharmony_ci#define PRESENT_EXT_STATUS 0x010 2508c2ecf20Sopenharmony_ci#define PRESENT_IOBASE_0 0x020 2518c2ecf20Sopenharmony_ci#define PRESENT_IOBASE_1 0x040 2528c2ecf20Sopenharmony_ci#define PRESENT_IOBASE_2 0x080 2538c2ecf20Sopenharmony_ci#define PRESENT_IOBASE_3 0x100 2548c2ecf20Sopenharmony_ci#define PRESENT_IOSIZE 0x200 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci/* flags to be passed to pcmcia_enable_device() */ 2578c2ecf20Sopenharmony_ci#define CONF_ENABLE_IRQ 0x0001 2588c2ecf20Sopenharmony_ci#define CONF_ENABLE_SPKR 0x0002 2598c2ecf20Sopenharmony_ci#define CONF_ENABLE_PULSE_IRQ 0x0004 2608c2ecf20Sopenharmony_ci#define CONF_ENABLE_ESR 0x0008 2618c2ecf20Sopenharmony_ci#define CONF_ENABLE_IOCARD 0x0010 /* auto-enabled if IO resources or IRQ 2628c2ecf20Sopenharmony_ci * (CONF_ENABLE_IRQ) in use */ 2638c2ecf20Sopenharmony_ci#define CONF_ENABLE_ZVCARD 0x0020 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci/* flags used by pcmcia_loop_config() autoconfiguration */ 2668c2ecf20Sopenharmony_ci#define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */ 2678c2ecf20Sopenharmony_ci#define CONF_AUTO_SET_VPP 0x0200 /* set Vpp? */ 2688c2ecf20Sopenharmony_ci#define CONF_AUTO_AUDIO 0x0400 /* enable audio line? */ 2698c2ecf20Sopenharmony_ci#define CONF_AUTO_SET_IO 0x0800 /* set ->resource[0,1] */ 2708c2ecf20Sopenharmony_ci#define CONF_AUTO_SET_IOMEM 0x1000 /* set ->resource[2] */ 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */ 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#endif /* _LINUX_DS_H */ 275