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