0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/module.h>
0016 #include <linux/usb.h>
0017 #include <linux/kernel.h>
0018 #include <linux/slab.h>
0019 #include <linux/dma-mapping.h>
0020 #include <linux/mmc/host.h>
0021
0022 enum ushc_request {
0023 USHC_GET_CAPS = 0x00,
0024 USHC_HOST_CTRL = 0x01,
0025 USHC_PWR_CTRL = 0x02,
0026 USHC_CLK_FREQ = 0x03,
0027 USHC_EXEC_CMD = 0x04,
0028 USHC_READ_RESP = 0x05,
0029 USHC_RESET = 0x06,
0030 };
0031
0032 enum ushc_request_type {
0033 USHC_GET_CAPS_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0034 USHC_HOST_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0035 USHC_PWR_CTRL_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0036 USHC_CLK_FREQ_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0037 USHC_EXEC_CMD_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0038 USHC_READ_RESP_TYPE = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0039 USHC_RESET_TYPE = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0040 };
0041
0042 #define USHC_GET_CAPS_VERSION_MASK 0xff
0043 #define USHC_GET_CAPS_3V3 (1 << 8)
0044 #define USHC_GET_CAPS_3V0 (1 << 9)
0045 #define USHC_GET_CAPS_1V8 (1 << 10)
0046 #define USHC_GET_CAPS_HIGH_SPD (1 << 16)
0047
0048 #define USHC_HOST_CTRL_4BIT (1 << 1)
0049 #define USHC_HOST_CTRL_HIGH_SPD (1 << 0)
0050
0051 #define USHC_PWR_CTRL_OFF 0x00
0052 #define USHC_PWR_CTRL_3V3 0x01
0053 #define USHC_PWR_CTRL_3V0 0x02
0054 #define USHC_PWR_CTRL_1V8 0x03
0055
0056 #define USHC_READ_RESP_BUSY (1 << 4)
0057 #define USHC_READ_RESP_ERR_TIMEOUT (1 << 3)
0058 #define USHC_READ_RESP_ERR_CRC (1 << 2)
0059 #define USHC_READ_RESP_ERR_DAT (1 << 1)
0060 #define USHC_READ_RESP_ERR_CMD (1 << 0)
0061 #define USHC_READ_RESP_ERR_MASK 0x0f
0062
0063 struct ushc_cbw {
0064 __u8 signature;
0065 __u8 cmd_idx;
0066 __le16 block_size;
0067 __le32 arg;
0068 } __attribute__((packed));
0069
0070 #define USHC_CBW_SIGNATURE 'C'
0071
0072 struct ushc_csw {
0073 __u8 signature;
0074 __u8 status;
0075 __le32 response;
0076 } __attribute__((packed));
0077
0078 #define USHC_CSW_SIGNATURE 'S'
0079
0080 struct ushc_int_data {
0081 u8 status;
0082 u8 reserved[3];
0083 };
0084
0085 #define USHC_INT_STATUS_SDIO_INT (1 << 1)
0086 #define USHC_INT_STATUS_CARD_PRESENT (1 << 0)
0087
0088
0089 struct ushc_data {
0090 struct usb_device *usb_dev;
0091 struct mmc_host *mmc;
0092
0093 struct urb *int_urb;
0094 struct ushc_int_data *int_data;
0095
0096 struct urb *cbw_urb;
0097 struct ushc_cbw *cbw;
0098
0099 struct urb *data_urb;
0100
0101 struct urb *csw_urb;
0102 struct ushc_csw *csw;
0103
0104 spinlock_t lock;
0105 struct mmc_request *current_req;
0106 u32 caps;
0107 u16 host_ctrl;
0108 unsigned long flags;
0109 u8 last_status;
0110 int clock_freq;
0111 };
0112
0113 #define DISCONNECTED 0
0114 #define INT_EN 1
0115 #define IGNORE_NEXT_INT 2
0116
0117 static void data_callback(struct urb *urb);
0118
0119 static int ushc_hw_reset(struct ushc_data *ushc)
0120 {
0121 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
0122 USHC_RESET, USHC_RESET_TYPE,
0123 0, 0, NULL, 0, 100);
0124 }
0125
0126 static int ushc_hw_get_caps(struct ushc_data *ushc)
0127 {
0128 int ret;
0129 int version;
0130
0131 ret = usb_control_msg(ushc->usb_dev, usb_rcvctrlpipe(ushc->usb_dev, 0),
0132 USHC_GET_CAPS, USHC_GET_CAPS_TYPE,
0133 0, 0, &ushc->caps, sizeof(ushc->caps), 100);
0134 if (ret < 0)
0135 return ret;
0136
0137 ushc->caps = le32_to_cpu(ushc->caps);
0138
0139 version = ushc->caps & USHC_GET_CAPS_VERSION_MASK;
0140 if (version != 0x02) {
0141 dev_err(&ushc->usb_dev->dev, "controller version %d is not supported\n", version);
0142 return -EINVAL;
0143 }
0144
0145 return 0;
0146 }
0147
0148 static int ushc_hw_set_host_ctrl(struct ushc_data *ushc, u16 mask, u16 val)
0149 {
0150 u16 host_ctrl;
0151 int ret;
0152
0153 host_ctrl = (ushc->host_ctrl & ~mask) | val;
0154 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
0155 USHC_HOST_CTRL, USHC_HOST_CTRL_TYPE,
0156 host_ctrl, 0, NULL, 0, 100);
0157 if (ret < 0)
0158 return ret;
0159 ushc->host_ctrl = host_ctrl;
0160 return 0;
0161 }
0162
0163 static void int_callback(struct urb *urb)
0164 {
0165 struct ushc_data *ushc = urb->context;
0166 u8 status, last_status;
0167
0168 if (urb->status < 0)
0169 return;
0170
0171 status = ushc->int_data->status;
0172 last_status = ushc->last_status;
0173 ushc->last_status = status;
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 if (!test_and_clear_bit(IGNORE_NEXT_INT, &ushc->flags)
0184 && test_bit(INT_EN, &ushc->flags)
0185 && status & USHC_INT_STATUS_SDIO_INT) {
0186 mmc_signal_sdio_irq(ushc->mmc);
0187 }
0188
0189 if ((status ^ last_status) & USHC_INT_STATUS_CARD_PRESENT)
0190 mmc_detect_change(ushc->mmc, msecs_to_jiffies(100));
0191
0192 if (!test_bit(INT_EN, &ushc->flags))
0193 set_bit(IGNORE_NEXT_INT, &ushc->flags);
0194 usb_submit_urb(ushc->int_urb, GFP_ATOMIC);
0195 }
0196
0197 static void cbw_callback(struct urb *urb)
0198 {
0199 struct ushc_data *ushc = urb->context;
0200
0201 if (urb->status != 0) {
0202 usb_unlink_urb(ushc->data_urb);
0203 usb_unlink_urb(ushc->csw_urb);
0204 }
0205 }
0206
0207 static void data_callback(struct urb *urb)
0208 {
0209 struct ushc_data *ushc = urb->context;
0210
0211 if (urb->status != 0)
0212 usb_unlink_urb(ushc->csw_urb);
0213 }
0214
0215 static void csw_callback(struct urb *urb)
0216 {
0217 struct ushc_data *ushc = urb->context;
0218 struct mmc_request *req = ushc->current_req;
0219 int status;
0220
0221 status = ushc->csw->status;
0222
0223 if (urb->status != 0) {
0224 req->cmd->error = urb->status;
0225 } else if (status & USHC_READ_RESP_ERR_CMD) {
0226 if (status & USHC_READ_RESP_ERR_CRC)
0227 req->cmd->error = -EIO;
0228 else
0229 req->cmd->error = -ETIMEDOUT;
0230 }
0231 if (req->data) {
0232 if (status & USHC_READ_RESP_ERR_DAT) {
0233 if (status & USHC_READ_RESP_ERR_CRC)
0234 req->data->error = -EIO;
0235 else
0236 req->data->error = -ETIMEDOUT;
0237 req->data->bytes_xfered = 0;
0238 } else {
0239 req->data->bytes_xfered = req->data->blksz * req->data->blocks;
0240 }
0241 }
0242
0243 req->cmd->resp[0] = le32_to_cpu(ushc->csw->response);
0244
0245 mmc_request_done(ushc->mmc, req);
0246 }
0247
0248 static void ushc_request(struct mmc_host *mmc, struct mmc_request *req)
0249 {
0250 struct ushc_data *ushc = mmc_priv(mmc);
0251 int ret;
0252 unsigned long flags;
0253
0254 spin_lock_irqsave(&ushc->lock, flags);
0255
0256 if (test_bit(DISCONNECTED, &ushc->flags)) {
0257 ret = -ENODEV;
0258 goto out;
0259 }
0260
0261
0262 if (req->cmd->flags & MMC_RSP_136) {
0263 ret = -EINVAL;
0264 goto out;
0265 }
0266
0267
0268
0269 if (req->data && ushc->clock_freq < 6000000) {
0270 ret = -EINVAL;
0271 goto out;
0272 }
0273
0274 ushc->current_req = req;
0275
0276
0277 ushc->cbw->cmd_idx = cpu_to_le16(req->cmd->opcode);
0278 if (req->data)
0279 ushc->cbw->block_size = cpu_to_le16(req->data->blksz);
0280 else
0281 ushc->cbw->block_size = 0;
0282 ushc->cbw->arg = cpu_to_le32(req->cmd->arg);
0283
0284 ret = usb_submit_urb(ushc->cbw_urb, GFP_ATOMIC);
0285 if (ret < 0)
0286 goto out;
0287
0288
0289 if (req->data) {
0290 struct mmc_data *data = req->data;
0291 int pipe;
0292
0293 if (data->flags & MMC_DATA_READ)
0294 pipe = usb_rcvbulkpipe(ushc->usb_dev, 6);
0295 else
0296 pipe = usb_sndbulkpipe(ushc->usb_dev, 2);
0297
0298 usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe,
0299 NULL, data->sg->length,
0300 data_callback, ushc);
0301 ushc->data_urb->num_sgs = 1;
0302 ushc->data_urb->sg = data->sg;
0303 ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC);
0304 if (ret < 0)
0305 goto out;
0306 }
0307
0308
0309 ret = usb_submit_urb(ushc->csw_urb, GFP_ATOMIC);
0310
0311 out:
0312 spin_unlock_irqrestore(&ushc->lock, flags);
0313 if (ret < 0) {
0314 usb_unlink_urb(ushc->cbw_urb);
0315 usb_unlink_urb(ushc->data_urb);
0316 req->cmd->error = ret;
0317 mmc_request_done(mmc, req);
0318 }
0319 }
0320
0321 static int ushc_set_power(struct ushc_data *ushc, unsigned char power_mode)
0322 {
0323 u16 voltage;
0324
0325 switch (power_mode) {
0326 case MMC_POWER_OFF:
0327 voltage = USHC_PWR_CTRL_OFF;
0328 break;
0329 case MMC_POWER_UP:
0330 case MMC_POWER_ON:
0331 voltage = USHC_PWR_CTRL_3V3;
0332 break;
0333 default:
0334 return -EINVAL;
0335 }
0336
0337 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
0338 USHC_PWR_CTRL, USHC_PWR_CTRL_TYPE,
0339 voltage, 0, NULL, 0, 100);
0340 }
0341
0342 static int ushc_set_bus_width(struct ushc_data *ushc, int bus_width)
0343 {
0344 return ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_4BIT,
0345 bus_width == 4 ? USHC_HOST_CTRL_4BIT : 0);
0346 }
0347
0348 static int ushc_set_bus_freq(struct ushc_data *ushc, int clk, bool enable_hs)
0349 {
0350 int ret;
0351
0352
0353 if (clk == 0)
0354 clk = 400000;
0355
0356 ret = ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_HIGH_SPD,
0357 enable_hs ? USHC_HOST_CTRL_HIGH_SPD : 0);
0358 if (ret < 0)
0359 return ret;
0360
0361 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0),
0362 USHC_CLK_FREQ, USHC_CLK_FREQ_TYPE,
0363 clk & 0xffff, (clk >> 16) & 0xffff, NULL, 0, 100);
0364 if (ret < 0)
0365 return ret;
0366
0367 ushc->clock_freq = clk;
0368 return 0;
0369 }
0370
0371 static void ushc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
0372 {
0373 struct ushc_data *ushc = mmc_priv(mmc);
0374
0375 ushc_set_power(ushc, ios->power_mode);
0376 ushc_set_bus_width(ushc, 1 << ios->bus_width);
0377 ushc_set_bus_freq(ushc, ios->clock, ios->timing == MMC_TIMING_SD_HS);
0378 }
0379
0380 static int ushc_get_cd(struct mmc_host *mmc)
0381 {
0382 struct ushc_data *ushc = mmc_priv(mmc);
0383
0384 return !!(ushc->last_status & USHC_INT_STATUS_CARD_PRESENT);
0385 }
0386
0387 static void ushc_enable_sdio_irq(struct mmc_host *mmc, int enable)
0388 {
0389 struct ushc_data *ushc = mmc_priv(mmc);
0390
0391 if (enable)
0392 set_bit(INT_EN, &ushc->flags);
0393 else
0394 clear_bit(INT_EN, &ushc->flags);
0395 }
0396
0397 static void ushc_clean_up(struct ushc_data *ushc)
0398 {
0399 usb_free_urb(ushc->int_urb);
0400 usb_free_urb(ushc->csw_urb);
0401 usb_free_urb(ushc->data_urb);
0402 usb_free_urb(ushc->cbw_urb);
0403
0404 kfree(ushc->int_data);
0405 kfree(ushc->cbw);
0406 kfree(ushc->csw);
0407
0408 mmc_free_host(ushc->mmc);
0409 }
0410
0411 static const struct mmc_host_ops ushc_ops = {
0412 .request = ushc_request,
0413 .set_ios = ushc_set_ios,
0414 .get_cd = ushc_get_cd,
0415 .enable_sdio_irq = ushc_enable_sdio_irq,
0416 };
0417
0418 static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id)
0419 {
0420 struct usb_device *usb_dev = interface_to_usbdev(intf);
0421 struct mmc_host *mmc;
0422 struct ushc_data *ushc;
0423 int ret;
0424
0425 if (intf->cur_altsetting->desc.bNumEndpoints < 1)
0426 return -ENODEV;
0427
0428 mmc = mmc_alloc_host(sizeof(struct ushc_data), &intf->dev);
0429 if (mmc == NULL)
0430 return -ENOMEM;
0431 ushc = mmc_priv(mmc);
0432 usb_set_intfdata(intf, ushc);
0433
0434 ushc->usb_dev = usb_dev;
0435 ushc->mmc = mmc;
0436
0437 spin_lock_init(&ushc->lock);
0438
0439 ret = ushc_hw_reset(ushc);
0440 if (ret < 0)
0441 goto err;
0442
0443
0444 ret = ushc_hw_get_caps(ushc);
0445 if (ret < 0)
0446 goto err;
0447
0448 mmc->ops = &ushc_ops;
0449
0450 mmc->f_min = 400000;
0451 mmc->f_max = 50000000;
0452 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
0453 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
0454 mmc->caps |= (ushc->caps & USHC_GET_CAPS_HIGH_SPD) ? MMC_CAP_SD_HIGHSPEED : 0;
0455
0456 mmc->max_seg_size = 512*511;
0457 mmc->max_segs = 1;
0458 mmc->max_req_size = 512*511;
0459 mmc->max_blk_size = 512;
0460 mmc->max_blk_count = 511;
0461
0462 ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL);
0463 if (ushc->int_urb == NULL) {
0464 ret = -ENOMEM;
0465 goto err;
0466 }
0467 ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL);
0468 if (ushc->int_data == NULL) {
0469 ret = -ENOMEM;
0470 goto err;
0471 }
0472 usb_fill_int_urb(ushc->int_urb, ushc->usb_dev,
0473 usb_rcvintpipe(usb_dev,
0474 intf->cur_altsetting->endpoint[0].desc.bEndpointAddress),
0475 ushc->int_data, sizeof(struct ushc_int_data),
0476 int_callback, ushc,
0477 intf->cur_altsetting->endpoint[0].desc.bInterval);
0478
0479 ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL);
0480 if (ushc->cbw_urb == NULL) {
0481 ret = -ENOMEM;
0482 goto err;
0483 }
0484 ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL);
0485 if (ushc->cbw == NULL) {
0486 ret = -ENOMEM;
0487 goto err;
0488 }
0489 ushc->cbw->signature = USHC_CBW_SIGNATURE;
0490
0491 usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2),
0492 ushc->cbw, sizeof(struct ushc_cbw),
0493 cbw_callback, ushc);
0494
0495 ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL);
0496 if (ushc->data_urb == NULL) {
0497 ret = -ENOMEM;
0498 goto err;
0499 }
0500
0501 ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL);
0502 if (ushc->csw_urb == NULL) {
0503 ret = -ENOMEM;
0504 goto err;
0505 }
0506 ushc->csw = kzalloc(sizeof(struct ushc_csw), GFP_KERNEL);
0507 if (ushc->csw == NULL) {
0508 ret = -ENOMEM;
0509 goto err;
0510 }
0511 usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6),
0512 ushc->csw, sizeof(struct ushc_csw),
0513 csw_callback, ushc);
0514
0515 ret = mmc_add_host(ushc->mmc);
0516 if (ret)
0517 goto err;
0518
0519 ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL);
0520 if (ret < 0) {
0521 mmc_remove_host(ushc->mmc);
0522 goto err;
0523 }
0524
0525 return 0;
0526
0527 err:
0528 ushc_clean_up(ushc);
0529 return ret;
0530 }
0531
0532 static void ushc_disconnect(struct usb_interface *intf)
0533 {
0534 struct ushc_data *ushc = usb_get_intfdata(intf);
0535
0536 spin_lock_irq(&ushc->lock);
0537 set_bit(DISCONNECTED, &ushc->flags);
0538 spin_unlock_irq(&ushc->lock);
0539
0540 usb_kill_urb(ushc->int_urb);
0541 usb_kill_urb(ushc->cbw_urb);
0542 usb_kill_urb(ushc->data_urb);
0543 usb_kill_urb(ushc->csw_urb);
0544
0545 mmc_remove_host(ushc->mmc);
0546
0547 ushc_clean_up(ushc);
0548 }
0549
0550 static struct usb_device_id ushc_id_table[] = {
0551
0552 { USB_DEVICE(0x0a12, 0x5d10) },
0553 { },
0554 };
0555 MODULE_DEVICE_TABLE(usb, ushc_id_table);
0556
0557 static struct usb_driver ushc_driver = {
0558 .name = "ushc",
0559 .id_table = ushc_id_table,
0560 .probe = ushc_probe,
0561 .disconnect = ushc_disconnect,
0562 };
0563
0564 module_usb_driver(ushc_driver);
0565
0566 MODULE_DESCRIPTION("USB SD Host Controller driver");
0567 MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>");
0568 MODULE_LICENSE("GPL");