auto
  	   …ˆÍÐ0¿Î     ‡ˆÍÐ„o<Ì¿Î >    ‡/* SPDX-License-Identifier: GPL-2.0-only */
/* Driver for Realtek RTS5139 USB card reader
 *
 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
 *
 * Author:
 *   Roger Tseng <rogerable@realtek.com>
 */

#ifndef __RTSX_USB_H
#define __RTSX_USB_H

#include <linux/usb.h>

#define DRV_NAME_RTSX_USB		"rtsx_usb"
#define DRV_NAME_RTSX_USB_SDMMC		"rtsx_usb_sdmmc"
#define DRV_NAME_RTSX_USB_MS		"rtsx_usb_ms"

/* related module names */
#define RTSX_USB_SD_CARD	0
#define RTSX_USB_MS_CARD	1

/* endpoint numbers */
#define EP_BULK_OUT		1
#define EP_BULK_IN		2
#define EP_INTR_IN		3

/* USB vendor requests */
#define RTSX_USB_REQ_REG_OP	0x00
#define RTSX_USB_REQ_POLL	0x02

/* miscellaneous parameters */
#define MIN_DIV_N		60
#define MAX_DIV_N		120

#define MAX_PHASE		15
#define RX_TUNING_CNT		3

#define QFN24			0
#define LQFP48			1
#define CHECK_PKG(ucr, pkg)	((ucr)->package == (pkg))

/* data structures */
struct rtsx_ucr {
	u16			vendor_id;
	u16			product_id;

	int			package;
	u8			ic_version;
	bool			is_rts5179;

	unsigned int		cur_clk;

	u8			*cmd_buf;
	unsigned int		cmd_idx;
	u8			*rsp_buf;

	struct usb_device	*pusb_dev;
	struct usb_interface	*pusb_intf;
	struct usb_sg_request	current_sg;

	struct timer_list	sg_timer;
	struct mutex		dev_mutex;
};

/* buffer size */
#define IOBUF_SIZE		1024

/* prototypes of exported functions */
extern int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status);

extern int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data);
extern int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
		u8 data);

extern int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask,
		u8 data);
extern int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr,
		u8 *data);

extern void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type,
		u16 reg_addr, u8 mask, u8 data);
extern int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout);
extern int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout);
extern int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
			      void *buf, unsigned int len, int use_sg,
			      unsigned int *act_len, int timeout);

extern int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
extern int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len);
extern int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock,
		u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk);
extern int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card);

/* card status */
#define SD_CD		0x01
#define MS_CD		0x02
#define XD_CD		0x04
#define CD_MASK		(SD_CD | MS_CD | XD_CD)
#define SD_WP		0x08

/* reader command field offset & parameters */
#define READ_REG_CMD		0
#define WRITE_REG_CMD		1
#define CHECK_REG_CMD		2

#define PACKET_TYPE		4
#define CNT_H			5
#define CNT_L			6
#define STAGE_FLAG		7
#define CMD_OFFSET		8
#define SEQ_WRITE_DATA_OFFSET	12

#define BATCH_CMD		0
#define SEQ_READ		1
#define SEQ_WRITE		2

#define STAGE_R			0x01
#define STAGE_DI		0x02
#define STAGE_DO		0x04
#define STAGE_MS_STATUS		0x08
#define STAGE_XD_STATUS		0x10
#define MODE_C			0x00
#define MODE_CR			(STAGE_R)
#define MODE_CDIR		(STAGE_R | STAGE_DI)
#define MODE_CDOR		(STAGE_R | STAGE_DO)

#define EP0_OP_SHIFT		14
#define EP0_READ_REG_CMD	2
#define EP0_WRITE_REG_CMD	3

#define rtsx_usb_cmd_hdr_tag(ucr)		\
	do {					\
		ucr->cmd_buf[0] = 'R';		\
		ucr->cmd_buf[1] = 'T';		\
		ucr->cmd_buf[2] = 'C';		\
		ucr->cmd_buf[3] = 'R';		\
	} while (0)

static inline void rtsx_usb_init_cmd(struct rtsx_ucr *ucr)
{
	rtsx_usb_cmd_hdr_tag(ucr);
	ucr->cmd_idx = 0;
	ucr->cmd_buf[PACKET_TYPE] = BATCH_CMD;
}

/* internal register address */
#define FPDCTL				0xFC00
#define SSC_DIV_N_0			0xFC07
#define SSC_CTL1			0xFC09
#define SSC_CTL2			0xFC0A
#define CFG_MODE			0xFC0E
#define CFG_MODE_1			0xFC0F
#define RCCTL				0xFC14
#define SOF_WDOG			0xFC28
#define SYS_DUMMY0			0xFC30

#define MS_BLKEND			0xFD30
#define MS_READ_START			0xFD31
#define 