569 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * USB SD Host Controller (USHC) controller driver.4 *5 * Copyright (C) 2010 Cambridge Silicon Radio Ltd.6 *7 * Notes:8 * - Only version 2 devices are supported.9 * - Version 2 devices only support SDIO cards/devices (R2 response is10 * unsupported).11 *12 * References:13 * [USHC] USB SD Host Controller specification (CS-118793-SP)14 */15#include <linux/module.h>16#include <linux/usb.h>17#include <linux/kernel.h>18#include <linux/slab.h>19#include <linux/dma-mapping.h>20#include <linux/mmc/host.h>21 22enum ushc_request {23 USHC_GET_CAPS = 0x00,24 USHC_HOST_CTRL = 0x01,25 USHC_PWR_CTRL = 0x02,26 USHC_CLK_FREQ = 0x03,27 USHC_EXEC_CMD = 0x04,28 USHC_READ_RESP = 0x05,29 USHC_RESET = 0x06,30};31 32enum ushc_request_type {33 USHC_GET_CAPS_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,34 USHC_HOST_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,35 USHC_PWR_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,36 USHC_CLK_FREQ_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,37 USHC_EXEC_CMD_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,38 USHC_READ_RESP_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,39 USHC_RESET_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,40};41 42#define USHC_GET_CAPS_VERSION_MASK 0xff43#define USHC_GET_CAPS_3V3 (1 << 8)44#define USHC_GET_CAPS_3V0 (1 << 9)45#define USHC_GET_CAPS_1V8 (1 << 10)46#define USHC_GET_CAPS_HIGH_SPD (1 << 16)47 48#define USHC_HOST_CTRL_4BIT (1 << 1)49#define USHC_HOST_CTRL_HIGH_SPD (1 << 0)50 51#define USHC_PWR_CTRL_OFF 0x0052#define USHC_PWR_CTRL_3V3 0x0153#define USHC_PWR_CTRL_3V0 0x0254#define USHC_PWR_CTRL_1V8 0x0355 56#define USHC_READ_RESP_BUSY (1 << 4)57#define USHC_READ_RESP_ERR_TIMEOUT (1 << 3)58#define USHC_READ_RESP_ERR_CRC (1 << 2)59#define USHC_READ_RESP_ERR_DAT (1 << 1)60#define USHC_READ_RESP_ERR_CMD (1 << 0)61#define USHC_READ_RESP_ERR_MASK 0x0f62 63struct ushc_cbw {64 __u8 signature;65 __u8 cmd_idx;66 __le16 block_size;67 __le32 arg;68} __attribute__((packed));69 70#define USHC_CBW_SIGNATURE 'C'71 72struct ushc_csw {73 __u8 signature;74 __u8 status;75 __le32 response;76} __attribute__((packed));77 78#define USHC_CSW_SIGNATURE 'S'79 80struct ushc_int_data {81 u8 status;82 u8 reserved[3];83};84 85#define USHC_INT_STATUS_SDIO_INT (1 << 1)86#define USHC_INT_STATUS_CARD_PRESENT (1 << 0)87 88 89struct ushc_data {90 struct usb_device *usb_dev;91 struct mmc_host *mmc;92 93 struct urb *int_urb;94 struct ushc_int_data *int_data;95 96 struct urb *cbw_urb;97 struct ushc_cbw *cbw;98 99 struct urb *data_urb;100 101 struct urb *csw_urb;102 struct ushc_csw *csw;103 104 spinlock_t lock;105 struct mmc_request *current_req;106 u32 caps;107 u16 host_ctrl;108 unsigned long flags;109 u8 last_status;110 int clock_freq;111};112 113#define DISCONNECTED 0114#define INT_EN 1115#define IGNORE_NEXT_INT 2116 117static void data_callback(struct urb *urb);118 119static int ushc_hw_reset(struct ushc_data *ushc)120{121 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),122 USHC_RESET, USHC_RESET_TYPE,123 0, 0, NULL, 0, 100);124}125 126static int ushc_hw_get_caps(struct ushc_data *ushc)127{128 int ret;129 int version;130 131 ret = usb_control_msg(ushc->usb_dev, usb_rcvctrlpipe(ushc->usb_dev, 0),132 USHC_GET_CAPS, USHC_GET_CAPS_TYPE,133 0, 0, &ushc->caps, sizeof(ushc->caps), 100);134 if (ret < 0)135 return ret;136 137 ushc->caps = le32_to_cpu(ushc->caps);138 139 version = ushc->caps & USHC_GET_CAPS_VERSION_MASK;140 if (version != 0x02) {141 dev_err(&ushc->usb_dev->dev, "controller version %d is not supported\n", version);142 return -EINVAL;143 }144 145 return 0;146}147 148static int ushc_hw_set_host_ctrl(struct ushc_data *ushc, u16 mask, u16 val)149{150 u16 host_ctrl;151 int ret;152 153 host_ctrl = (ushc->host_ctrl & ~mask) | val;154 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),155 USHC_HOST_CTRL, USHC_HOST_CTRL_TYPE,156 host_ctrl, 0, NULL, 0, 100);157 if (ret < 0)158 return ret;159 ushc->host_ctrl = host_ctrl;160 return 0;161}162 163static void int_callback(struct urb *urb)164{165 struct ushc_data *ushc = urb->context;166 u8 status, last_status;167 168 if (urb->status < 0)169 return;170 171 status = ushc->int_data->status;172 last_status = ushc->last_status;173 ushc->last_status = status;174 175 /*176 * Ignore the card interrupt status on interrupt transfers that177 * were submitted while card interrupts where disabled.178 *179 * This avoid occasional spurious interrupts when enabling180 * interrupts immediately after clearing the source on the card.181 */182 183 if (!test_and_clear_bit(IGNORE_NEXT_INT, &ushc->flags)184 && test_bit(INT_EN, &ushc->flags)185 && status & USHC_INT_STATUS_SDIO_INT) {186 mmc_signal_sdio_irq(ushc->mmc);187 }188 189 if ((status ^ last_status) & USHC_INT_STATUS_CARD_PRESENT)190 mmc_detect_change(ushc->mmc, msecs_to_jiffies(100));191 192 if (!test_bit(INT_EN, &ushc->flags))193 set_bit(IGNORE_NEXT_INT, &ushc->flags);194 usb_submit_urb(ushc->int_urb, GFP_ATOMIC);195}196 197static void cbw_callback(struct urb *urb)198{199 struct ushc_data *ushc = urb->context;200 201 if (urb->status != 0) {202 usb_unlink_urb(ushc->data_urb);203 usb_unlink_urb(ushc->csw_urb);204 }205}206 207static void data_callback(struct urb *urb)208{209 struct ushc_data *ushc = urb->context;210 211 if (urb->status != 0)212 usb_unlink_urb(ushc->csw_urb);213}214 215static void csw_callback(struct urb *urb)216{217 struct ushc_data *ushc = urb->context;218 struct mmc_request *req = ushc->current_req;219 int status;220 221 status = ushc->csw->status;222 223 if (urb->status != 0) {224 req->cmd->error = urb->status;225 } else if (status & USHC_READ_RESP_ERR_CMD) {226 if (status & USHC_READ_RESP_ERR_CRC)227 req->cmd->error = -EIO;228 else229 req->cmd->error = -ETIMEDOUT;230 }231 if (req->data) {232 if (status & USHC_READ_RESP_ERR_DAT) {233 if (status & USHC_READ_RESP_ERR_CRC)234 req->data->error = -EIO;235 else236 req->data->error = -ETIMEDOUT;237 req->data->bytes_xfered = 0;238 } else {239 req->data->bytes_xfered = req->data->blksz * req->data->blocks;240 }241 }242 243 req->cmd->resp[0] = le32_to_cpu(ushc->csw->response);244 245 mmc_request_done(ushc->mmc, req);246}247 248static void ushc_request(struct mmc_host *mmc, struct mmc_request *req)249{250 struct ushc_data *ushc = mmc_priv(mmc);251 int ret;252 unsigned long flags;253 254 spin_lock_irqsave(&ushc->lock, flags);255 256 if (test_bit(DISCONNECTED, &ushc->flags)) {257 ret = -ENODEV;258 goto out;259 }260 261 /* Version 2 firmware doesn't support the R2 response format. */262 if (req->cmd->flags & MMC_RSP_136) {263 ret = -EINVAL;264 goto out;265 }266 267 /* The Astoria's data FIFOs don't work with clock speeds < 5MHz so268 limit commands with data to 6MHz or more. */269 if (req->data && ushc->clock_freq < 6000000) {270 ret = -EINVAL;271 goto out;272 }273 274 ushc->current_req = req;275 276 /* Start cmd with CBW. */277 ushc->cbw->cmd_idx = cpu_to_le16(req->cmd->opcode);278 if (req->data)279 ushc->cbw->block_size = cpu_to_le16(req->data->blksz);280 else281 ushc->cbw->block_size = 0;282 ushc->cbw->arg = cpu_to_le32(req->cmd->arg);283 284 ret = usb_submit_urb(ushc->cbw_urb, GFP_ATOMIC);285 if (ret < 0)286 goto out;287 288 /* Submit data (if any). */289 if (req->data) {290 struct mmc_data *data = req->data;291 int pipe;292 293 if (data->flags & MMC_DATA_READ)294 pipe = usb_rcvbulkpipe(ushc->usb_dev, 6);295 else296 pipe = usb_sndbulkpipe(ushc->usb_dev, 2);297 298 usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe,299 NULL, data->sg->length,300 data_callback, ushc);301 ushc->data_urb->num_sgs = 1;302 ushc->data_urb->sg = data->sg;303 ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC);304 if (ret < 0)305 goto out;306 }307 308 /* Submit CSW. */309 ret = usb_submit_urb(ushc->csw_urb, GFP_ATOMIC);310 311out:312 spin_unlock_irqrestore(&ushc->lock, flags);313 if (ret < 0) {314 usb_unlink_urb(ushc->cbw_urb);315 usb_unlink_urb(ushc->data_urb);316 req->cmd->error = ret;317 mmc_request_done(mmc, req);318 }319}320 321static int ushc_set_power(struct ushc_data *ushc, unsigned char power_mode)322{323 u16 voltage;324 325 switch (power_mode) {326 case MMC_POWER_OFF:327 voltage = USHC_PWR_CTRL_OFF;328 break;329 case MMC_POWER_UP:330 case MMC_POWER_ON:331 voltage = USHC_PWR_CTRL_3V3;332 break;333 default:334 return -EINVAL;335 }336 337 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),338 USHC_PWR_CTRL, USHC_PWR_CTRL_TYPE,339 voltage, 0, NULL, 0, 100);340}341 342static int ushc_set_bus_width(struct ushc_data *ushc, int bus_width)343{344 return ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_4BIT,345 bus_width == 4 ? USHC_HOST_CTRL_4BIT : 0);346}347 348static int ushc_set_bus_freq(struct ushc_data *ushc, int clk, bool enable_hs)349{350 int ret;351 352 /* Hardware can't detect interrupts while the clock is off. */353 if (clk == 0)354 clk = 400000;355 356 ret = ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_HIGH_SPD,357 enable_hs ? USHC_HOST_CTRL_HIGH_SPD : 0);358 if (ret < 0)359 return ret;360 361 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),362 USHC_CLK_FREQ, USHC_CLK_FREQ_TYPE,363 clk & 0xffff, (clk >> 16) & 0xffff, NULL, 0, 100);364 if (ret < 0)365 return ret;366 367 ushc->clock_freq = clk;368 return 0;369}370 371static void ushc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)372{373 struct ushc_data *ushc = mmc_priv(mmc);374 375 ushc_set_power(ushc, ios->power_mode);376 ushc_set_bus_width(ushc, 1 << ios->bus_width);377 ushc_set_bus_freq(ushc, ios->clock, ios->timing == MMC_TIMING_SD_HS);378}379 380static int ushc_get_cd(struct mmc_host *mmc)381{382 struct ushc_data *ushc = mmc_priv(mmc);383 384 return !!(ushc->last_status & USHC_INT_STATUS_CARD_PRESENT);385}386 387static void ushc_enable_sdio_irq(struct mmc_host *mmc, int enable)388{389 struct ushc_data *ushc = mmc_priv(mmc);390 391 if (enable)392 set_bit(INT_EN, &ushc->flags);393 else394 clear_bit(INT_EN, &ushc->flags);395}396 397static void ushc_clean_up(struct ushc_data *ushc)398{399 usb_free_urb(ushc->int_urb);400 usb_free_urb(ushc->csw_urb);401 usb_free_urb(ushc->data_urb);402 usb_free_urb(ushc->cbw_urb);403 404 kfree(ushc->int_data);405 kfree(ushc->cbw);406 kfree(ushc->csw);407 408 mmc_free_host(ushc->mmc);409}410 411static const struct mmc_host_ops ushc_ops = {412 .request = ushc_request,413 .set_ios = ushc_set_ios,414 .get_cd = ushc_get_cd,415 .enable_sdio_irq = ushc_enable_sdio_irq,416};417 418static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id)419{420 struct usb_device *usb_dev = interface_to_usbdev(intf);421 struct mmc_host *mmc;422 struct ushc_data *ushc;423 int ret;424 425 if (intf->cur_altsetting->desc.bNumEndpoints < 1)426 return -ENODEV;427 428 mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);429 if (mmc == NULL)430 return -ENOMEM;431 ushc = mmc_priv(mmc);432 usb_set_intfdata(intf, ushc);433 434 ushc->usb_dev = usb_dev;435 ushc->mmc = mmc;436 437 spin_lock_init(&ushc->lock);438 439 ret = ushc_hw_reset(ushc);440 if (ret < 0)441 goto err;442 443 /* Read capabilities. */444 ret = ushc_hw_get_caps(ushc);445 if (ret < 0)446 goto err;447 448 mmc->ops = &ushc_ops;449 450 mmc->f_min = 400000;451 mmc->f_max = 50000000;452 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;453 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;454 mmc->caps |= (ushc->caps & USHC_GET_CAPS_HIGH_SPD) ? MMC_CAP_SD_HIGHSPEED : 0;455 456 mmc->max_seg_size = 512*511;457 mmc->max_segs = 1;458 mmc->max_req_size = 512*511;459 mmc->max_blk_size = 512;460 mmc->max_blk_count = 511;461 462 ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);463 if (ushc->int_urb == NULL) {464 ret = -ENOMEM;465 goto err;466 }467 ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);468 if (ushc->int_data == NULL) {469 ret = -ENOMEM;470 goto err;471 }472 usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,473 usb_rcvintpipe(usb_dev,474 intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),475 ushc->int_data, sizeof(struct ushc_int_data),476 int_callback, ushc,477 intf->cur_altsetting->endpoint[0].desc.bInterval);478 479 ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);480 if (ushc->cbw_urb == NULL) {481 ret = -ENOMEM;482 goto err;483 }484 ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);485 if (ushc->cbw == NULL) {486 ret = -ENOMEM;487 goto err;488 }489 ushc->cbw->signature = USHC_CBW_SIGNATURE;490 491 usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),492 ushc->cbw, sizeof(struct ushc_cbw),493 cbw_callback, ushc);494 495 ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);496 if (ushc->data_urb == NULL) {497 ret = -ENOMEM;498 goto err;499 }500 501 ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);502 if (ushc->csw_urb == NULL) {503 ret = -ENOMEM;504 goto err;505 }506 ushc->csw = kzalloc(sizeof(struct ushc_csw), GFP_KERNEL);507 if (ushc->csw == NULL) {508 ret = -ENOMEM;509 goto err;510 }511 usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),512 ushc->csw, sizeof(struct ushc_csw),513 csw_callback, ushc);514 515 ret = mmc_add_host(ushc->mmc);516 if (ret)517 goto err;518 519 ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL);520 if (ret < 0) {521 mmc_remove_host(ushc->mmc);522 goto err;523 }524 525 return 0;526 527err:528 ushc_clean_up(ushc);529 return ret;530}531 532static void ushc_disconnect(struct usb_interface *intf)533{534 struct ushc_data *ushc = usb_get_intfdata(intf);535 536 spin_lock_irq(&ushc->lock);537 set_bit(DISCONNECTED, &ushc->flags);538 spin_unlock_irq(&ushc->lock);539 540 usb_kill_urb(ushc->int_urb);541 usb_kill_urb(ushc->cbw_urb);542 usb_kill_urb(ushc->data_urb);543 usb_kill_urb(ushc->csw_urb);544 545 mmc_remove_host(ushc->mmc);546 547 ushc_clean_up(ushc);548}549 550static struct usb_device_id ushc_id_table[] = {551 /* CSR USB SD Host Controller */552 { USB_DEVICE(0x0a12, 0x5d10) },553 { },554};555MODULE_DEVICE_TABLE(usb, ushc_id_table);556 557static struct usb_driver ushc_driver = {558 .name = "ushc",559 .id_table = ushc_id_table,560 .probe = ushc_probe,561 .disconnect = ushc_disconnect,562};563 564module_usb_driver(ushc_driver);565 566MODULE_DESCRIPTION("USB SD Host Controller driver");567MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>");568MODULE_LICENSE("GPL");569