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