1 /* Driver for Realtek PCI-Express card reader
3 * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved.
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
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.
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/>.
19 * wwang (wei_wang@realsil.com.cn)
20 * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China
23 #include <linux/blkdev.h>
24 #include <linux/kthread.h>
25 #include <linux/sched.h>
28 #include "rtsx_transport.h"
29 #include "rtsx_scsi.h"
30 #include "rtsx_card.h"
33 static inline void spi_set_err_code(struct rtsx_chip
*chip
, u8 err_code
)
35 struct spi_info
*spi
= &(chip
->spi
);
37 spi
->err_code
= err_code
;
40 static int spi_init(struct rtsx_chip
*chip
)
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
);
46 return STATUS_SUCCESS
;
49 static int spi_set_init_para(struct rtsx_chip
*chip
)
51 struct spi_info
*spi
= &(chip
->spi
);
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
));
57 retval
= switch_clock(chip
, spi
->spi_clock
);
58 if (retval
!= STATUS_SUCCESS
) {
59 TRACE_RET(chip
, STATUS_FAIL
);
62 retval
= select_card(chip
, SPI_CARD
);
63 if (retval
!= STATUS_SUCCESS
) {
64 TRACE_RET(chip
, STATUS_FAIL
);
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
);
72 retval
= spi_init(chip
);
73 if (retval
!= STATUS_SUCCESS
) {
74 TRACE_RET(chip
, STATUS_FAIL
);
77 return STATUS_SUCCESS
;
80 static int sf_polling_status(struct rtsx_chip
*chip
, int msec
)
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
);
90 retval
= rtsx_send_cmd(chip
, 0, msec
);
92 rtsx_clear_spi_error(chip
);
93 spi_set_err_code(chip
, SPI_BUSY_ERR
);
94 TRACE_RET(chip
, STATUS_FAIL
);
97 return STATUS_SUCCESS
;
100 static int sf_enable_write(struct rtsx_chip
*chip
, u8 ins
)
102 struct spi_info
*spi
= &(chip
->spi
);
106 return STATUS_SUCCESS
;
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
);
115 retval
= rtsx_send_cmd(chip
, 0, 100);
117 rtsx_clear_spi_error(chip
);
118 spi_set_err_code(chip
, SPI_HW_ERR
);
119 TRACE_RET(chip
, STATUS_FAIL
);
122 return STATUS_SUCCESS
;
125 static int sf_disable_write(struct rtsx_chip
*chip
, u8 ins
)
127 struct spi_info
*spi
= &(chip
->spi
);
131 return STATUS_SUCCESS
;
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
);
140 retval
= rtsx_send_cmd(chip
, 0, 100);
142 rtsx_clear_spi_error(chip
);
143 spi_set_err_code(chip
, SPI_HW_ERR
);
144 TRACE_RET(chip
, STATUS_FAIL
);
147 return STATUS_SUCCESS
;
150 static void sf_program(struct rtsx_chip
*chip
, u8 ins
, u8 addr_mode
, u32 addr
, u16 len
)
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));
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
);
162 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
, 0xFF, SPI_TRANSFER0_START
| SPI_CDO_MODE0
);
164 rtsx_add_cmd(chip
, CHECK_REG_CMD
, SPI_TRANSFER0
, SPI_TRANSFER0_END
, SPI_TRANSFER0_END
);
167 static int sf_erase(struct rtsx_chip
*chip
, u8 ins
, u8 addr_mode
, u32 addr
)
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
);
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
);
181 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
, 0xFF, SPI_TRANSFER0_START
| SPI_C_MODE0
);
183 rtsx_add_cmd(chip
, CHECK_REG_CMD
, SPI_TRANSFER0
, SPI_TRANSFER0_END
, SPI_TRANSFER0_END
);
185 retval
= rtsx_send_cmd(chip
, 0, 100);
187 rtsx_clear_spi_error(chip
);
188 spi_set_err_code(chip
, SPI_HW_ERR
);
189 TRACE_RET(chip
, STATUS_FAIL
);
192 return STATUS_SUCCESS
;
195 static int spi_init_eeprom(struct rtsx_chip
*chip
)
200 if (chip
->asic_code
) {
206 RTSX_WRITE_REG(chip
, SPI_CLK_DIVIDER1
, 0xFF, 0x00);
207 RTSX_WRITE_REG(chip
, SPI_CLK_DIVIDER0
, 0xFF, 0x27);
209 retval
= switch_clock(chip
, clk
);
210 if (retval
!= STATUS_SUCCESS
) {
211 TRACE_RET(chip
, STATUS_FAIL
);
214 retval
= select_card(chip
, SPI_CARD
);
215 if (retval
!= STATUS_SUCCESS
) {
216 TRACE_RET(chip
, STATUS_FAIL
);
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
);
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
);
227 return STATUS_SUCCESS
;
230 int spi_eeprom_program_enable(struct rtsx_chip
*chip
)
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
);
241 retval
= rtsx_send_cmd(chip
, 0, 100);
243 TRACE_RET(chip
, STATUS_FAIL
);
246 return STATUS_SUCCESS
;
249 int spi_erase_eeprom_chip(struct rtsx_chip
*chip
)
253 retval
= spi_init_eeprom(chip
);
254 if (retval
!= STATUS_SUCCESS
) {
255 TRACE_RET(chip
, STATUS_FAIL
);
258 retval
= spi_eeprom_program_enable(chip
);
259 if (retval
!= STATUS_SUCCESS
) {
260 TRACE_RET(chip
, STATUS_FAIL
);
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
);
272 retval
= rtsx_send_cmd(chip
, 0, 100);
274 TRACE_RET(chip
, STATUS_FAIL
);
277 RTSX_WRITE_REG(chip
, CARD_GPIO_DIR
, 0x01, 0x01);
279 return STATUS_SUCCESS
;
282 int spi_erase_eeprom_byte(struct rtsx_chip
*chip
, u16 addr
)
286 retval
= spi_init_eeprom(chip
);
287 if (retval
!= STATUS_SUCCESS
) {
288 TRACE_RET(chip
, STATUS_FAIL
);
291 retval
= spi_eeprom_program_enable(chip
);
292 if (retval
!= STATUS_SUCCESS
) {
293 TRACE_RET(chip
, STATUS_FAIL
);
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
);
307 retval
= rtsx_send_cmd(chip
, 0, 100);
309 TRACE_RET(chip
, STATUS_FAIL
);
312 RTSX_WRITE_REG(chip
, CARD_GPIO_DIR
, 0x01, 0x01);
314 return STATUS_SUCCESS
;
318 int spi_read_eeprom(struct rtsx_chip
*chip
, u16 addr
, u8
*val
)
323 retval
= spi_init_eeprom(chip
);
324 if (retval
!= STATUS_SUCCESS
) {
325 TRACE_RET(chip
, STATUS_FAIL
);
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
);
340 retval
= rtsx_send_cmd(chip
, 0, 100);
342 TRACE_RET(chip
, STATUS_FAIL
);
346 RTSX_READ_REG(chip
, SPI_DATA
, &data
);
352 RTSX_WRITE_REG(chip
, CARD_GPIO_DIR
, 0x01, 0x01);
354 return STATUS_SUCCESS
;
357 int spi_write_eeprom(struct rtsx_chip
*chip
, u16 addr
, u8 val
)
361 retval
= spi_init_eeprom(chip
);
362 if (retval
!= STATUS_SUCCESS
) {
363 TRACE_RET(chip
, STATUS_FAIL
);
366 retval
= spi_eeprom_program_enable(chip
);
367 if (retval
!= STATUS_SUCCESS
) {
368 TRACE_RET(chip
, STATUS_FAIL
);
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
);
383 retval
= rtsx_send_cmd(chip
, 0, 100);
385 TRACE_RET(chip
, STATUS_FAIL
);
388 RTSX_WRITE_REG(chip
, CARD_GPIO_DIR
, 0x01, 0x01);
390 return STATUS_SUCCESS
;
394 int spi_get_status(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
396 struct spi_info
*spi
= &(chip
->spi
);
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);
402 return STATUS_SUCCESS
;
405 int spi_set_parameter(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
407 struct spi_info
*spi
= &(chip
->spi
);
409 spi_set_err_code(chip
, SPI_NO_ERR
);
411 if (chip
->asic_code
) {
412 spi
->spi_clock
= ((u16
)(srb
->cmnd
[8]) << 8) | srb
->cmnd
[9];
414 spi
->spi_clock
= srb
->cmnd
[3];
417 spi
->clk_div
= ((u16
)(srb
->cmnd
[4]) << 8) | srb
->cmnd
[5];
418 spi
->write_en
= srb
->cmnd
[6];
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
);
423 return STATUS_SUCCESS
;
426 int spi_read_flash_id(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
432 spi_set_err_code(chip
, SPI_NO_ERR
);
434 len
= ((u16
)(srb
->cmnd
[7]) << 8) | srb
->cmnd
[8];
436 spi_set_err_code(chip
, SPI_INVALID_COMMAND
);
437 TRACE_RET(chip
, STATUS_FAIL
);
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
);
448 rtsx_add_cmd(chip
, WRITE_REG_CMD
, CARD_DATA_SOURCE
, 0x01, PINGPONG_BUFFER
);
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]);
460 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
,
461 0xFF, SPI_TRANSFER0_START
| SPI_CA_MODE0
);
463 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
,
464 0xFF, SPI_TRANSFER0_START
| SPI_C_MODE0
);
468 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
,
469 0xFF, SPI_TRANSFER0_START
| SPI_CADI_MODE0
);
471 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_TRANSFER0
,
472 0xFF, SPI_TRANSFER0_START
| SPI_CDI_MODE0
);
476 rtsx_add_cmd(chip
, CHECK_REG_CMD
, SPI_TRANSFER0
, SPI_TRANSFER0_END
, SPI_TRANSFER0_END
);
478 retval
= rtsx_send_cmd(chip
, 0, 100);
480 rtsx_clear_spi_error(chip
);
481 spi_set_err_code(chip
, SPI_HW_ERR
);
482 TRACE_RET(chip
, STATUS_FAIL
);
486 buf
= (u8
*)kmalloc(len
, GFP_KERNEL
);
488 TRACE_RET(chip
, STATUS_ERROR
);
491 retval
= rtsx_read_ppbuf(chip
, buf
, len
);
492 if (retval
!= STATUS_SUCCESS
) {
493 spi_set_err_code(chip
, SPI_READ_ERR
);
495 TRACE_RET(chip
, STATUS_FAIL
);
498 rtsx_stor_set_xfer_buf(buf
, scsi_bufflen(srb
), srb
);
499 scsi_set_resid(srb
, 0);
504 return STATUS_SUCCESS
;
507 int spi_read_flash(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
510 unsigned int index
= 0, offset
= 0;
516 spi_set_err_code(chip
, SPI_NO_ERR
);
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];
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
);
529 buf
= (u8
*)rtsx_alloc_dma_buf(chip
, SF_PAGE_LEN
, GFP_KERNEL
);
531 TRACE_RET(chip
, STATUS_ERROR
);
535 u16 pagelen
= SF_PAGE_LEN
- (u8
)addr
;
543 trans_dma_enable(DMA_FROM_DEVICE
, chip
, 256, DMA_256
);
545 rtsx_add_cmd(chip
, WRITE_REG_CMD
, SPI_COMMAND
, 0xFF, ins
);
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
);
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
);
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
);
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
);
565 rtsx_send_cmd_no_wait(chip
);
567 retval
= rtsx_transfer_data(chip
, 0, buf
, pagelen
, 0, DMA_FROM_DEVICE
, 10000);
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
);
575 rtsx_stor_access_xfer_buf(buf
, pagelen
, srb
, &index
, &offset
, TO_XFER_BUF
);
581 scsi_set_resid(srb
, 0);
582 rtsx_free_dma_buf(chip
, buf
);
584 return STATUS_SUCCESS
;
587 int spi_write_flash(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
590 u8 ins
, program_mode
;
594 unsigned int index
= 0, offset
= 0;
596 spi_set_err_code(chip
, SPI_NO_ERR
);
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];
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
);
609 if (program_mode
== BYTE_PROGRAM
) {
610 buf
= rtsx_alloc_dma_buf(chip
, 4, GFP_KERNEL
);
612 TRACE_RET(chip
, STATUS_ERROR
);
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
);
622 rtsx_stor_access_xfer_buf(buf
, 1, srb
, &index
, &offset
, FROM_XFER_BUF
);
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);
630 retval
= rtsx_send_cmd(chip
, 0, 100);
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
);
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
);
648 rtsx_free_dma_buf(chip
, buf
);
650 } else if (program_mode
== AAI_PROGRAM
) {
653 retval
= sf_enable_write(chip
, SPI_WREN
);
654 if (retval
!= STATUS_SUCCESS
) {
655 TRACE_RET(chip
, STATUS_FAIL
);
658 buf
= rtsx_alloc_dma_buf(chip
, 4, GFP_KERNEL
);
660 TRACE_RET(chip
, STATUS_ERROR
);
664 rtsx_stor_access_xfer_buf(buf
, 1, srb
, &index
, &offset
, FROM_XFER_BUF
);
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]);
671 sf_program(chip
, ins
, 1, addr
, 1);
674 sf_program(chip
, ins
, 0, 0, 1);
677 retval
= rtsx_send_cmd(chip
, 0, 100);
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
);
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
);
694 rtsx_free_dma_buf(chip
, buf
);
696 retval
= sf_disable_write(chip
, SPI_WRDI
);
697 if (retval
!= STATUS_SUCCESS
) {
698 TRACE_RET(chip
, STATUS_FAIL
);
701 retval
= sf_polling_status(chip
, 100);
702 if (retval
!= STATUS_SUCCESS
) {
703 TRACE_RET(chip
, STATUS_FAIL
);
705 } else if (program_mode
== PAGE_PROGRAM
) {
706 buf
= rtsx_alloc_dma_buf(chip
, SF_PAGE_LEN
, GFP_KERNEL
);
708 TRACE_RET(chip
, STATUS_NOMEM
);
712 u16 pagelen
= SF_PAGE_LEN
- (u8
)addr
;
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
);
726 trans_dma_enable(DMA_TO_DEVICE
, chip
, 256, DMA_256
);
727 sf_program(chip
, ins
, 1, addr
, pagelen
);
729 rtsx_send_cmd_no_wait(chip
);
731 rtsx_stor_access_xfer_buf(buf
, pagelen
, srb
, &index
, &offset
, FROM_XFER_BUF
);
733 retval
= rtsx_transfer_data(chip
, 0, buf
, pagelen
, 0, DMA_TO_DEVICE
, 100);
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
);
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
);
751 rtsx_free_dma_buf(chip
, buf
);
753 spi_set_err_code(chip
, SPI_INVALID_COMMAND
);
754 TRACE_RET(chip
, STATUS_FAIL
);
757 return STATUS_SUCCESS
;
760 int spi_erase_flash(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
766 spi_set_err_code(chip
, SPI_NO_ERR
);
769 addr
= ((u32
)(srb
->cmnd
[4]) << 16) | ((u32
)(srb
->cmnd
[5]) << 8) | srb
->cmnd
[6];
770 erase_mode
= srb
->cmnd
[9];
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
);
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
);
784 retval
= sf_erase(chip
, ins
, 1, addr
);
785 if (retval
!= STATUS_SUCCESS
) {
786 TRACE_RET(chip
, STATUS_FAIL
);
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
);
794 retval
= sf_erase(chip
, ins
, 0, 0);
795 if (retval
!= STATUS_SUCCESS
) {
796 TRACE_RET(chip
, STATUS_FAIL
);
799 spi_set_err_code(chip
, SPI_INVALID_COMMAND
);
800 TRACE_RET(chip
, STATUS_FAIL
);
803 return STATUS_SUCCESS
;
806 int spi_write_flash_status(struct scsi_cmnd
*srb
, struct rtsx_chip
*chip
)
809 u8 ins
, status
, ewsr
;
812 status
= srb
->cmnd
[4];
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
);
821 retval
= sf_enable_write(chip
, ewsr
);
822 if (retval
!= STATUS_SUCCESS
) {
823 TRACE_RET(chip
, STATUS_FAIL
);
828 rtsx_add_cmd(chip
, WRITE_REG_CMD
, CARD_DATA_SOURCE
, 0x01, PINGPONG_BUFFER
);
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
);
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
);
845 return STATUS_SUCCESS
;
This page took 0.049923 seconds and 5 git commands to generate.