1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Sony MemoryStick support |
4 | * |
5 | * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com> |
6 | */ |
7 | |
8 | #ifndef _MEMSTICK_H |
9 | #define _MEMSTICK_H |
10 | |
11 | #include <linux/workqueue.h> |
12 | #include <linux/scatterlist.h> |
13 | #include <linux/device.h> |
14 | |
15 | /*** Hardware based structures ***/ |
16 | |
17 | struct ms_status_register { |
18 | unsigned char reserved; |
19 | unsigned char interrupt; |
20 | #define MEMSTICK_INT_CMDNAK 0x01 |
21 | #define MEMSTICK_INT_IOREQ 0x08 |
22 | #define MEMSTICK_INT_IOBREQ 0x10 |
23 | #define MEMSTICK_INT_BREQ 0x20 |
24 | #define MEMSTICK_INT_ERR 0x40 |
25 | #define MEMSTICK_INT_CED 0x80 |
26 | |
27 | unsigned char status0; |
28 | #define MEMSTICK_STATUS0_WP 0x01 |
29 | #define MEMSTICK_STATUS0_SL 0x02 |
30 | #define MEMSTICK_STATUS0_BF 0x10 |
31 | #define MEMSTICK_STATUS0_BE 0x20 |
32 | #define MEMSTICK_STATUS0_FB0 0x40 |
33 | #define MEMSTICK_STATUS0_MB 0x80 |
34 | |
35 | unsigned char status1; |
36 | #define MEMSTICK_STATUS1_UCFG 0x01 |
37 | #define MEMSTICK_STATUS1_FGER 0x02 |
38 | #define MEMSTICK_STATUS1_UCEX 0x04 |
39 | #define MEMSTICK_STATUS1_EXER 0x08 |
40 | #define MEMSTICK_STATUS1_UCDT 0x10 |
41 | #define MEMSTICK_STATUS1_DTER 0x20 |
42 | #define MEMSTICK_STATUS1_FB1 0x40 |
43 | #define MEMSTICK_STATUS1_MB 0x80 |
44 | } __attribute__((packed)); |
45 | |
46 | struct ms_id_register { |
47 | unsigned char type; |
48 | unsigned char if_mode; |
49 | unsigned char category; |
50 | unsigned char class; |
51 | } __attribute__((packed)); |
52 | |
53 | struct ms_param_register { |
54 | unsigned char system; |
55 | #define MEMSTICK_SYS_PAM 0x08 |
56 | #define MEMSTICK_SYS_BAMD 0x80 |
57 | |
58 | unsigned char block_address_msb; |
59 | unsigned short block_address; |
60 | unsigned char cp; |
61 | #define MEMSTICK_CP_BLOCK 0x00 |
62 | #define MEMSTICK_CP_PAGE 0x20 |
63 | #define 0x40 |
64 | #define MEMSTICK_CP_OVERWRITE 0x80 |
65 | |
66 | unsigned char page_address; |
67 | } __attribute__((packed)); |
68 | |
69 | struct { |
70 | unsigned char ; |
71 | #define MEMSTICK_OVERWRITE_UDST 0x10 |
72 | #define MEMSTICK_OVERWRITE_PGST1 0x20 |
73 | #define MEMSTICK_OVERWRITE_PGST0 0x40 |
74 | #define MEMSTICK_OVERWRITE_BKST 0x80 |
75 | |
76 | unsigned char ; |
77 | #define MEMSTICK_MANAGEMENT_SYSFLG 0x04 |
78 | #define MEMSTICK_MANAGEMENT_ATFLG 0x08 |
79 | #define MEMSTICK_MANAGEMENT_SCMS1 0x10 |
80 | #define MEMSTICK_MANAGEMENT_SCMS0 0x20 |
81 | |
82 | unsigned short ; |
83 | } __attribute__((packed)); |
84 | |
85 | struct ms_register { |
86 | struct ms_status_register status; |
87 | struct ms_id_register id; |
88 | unsigned char reserved[8]; |
89 | struct ms_param_register param; |
90 | struct ms_extra_data_register ; |
91 | } __attribute__((packed)); |
92 | |
93 | struct mspro_param_register { |
94 | unsigned char system; |
95 | #define MEMSTICK_SYS_PAR4 0x00 |
96 | #define MEMSTICK_SYS_PAR8 0x40 |
97 | #define MEMSTICK_SYS_SERIAL 0x80 |
98 | |
99 | __be16 data_count; |
100 | __be32 data_address; |
101 | unsigned char tpc_param; |
102 | } __attribute__((packed)); |
103 | |
104 | struct mspro_io_info_register { |
105 | unsigned char version; |
106 | unsigned char io_category; |
107 | unsigned char current_req; |
108 | unsigned char card_opt_info; |
109 | unsigned char rdy_wait_time; |
110 | } __attribute__((packed)); |
111 | |
112 | struct mspro_io_func_register { |
113 | unsigned char func_enable; |
114 | unsigned char func_select; |
115 | unsigned char func_intmask; |
116 | unsigned char transfer_mode; |
117 | } __attribute__((packed)); |
118 | |
119 | struct mspro_io_cmd_register { |
120 | unsigned short tpc_param; |
121 | unsigned short data_count; |
122 | unsigned int data_address; |
123 | } __attribute__((packed)); |
124 | |
125 | struct mspro_register { |
126 | struct ms_status_register status; |
127 | struct ms_id_register id; |
128 | unsigned char reserved0[8]; |
129 | struct mspro_param_register param; |
130 | unsigned char reserved1[8]; |
131 | struct mspro_io_info_register io_info; |
132 | struct mspro_io_func_register io_func; |
133 | unsigned char reserved2[7]; |
134 | struct mspro_io_cmd_register io_cmd; |
135 | unsigned char io_int; |
136 | unsigned char io_int_func; |
137 | } __attribute__((packed)); |
138 | |
139 | struct ms_register_addr { |
140 | unsigned char r_offset; |
141 | unsigned char r_length; |
142 | unsigned char w_offset; |
143 | unsigned char w_length; |
144 | } __attribute__((packed)); |
145 | |
146 | enum memstick_tpc { |
147 | MS_TPC_READ_MG_STATUS = 0x01, |
148 | MS_TPC_READ_LONG_DATA = 0x02, |
149 | MS_TPC_READ_SHORT_DATA = 0x03, |
150 | MS_TPC_READ_MG_DATA = 0x03, |
151 | MS_TPC_READ_REG = 0x04, |
152 | MS_TPC_READ_QUAD_DATA = 0x05, |
153 | MS_TPC_READ_IO_DATA = 0x05, |
154 | MS_TPC_GET_INT = 0x07, |
155 | MS_TPC_SET_RW_REG_ADRS = 0x08, |
156 | MS_TPC_EX_SET_CMD = 0x09, |
157 | MS_TPC_WRITE_QUAD_DATA = 0x0a, |
158 | MS_TPC_WRITE_IO_DATA = 0x0a, |
159 | MS_TPC_WRITE_REG = 0x0b, |
160 | MS_TPC_WRITE_SHORT_DATA = 0x0c, |
161 | MS_TPC_WRITE_MG_DATA = 0x0c, |
162 | MS_TPC_WRITE_LONG_DATA = 0x0d, |
163 | MS_TPC_SET_CMD = 0x0e |
164 | }; |
165 | |
166 | enum memstick_command { |
167 | MS_CMD_BLOCK_END = 0x33, |
168 | MS_CMD_RESET = 0x3c, |
169 | MS_CMD_BLOCK_WRITE = 0x55, |
170 | MS_CMD_SLEEP = 0x5a, |
171 | MS_CMD_BLOCK_ERASE = 0x99, |
172 | MS_CMD_BLOCK_READ = 0xaa, |
173 | MS_CMD_CLEAR_BUF = 0xc3, |
174 | MS_CMD_FLASH_STOP = 0xcc, |
175 | MS_CMD_LOAD_ID = 0x60, |
176 | MS_CMD_CMP_ICV = 0x7f, |
177 | MSPRO_CMD_FORMAT = 0x10, |
178 | MSPRO_CMD_SLEEP = 0x11, |
179 | MSPRO_CMD_WAKEUP = 0x12, |
180 | MSPRO_CMD_READ_DATA = 0x20, |
181 | MSPRO_CMD_WRITE_DATA = 0x21, |
182 | MSPRO_CMD_READ_ATRB = 0x24, |
183 | MSPRO_CMD_STOP = 0x25, |
184 | MSPRO_CMD_ERASE = 0x26, |
185 | MSPRO_CMD_READ_QUAD = 0x27, |
186 | MSPRO_CMD_WRITE_QUAD = 0x28, |
187 | MSPRO_CMD_SET_IBD = 0x46, |
188 | MSPRO_CMD_GET_IBD = 0x47, |
189 | MSPRO_CMD_IN_IO_DATA = 0xb0, |
190 | MSPRO_CMD_OUT_IO_DATA = 0xb1, |
191 | MSPRO_CMD_READ_IO_ATRB = 0xb2, |
192 | MSPRO_CMD_IN_IO_FIFO = 0xb3, |
193 | MSPRO_CMD_OUT_IO_FIFO = 0xb4, |
194 | MSPRO_CMD_IN_IOM = 0xb5, |
195 | MSPRO_CMD_OUT_IOM = 0xb6, |
196 | }; |
197 | |
198 | /*** Driver structures and functions ***/ |
199 | |
200 | enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE }; |
201 | |
202 | #define MEMSTICK_POWER_OFF 0 |
203 | #define MEMSTICK_POWER_ON 1 |
204 | |
205 | #define MEMSTICK_SERIAL 0 |
206 | #define MEMSTICK_PAR4 1 |
207 | #define MEMSTICK_PAR8 2 |
208 | |
209 | struct memstick_host; |
210 | struct memstick_driver; |
211 | |
212 | struct memstick_device_id { |
213 | unsigned char match_flags; |
214 | #define MEMSTICK_MATCH_ALL 0x01 |
215 | |
216 | unsigned char type; |
217 | #define MEMSTICK_TYPE_LEGACY 0xff |
218 | #define MEMSTICK_TYPE_DUO 0x00 |
219 | #define MEMSTICK_TYPE_PRO 0x01 |
220 | |
221 | unsigned char category; |
222 | #define MEMSTICK_CATEGORY_STORAGE 0xff |
223 | #define MEMSTICK_CATEGORY_STORAGE_DUO 0x00 |
224 | #define MEMSTICK_CATEGORY_IO 0x01 |
225 | #define MEMSTICK_CATEGORY_IO_PRO 0x10 |
226 | |
227 | unsigned char class; |
228 | #define MEMSTICK_CLASS_FLASH 0xff |
229 | #define MEMSTICK_CLASS_DUO 0x00 |
230 | #define MEMSTICK_CLASS_ROM 0x01 |
231 | #define MEMSTICK_CLASS_RO 0x02 |
232 | #define MEMSTICK_CLASS_WP 0x03 |
233 | }; |
234 | |
235 | struct memstick_request { |
236 | unsigned char tpc; |
237 | unsigned char data_dir:1, |
238 | need_card_int:1, |
239 | long_data:1; |
240 | unsigned char int_reg; |
241 | int error; |
242 | union { |
243 | struct scatterlist sg; |
244 | struct { |
245 | unsigned char data_len; |
246 | unsigned char data[15]; |
247 | }; |
248 | }; |
249 | }; |
250 | |
251 | struct memstick_dev { |
252 | struct memstick_device_id id; |
253 | struct memstick_host *host; |
254 | struct ms_register_addr reg_addr; |
255 | struct completion mrq_complete; |
256 | struct memstick_request current_mrq; |
257 | |
258 | /* Check that media driver is still willing to operate the device. */ |
259 | int (*check)(struct memstick_dev *card); |
260 | /* Get next request from the media driver. */ |
261 | int (*next_request)(struct memstick_dev *card, |
262 | struct memstick_request **mrq); |
263 | /* Tell the media driver to stop doing things */ |
264 | void (*stop)(struct memstick_dev *card); |
265 | /* Allow the media driver to continue */ |
266 | void (*start)(struct memstick_dev *card); |
267 | |
268 | struct device dev; |
269 | }; |
270 | |
271 | struct memstick_host { |
272 | struct mutex lock; |
273 | unsigned int id; |
274 | unsigned int caps; |
275 | #define MEMSTICK_CAP_AUTO_GET_INT 1 |
276 | #define MEMSTICK_CAP_PAR4 2 |
277 | #define MEMSTICK_CAP_PAR8 4 |
278 | |
279 | struct work_struct media_checker; |
280 | struct device dev; |
281 | |
282 | struct memstick_dev *card; |
283 | unsigned int retries; |
284 | bool removing; |
285 | |
286 | /* Notify the host that some requests are pending. */ |
287 | void (*request)(struct memstick_host *host); |
288 | /* Set host IO parameters (power, clock, etc). */ |
289 | int (*set_param)(struct memstick_host *host, |
290 | enum memstick_param param, |
291 | int value); |
292 | unsigned long private[] ____cacheline_aligned; |
293 | }; |
294 | |
295 | struct memstick_driver { |
296 | struct memstick_device_id *id_table; |
297 | int (*probe)(struct memstick_dev *card); |
298 | void (*remove)(struct memstick_dev *card); |
299 | int (*suspend)(struct memstick_dev *card, |
300 | pm_message_t state); |
301 | int (*resume)(struct memstick_dev *card); |
302 | |
303 | struct device_driver driver; |
304 | }; |
305 | |
306 | int memstick_register_driver(struct memstick_driver *drv); |
307 | void memstick_unregister_driver(struct memstick_driver *drv); |
308 | |
309 | struct memstick_host *memstick_alloc_host(unsigned int , |
310 | struct device *dev); |
311 | |
312 | int memstick_add_host(struct memstick_host *host); |
313 | void memstick_remove_host(struct memstick_host *host); |
314 | void memstick_free_host(struct memstick_host *host); |
315 | void memstick_detect_change(struct memstick_host *host); |
316 | void memstick_suspend_host(struct memstick_host *host); |
317 | void memstick_resume_host(struct memstick_host *host); |
318 | |
319 | void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, |
320 | const struct scatterlist *sg); |
321 | void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, |
322 | const void *buf, size_t length); |
323 | int memstick_next_req(struct memstick_host *host, |
324 | struct memstick_request **mrq); |
325 | void memstick_new_req(struct memstick_host *host); |
326 | |
327 | int memstick_set_rw_addr(struct memstick_dev *card); |
328 | |
329 | static inline void *memstick_priv(struct memstick_host *host) |
330 | { |
331 | return (void *)host->private; |
332 | } |
333 | |
334 | static inline void *memstick_get_drvdata(struct memstick_dev *card) |
335 | { |
336 | return dev_get_drvdata(dev: &card->dev); |
337 | } |
338 | |
339 | static inline void memstick_set_drvdata(struct memstick_dev *card, void *data) |
340 | { |
341 | dev_set_drvdata(dev: &card->dev, data); |
342 | } |
343 | |
344 | #endif |
345 | |