Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

memstick: Add realtek USB memstick host driver

Realtek USB memstick host driver provides memstick host support based on the
Realtek USB card reader MFD driver.

Signed-off-by: Roger Tseng <rogerable@realtek.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Roger Tseng and committed by
Lee Jones
99451dce 1d14310a

+850
+10
drivers/memstick/host/Kconfig
··· 52 52 53 53 To compile this driver as a module, choose M here: the module will 54 54 be called rtsx_pci_ms. 55 + 56 + config MEMSTICK_REALTEK_USB 57 + tristate "Realtek USB Memstick Card Interface Driver" 58 + depends on MFD_RTSX_USB 59 + help 60 + Say Y here to include driver code to support Memstick card interface 61 + of Realtek RTS5129/39 series USB card reader 62 + 63 + To compile this driver as a module, choose M here: the module will 64 + be called rts5139_ms.
+1
drivers/memstick/host/Makefile
··· 6 6 obj-$(CONFIG_MEMSTICK_JMICRON_38X) += jmb38x_ms.o 7 7 obj-$(CONFIG_MEMSTICK_R592) += r592.o 8 8 obj-$(CONFIG_MEMSTICK_REALTEK_PCI) += rtsx_pci_ms.o 9 + obj-$(CONFIG_MEMSTICK_REALTEK_USB) += rtsx_usb_ms.o
+839
drivers/memstick/host/rtsx_usb_ms.c
··· 1 + /* Realtek USB Memstick Card Interface driver 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 version 2 7 + * as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but 10 + * WITHOUT ANY WARRANTY; without even the implied warranty of 11 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 + * General Public License for more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along 15 + * with this program; if not, see <http://www.gnu.org/licenses/>. 16 + * 17 + * Author: 18 + * Roger Tseng <rogerable@realtek.com> 19 + */ 20 + 21 + #include <linux/module.h> 22 + #include <linux/highmem.h> 23 + #include <linux/delay.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/workqueue.h> 26 + #include <linux/memstick.h> 27 + #include <linux/kthread.h> 28 + #include <linux/mfd/rtsx_usb.h> 29 + #include <linux/pm_runtime.h> 30 + #include <linux/mutex.h> 31 + #include <linux/sched.h> 32 + #include <linux/completion.h> 33 + #include <asm/unaligned.h> 34 + 35 + struct rtsx_usb_ms { 36 + struct platform_device *pdev; 37 + struct rtsx_ucr *ucr; 38 + struct memstick_host *msh; 39 + struct memstick_request *req; 40 + 41 + struct mutex host_mutex; 42 + struct work_struct handle_req; 43 + 44 + struct task_struct *detect_ms; 45 + struct completion detect_ms_exit; 46 + 47 + u8 ssc_depth; 48 + unsigned int clock; 49 + int power_mode; 50 + unsigned char ifmode; 51 + bool eject; 52 + }; 53 + 54 + static inline struct device *ms_dev(struct rtsx_usb_ms *host) 55 + { 56 + return &(host->pdev->dev); 57 + } 58 + 59 + static inline void ms_clear_error(struct rtsx_usb_ms *host) 60 + { 61 + struct rtsx_ucr *ucr = host->ucr; 62 + rtsx_usb_ep0_write_register(ucr, CARD_STOP, 63 + MS_STOP | MS_CLR_ERR, 64 + MS_STOP | MS_CLR_ERR); 65 + 66 + rtsx_usb_clear_dma_err(ucr); 67 + rtsx_usb_clear_fsm_err(ucr); 68 + } 69 + 70 + #ifdef DEBUG 71 + 72 + static void ms_print_debug_regs(struct rtsx_usb_ms *host) 73 + { 74 + struct rtsx_ucr *ucr = host->ucr; 75 + u16 i; 76 + u8 *ptr; 77 + 78 + /* Print MS host internal registers */ 79 + rtsx_usb_init_cmd(ucr); 80 + 81 + /* MS_CFG to MS_INT_REG */ 82 + for (i = 0xFD40; i <= 0xFD44; i++) 83 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0); 84 + 85 + /* CARD_SHARE_MODE to CARD_GPIO */ 86 + for (i = 0xFD51; i <= 0xFD56; i++) 87 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0); 88 + 89 + /* CARD_PULL_CTLx */ 90 + for (i = 0xFD60; i <= 0xFD65; i++) 91 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, i, 0, 0); 92 + 93 + /* CARD_DATA_SOURCE, CARD_SELECT, CARD_CLK_EN, CARD_PWR_CTL */ 94 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_DATA_SOURCE, 0, 0); 95 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_SELECT, 0, 0); 96 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_CLK_EN, 0, 0); 97 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_PWR_CTL, 0, 0); 98 + 99 + rtsx_usb_send_cmd(ucr, MODE_CR, 100); 100 + rtsx_usb_get_rsp(ucr, 21, 100); 101 + 102 + ptr = ucr->rsp_buf; 103 + for (i = 0xFD40; i <= 0xFD44; i++) 104 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); 105 + for (i = 0xFD51; i <= 0xFD56; i++) 106 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); 107 + for (i = 0xFD60; i <= 0xFD65; i++) 108 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", i, *(ptr++)); 109 + 110 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_DATA_SOURCE, *(ptr++)); 111 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_SELECT, *(ptr++)); 112 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_CLK_EN, *(ptr++)); 113 + dev_dbg(ms_dev(host), "0x%04X: 0x%02x\n", CARD_PWR_CTL, *(ptr++)); 114 + } 115 + 116 + #else 117 + 118 + static void ms_print_debug_regs(struct rtsx_usb_ms *host) 119 + { 120 + } 121 + 122 + #endif 123 + 124 + static int ms_pull_ctl_disable_lqfp48(struct rtsx_ucr *ucr) 125 + { 126 + rtsx_usb_init_cmd(ucr); 127 + 128 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); 129 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); 130 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); 131 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); 132 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); 133 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); 134 + 135 + return rtsx_usb_send_cmd(ucr, MODE_C, 100); 136 + } 137 + 138 + static int ms_pull_ctl_disable_qfn24(struct rtsx_ucr *ucr) 139 + { 140 + rtsx_usb_init_cmd(ucr); 141 + 142 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); 143 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); 144 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); 145 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); 146 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); 147 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); 148 + 149 + return rtsx_usb_send_cmd(ucr, MODE_C, 100); 150 + } 151 + 152 + static int ms_pull_ctl_enable_lqfp48(struct rtsx_ucr *ucr) 153 + { 154 + rtsx_usb_init_cmd(ucr); 155 + 156 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); 157 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); 158 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); 159 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); 160 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); 161 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); 162 + 163 + return rtsx_usb_send_cmd(ucr, MODE_C, 100); 164 + } 165 + 166 + static int ms_pull_ctl_enable_qfn24(struct rtsx_ucr *ucr) 167 + { 168 + rtsx_usb_init_cmd(ucr); 169 + 170 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); 171 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); 172 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); 173 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); 174 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); 175 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); 176 + 177 + return rtsx_usb_send_cmd(ucr, MODE_C, 100); 178 + } 179 + 180 + static int ms_power_on(struct rtsx_usb_ms *host) 181 + { 182 + struct rtsx_ucr *ucr = host->ucr; 183 + int err; 184 + 185 + dev_dbg(ms_dev(host), "%s\n", __func__); 186 + 187 + rtsx_usb_init_cmd(ucr); 188 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SELECT, 0x07, MS_MOD_SEL); 189 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SHARE_MODE, 190 + CARD_SHARE_MASK, CARD_SHARE_MS); 191 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN, 192 + MS_CLK_EN, MS_CLK_EN); 193 + err = rtsx_usb_send_cmd(ucr, MODE_C, 100); 194 + if (err < 0) 195 + return err; 196 + 197 + if (CHECK_PKG(ucr, LQFP48)) 198 + err = ms_pull_ctl_enable_lqfp48(ucr); 199 + else 200 + err = ms_pull_ctl_enable_qfn24(ucr); 201 + if (err < 0) 202 + return err; 203 + 204 + err = rtsx_usb_write_register(ucr, CARD_PWR_CTL, 205 + POWER_MASK, PARTIAL_POWER_ON); 206 + if (err) 207 + return err; 208 + 209 + usleep_range(800, 1000); 210 + 211 + rtsx_usb_init_cmd(ucr); 212 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL, 213 + POWER_MASK, POWER_ON); 214 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE, 215 + MS_OUTPUT_EN, MS_OUTPUT_EN); 216 + 217 + return rtsx_usb_send_cmd(ucr, MODE_C, 100); 218 + } 219 + 220 + static int ms_power_off(struct rtsx_usb_ms *host) 221 + { 222 + struct rtsx_ucr *ucr = host->ucr; 223 + int err; 224 + 225 + dev_dbg(ms_dev(host), "%s\n", __func__); 226 + 227 + rtsx_usb_init_cmd(ucr); 228 + 229 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); 230 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); 231 + 232 + err = rtsx_usb_send_cmd(ucr, MODE_C, 100); 233 + if (err < 0) 234 + return err; 235 + 236 + if (CHECK_PKG(ucr, LQFP48)) 237 + return ms_pull_ctl_disable_lqfp48(ucr); 238 + 239 + return ms_pull_ctl_disable_qfn24(ucr); 240 + } 241 + 242 + static int ms_transfer_data(struct rtsx_usb_ms *host, unsigned char data_dir, 243 + u8 tpc, u8 cfg, struct scatterlist *sg) 244 + { 245 + struct rtsx_ucr *ucr = host->ucr; 246 + int err; 247 + unsigned int length = sg->length; 248 + u16 sec_cnt = (u16)(length / 512); 249 + u8 trans_mode, dma_dir, flag; 250 + unsigned int pipe; 251 + struct memstick_dev *card = host->msh->card; 252 + 253 + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x, data_dir = %s, length = %d\n", 254 + __func__, tpc, (data_dir == READ) ? "READ" : "WRITE", 255 + length); 256 + 257 + if (data_dir == READ) { 258 + flag = MODE_CDIR; 259 + dma_dir = DMA_DIR_FROM_CARD; 260 + if (card->id.type != MEMSTICK_TYPE_PRO) 261 + trans_mode = MS_TM_NORMAL_READ; 262 + else 263 + trans_mode = MS_TM_AUTO_READ; 264 + pipe = usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN); 265 + } else { 266 + flag = MODE_CDOR; 267 + dma_dir = DMA_DIR_TO_CARD; 268 + if (card->id.type != MEMSTICK_TYPE_PRO) 269 + trans_mode = MS_TM_NORMAL_WRITE; 270 + else 271 + trans_mode = MS_TM_AUTO_WRITE; 272 + pipe = usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT); 273 + } 274 + 275 + rtsx_usb_init_cmd(ucr); 276 + 277 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 278 + if (card->id.type == MEMSTICK_TYPE_PRO) { 279 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_SECTOR_CNT_H, 280 + 0xFF, (u8)(sec_cnt >> 8)); 281 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_SECTOR_CNT_L, 282 + 0xFF, (u8)sec_cnt); 283 + } 284 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 285 + 286 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC3, 287 + 0xFF, (u8)(length >> 24)); 288 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC2, 289 + 0xFF, (u8)(length >> 16)); 290 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC1, 291 + 0xFF, (u8)(length >> 8)); 292 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_TC0, 0xFF, 293 + (u8)length); 294 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MC_DMA_CTL, 295 + 0x03 | DMA_PACK_SIZE_MASK, dma_dir | DMA_EN | DMA_512); 296 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE, 297 + 0x01, RING_BUFFER); 298 + 299 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER, 300 + 0xFF, MS_TRANSFER_START | trans_mode); 301 + rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER, 302 + MS_TRANSFER_END, MS_TRANSFER_END); 303 + 304 + err = rtsx_usb_send_cmd(ucr, flag | STAGE_MS_STATUS, 100); 305 + if (err) 306 + return err; 307 + 308 + err = rtsx_usb_transfer_data(ucr, pipe, sg, length, 309 + 1, NULL, 10000); 310 + if (err) 311 + goto err_out; 312 + 313 + err = rtsx_usb_get_rsp(ucr, 3, 15000); 314 + if (err) 315 + goto err_out; 316 + 317 + if (ucr->rsp_buf[0] & MS_TRANSFER_ERR || 318 + ucr->rsp_buf[1] & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { 319 + err = -EIO; 320 + goto err_out; 321 + } 322 + return 0; 323 + err_out: 324 + ms_clear_error(host); 325 + return err; 326 + } 327 + 328 + static int ms_write_bytes(struct rtsx_usb_ms *host, u8 tpc, 329 + u8 cfg, u8 cnt, u8 *data, u8 *int_reg) 330 + { 331 + struct rtsx_ucr *ucr = host->ucr; 332 + int err, i; 333 + 334 + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); 335 + 336 + rtsx_usb_init_cmd(ucr); 337 + 338 + for (i = 0; i < cnt; i++) 339 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, 340 + PPBUF_BASE2 + i, 0xFF, data[i]); 341 + 342 + if (cnt % 2) 343 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, 344 + PPBUF_BASE2 + i, 0xFF, 0xFF); 345 + 346 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 347 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); 348 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 349 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE, 350 + 0x01, PINGPONG_BUFFER); 351 + 352 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER, 353 + 0xFF, MS_TRANSFER_START | MS_TM_WRITE_BYTES); 354 + rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER, 355 + MS_TRANSFER_END, MS_TRANSFER_END); 356 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); 357 + 358 + err = rtsx_usb_send_cmd(ucr, MODE_CR, 100); 359 + if (err) 360 + return err; 361 + 362 + err = rtsx_usb_get_rsp(ucr, 2, 5000); 363 + if (err || (ucr->rsp_buf[0] & MS_TRANSFER_ERR)) { 364 + u8 val; 365 + 366 + rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, &val); 367 + dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); 368 + 369 + if (int_reg) 370 + *int_reg = val & 0x0F; 371 + 372 + ms_print_debug_regs(host); 373 + 374 + ms_clear_error(host); 375 + 376 + if (!(tpc & 0x08)) { 377 + if (val & MS_CRC16_ERR) 378 + return -EIO; 379 + } else { 380 + if (!(val & 0x80)) { 381 + if (val & (MS_INT_ERR | MS_INT_CMDNK)) 382 + return -EIO; 383 + } 384 + } 385 + 386 + return -ETIMEDOUT; 387 + } 388 + 389 + if (int_reg) 390 + *int_reg = ucr->rsp_buf[1] & 0x0F; 391 + 392 + return 0; 393 + } 394 + 395 + static int ms_read_bytes(struct rtsx_usb_ms *host, u8 tpc, 396 + u8 cfg, u8 cnt, u8 *data, u8 *int_reg) 397 + { 398 + struct rtsx_ucr *ucr = host->ucr; 399 + int err, i; 400 + u8 *ptr; 401 + 402 + dev_dbg(ms_dev(host), "%s: tpc = 0x%02x\n", __func__, tpc); 403 + 404 + rtsx_usb_init_cmd(ucr); 405 + 406 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); 407 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); 408 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); 409 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DATA_SOURCE, 410 + 0x01, PINGPONG_BUFFER); 411 + 412 + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, MS_TRANSFER, 413 + 0xFF, MS_TRANSFER_START | MS_TM_READ_BYTES); 414 + rtsx_usb_add_cmd(ucr, CHECK_REG_CMD, MS_TRANSFER, 415 + MS_TRANSFER_END, MS_TRANSFER_END); 416 + for (i = 0; i < cnt - 1; i++) 417 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); 418 + if (cnt % 2) 419 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, PPBUF_BASE2 + cnt, 0, 0); 420 + else 421 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, 422 + PPBUF_BASE2 + cnt - 1, 0, 0); 423 + 424 + rtsx_usb_add_cmd(ucr, READ_REG_CMD, MS_TRANS_CFG, 0, 0); 425 + 426 + err = rtsx_usb_send_cmd(ucr, MODE_CR, 100); 427 + if (err) 428 + return err; 429 + 430 + err = rtsx_usb_get_rsp(ucr, cnt + 2, 5000); 431 + if (err || (ucr->rsp_buf[0] & MS_TRANSFER_ERR)) { 432 + u8 val; 433 + 434 + rtsx_usb_ep0_read_register(ucr, MS_TRANS_CFG, &val); 435 + dev_dbg(ms_dev(host), "MS_TRANS_CFG: 0x%02x\n", val); 436 + 437 + if (int_reg && (host->ifmode != MEMSTICK_SERIAL)) 438 + *int_reg = val & 0x0F; 439 + 440 + ms_print_debug_regs(host); 441 + 442 + ms_clear_error(host); 443 + 444 + if (!(tpc & 0x08)) { 445 + if (val & MS_CRC16_ERR) 446 + return -EIO; 447 + } else { 448 + if (!(val & 0x80)) { 449 + if (val & (MS_INT_ERR | MS_INT_CMDNK)) 450 + return -EIO; 451 + } 452 + } 453 + 454 + return -ETIMEDOUT; 455 + } 456 + 457 + ptr = ucr->rsp_buf + 1; 458 + for (i = 0; i < cnt; i++) 459 + data[i] = *ptr++; 460 + 461 + 462 + if (int_reg && (host->ifmode != MEMSTICK_SERIAL)) 463 + *int_reg = *ptr & 0x0F; 464 + 465 + return 0; 466 + } 467 + 468 + static int rtsx_usb_ms_issue_cmd(struct rtsx_usb_ms *host) 469 + { 470 + struct memstick_request *req = host->req; 471 + int err = 0; 472 + u8 cfg = 0, int_reg; 473 + 474 + dev_dbg(ms_dev(host), "%s\n", __func__); 475 + 476 + if (req->need_card_int) { 477 + if (host->ifmode != MEMSTICK_SERIAL) 478 + cfg = WAIT_INT; 479 + } 480 + 481 + if (req->long_data) { 482 + err = ms_transfer_data(host, req->data_dir, 483 + req->tpc, cfg, &(req->sg)); 484 + } else { 485 + if (req->data_dir == READ) 486 + err = ms_read_bytes(host, req->tpc, cfg, 487 + req->data_len, req->data, &int_reg); 488 + else 489 + err = ms_write_bytes(host, req->tpc, cfg, 490 + req->data_len, req->data, &int_reg); 491 + } 492 + if (err < 0) 493 + return err; 494 + 495 + if (req->need_card_int) { 496 + if (host->ifmode == MEMSTICK_SERIAL) { 497 + err = ms_read_bytes(host, MS_TPC_GET_INT, 498 + NO_WAIT_INT, 1, &req->int_reg, NULL); 499 + if (err < 0) 500 + return err; 501 + } else { 502 + 503 + if (int_reg & MS_INT_CMDNK) 504 + req->int_reg |= MEMSTICK_INT_CMDNAK; 505 + if (int_reg & MS_INT_BREQ) 506 + req->int_reg |= MEMSTICK_INT_BREQ; 507 + if (int_reg & MS_INT_ERR) 508 + req->int_reg |= MEMSTICK_INT_ERR; 509 + if (int_reg & MS_INT_CED) 510 + req->int_reg |= MEMSTICK_INT_CED; 511 + } 512 + dev_dbg(ms_dev(host), "int_reg: 0x%02x\n", req->int_reg); 513 + } 514 + 515 + return 0; 516 + } 517 + 518 + static void rtsx_usb_ms_handle_req(struct work_struct *work) 519 + { 520 + struct rtsx_usb_ms *host = container_of(work, 521 + struct rtsx_usb_ms, handle_req); 522 + struct rtsx_ucr *ucr = host->ucr; 523 + struct memstick_host *msh = host->msh; 524 + int rc; 525 + 526 + if (!host->req) { 527 + do { 528 + rc = memstick_next_req(msh, &host->req); 529 + dev_dbg(ms_dev(host), "next req %d\n", rc); 530 + 531 + if (!rc) { 532 + mutex_lock(&ucr->dev_mutex); 533 + 534 + if (rtsx_usb_card_exclusive_check(ucr, 535 + RTSX_USB_MS_CARD)) 536 + host->req->error = -EIO; 537 + else 538 + host->req->error = 539 + rtsx_usb_ms_issue_cmd(host); 540 + 541 + mutex_unlock(&ucr->dev_mutex); 542 + 543 + dev_dbg(ms_dev(host), "req result %d\n", 544 + host->req->error); 545 + } 546 + } while (!rc); 547 + } 548 + 549 + } 550 + 551 + static void rtsx_usb_ms_request(struct memstick_host *msh) 552 + { 553 + struct rtsx_usb_ms *host = memstick_priv(msh); 554 + 555 + dev_dbg(ms_dev(host), "--> %s\n", __func__); 556 + 557 + if (!host->eject) 558 + schedule_work(&host->handle_req); 559 + } 560 + 561 + static int rtsx_usb_ms_set_param(struct memstick_host *msh, 562 + enum memstick_param param, int value) 563 + { 564 + struct rtsx_usb_ms *host = memstick_priv(msh); 565 + struct rtsx_ucr *ucr = host->ucr; 566 + unsigned int clock = 0; 567 + u8 ssc_depth = 0; 568 + int err; 569 + 570 + dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n", 571 + __func__, param, value); 572 + 573 + mutex_lock(&ucr->dev_mutex); 574 + 575 + err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_MS_CARD); 576 + if (err) 577 + goto out; 578 + 579 + switch (param) { 580 + case MEMSTICK_POWER: 581 + if (value == host->power_mode) 582 + break; 583 + 584 + if (value == MEMSTICK_POWER_ON) { 585 + pm_runtime_get_sync(ms_dev(host)); 586 + err = ms_power_on(host); 587 + } else if (value == MEMSTICK_POWER_OFF) { 588 + err = ms_power_off(host); 589 + if (host->msh->card) 590 + pm_runtime_put_noidle(ms_dev(host)); 591 + else 592 + pm_runtime_put(ms_dev(host)); 593 + } else 594 + err = -EINVAL; 595 + if (!err) 596 + host->power_mode = value; 597 + break; 598 + 599 + case MEMSTICK_INTERFACE: 600 + if (value == MEMSTICK_SERIAL) { 601 + clock = 19000000; 602 + ssc_depth = SSC_DEPTH_512K; 603 + err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A, 604 + MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT); 605 + if (err < 0) 606 + break; 607 + } else if (value == MEMSTICK_PAR4) { 608 + clock = 39000000; 609 + ssc_depth = SSC_DEPTH_1M; 610 + 611 + err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A, 612 + MS_BUS_WIDTH_4 | PUSH_TIME_ODD | 613 + MS_NO_CHECK_INT); 614 + if (err < 0) 615 + break; 616 + } else { 617 + err = -EINVAL; 618 + break; 619 + } 620 + 621 + err = rtsx_usb_switch_clock(ucr, clock, 622 + ssc_depth, false, true, false); 623 + if (err < 0) { 624 + dev_dbg(ms_dev(host), "switch clock failed\n"); 625 + break; 626 + } 627 + 628 + host->ssc_depth = ssc_depth; 629 + host->clock = clock; 630 + host->ifmode = value; 631 + break; 632 + default: 633 + err = -EINVAL; 634 + break; 635 + } 636 + out: 637 + mutex_unlock(&ucr->dev_mutex); 638 + 639 + /* power-on delay */ 640 + if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON) 641 + usleep_range(10000, 12000); 642 + 643 + dev_dbg(ms_dev(host), "%s: return = %d\n", __func__, err); 644 + return err; 645 + } 646 + 647 + #ifdef CONFIG_PM_SLEEP 648 + static int rtsx_usb_ms_suspend(struct device *dev) 649 + { 650 + struct rtsx_usb_ms *host = dev_get_drvdata(dev); 651 + struct memstick_host *msh = host->msh; 652 + 653 + dev_dbg(ms_dev(host), "--> %s\n", __func__); 654 + 655 + memstick_suspend_host(msh); 656 + return 0; 657 + } 658 + 659 + static int rtsx_usb_ms_resume(struct device *dev) 660 + { 661 + struct rtsx_usb_ms *host = dev_get_drvdata(dev); 662 + struct memstick_host *msh = host->msh; 663 + 664 + dev_dbg(ms_dev(host), "--> %s\n", __func__); 665 + 666 + memstick_resume_host(msh); 667 + return 0; 668 + } 669 + #endif /* CONFIG_PM_SLEEP */ 670 + 671 + /* 672 + * Thread function of ms card slot detection. The thread starts right after 673 + * successful host addition. It stops while the driver removal function sets 674 + * host->eject true. 675 + */ 676 + static int rtsx_usb_detect_ms_card(void *__host) 677 + { 678 + struct rtsx_usb_ms *host = (struct rtsx_usb_ms *)__host; 679 + struct rtsx_ucr *ucr = host->ucr; 680 + u8 val = 0; 681 + int err; 682 + 683 + for (;;) { 684 + mutex_lock(&ucr->dev_mutex); 685 + 686 + /* Check pending MS card changes */ 687 + err = rtsx_usb_read_register(ucr, CARD_INT_PEND, &val); 688 + if (err) { 689 + mutex_unlock(&ucr->dev_mutex); 690 + goto poll_again; 691 + } 692 + 693 + /* Clear the pending */ 694 + rtsx_usb_write_register(ucr, CARD_INT_PEND, 695 + XD_INT | MS_INT | SD_INT, 696 + XD_INT | MS_INT | SD_INT); 697 + 698 + mutex_unlock(&ucr->dev_mutex); 699 + 700 + if (val & MS_INT) { 701 + dev_dbg(ms_dev(host), "MS slot change detected\n"); 702 + memstick_detect_change(host->msh); 703 + } 704 + 705 + poll_again: 706 + if (host->eject) 707 + break; 708 + 709 + msleep(1000); 710 + } 711 + 712 + complete(&host->detect_ms_exit); 713 + return 0; 714 + } 715 + 716 + static int rtsx_usb_ms_drv_probe(struct platform_device *pdev) 717 + { 718 + struct memstick_host *msh; 719 + struct rtsx_usb_ms *host; 720 + struct rtsx_ucr *ucr; 721 + int err; 722 + 723 + ucr = usb_get_intfdata(to_usb_interface(pdev->dev.parent)); 724 + if (!ucr) 725 + return -ENXIO; 726 + 727 + dev_dbg(&(pdev->dev), 728 + "Realtek USB Memstick controller found\n"); 729 + 730 + msh = memstick_alloc_host(sizeof(*host), &pdev->dev); 731 + if (!msh) 732 + return -ENOMEM; 733 + 734 + host = memstick_priv(msh); 735 + host->ucr = ucr; 736 + host->msh = msh; 737 + host->pdev = pdev; 738 + host->power_mode = MEMSTICK_POWER_OFF; 739 + platform_set_drvdata(pdev, host); 740 + 741 + mutex_init(&host->host_mutex); 742 + INIT_WORK(&host->handle_req, rtsx_usb_ms_handle_req); 743 + 744 + init_completion(&host->detect_ms_exit); 745 + host->detect_ms = kthread_create(rtsx_usb_detect_ms_card, host, 746 + "rtsx_usb_ms_%d", pdev->id); 747 + if (IS_ERR(host->detect_ms)) { 748 + dev_dbg(&(pdev->dev), 749 + "Unable to create polling thread.\n"); 750 + err = PTR_ERR(host->detect_ms); 751 + goto err_out; 752 + } 753 + 754 + msh->request = rtsx_usb_ms_request; 755 + msh->set_param = rtsx_usb_ms_set_param; 756 + msh->caps = MEMSTICK_CAP_PAR4; 757 + 758 + pm_runtime_enable(&pdev->dev); 759 + err = memstick_add_host(msh); 760 + if (err) 761 + goto err_out; 762 + 763 + wake_up_process(host->detect_ms); 764 + return 0; 765 + err_out: 766 + memstick_free_host(msh); 767 + return err; 768 + } 769 + 770 + static int rtsx_usb_ms_drv_remove(struct platform_device *pdev) 771 + { 772 + struct rtsx_usb_ms *host = platform_get_drvdata(pdev); 773 + struct memstick_host *msh; 774 + int err; 775 + 776 + msh = host->msh; 777 + host->eject = true; 778 + cancel_work_sync(&host->handle_req); 779 + 780 + mutex_lock(&host->host_mutex); 781 + if (host->req) { 782 + dev_dbg(&(pdev->dev), 783 + "%s: Controller removed during transfer\n", 784 + dev_name(&msh->dev)); 785 + host->req->error = -ENOMEDIUM; 786 + do { 787 + err = memstick_next_req(msh, &host->req); 788 + if (!err) 789 + host->req->error = -ENOMEDIUM; 790 + } while (!err); 791 + } 792 + mutex_unlock(&host->host_mutex); 793 + 794 + wait_for_completion(&host->detect_ms_exit); 795 + memstick_remove_host(msh); 796 + memstick_free_host(msh); 797 + 798 + /* Balance possible unbalanced usage count 799 + * e.g. unconditional module removal 800 + */ 801 + if (pm_runtime_active(ms_dev(host))) 802 + pm_runtime_put(ms_dev(host)); 803 + 804 + pm_runtime_disable(&pdev->dev); 805 + platform_set_drvdata(pdev, NULL); 806 + 807 + dev_dbg(&(pdev->dev), 808 + ": Realtek USB Memstick controller has been removed\n"); 809 + 810 + return 0; 811 + } 812 + 813 + static SIMPLE_DEV_PM_OPS(rtsx_usb_ms_pm_ops, 814 + rtsx_usb_ms_suspend, rtsx_usb_ms_resume); 815 + 816 + static struct platform_device_id rtsx_usb_ms_ids[] = { 817 + { 818 + .name = "rtsx_usb_ms", 819 + }, { 820 + /* sentinel */ 821 + } 822 + }; 823 + MODULE_DEVICE_TABLE(platform, rtsx_usb_ms_ids); 824 + 825 + static struct platform_driver rtsx_usb_ms_driver = { 826 + .probe = rtsx_usb_ms_drv_probe, 827 + .remove = rtsx_usb_ms_drv_remove, 828 + .id_table = rtsx_usb_ms_ids, 829 + .driver = { 830 + .owner = THIS_MODULE, 831 + .name = "rtsx_usb_ms", 832 + .pm = &rtsx_usb_ms_pm_ops, 833 + }, 834 + }; 835 + module_platform_driver(rtsx_usb_ms_driver); 836 + 837 + MODULE_LICENSE("GPL v2"); 838 + MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>"); 839 + MODULE_DESCRIPTION("Realtek USB Memstick Card Host Driver");