staging: add rts_pstor for Realtek PCIE cardreader
[deliverable/linux.git] / drivers / staging / rts_pstor / spi.c
1 /* Driver for Realtek PCI-Express card reader
2 *
3 * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
8 * later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Author:
19 * wwang (wei_wang@realsil.com.cn)
20 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
21 */
22
23 #include <linux/blkdev.h>
24 #include <linux/kthread.h>
25 #include <linux/sched.h>
26
27 #include "rtsx.h"
28 #include "rtsx_transport.h"
29 #include "rtsx_scsi.h"
30 #include "rtsx_card.h"
31 #include "spi.h"
32
33 static inline void spi_set_err_code(struct rtsx_chip *chip, u8 err_code)
34 {
35 struct spi_info *spi = &(chip->spi);
36
37 spi->err_code = err_code;
38 }
39
40 static int spi_init(struct rtsx_chip *chip)
41 {
42 RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF,
43 CS_POLARITY_LOW | DTO_MSB_FIRST | SPI_MASTER | SPI_MODE0 | SPI_AUTO);
44 RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
45
46 return STATUS_SUCCESS;
47 }
48
49 static int spi_set_init_para(struct rtsx_chip *chip)
50 {
51 struct spi_info *spi = &(chip->spi);
52 int retval;
53
54 RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, (u8)(spi->clk_div >> 8));
55 RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, (u8)(spi->clk_div));
56
57 retval = switch_clock(chip, spi->spi_clock);
58 if (retval != STATUS_SUCCESS) {
59 TRACE_RET(chip, STATUS_FAIL);
60 }
61
62 retval = select_card(chip, SPI_CARD);
63 if (retval != STATUS_SUCCESS) {
64 TRACE_RET(chip, STATUS_FAIL);
65 }
66
67 RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
68 RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
69
70 wait_timeout(10);
71
72 retval = spi_init(chip);
73 if (retval != STATUS_SUCCESS) {
74 TRACE_RET(chip, STATUS_FAIL);
75 }
76
77 return STATUS_SUCCESS;
78 }
79
80 static int sf_polling_status(struct rtsx_chip *chip, int msec)
81 {
82 int retval;
83
84 rtsx_init_cmd(chip);
85
86 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, SPI_RDSR);
87 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_POLLING_MODE0);
88 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
89
90 retval = rtsx_send_cmd(chip, 0, msec);
91 if (retval < 0) {
92 rtsx_clear_spi_error(chip);
93 spi_set_err_code(chip, SPI_BUSY_ERR);
94 TRACE_RET(chip, STATUS_FAIL);
95 }
96
97 return STATUS_SUCCESS;
98 }
99
100 static int sf_enable_write(struct rtsx_chip *chip, u8 ins)
101 {
102 struct spi_info *spi = &(chip->spi);
103 int retval;
104
105 if (!spi->write_en)
106 return STATUS_SUCCESS;
107
108 rtsx_init_cmd(chip);
109
110 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
111 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
112 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
113 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
114
115 retval = rtsx_send_cmd(chip, 0, 100);
116 if (retval < 0) {
117 rtsx_clear_spi_error(chip);
118 spi_set_err_code(chip, SPI_HW_ERR);
119 TRACE_RET(chip, STATUS_FAIL);
120 }
121
122 return STATUS_SUCCESS;
123 }
124
125 static int sf_disable_write(struct rtsx_chip *chip, u8 ins)
126 {
127 struct spi_info *spi = &(chip->spi);
128 int retval;
129
130 if (!spi->write_en)
131 return STATUS_SUCCESS;
132
133 rtsx_init_cmd(chip);
134
135 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
136 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
137 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
138 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
139
140 retval = rtsx_send_cmd(chip, 0, 100);
141 if (retval < 0) {
142 rtsx_clear_spi_error(chip);
143 spi_set_err_code(chip, SPI_HW_ERR);
144 TRACE_RET(chip, STATUS_FAIL);
145 }
146
147 return STATUS_SUCCESS;
148 }
149
150 static void sf_program(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr, u16 len)
151 {
152 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
153 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
154 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)len);
155 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(len >> 8));
156 if (addr_mode) {
157 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
158 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
159 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
160 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADO_MODE0);
161 } else {
162 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0);
163 }
164 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
165 }
166
167 static int sf_erase(struct rtsx_chip *chip, u8 ins, u8 addr_mode, u32 addr)
168 {
169 int retval;
170
171 rtsx_init_cmd(chip);
172
173 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
174 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
175 if (addr_mode) {
176 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
177 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
178 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
179 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
180 } else {
181 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
182 }
183 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
184
185 retval = rtsx_send_cmd(chip, 0, 100);
186 if (retval < 0) {
187 rtsx_clear_spi_error(chip);
188 spi_set_err_code(chip, SPI_HW_ERR);
189 TRACE_RET(chip, STATUS_FAIL);
190 }
191
192 return STATUS_SUCCESS;
193 }
194
195 static int spi_init_eeprom(struct rtsx_chip *chip)
196 {
197 int retval;
198 int clk;
199
200 if (chip->asic_code) {
201 clk = 30;
202 } else {
203 clk = CLK_30;
204 }
205
206 RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER1, 0xFF, 0x00);
207 RTSX_WRITE_REG(chip, SPI_CLK_DIVIDER0, 0xFF, 0x27);
208
209 retval = switch_clock(chip, clk);
210 if (retval != STATUS_SUCCESS) {
211 TRACE_RET(chip, STATUS_FAIL);
212 }
213
214 retval = select_card(chip, SPI_CARD);
215 if (retval != STATUS_SUCCESS) {
216 TRACE_RET(chip, STATUS_FAIL);
217 }
218
219 RTSX_WRITE_REG(chip, CARD_CLK_EN, SPI_CLK_EN, SPI_CLK_EN);
220 RTSX_WRITE_REG(chip, CARD_OE, SPI_OUTPUT_EN, SPI_OUTPUT_EN);
221
222 wait_timeout(10);
223
224 RTSX_WRITE_REG(chip, SPI_CONTROL, 0xFF, CS_POLARITY_HIGH | SPI_EEPROM_AUTO);
225 RTSX_WRITE_REG(chip, SPI_TCTL, EDO_TIMING_MASK, SAMPLE_DELAY_HALF);
226
227 return STATUS_SUCCESS;
228 }
229
230 int spi_eeprom_program_enable(struct rtsx_chip *chip)
231 {
232 int retval;
233
234 rtsx_init_cmd(chip);
235
236 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x86);
237 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x13);
238 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
239 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
240
241 retval = rtsx_send_cmd(chip, 0, 100);
242 if (retval < 0) {
243 TRACE_RET(chip, STATUS_FAIL);
244 }
245
246 return STATUS_SUCCESS;
247 }
248
249 int spi_erase_eeprom_chip(struct rtsx_chip *chip)
250 {
251 int retval;
252
253 retval = spi_init_eeprom(chip);
254 if (retval != STATUS_SUCCESS) {
255 TRACE_RET(chip, STATUS_FAIL);
256 }
257
258 retval = spi_eeprom_program_enable(chip);
259 if (retval != STATUS_SUCCESS) {
260 TRACE_RET(chip, STATUS_FAIL);
261 }
262
263 rtsx_init_cmd(chip);
264
265 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
266 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
267 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x12);
268 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x84);
269 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
270 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
271
272 retval = rtsx_send_cmd(chip, 0, 100);
273 if (retval < 0) {
274 TRACE_RET(chip, STATUS_FAIL);
275 }
276
277 RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
278
279 return STATUS_SUCCESS;
280 }
281
282 int spi_erase_eeprom_byte(struct rtsx_chip *chip, u16 addr)
283 {
284 int retval;
285
286 retval = spi_init_eeprom(chip);
287 if (retval != STATUS_SUCCESS) {
288 TRACE_RET(chip, STATUS_FAIL);
289 }
290
291 retval = spi_eeprom_program_enable(chip);
292 if (retval != STATUS_SUCCESS) {
293 TRACE_RET(chip, STATUS_FAIL);
294 }
295
296 rtsx_init_cmd(chip);
297
298 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
299 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
300 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x07);
301 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
302 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
303 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
304 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
305 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
306
307 retval = rtsx_send_cmd(chip, 0, 100);
308 if (retval < 0) {
309 TRACE_RET(chip, STATUS_FAIL);
310 }
311
312 RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
313
314 return STATUS_SUCCESS;
315 }
316
317
318 int spi_read_eeprom(struct rtsx_chip *chip, u16 addr, u8 *val)
319 {
320 int retval;
321 u8 data;
322
323 retval = spi_init_eeprom(chip);
324 if (retval != STATUS_SUCCESS) {
325 TRACE_RET(chip, STATUS_FAIL);
326 }
327
328 rtsx_init_cmd(chip);
329
330 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
331 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
332 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x06);
333 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
334 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
335 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x46);
336 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
337 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
338 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
339
340 retval = rtsx_send_cmd(chip, 0, 100);
341 if (retval < 0) {
342 TRACE_RET(chip, STATUS_FAIL);
343 }
344
345 wait_timeout(5);
346 RTSX_READ_REG(chip, SPI_DATA, &data);
347
348 if (val) {
349 *val = data;
350 }
351
352 RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
353
354 return STATUS_SUCCESS;
355 }
356
357 int spi_write_eeprom(struct rtsx_chip *chip, u16 addr, u8 val)
358 {
359 int retval;
360
361 retval = spi_init_eeprom(chip);
362 if (retval != STATUS_SUCCESS) {
363 TRACE_RET(chip, STATUS_FAIL);
364 }
365
366 retval = spi_eeprom_program_enable(chip);
367 if (retval != STATUS_SUCCESS) {
368 TRACE_RET(chip, STATUS_FAIL);
369 }
370
371 rtsx_init_cmd(chip);
372
373 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO_DIR, 0x01, 0);
374 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, RING_BUFFER);
375 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, 0x05);
376 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, val);
377 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
378 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
379 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, 0x4E);
380 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
381 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
382
383 retval = rtsx_send_cmd(chip, 0, 100);
384 if (retval < 0) {
385 TRACE_RET(chip, STATUS_FAIL);
386 }
387
388 RTSX_WRITE_REG(chip, CARD_GPIO_DIR, 0x01, 0x01);
389
390 return STATUS_SUCCESS;
391 }
392
393
394 int spi_get_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
395 {
396 struct spi_info *spi = &(chip->spi);
397
398 RTSX_DEBUGP("spi_get_status: err_code = 0x%x\n", spi->err_code);
399 rtsx_stor_set_xfer_buf(&(spi->err_code), min((int)scsi_bufflen(srb), 1), srb);
400 scsi_set_resid(srb, scsi_bufflen(srb) - 1);
401
402 return STATUS_SUCCESS;
403 }
404
405 int spi_set_parameter(struct scsi_cmnd *srb, struct rtsx_chip *chip)
406 {
407 struct spi_info *spi = &(chip->spi);
408
409 spi_set_err_code(chip, SPI_NO_ERR);
410
411 if (chip->asic_code) {
412 spi->spi_clock = ((u16)(srb->cmnd[8]) << 8) | srb->cmnd[9];
413 } else {
414 spi->spi_clock = srb->cmnd[3];
415 }
416
417 spi->clk_div = ((u16)(srb->cmnd[4]) << 8) | srb->cmnd[5];
418 spi->write_en = srb->cmnd[6];
419
420 RTSX_DEBUGP("spi_set_parameter: spi_clock = %d, clk_div = %d, write_en = %d\n",
421 spi->spi_clock, spi->clk_div, spi->write_en);
422
423 return STATUS_SUCCESS;
424 }
425
426 int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip)
427 {
428 int retval;
429 u16 len;
430 u8 *buf;
431
432 spi_set_err_code(chip, SPI_NO_ERR);
433
434 len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
435 if (len > 512) {
436 spi_set_err_code(chip, SPI_INVALID_COMMAND);
437 TRACE_RET(chip, STATUS_FAIL);
438 }
439
440 retval = spi_set_init_para(chip);
441 if (retval != STATUS_SUCCESS) {
442 spi_set_err_code(chip, SPI_HW_ERR);
443 TRACE_RET(chip, STATUS_FAIL);
444 }
445
446 rtsx_init_cmd(chip);
447
448 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
449
450 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, srb->cmnd[3]);
451 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, srb->cmnd[4]);
452 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, srb->cmnd[5]);
453 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, srb->cmnd[6]);
454 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
455 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, srb->cmnd[7]);
456 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, srb->cmnd[8]);
457
458 if (len == 0) {
459 if (srb->cmnd[9]) {
460 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
461 0xFF, SPI_TRANSFER0_START | SPI_CA_MODE0);
462 } else {
463 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
464 0xFF, SPI_TRANSFER0_START | SPI_C_MODE0);
465 }
466 } else {
467 if (srb->cmnd[9]) {
468 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
469 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
470 } else {
471 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0,
472 0xFF, SPI_TRANSFER0_START | SPI_CDI_MODE0);
473 }
474 }
475
476 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
477
478 retval = rtsx_send_cmd(chip, 0, 100);
479 if (retval < 0) {
480 rtsx_clear_spi_error(chip);
481 spi_set_err_code(chip, SPI_HW_ERR);
482 TRACE_RET(chip, STATUS_FAIL);
483 }
484
485 if (len) {
486 buf = (u8 *)kmalloc(len, GFP_KERNEL);
487 if (!buf) {
488 TRACE_RET(chip, STATUS_ERROR);
489 }
490
491 retval = rtsx_read_ppbuf(chip, buf, len);
492 if (retval != STATUS_SUCCESS) {
493 spi_set_err_code(chip, SPI_READ_ERR);
494 kfree(buf);
495 TRACE_RET(chip, STATUS_FAIL);
496 }
497
498 rtsx_stor_set_xfer_buf(buf, scsi_bufflen(srb), srb);
499 scsi_set_resid(srb, 0);
500
501 kfree(buf);
502 }
503
504 return STATUS_SUCCESS;
505 }
506
507 int spi_read_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
508 {
509 int retval;
510 unsigned int index = 0, offset = 0;
511 u8 ins, slow_read;
512 u32 addr;
513 u16 len;
514 u8 *buf;
515
516 spi_set_err_code(chip, SPI_NO_ERR);
517
518 ins = srb->cmnd[3];
519 addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
520 len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
521 slow_read = srb->cmnd[9];
522
523 retval = spi_set_init_para(chip);
524 if (retval != STATUS_SUCCESS) {
525 spi_set_err_code(chip, SPI_HW_ERR);
526 TRACE_RET(chip, STATUS_FAIL);
527 }
528
529 buf = (u8 *)rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL);
530 if (buf == NULL) {
531 TRACE_RET(chip, STATUS_ERROR);
532 }
533
534 while (len) {
535 u16 pagelen = SF_PAGE_LEN - (u8)addr;
536
537 if (pagelen > len) {
538 pagelen = len;
539 }
540
541 rtsx_init_cmd(chip);
542
543 trans_dma_enable(DMA_FROM_DEVICE, chip, 256, DMA_256);
544
545 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
546
547 if (slow_read) {
548 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR0, 0xFF, (u8)addr);
549 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)(addr >> 8));
550 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 16));
551 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
552 } else {
553 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR1, 0xFF, (u8)addr);
554 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR2, 0xFF, (u8)(addr >> 8));
555 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_ADDR3, 0xFF, (u8)(addr >> 16));
556 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_32);
557 }
558
559 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, (u8)(pagelen >> 8));
560 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, (u8)pagelen);
561
562 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CADI_MODE0);
563 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
564
565 rtsx_send_cmd_no_wait(chip);
566
567 retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000);
568 if (retval < 0) {
569 rtsx_free_dma_buf(chip, buf);
570 rtsx_clear_spi_error(chip);
571 spi_set_err_code(chip, SPI_HW_ERR);
572 TRACE_RET(chip, STATUS_FAIL);
573 }
574
575 rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, TO_XFER_BUF);
576
577 addr += pagelen;
578 len -= pagelen;
579 }
580
581 scsi_set_resid(srb, 0);
582 rtsx_free_dma_buf(chip, buf);
583
584 return STATUS_SUCCESS;
585 }
586
587 int spi_write_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
588 {
589 int retval;
590 u8 ins, program_mode;
591 u32 addr;
592 u16 len;
593 u8 *buf;
594 unsigned int index = 0, offset = 0;
595
596 spi_set_err_code(chip, SPI_NO_ERR);
597
598 ins = srb->cmnd[3];
599 addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
600 len = ((u16)(srb->cmnd[7]) << 8) | srb->cmnd[8];
601 program_mode = srb->cmnd[9];
602
603 retval = spi_set_init_para(chip);
604 if (retval != STATUS_SUCCESS) {
605 spi_set_err_code(chip, SPI_HW_ERR);
606 TRACE_RET(chip, STATUS_FAIL);
607 }
608
609 if (program_mode == BYTE_PROGRAM) {
610 buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL);
611 if (!buf) {
612 TRACE_RET(chip, STATUS_ERROR);
613 }
614
615 while (len) {
616 retval = sf_enable_write(chip, SPI_WREN);
617 if (retval != STATUS_SUCCESS) {
618 rtsx_free_dma_buf(chip, buf);
619 TRACE_RET(chip, STATUS_FAIL);
620 }
621
622 rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
623
624 rtsx_init_cmd(chip);
625
626 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
627 rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
628 sf_program(chip, ins, 1, addr, 1);
629
630 retval = rtsx_send_cmd(chip, 0, 100);
631 if (retval < 0) {
632 rtsx_free_dma_buf(chip, buf);
633 rtsx_clear_spi_error(chip);
634 spi_set_err_code(chip, SPI_HW_ERR);
635 TRACE_RET(chip, STATUS_FAIL);
636 }
637
638 retval = sf_polling_status(chip, 100);
639 if (retval != STATUS_SUCCESS) {
640 rtsx_free_dma_buf(chip, buf);
641 TRACE_RET(chip, STATUS_FAIL);
642 }
643
644 addr++;
645 len--;
646 }
647
648 rtsx_free_dma_buf(chip, buf);
649
650 } else if (program_mode == AAI_PROGRAM) {
651 int first_byte = 1;
652
653 retval = sf_enable_write(chip, SPI_WREN);
654 if (retval != STATUS_SUCCESS) {
655 TRACE_RET(chip, STATUS_FAIL);
656 }
657
658 buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL);
659 if (!buf) {
660 TRACE_RET(chip, STATUS_ERROR);
661 }
662
663 while (len) {
664 rtsx_stor_access_xfer_buf(buf, 1, srb, &index, &offset, FROM_XFER_BUF);
665
666 rtsx_init_cmd(chip);
667
668 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
669 rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, buf[0]);
670 if (first_byte) {
671 sf_program(chip, ins, 1, addr, 1);
672 first_byte = 0;
673 } else {
674 sf_program(chip, ins, 0, 0, 1);
675 }
676
677 retval = rtsx_send_cmd(chip, 0, 100);
678 if (retval < 0) {
679 rtsx_free_dma_buf(chip, buf);
680 rtsx_clear_spi_error(chip);
681 spi_set_err_code(chip, SPI_HW_ERR);
682 TRACE_RET(chip, STATUS_FAIL);
683 }
684
685 retval = sf_polling_status(chip, 100);
686 if (retval != STATUS_SUCCESS) {
687 rtsx_free_dma_buf(chip, buf);
688 TRACE_RET(chip, STATUS_FAIL);
689 }
690
691 len--;
692 }
693
694 rtsx_free_dma_buf(chip, buf);
695
696 retval = sf_disable_write(chip, SPI_WRDI);
697 if (retval != STATUS_SUCCESS) {
698 TRACE_RET(chip, STATUS_FAIL);
699 }
700
701 retval = sf_polling_status(chip, 100);
702 if (retval != STATUS_SUCCESS) {
703 TRACE_RET(chip, STATUS_FAIL);
704 }
705 } else if (program_mode == PAGE_PROGRAM) {
706 buf = rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL);
707 if (!buf) {
708 TRACE_RET(chip, STATUS_NOMEM);
709 }
710
711 while (len) {
712 u16 pagelen = SF_PAGE_LEN - (u8)addr;
713
714 if (pagelen > len) {
715 pagelen = len;
716 }
717
718 retval = sf_enable_write(chip, SPI_WREN);
719 if (retval != STATUS_SUCCESS) {
720 rtsx_free_dma_buf(chip, buf);
721 TRACE_RET(chip, STATUS_FAIL);
722 }
723
724 rtsx_init_cmd(chip);
725
726 trans_dma_enable(DMA_TO_DEVICE, chip, 256, DMA_256);
727 sf_program(chip, ins, 1, addr, pagelen);
728
729 rtsx_send_cmd_no_wait(chip);
730
731 rtsx_stor_access_xfer_buf(buf, pagelen, srb, &index, &offset, FROM_XFER_BUF);
732
733 retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100);
734 if (retval < 0) {
735 rtsx_free_dma_buf(chip, buf);
736 rtsx_clear_spi_error(chip);
737 spi_set_err_code(chip, SPI_HW_ERR);
738 TRACE_RET(chip, STATUS_FAIL);
739 }
740
741 retval = sf_polling_status(chip, 100);
742 if (retval != STATUS_SUCCESS) {
743 rtsx_free_dma_buf(chip, buf);
744 TRACE_RET(chip, STATUS_FAIL);
745 }
746
747 addr += pagelen;
748 len -= pagelen;
749 }
750
751 rtsx_free_dma_buf(chip, buf);
752 } else {
753 spi_set_err_code(chip, SPI_INVALID_COMMAND);
754 TRACE_RET(chip, STATUS_FAIL);
755 }
756
757 return STATUS_SUCCESS;
758 }
759
760 int spi_erase_flash(struct scsi_cmnd *srb, struct rtsx_chip *chip)
761 {
762 int retval;
763 u8 ins, erase_mode;
764 u32 addr;
765
766 spi_set_err_code(chip, SPI_NO_ERR);
767
768 ins = srb->cmnd[3];
769 addr = ((u32)(srb->cmnd[4]) << 16) | ((u32)(srb->cmnd[5]) << 8) | srb->cmnd[6];
770 erase_mode = srb->cmnd[9];
771
772 retval = spi_set_init_para(chip);
773 if (retval != STATUS_SUCCESS) {
774 spi_set_err_code(chip, SPI_HW_ERR);
775 TRACE_RET(chip, STATUS_FAIL);
776 }
777
778 if (erase_mode == PAGE_ERASE) {
779 retval = sf_enable_write(chip, SPI_WREN);
780 if (retval != STATUS_SUCCESS) {
781 TRACE_RET(chip, STATUS_FAIL);
782 }
783
784 retval = sf_erase(chip, ins, 1, addr);
785 if (retval != STATUS_SUCCESS) {
786 TRACE_RET(chip, STATUS_FAIL);
787 }
788 } else if (erase_mode == CHIP_ERASE) {
789 retval = sf_enable_write(chip, SPI_WREN);
790 if (retval != STATUS_SUCCESS) {
791 TRACE_RET(chip, STATUS_FAIL);
792 }
793
794 retval = sf_erase(chip, ins, 0, 0);
795 if (retval != STATUS_SUCCESS) {
796 TRACE_RET(chip, STATUS_FAIL);
797 }
798 } else {
799 spi_set_err_code(chip, SPI_INVALID_COMMAND);
800 TRACE_RET(chip, STATUS_FAIL);
801 }
802
803 return STATUS_SUCCESS;
804 }
805
806 int spi_write_flash_status(struct scsi_cmnd *srb, struct rtsx_chip *chip)
807 {
808 int retval;
809 u8 ins, status, ewsr;
810
811 ins = srb->cmnd[3];
812 status = srb->cmnd[4];
813 ewsr = srb->cmnd[5];
814
815 retval = spi_set_init_para(chip);
816 if (retval != STATUS_SUCCESS) {
817 spi_set_err_code(chip, SPI_HW_ERR);
818 TRACE_RET(chip, STATUS_FAIL);
819 }
820
821 retval = sf_enable_write(chip, ewsr);
822 if (retval != STATUS_SUCCESS) {
823 TRACE_RET(chip, STATUS_FAIL);
824 }
825
826 rtsx_init_cmd(chip);
827
828 rtsx_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER);
829
830 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_COMMAND, 0xFF, ins);
831 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_CA_NUMBER, 0xFF, SPI_COMMAND_BIT_8 | SPI_ADDRESS_BIT_24);
832 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH1, 0xFF, 0);
833 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_LENGTH0, 0xFF, 1);
834 rtsx_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2, 0xFF, status);
835 rtsx_add_cmd(chip, WRITE_REG_CMD, SPI_TRANSFER0, 0xFF, SPI_TRANSFER0_START | SPI_CDO_MODE0);
836 rtsx_add_cmd(chip, CHECK_REG_CMD, SPI_TRANSFER0, SPI_TRANSFER0_END, SPI_TRANSFER0_END);
837
838 retval = rtsx_send_cmd(chip, 0, 100);
839 if (retval != STATUS_SUCCESS) {
840 rtsx_clear_spi_error(chip);
841 spi_set_err_code(chip, SPI_HW_ERR);
842 TRACE_RET(chip, STATUS_FAIL);
843 }
844
845 return STATUS_SUCCESS;
846 }
847
This page took 0.049923 seconds and 5 git commands to generate.