162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ds.h -- 16-bit PCMCIA core support 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * The initial developer of the original code is David A. Hinds 662306a36Sopenharmony_ci * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 762306a36Sopenharmony_ci * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * (C) 1999 David A. Hinds 1062306a36Sopenharmony_ci * (C) 2003 - 2008 Dominik Brodowski 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifndef _LINUX_DS_H 1462306a36Sopenharmony_ci#define _LINUX_DS_H 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifdef __KERNEL__ 1762306a36Sopenharmony_ci#include <linux/mod_devicetable.h> 1862306a36Sopenharmony_ci#endif 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <pcmcia/device_id.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#ifdef __KERNEL__ 2362306a36Sopenharmony_ci#include <linux/device.h> 2462306a36Sopenharmony_ci#include <linux/interrupt.h> 2562306a36Sopenharmony_ci#include <pcmcia/ss.h> 2662306a36Sopenharmony_ci#include <linux/atomic.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus 3162306a36Sopenharmony_ci * a.k.a. PCI drivers 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_cistruct pcmcia_socket; 3462306a36Sopenharmony_cistruct pcmcia_device; 3562306a36Sopenharmony_cistruct config_t; 3662306a36Sopenharmony_cistruct net_device; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* dynamic device IDs for PCMCIA device drivers. See 3962306a36Sopenharmony_ci * Documentation/pcmcia/driver.rst for details. 4062306a36Sopenharmony_ci*/ 4162306a36Sopenharmony_cistruct pcmcia_dynids { 4262306a36Sopenharmony_ci struct mutex lock; 4362306a36Sopenharmony_ci struct list_head list; 4462306a36Sopenharmony_ci}; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistruct pcmcia_driver { 4762306a36Sopenharmony_ci const char *name; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci int (*probe) (struct pcmcia_device *dev); 5062306a36Sopenharmony_ci void (*remove) (struct pcmcia_device *dev); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci int (*suspend) (struct pcmcia_device *dev); 5362306a36Sopenharmony_ci int (*resume) (struct pcmcia_device *dev); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci struct module *owner; 5662306a36Sopenharmony_ci const struct pcmcia_device_id *id_table; 5762306a36Sopenharmony_ci struct device_driver drv; 5862306a36Sopenharmony_ci struct pcmcia_dynids dynids; 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci/* driver registration */ 6262306a36Sopenharmony_ciint pcmcia_register_driver(struct pcmcia_driver *driver); 6362306a36Sopenharmony_civoid pcmcia_unregister_driver(struct pcmcia_driver *driver); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/** 6662306a36Sopenharmony_ci * module_pcmcia_driver() - Helper macro for registering a pcmcia driver 6762306a36Sopenharmony_ci * @__pcmcia_driver: pcmcia_driver struct 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * Helper macro for pcmcia drivers which do not do anything special in module 7062306a36Sopenharmony_ci * init/exit. This eliminates a lot of boilerplate. Each module may only use 7162306a36Sopenharmony_ci * this macro once, and calling it replaces module_init() and module_exit(). 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci#define module_pcmcia_driver(__pcmcia_driver) \ 7462306a36Sopenharmony_ci module_driver(__pcmcia_driver, pcmcia_register_driver, \ 7562306a36Sopenharmony_ci pcmcia_unregister_driver) 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* for struct resource * array embedded in struct pcmcia_device */ 7862306a36Sopenharmony_cienum { 7962306a36Sopenharmony_ci PCMCIA_IOPORT_0, 8062306a36Sopenharmony_ci PCMCIA_IOPORT_1, 8162306a36Sopenharmony_ci PCMCIA_IOMEM_0, 8262306a36Sopenharmony_ci PCMCIA_IOMEM_1, 8362306a36Sopenharmony_ci PCMCIA_IOMEM_2, 8462306a36Sopenharmony_ci PCMCIA_IOMEM_3, 8562306a36Sopenharmony_ci PCMCIA_NUM_RESOURCES, 8662306a36Sopenharmony_ci}; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistruct pcmcia_device { 8962306a36Sopenharmony_ci /* the socket and the device_no [for multifunction devices] 9062306a36Sopenharmony_ci uniquely define a pcmcia_device */ 9162306a36Sopenharmony_ci struct pcmcia_socket *socket; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci char *devname; 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci u8 device_no; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* the hardware "function" device; certain subdevices can 9862306a36Sopenharmony_ci * share one hardware "function" device. */ 9962306a36Sopenharmony_ci u8 func; 10062306a36Sopenharmony_ci struct config_t *function_config; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci struct list_head socket_device_list; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* device setup */ 10562306a36Sopenharmony_ci unsigned int irq; 10662306a36Sopenharmony_ci struct resource *resource[PCMCIA_NUM_RESOURCES]; 10762306a36Sopenharmony_ci resource_size_t card_addr; /* for the 1st IOMEM resource */ 10862306a36Sopenharmony_ci unsigned int vpp; 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci unsigned int config_flags; /* CONF_ENABLE_ flags below */ 11162306a36Sopenharmony_ci unsigned int config_base; 11262306a36Sopenharmony_ci unsigned int config_index; 11362306a36Sopenharmony_ci unsigned int config_regs; /* PRESENT_ flags below */ 11462306a36Sopenharmony_ci unsigned int io_lines; /* number of I/O lines */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci /* Is the device suspended? */ 11762306a36Sopenharmony_ci u16 suspended:1; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* Flags whether io, irq, win configurations were 12062306a36Sopenharmony_ci * requested, and whether the configuration is "locked" */ 12162306a36Sopenharmony_ci u16 _irq:1; 12262306a36Sopenharmony_ci u16 _io:1; 12362306a36Sopenharmony_ci u16 _win:4; 12462306a36Sopenharmony_ci u16 _locked:1; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci /* Flag whether a "fuzzy" func_id based match is 12762306a36Sopenharmony_ci * allowed. */ 12862306a36Sopenharmony_ci u16 allow_func_id_match:1; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci /* information about this device */ 13162306a36Sopenharmony_ci u16 has_manf_id:1; 13262306a36Sopenharmony_ci u16 has_card_id:1; 13362306a36Sopenharmony_ci u16 has_func_id:1; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci u16 reserved:4; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci u8 func_id; 13862306a36Sopenharmony_ci u16 manf_id; 13962306a36Sopenharmony_ci u16 card_id; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci char *prod_id[4]; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci u64 dma_mask; 14462306a36Sopenharmony_ci struct device dev; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* data private to drivers */ 14762306a36Sopenharmony_ci void *priv; 14862306a36Sopenharmony_ci unsigned int open; 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci#define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev) 15262306a36Sopenharmony_ci#define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv) 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci/* 15662306a36Sopenharmony_ci * CIS access. 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * Please use the following functions to access CIS tuples: 15962306a36Sopenharmony_ci * - pcmcia_get_tuple() 16062306a36Sopenharmony_ci * - pcmcia_loop_tuple() 16162306a36Sopenharmony_ci * - pcmcia_get_mac_from_cis() 16262306a36Sopenharmony_ci * 16362306a36Sopenharmony_ci * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface 16462306a36Sopenharmony_ci * might change in future. 16562306a36Sopenharmony_ci */ 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci/* get the very first CIS entry of type @code. Note that buf is pointer 16862306a36Sopenharmony_ci * to u8 *buf; and that you need to kfree(buf) afterwards. */ 16962306a36Sopenharmony_cisize_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code, 17062306a36Sopenharmony_ci u8 **buf); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci/* loop over CIS entries */ 17362306a36Sopenharmony_ciint pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code, 17462306a36Sopenharmony_ci int (*loop_tuple) (struct pcmcia_device *p_dev, 17562306a36Sopenharmony_ci tuple_t *tuple, 17662306a36Sopenharmony_ci void *priv_data), 17762306a36Sopenharmony_ci void *priv_data); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci/* get the MAC address from CISTPL_FUNCE */ 18062306a36Sopenharmony_ciint pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, 18162306a36Sopenharmony_ci struct net_device *dev); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci/* parse a tuple_t */ 18562306a36Sopenharmony_ciint pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse); 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci/* loop CIS entries for valid configuration */ 18862306a36Sopenharmony_ciint pcmcia_loop_config(struct pcmcia_device *p_dev, 18962306a36Sopenharmony_ci int (*conf_check) (struct pcmcia_device *p_dev, 19062306a36Sopenharmony_ci void *priv_data), 19162306a36Sopenharmony_ci void *priv_data); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci/* is the device still there? */ 19462306a36Sopenharmony_cistruct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* low-level interface reset */ 19762306a36Sopenharmony_ciint pcmcia_reset_card(struct pcmcia_socket *skt); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci/* CIS config */ 20062306a36Sopenharmony_ciint pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val); 20162306a36Sopenharmony_ciint pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/* device configuration */ 20462306a36Sopenharmony_ciint pcmcia_request_io(struct pcmcia_device *p_dev); 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ciint __must_check pcmcia_request_irq(struct pcmcia_device *p_dev, 20762306a36Sopenharmony_ci irq_handler_t handler); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ciint pcmcia_enable_device(struct pcmcia_device *p_dev); 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ciint pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res, 21262306a36Sopenharmony_ci unsigned int speed); 21362306a36Sopenharmony_ciint pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res); 21462306a36Sopenharmony_ciint pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res, 21562306a36Sopenharmony_ci unsigned int offset); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ciint pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp); 21862306a36Sopenharmony_ciint pcmcia_fixup_iowidth(struct pcmcia_device *p_dev); 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_civoid pcmcia_disable_device(struct pcmcia_device *p_dev); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci/* IO ports */ 22362306a36Sopenharmony_ci#define IO_DATA_PATH_WIDTH 0x18 22462306a36Sopenharmony_ci#define IO_DATA_PATH_WIDTH_8 0x00 22562306a36Sopenharmony_ci#define IO_DATA_PATH_WIDTH_16 0x08 22662306a36Sopenharmony_ci#define IO_DATA_PATH_WIDTH_AUTO 0x10 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci/* IO memory */ 22962306a36Sopenharmony_ci#define WIN_MEMORY_TYPE_CM 0x00 /* default */ 23062306a36Sopenharmony_ci#define WIN_MEMORY_TYPE_AM 0x20 /* MAP_ATTRIB */ 23162306a36Sopenharmony_ci#define WIN_DATA_WIDTH_8 0x00 /* default */ 23262306a36Sopenharmony_ci#define WIN_DATA_WIDTH_16 0x02 /* MAP_16BIT */ 23362306a36Sopenharmony_ci#define WIN_ENABLE 0x01 /* MAP_ACTIVE */ 23462306a36Sopenharmony_ci#define WIN_USE_WAIT 0x40 /* MAP_USE_WAIT */ 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci#define WIN_FLAGS_MAP 0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE | 23762306a36Sopenharmony_ci MAP_USE_WAIT */ 23862306a36Sopenharmony_ci#define WIN_FLAGS_REQ 0x1c /* mapping to socket->win[i]: 23962306a36Sopenharmony_ci 0x04 -> 0 24062306a36Sopenharmony_ci 0x08 -> 1 24162306a36Sopenharmony_ci 0x0c -> 2 24262306a36Sopenharmony_ci 0x10 -> 3 */ 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci/* config_reg{ister}s present for this PCMCIA device */ 24562306a36Sopenharmony_ci#define PRESENT_OPTION 0x001 24662306a36Sopenharmony_ci#define PRESENT_STATUS 0x002 24762306a36Sopenharmony_ci#define PRESENT_PIN_REPLACE 0x004 24862306a36Sopenharmony_ci#define PRESENT_COPY 0x008 24962306a36Sopenharmony_ci#define PRESENT_EXT_STATUS 0x010 25062306a36Sopenharmony_ci#define PRESENT_IOBASE_0 0x020 25162306a36Sopenharmony_ci#define PRESENT_IOBASE_1 0x040 25262306a36Sopenharmony_ci#define PRESENT_IOBASE_2 0x080 25362306a36Sopenharmony_ci#define PRESENT_IOBASE_3 0x100 25462306a36Sopenharmony_ci#define PRESENT_IOSIZE 0x200 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci/* flags to be passed to pcmcia_enable_device() */ 25762306a36Sopenharmony_ci#define CONF_ENABLE_IRQ 0x0001 25862306a36Sopenharmony_ci#define CONF_ENABLE_SPKR 0x0002 25962306a36Sopenharmony_ci#define CONF_ENABLE_PULSE_IRQ 0x0004 26062306a36Sopenharmony_ci#define CONF_ENABLE_ESR 0x0008 26162306a36Sopenharmony_ci#define CONF_ENABLE_IOCARD 0x0010 /* auto-enabled if IO resources or IRQ 26262306a36Sopenharmony_ci * (CONF_ENABLE_IRQ) in use */ 26362306a36Sopenharmony_ci#define CONF_ENABLE_ZVCARD 0x0020 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/* flags used by pcmcia_loop_config() autoconfiguration */ 26662306a36Sopenharmony_ci#define CONF_AUTO_CHECK_VCC 0x0100 /* check for matching Vcc? */ 26762306a36Sopenharmony_ci#define CONF_AUTO_SET_VPP 0x0200 /* set Vpp? */ 26862306a36Sopenharmony_ci#define CONF_AUTO_AUDIO 0x0400 /* enable audio line? */ 26962306a36Sopenharmony_ci#define CONF_AUTO_SET_IO 0x0800 /* set ->resource[0,1] */ 27062306a36Sopenharmony_ci#define CONF_AUTO_SET_IOMEM 0x1000 /* set ->resource[2] */ 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci#endif /* __KERNEL__ */ 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci#endif /* _LINUX_DS_H */ 275