Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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