xref: /OK3568_Linux_fs/kernel/include/pcmcia/ds.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * ds.h -- 16-bit PCMCIA core support
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * The initial developer of the original code is David A. Hinds
6*4882a593Smuzhiyun  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
7*4882a593Smuzhiyun  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
8*4882a593Smuzhiyun  *
9*4882a593Smuzhiyun  * (C) 1999		David A. Hinds
10*4882a593Smuzhiyun  * (C) 2003 - 2008	Dominik Brodowski
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #ifndef _LINUX_DS_H
14*4882a593Smuzhiyun #define _LINUX_DS_H
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #ifdef __KERNEL__
17*4882a593Smuzhiyun #include <linux/mod_devicetable.h>
18*4882a593Smuzhiyun #endif
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include <pcmcia/device_id.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #ifdef __KERNEL__
23*4882a593Smuzhiyun #include <linux/device.h>
24*4882a593Smuzhiyun #include <linux/interrupt.h>
25*4882a593Smuzhiyun #include <pcmcia/ss.h>
26*4882a593Smuzhiyun #include <linux/atomic.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus
31*4882a593Smuzhiyun  * a.k.a. PCI drivers
32*4882a593Smuzhiyun  */
33*4882a593Smuzhiyun struct pcmcia_socket;
34*4882a593Smuzhiyun struct pcmcia_device;
35*4882a593Smuzhiyun struct config_t;
36*4882a593Smuzhiyun struct net_device;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /* dynamic device IDs for PCMCIA device drivers. See
39*4882a593Smuzhiyun  * Documentation/pcmcia/driver.rst for details.
40*4882a593Smuzhiyun */
41*4882a593Smuzhiyun struct pcmcia_dynids {
42*4882a593Smuzhiyun 	struct mutex		lock;
43*4882a593Smuzhiyun 	struct list_head	list;
44*4882a593Smuzhiyun };
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun struct pcmcia_driver {
47*4882a593Smuzhiyun 	const char		*name;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	int (*probe)		(struct pcmcia_device *dev);
50*4882a593Smuzhiyun 	void (*remove)		(struct pcmcia_device *dev);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 	int (*suspend)		(struct pcmcia_device *dev);
53*4882a593Smuzhiyun 	int (*resume)		(struct pcmcia_device *dev);
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun 	struct module		*owner;
56*4882a593Smuzhiyun 	const struct pcmcia_device_id	*id_table;
57*4882a593Smuzhiyun 	struct device_driver	drv;
58*4882a593Smuzhiyun 	struct pcmcia_dynids	dynids;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun /* driver registration */
62*4882a593Smuzhiyun int pcmcia_register_driver(struct pcmcia_driver *driver);
63*4882a593Smuzhiyun void pcmcia_unregister_driver(struct pcmcia_driver *driver);
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun /**
66*4882a593Smuzhiyun  * module_pcmcia_driver() - Helper macro for registering a pcmcia driver
67*4882a593Smuzhiyun  * @__pcmcia_driver: pcmcia_driver struct
68*4882a593Smuzhiyun  *
69*4882a593Smuzhiyun  * Helper macro for pcmcia drivers which do not do anything special in module
70*4882a593Smuzhiyun  * init/exit. This eliminates a lot of boilerplate. Each module may only use
71*4882a593Smuzhiyun  * this macro once, and calling it replaces module_init() and module_exit().
72*4882a593Smuzhiyun  */
73*4882a593Smuzhiyun #define module_pcmcia_driver(__pcmcia_driver) \
74*4882a593Smuzhiyun 	module_driver(__pcmcia_driver, pcmcia_register_driver, \
75*4882a593Smuzhiyun 			pcmcia_unregister_driver)
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun /* for struct resource * array embedded in struct pcmcia_device */
78*4882a593Smuzhiyun enum {
79*4882a593Smuzhiyun 	PCMCIA_IOPORT_0,
80*4882a593Smuzhiyun 	PCMCIA_IOPORT_1,
81*4882a593Smuzhiyun 	PCMCIA_IOMEM_0,
82*4882a593Smuzhiyun 	PCMCIA_IOMEM_1,
83*4882a593Smuzhiyun 	PCMCIA_IOMEM_2,
84*4882a593Smuzhiyun 	PCMCIA_IOMEM_3,
85*4882a593Smuzhiyun 	PCMCIA_NUM_RESOURCES,
86*4882a593Smuzhiyun };
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun struct pcmcia_device {
89*4882a593Smuzhiyun 	/* the socket and the device_no [for multifunction devices]
90*4882a593Smuzhiyun 	   uniquely define a pcmcia_device */
91*4882a593Smuzhiyun 	struct pcmcia_socket	*socket;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	char			*devname;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	u8			device_no;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	/* the hardware "function" device; certain subdevices can
98*4882a593Smuzhiyun 	 * share one hardware "function" device. */
99*4882a593Smuzhiyun 	u8			func;
100*4882a593Smuzhiyun 	struct config_t		*function_config;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	struct list_head	socket_device_list;
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	/* device setup */
105*4882a593Smuzhiyun 	unsigned int		irq;
106*4882a593Smuzhiyun 	struct resource		*resource[PCMCIA_NUM_RESOURCES];
107*4882a593Smuzhiyun 	resource_size_t		card_addr;	/* for the 1st IOMEM resource */
108*4882a593Smuzhiyun 	unsigned int		vpp;
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	unsigned int		config_flags;	/* CONF_ENABLE_ flags below */
111*4882a593Smuzhiyun 	unsigned int		config_base;
112*4882a593Smuzhiyun 	unsigned int		config_index;
113*4882a593Smuzhiyun 	unsigned int		config_regs;	/* PRESENT_ flags below */
114*4882a593Smuzhiyun 	unsigned int		io_lines;	/* number of I/O lines */
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* Is the device suspended? */
117*4882a593Smuzhiyun 	u16			suspended:1;
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	/* Flags whether io, irq, win configurations were
120*4882a593Smuzhiyun 	 * requested, and whether the configuration is "locked" */
121*4882a593Smuzhiyun 	u16			_irq:1;
122*4882a593Smuzhiyun 	u16			_io:1;
123*4882a593Smuzhiyun 	u16			_win:4;
124*4882a593Smuzhiyun 	u16			_locked:1;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	/* Flag whether a "fuzzy" func_id based match is
127*4882a593Smuzhiyun 	 * allowed. */
128*4882a593Smuzhiyun 	u16			allow_func_id_match:1;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	/* information about this device */
131*4882a593Smuzhiyun 	u16			has_manf_id:1;
132*4882a593Smuzhiyun 	u16			has_card_id:1;
133*4882a593Smuzhiyun 	u16			has_func_id:1;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	u16			reserved:4;
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	u8			func_id;
138*4882a593Smuzhiyun 	u16			manf_id;
139*4882a593Smuzhiyun 	u16			card_id;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	char			*prod_id[4];
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	u64			dma_mask;
144*4882a593Smuzhiyun 	struct device		dev;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	/* data private to drivers */
147*4882a593Smuzhiyun 	void			*priv;
148*4882a593Smuzhiyun 	unsigned int		open;
149*4882a593Smuzhiyun };
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
152*4882a593Smuzhiyun #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun /*
156*4882a593Smuzhiyun  * CIS access.
157*4882a593Smuzhiyun  *
158*4882a593Smuzhiyun  * Please use the following functions to access CIS tuples:
159*4882a593Smuzhiyun  * - pcmcia_get_tuple()
160*4882a593Smuzhiyun  * - pcmcia_loop_tuple()
161*4882a593Smuzhiyun  * - pcmcia_get_mac_from_cis()
162*4882a593Smuzhiyun  *
163*4882a593Smuzhiyun  * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface
164*4882a593Smuzhiyun  * might change in future.
165*4882a593Smuzhiyun  */
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun /* get the very first CIS entry of type @code. Note that buf is pointer
168*4882a593Smuzhiyun  * to u8 *buf; and that you need to kfree(buf) afterwards. */
169*4882a593Smuzhiyun size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
170*4882a593Smuzhiyun 			u8 **buf);
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun /* loop over CIS entries */
173*4882a593Smuzhiyun int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
174*4882a593Smuzhiyun 		      int (*loop_tuple) (struct pcmcia_device *p_dev,
175*4882a593Smuzhiyun 					 tuple_t *tuple,
176*4882a593Smuzhiyun 					 void *priv_data),
177*4882a593Smuzhiyun 		      void *priv_data);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun /* get the MAC address from CISTPL_FUNCE */
180*4882a593Smuzhiyun int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev,
181*4882a593Smuzhiyun 			    struct net_device *dev);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /* parse a tuple_t */
185*4882a593Smuzhiyun int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /* loop CIS entries for valid configuration */
188*4882a593Smuzhiyun int pcmcia_loop_config(struct pcmcia_device *p_dev,
189*4882a593Smuzhiyun 		       int	(*conf_check)	(struct pcmcia_device *p_dev,
190*4882a593Smuzhiyun 						 void *priv_data),
191*4882a593Smuzhiyun 		       void *priv_data);
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun /* is the device still there? */
194*4882a593Smuzhiyun struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *p_dev);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun /* low-level interface reset */
197*4882a593Smuzhiyun int pcmcia_reset_card(struct pcmcia_socket *skt);
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun /* CIS config */
200*4882a593Smuzhiyun int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val);
201*4882a593Smuzhiyun int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val);
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun /* device configuration */
204*4882a593Smuzhiyun int pcmcia_request_io(struct pcmcia_device *p_dev);
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
207*4882a593Smuzhiyun 				irq_handler_t handler);
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun int pcmcia_enable_device(struct pcmcia_device *p_dev);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun int pcmcia_request_window(struct pcmcia_device *p_dev, struct resource *res,
212*4882a593Smuzhiyun 			unsigned int speed);
213*4882a593Smuzhiyun int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res);
214*4882a593Smuzhiyun int pcmcia_map_mem_page(struct pcmcia_device *p_dev, struct resource *res,
215*4882a593Smuzhiyun 			unsigned int offset);
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun int pcmcia_fixup_vpp(struct pcmcia_device *p_dev, unsigned char new_vpp);
218*4882a593Smuzhiyun int pcmcia_fixup_iowidth(struct pcmcia_device *p_dev);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun void pcmcia_disable_device(struct pcmcia_device *p_dev);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun /* IO ports */
223*4882a593Smuzhiyun #define IO_DATA_PATH_WIDTH	0x18
224*4882a593Smuzhiyun #define IO_DATA_PATH_WIDTH_8	0x00
225*4882a593Smuzhiyun #define IO_DATA_PATH_WIDTH_16	0x08
226*4882a593Smuzhiyun #define IO_DATA_PATH_WIDTH_AUTO	0x10
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun /* IO memory */
229*4882a593Smuzhiyun #define WIN_MEMORY_TYPE_CM	0x00 /* default */
230*4882a593Smuzhiyun #define WIN_MEMORY_TYPE_AM	0x20 /* MAP_ATTRIB */
231*4882a593Smuzhiyun #define WIN_DATA_WIDTH_8	0x00 /* default */
232*4882a593Smuzhiyun #define WIN_DATA_WIDTH_16	0x02 /* MAP_16BIT */
233*4882a593Smuzhiyun #define WIN_ENABLE		0x01 /* MAP_ACTIVE */
234*4882a593Smuzhiyun #define WIN_USE_WAIT		0x40 /* MAP_USE_WAIT */
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun #define WIN_FLAGS_MAP		0x63 /* MAP_ATTRIB | MAP_16BIT | MAP_ACTIVE |
237*4882a593Smuzhiyun 					MAP_USE_WAIT */
238*4882a593Smuzhiyun #define WIN_FLAGS_REQ		0x1c /* mapping to socket->win[i]:
239*4882a593Smuzhiyun 					0x04 -> 0
240*4882a593Smuzhiyun 					0x08 -> 1
241*4882a593Smuzhiyun 					0x0c -> 2
242*4882a593Smuzhiyun 					0x10 -> 3 */
243*4882a593Smuzhiyun 
244*4882a593Smuzhiyun /* config_reg{ister}s present for this PCMCIA device */
245*4882a593Smuzhiyun #define PRESENT_OPTION		0x001
246*4882a593Smuzhiyun #define PRESENT_STATUS		0x002
247*4882a593Smuzhiyun #define PRESENT_PIN_REPLACE	0x004
248*4882a593Smuzhiyun #define PRESENT_COPY		0x008
249*4882a593Smuzhiyun #define PRESENT_EXT_STATUS	0x010
250*4882a593Smuzhiyun #define PRESENT_IOBASE_0	0x020
251*4882a593Smuzhiyun #define PRESENT_IOBASE_1	0x040
252*4882a593Smuzhiyun #define PRESENT_IOBASE_2	0x080
253*4882a593Smuzhiyun #define PRESENT_IOBASE_3	0x100
254*4882a593Smuzhiyun #define PRESENT_IOSIZE		0x200
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun /* flags to be passed to pcmcia_enable_device() */
257*4882a593Smuzhiyun #define CONF_ENABLE_IRQ         0x0001
258*4882a593Smuzhiyun #define CONF_ENABLE_SPKR        0x0002
259*4882a593Smuzhiyun #define CONF_ENABLE_PULSE_IRQ   0x0004
260*4882a593Smuzhiyun #define CONF_ENABLE_ESR         0x0008
261*4882a593Smuzhiyun #define CONF_ENABLE_IOCARD	0x0010 /* auto-enabled if IO resources or IRQ
262*4882a593Smuzhiyun 					* (CONF_ENABLE_IRQ) in use */
263*4882a593Smuzhiyun #define CONF_ENABLE_ZVCARD	0x0020
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun /* flags used by pcmcia_loop_config() autoconfiguration */
266*4882a593Smuzhiyun #define CONF_AUTO_CHECK_VCC	0x0100 /* check for matching Vcc? */
267*4882a593Smuzhiyun #define CONF_AUTO_SET_VPP	0x0200 /* set Vpp? */
268*4882a593Smuzhiyun #define CONF_AUTO_AUDIO		0x0400 /* enable audio line? */
269*4882a593Smuzhiyun #define CONF_AUTO_SET_IO	0x0800 /* set ->resource[0,1] */
270*4882a593Smuzhiyun #define CONF_AUTO_SET_IOMEM	0x1000 /* set ->resource[2] */
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun #endif /* __KERNEL__ */
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun #endif /* _LINUX_DS_H */
275