Lines Matching refs:ushc
119 static int ushc_hw_reset(struct ushc_data *ushc) in ushc_hw_reset() argument
121 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0), in ushc_hw_reset()
126 static int ushc_hw_get_caps(struct ushc_data *ushc) in ushc_hw_get_caps() argument
131 ret = usb_control_msg(ushc->usb_dev, usb_rcvctrlpipe(ushc->usb_dev, 0), in ushc_hw_get_caps()
133 0, 0, &ushc->caps, sizeof(ushc->caps), 100); in ushc_hw_get_caps()
137 ushc->caps = le32_to_cpu(ushc->caps); in ushc_hw_get_caps()
139 version = ushc->caps & USHC_GET_CAPS_VERSION_MASK; in ushc_hw_get_caps()
141 dev_err(&ushc->usb_dev->dev, "controller version %d is not supported\n", version); in ushc_hw_get_caps()
148 static int ushc_hw_set_host_ctrl(struct ushc_data *ushc, u16 mask, u16 val) in ushc_hw_set_host_ctrl() argument
153 host_ctrl = (ushc->host_ctrl & ~mask) | val; in ushc_hw_set_host_ctrl()
154 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0), in ushc_hw_set_host_ctrl()
159 ushc->host_ctrl = host_ctrl; in ushc_hw_set_host_ctrl()
165 struct ushc_data *ushc = urb->context; in int_callback() local
171 status = ushc->int_data->status; in int_callback()
172 last_status = ushc->last_status; in int_callback()
173 ushc->last_status = status; in int_callback()
183 if (!test_and_clear_bit(IGNORE_NEXT_INT, &ushc->flags) in int_callback()
184 && test_bit(INT_EN, &ushc->flags) in int_callback()
186 mmc_signal_sdio_irq(ushc->mmc); in int_callback()
190 mmc_detect_change(ushc->mmc, msecs_to_jiffies(100)); in int_callback()
192 if (!test_bit(INT_EN, &ushc->flags)) in int_callback()
193 set_bit(IGNORE_NEXT_INT, &ushc->flags); in int_callback()
194 usb_submit_urb(ushc->int_urb, GFP_ATOMIC); in int_callback()
199 struct ushc_data *ushc = urb->context; in cbw_callback() local
202 usb_unlink_urb(ushc->data_urb); in cbw_callback()
203 usb_unlink_urb(ushc->csw_urb); in cbw_callback()
209 struct ushc_data *ushc = urb->context; in data_callback() local
212 usb_unlink_urb(ushc->csw_urb); in data_callback()
217 struct ushc_data *ushc = urb->context; in csw_callback() local
218 struct mmc_request *req = ushc->current_req; in csw_callback()
221 status = ushc->csw->status; in csw_callback()
243 req->cmd->resp[0] = le32_to_cpu(ushc->csw->response); in csw_callback()
245 mmc_request_done(ushc->mmc, req); in csw_callback()
250 struct ushc_data *ushc = mmc_priv(mmc); in ushc_request() local
254 spin_lock_irqsave(&ushc->lock, flags); in ushc_request()
256 if (test_bit(DISCONNECTED, &ushc->flags)) { in ushc_request()
269 if (req->data && ushc->clock_freq < 6000000) { in ushc_request()
274 ushc->current_req = req; in ushc_request()
277 ushc->cbw->cmd_idx = cpu_to_le16(req->cmd->opcode); in ushc_request()
279 ushc->cbw->block_size = cpu_to_le16(req->data->blksz); in ushc_request()
281 ushc->cbw->block_size = 0; in ushc_request()
282 ushc->cbw->arg = cpu_to_le32(req->cmd->arg); in ushc_request()
284 ret = usb_submit_urb(ushc->cbw_urb, GFP_ATOMIC); in ushc_request()
294 pipe = usb_rcvbulkpipe(ushc->usb_dev, 6); in ushc_request()
296 pipe = usb_sndbulkpipe(ushc->usb_dev, 2); in ushc_request()
298 usb_fill_bulk_urb(ushc->data_urb, ushc->usb_dev, pipe, in ushc_request()
300 data_callback, ushc); in ushc_request()
301 ushc->data_urb->num_sgs = 1; in ushc_request()
302 ushc->data_urb->sg = data->sg; in ushc_request()
303 ret = usb_submit_urb(ushc->data_urb, GFP_ATOMIC); in ushc_request()
309 ret = usb_submit_urb(ushc->csw_urb, GFP_ATOMIC); in ushc_request()
312 spin_unlock_irqrestore(&ushc->lock, flags); in ushc_request()
314 usb_unlink_urb(ushc->cbw_urb); in ushc_request()
315 usb_unlink_urb(ushc->data_urb); in ushc_request()
321 static int ushc_set_power(struct ushc_data *ushc, unsigned char power_mode) in ushc_set_power() argument
337 return usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0), in ushc_set_power()
342 static int ushc_set_bus_width(struct ushc_data *ushc, int bus_width) in ushc_set_bus_width() argument
344 return ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_4BIT, in ushc_set_bus_width()
348 static int ushc_set_bus_freq(struct ushc_data *ushc, int clk, bool enable_hs) in ushc_set_bus_freq() argument
356 ret = ushc_hw_set_host_ctrl(ushc, USHC_HOST_CTRL_HIGH_SPD, in ushc_set_bus_freq()
361 ret = usb_control_msg(ushc->usb_dev, usb_sndctrlpipe(ushc->usb_dev, 0), in ushc_set_bus_freq()
367 ushc->clock_freq = clk; in ushc_set_bus_freq()
373 struct ushc_data *ushc = mmc_priv(mmc); in ushc_set_ios() local
375 ushc_set_power(ushc, ios->power_mode); in ushc_set_ios()
376 ushc_set_bus_width(ushc, 1 << ios->bus_width); in ushc_set_ios()
377 ushc_set_bus_freq(ushc, ios->clock, ios->timing == MMC_TIMING_SD_HS); in ushc_set_ios()
382 struct ushc_data *ushc = mmc_priv(mmc); in ushc_get_cd() local
384 return !!(ushc->last_status & USHC_INT_STATUS_CARD_PRESENT); in ushc_get_cd()
389 struct ushc_data *ushc = mmc_priv(mmc); in ushc_enable_sdio_irq() local
392 set_bit(INT_EN, &ushc->flags); in ushc_enable_sdio_irq()
394 clear_bit(INT_EN, &ushc->flags); in ushc_enable_sdio_irq()
397 static void ushc_clean_up(struct ushc_data *ushc) in ushc_clean_up() argument
399 usb_free_urb(ushc->int_urb); in ushc_clean_up()
400 usb_free_urb(ushc->csw_urb); in ushc_clean_up()
401 usb_free_urb(ushc->data_urb); in ushc_clean_up()
402 usb_free_urb(ushc->cbw_urb); in ushc_clean_up()
404 kfree(ushc->int_data); in ushc_clean_up()
405 kfree(ushc->cbw); in ushc_clean_up()
406 kfree(ushc->csw); in ushc_clean_up()
408 mmc_free_host(ushc->mmc); in ushc_clean_up()
422 struct ushc_data *ushc; in ushc_probe() local
431 ushc = mmc_priv(mmc); in ushc_probe()
432 usb_set_intfdata(intf, ushc); in ushc_probe()
434 ushc->usb_dev = usb_dev; in ushc_probe()
435 ushc->mmc = mmc; in ushc_probe()
437 spin_lock_init(&ushc->lock); in ushc_probe()
439 ret = ushc_hw_reset(ushc); in ushc_probe()
444 ret = ushc_hw_get_caps(ushc); in ushc_probe()
454 mmc->caps |= (ushc->caps & USHC_GET_CAPS_HIGH_SPD) ? MMC_CAP_SD_HIGHSPEED : 0; in ushc_probe()
462 ushc->int_urb = usb_alloc_urb(0, GFP_KERNEL); in ushc_probe()
463 if (ushc->int_urb == NULL) { in ushc_probe()
467 ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); in ushc_probe()
468 if (ushc->int_data == NULL) { in ushc_probe()
472 usb_fill_int_urb(ushc->int_urb, ushc->usb_dev, in ushc_probe()
475 ushc->int_data, sizeof(struct ushc_int_data), in ushc_probe()
476 int_callback, ushc, in ushc_probe()
479 ushc->cbw_urb = usb_alloc_urb(0, GFP_KERNEL); in ushc_probe()
480 if (ushc->cbw_urb == NULL) { in ushc_probe()
484 ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); in ushc_probe()
485 if (ushc->cbw == NULL) { in ushc_probe()
489 ushc->cbw->signature = USHC_CBW_SIGNATURE; in ushc_probe()
491 usb_fill_bulk_urb(ushc->cbw_urb, ushc->usb_dev, usb_sndbulkpipe(usb_dev, 2), in ushc_probe()
492 ushc->cbw, sizeof(struct ushc_cbw), in ushc_probe()
493 cbw_callback, ushc); in ushc_probe()
495 ushc->data_urb = usb_alloc_urb(0, GFP_KERNEL); in ushc_probe()
496 if (ushc->data_urb == NULL) { in ushc_probe()
501 ushc->csw_urb = usb_alloc_urb(0, GFP_KERNEL); in ushc_probe()
502 if (ushc->csw_urb == NULL) { in ushc_probe()
506 ushc->csw = kzalloc(sizeof(struct ushc_csw), GFP_KERNEL); in ushc_probe()
507 if (ushc->csw == NULL) { in ushc_probe()
511 usb_fill_bulk_urb(ushc->csw_urb, ushc->usb_dev, usb_rcvbulkpipe(usb_dev, 6), in ushc_probe()
512 ushc->csw, sizeof(struct ushc_csw), in ushc_probe()
513 csw_callback, ushc); in ushc_probe()
515 ret = mmc_add_host(ushc->mmc); in ushc_probe()
519 ret = usb_submit_urb(ushc->int_urb, GFP_KERNEL); in ushc_probe()
521 mmc_remove_host(ushc->mmc); in ushc_probe()
528 ushc_clean_up(ushc); in ushc_probe()
534 struct ushc_data *ushc = usb_get_intfdata(intf); in ushc_disconnect() local
536 spin_lock_irq(&ushc->lock); in ushc_disconnect()
537 set_bit(DISCONNECTED, &ushc->flags); in ushc_disconnect()
538 spin_unlock_irq(&ushc->lock); in ushc_disconnect()
540 usb_kill_urb(ushc->int_urb); in ushc_disconnect()
541 usb_kill_urb(ushc->cbw_urb); in ushc_disconnect()
542 usb_kill_urb(ushc->data_urb); in ushc_disconnect()
543 usb_kill_urb(ushc->csw_urb); in ushc_disconnect()
545 mmc_remove_host(ushc->mmc); in ushc_disconnect()
547 ushc_clean_up(ushc); in ushc_disconnect()