2 * USB SD Host Controller (USHC) controller driver.
4 * Copyright (C) 2010 Cambridge Silicon Radio Ltd.
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.
12 * - Only version 2 devices are supported.
13 * - Version 2 devices only support SDIO cards/devices (R2 response is
17 * [USHC] USB SD Host Controller specification (CS-118793-SP)
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>
28 USHC_HOST_CTRL
= 0x01,
32 USHC_READ_RESP
= 0x05,
36 enum 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
,
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)
52 #define USHC_HOST_CTRL_4BIT (1 << 1)
53 #define USHC_HOST_CTRL_HIGH_SPD (1 << 0)
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
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
72 } __attribute__((packed
));
74 #define USHC_CBW_SIGNATURE 'C'
80 } __attribute__((packed
));
82 #define USHC_CSW_SIGNATURE 'S'
84 struct ushc_int_data
{
89 #define USHC_INT_STATUS_SDIO_INT (1 << 1)
90 #define USHC_INT_STATUS_CARD_PRESENT (1 << 0)
94 struct usb_device
*usb_dev
;
98 struct ushc_int_data
*int_data
;
101 struct ushc_cbw
*cbw
;
103 struct urb
*data_urb
;
106 struct ushc_csw
*csw
;
109 struct mmc_request
*current_req
;
117 #define DISCONNECTED 0
119 #define IGNORE_NEXT_INT 2
121 static void data_callback(struct urb
*urb
);
123 static int ushc_hw_reset(struct ushc_data
*ushc
)
125 return usb_control_msg(ushc
->usb_dev
, usb_sndctrlpipe(ushc
->usb_dev
, 0),
126 USHC_RESET
, USHC_RESET_TYPE
,
130 static int ushc_hw_get_caps(struct ushc_data
*ushc
)
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);
141 ushc
->caps
= le32_to_cpu(ushc
->caps
);
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
);
152 static int ushc_hw_set_host_ctrl(struct ushc_data
*ushc
, u16 mask
, u16 val
)
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);
163 ushc
->host_ctrl
= host_ctrl
;
167 static void int_callback(struct urb
*urb
)
169 struct ushc_data
*ushc
= urb
->context
;
170 u8 status
, last_status
;
175 status
= ushc
->int_data
->status
;
176 last_status
= ushc
->last_status
;
177 ushc
->last_status
= status
;
180 * Ignore the card interrupt status on interrupt transfers that
181 * were submitted while card interrupts where disabled.
183 * This avoid occasional spurious interrupts when enabling
184 * interrupts immediately after clearing the source on the card.
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
);
193 if ((status
^ last_status
) & USHC_INT_STATUS_CARD_PRESENT
)
194 mmc_detect_change(ushc
->mmc
, msecs_to_jiffies(100));
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
);
201 static void cbw_callback(struct urb
*urb
)
203 struct ushc_data
*ushc
= urb
->context
;
205 if (urb
->status
!= 0) {
206 usb_unlink_urb(ushc
->data_urb
);
207 usb_unlink_urb(ushc
->csw_urb
);
211 static void data_callback(struct urb
*urb
)
213 struct ushc_data
*ushc
= urb
->context
;
215 if (urb
->status
!= 0)
216 usb_unlink_urb(ushc
->csw_urb
);
219 static void csw_callback(struct urb
*urb
)
221 struct ushc_data
*ushc
= urb
->context
;
222 struct mmc_request
*req
= ushc
->current_req
;
225 status
= ushc
->csw
->status
;
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
;
233 req
->cmd
->error
= -ETIMEDOUT
;
236 if (status
& USHC_READ_RESP_ERR_DAT
) {
237 if (status
& USHC_READ_RESP_ERR_CRC
)
238 req
->data
->error
= -EIO
;
240 req
->data
->error
= -ETIMEDOUT
;
241 req
->data
->bytes_xfered
= 0;
243 req
->data
->bytes_xfered
= req
->data
->blksz
* req
->data
->blocks
;
247 req
->cmd
->resp
[0] = le32_to_cpu(ushc
->csw
->response
);
249 mmc_request_done(ushc
->mmc
, req
);
252 static void ushc_request(struct mmc_host
*mmc
, struct mmc_request
*req
)
254 struct ushc_data
*ushc
= mmc_priv(mmc
);
258 spin_lock_irqsave(&ushc
->lock
, flags
);
260 if (test_bit(DISCONNECTED
, &ushc
->flags
)) {
265 /* Version 2 firmware doesn't support the R2 response format. */
266 if (req
->cmd
->flags
& MMC_RSP_136
) {
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) {
278 ushc
->current_req
= req
;
280 /* Start cmd with CBW. */
281 ushc
->cbw
->cmd_idx
= cpu_to_le16(req
->cmd
->opcode
);
283 ushc
->cbw
->block_size
= cpu_to_le16(req
->data
->blksz
);
285 ushc
->cbw
->block_size
= 0;
286 ushc
->cbw
->arg
= cpu_to_le32(req
->cmd
->arg
);
288 ret
= usb_submit_urb(ushc
->cbw_urb
, GFP_ATOMIC
);
292 /* Submit data (if any). */
294 struct mmc_data
*data
= req
->data
;
297 if (data
->flags
& MMC_DATA_READ
)
298 pipe
= usb_rcvbulkpipe(ushc
->usb_dev
, 6);
300 pipe
= usb_sndbulkpipe(ushc
->usb_dev
, 2);
302 usb_fill_bulk_urb(ushc
->data_urb
, ushc
->usb_dev
, pipe
,
303 NULL
, data
->sg
->length
,
304 data_callback
, ushc
);
305 ushc
->data_urb
->num_sgs
= 1;
306 ushc
->data_urb
->sg
= data
->sg
;
307 ret
= usb_submit_urb(ushc
->data_urb
, GFP_ATOMIC
);
313 ret
= usb_submit_urb(ushc
->csw_urb
, GFP_ATOMIC
);
316 spin_unlock_irqrestore(&ushc
->lock
, flags
);
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
);
325 static int ushc_set_power(struct ushc_data
*ushc
, unsigned char power_mode
)
329 switch (power_mode
) {
331 voltage
= USHC_PWR_CTRL_OFF
;
335 voltage
= USHC_PWR_CTRL_3V3
;
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);
346 static int ushc_set_bus_width(struct ushc_data
*ushc
, int bus_width
)
348 return ushc_hw_set_host_ctrl(ushc
, USHC_HOST_CTRL_4BIT
,
349 bus_width
== 4 ? USHC_HOST_CTRL_4BIT
: 0);
352 static int ushc_set_bus_freq(struct ushc_data
*ushc
, int clk
, bool enable_hs
)
356 /* Hardware can't detect interrupts while the clock is off. */
360 ret
= ushc_hw_set_host_ctrl(ushc
, USHC_HOST_CTRL_HIGH_SPD
,
361 enable_hs
? USHC_HOST_CTRL_HIGH_SPD
: 0);
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);
371 ushc
->clock_freq
= clk
;
375 static void ushc_set_ios(struct mmc_host
*mmc
, struct mmc_ios
*ios
)
377 struct ushc_data
*ushc
= mmc_priv(mmc
);
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
);
384 static int ushc_get_cd(struct mmc_host
*mmc
)
386 struct ushc_data
*ushc
= mmc_priv(mmc
);
388 return !!(ushc
->last_status
& USHC_INT_STATUS_CARD_PRESENT
);
391 static void ushc_enable_sdio_irq(struct mmc_host
*mmc
, int enable
)
393 struct ushc_data
*ushc
= mmc_priv(mmc
);
396 set_bit(INT_EN
, &ushc
->flags
);
398 clear_bit(INT_EN
, &ushc
->flags
);
401 static void ushc_clean_up(struct ushc_data
*ushc
)
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
);
408 kfree(ushc
->int_data
);
412 mmc_free_host(ushc
->mmc
);
415 static 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
,
422 static int ushc_probe(struct usb_interface
*intf
, const struct usb_device_id
*id
)
424 struct usb_device
*usb_dev
= interface_to_usbdev(intf
);
425 struct mmc_host
*mmc
;
426 struct ushc_data
*ushc
;
429 if (intf
->cur_altsetting
->desc
.bNumEndpoints
< 1)
432 mmc
= mmc_alloc_host(sizeof(struct ushc_data
), &intf
->dev
);
435 ushc
= mmc_priv(mmc
);
436 usb_set_intfdata(intf
, ushc
);
438 ushc
->usb_dev
= usb_dev
;
441 spin_lock_init(&ushc
->lock
);
443 ret
= ushc_hw_reset(ushc
);
447 /* Read capabilities. */
448 ret
= ushc_hw_get_caps(ushc
);
452 mmc
->ops
= &ushc_ops
;
455 mmc
->f_max
= 50000000;
456 mmc
->ocr_avail
= MMC_VDD_32_33
| MMC_VDD_33_34
;
457 mmc
->caps
= MMC_CAP_4_BIT_DATA
| MMC_CAP_SDIO_IRQ
;
458 mmc
->caps
|= (ushc
->caps
& USHC_GET_CAPS_HIGH_SPD
) ? MMC_CAP_SD_HIGHSPEED
: 0;
460 mmc
->max_seg_size
= 512*511;
462 mmc
->max_req_size
= 512*511;
463 mmc
->max_blk_size
= 512;
464 mmc
->max_blk_count
= 511;
466 ushc
->int_urb
= usb_alloc_urb(0, GFP_KERNEL
);
467 if (ushc
->int_urb
== NULL
) {
471 ushc
->int_data
= kzalloc(sizeof(struct ushc_int_data
), GFP_KERNEL
);
472 if (ushc
->int_data
== NULL
) {
476 usb_fill_int_urb(ushc
->int_urb
, ushc
->usb_dev
,
477 usb_rcvintpipe(usb_dev
,
478 intf
->cur_altsetting
->endpoint
[0].desc
.bEndpointAddress
),
479 ushc
->int_data
, sizeof(struct ushc_int_data
),
481 intf
->cur_altsetting
->endpoint
[0].desc
.bInterval
);
483 ushc
->cbw_urb
= usb_alloc_urb(0, GFP_KERNEL
);
484 if (ushc
->cbw_urb
== NULL
) {
488 ushc
->cbw
= kzalloc(sizeof(struct ushc_cbw
), GFP_KERNEL
);
489 if (ushc
->cbw
== NULL
) {
493 ushc
->cbw
->signature
= USHC_CBW_SIGNATURE
;
495 usb_fill_bulk_urb(ushc
->cbw_urb
, ushc
->usb_dev
, usb_sndbulkpipe(usb_dev
, 2),
496 ushc
->cbw
, sizeof(struct ushc_cbw
),
499 ushc
->data_urb
= usb_alloc_urb(0, GFP_KERNEL
);
500 if (ushc
->data_urb
== NULL
) {
505 ushc
->csw_urb
= usb_alloc_urb(0, GFP_KERNEL
);
506 if (ushc
->csw_urb
== NULL
) {
510 ushc
->csw
= kzalloc(sizeof(struct ushc_csw
), GFP_KERNEL
);
511 if (ushc
->csw
== NULL
) {
515 usb_fill_bulk_urb(ushc
->csw_urb
, ushc
->usb_dev
, usb_rcvbulkpipe(usb_dev
, 6),
516 ushc
->csw
, sizeof(struct ushc_csw
),
519 ret
= mmc_add_host(ushc
->mmc
);
523 ret
= usb_submit_urb(ushc
->int_urb
, GFP_KERNEL
);
525 mmc_remove_host(ushc
->mmc
);
536 static void ushc_disconnect(struct usb_interface
*intf
)
538 struct ushc_data
*ushc
= usb_get_intfdata(intf
);
540 spin_lock_irq(&ushc
->lock
);
541 set_bit(DISCONNECTED
, &ushc
->flags
);
542 spin_unlock_irq(&ushc
->lock
);
544 usb_kill_urb(ushc
->int_urb
);
545 usb_kill_urb(ushc
->cbw_urb
);
546 usb_kill_urb(ushc
->data_urb
);
547 usb_kill_urb(ushc
->csw_urb
);
549 mmc_remove_host(ushc
->mmc
);
554 static struct usb_device_id ushc_id_table
[] = {
555 /* CSR USB SD Host Controller */
556 { USB_DEVICE(0x0a12, 0x5d10) },
559 MODULE_DEVICE_TABLE(usb
, ushc_id_table
);
561 static struct usb_driver ushc_driver
= {
563 .id_table
= ushc_id_table
,
565 .disconnect
= ushc_disconnect
,
568 module_usb_driver(ushc_driver
);
570 MODULE_DESCRIPTION("USB SD Host Controller driver");
571 MODULE_AUTHOR("David Vrabel <david.vrabel@csr.com>");
572 MODULE_LICENSE("GPL");