drivers/misc/cardreader/rts5261.c

Source file repositories/reference/linux-study-clean/drivers/misc/cardreader/rts5261.c

File Facts

System
Linux kernel
Corpus path
drivers/misc/cardreader/rts5261.c
Extension
.c
Size
22599 bytes
Lines
807
Domain
Driver Families
Bucket
drivers/misc
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (valid == 3) {
			/* Bypass efuse */
			setting_reg1 = PCR_SETTING_REG1;
			setting_reg2 = PCR_SETTING_REG2;
		} else {
			/* Use efuse data */
			setting_reg1 = PCR_SETTING_REG4;
			setting_reg2 = PCR_SETTING_REG5;
		}
	} else if (efuse_valid == 0) {
		// default
		setting_reg1 = PCR_SETTING_REG1;
		setting_reg2 = PCR_SETTING_REG2;
	} else {
		return;
	}

	pci_read_config_dword(pdev, setting_reg2, &lval2);
	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg2, lval2);

	if (!rts5261_vendor_setting_valid(lval2)) {
		/* Not support MMC default */
		pcr->extra_caps |= EXTRA_CAPS_NO_MMC;
		pcr_dbg(pcr, "skip fetch vendor setting\n");
		return;
	}

	if (!rts5261_reg_check_mmc_support(lval2))
		pcr->extra_caps |= EXTRA_CAPS_NO_MMC;

	pcr->rtd3_en = rts5261_reg_to_rtd3(lval2);

	if (rts5261_reg_check_reverse_socket(lval2))
		pcr->flags |= PCR_REVERSE_SOCKET;

	pci_read_config_dword(pdev, setting_reg1, &lval1);
	pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", setting_reg1, lval1);

	pcr->aspm_en = rts5261_reg_to_aspm(lval1);
	pcr->sd30_drive_sel_1v8 = rts5261_reg_to_sd30_drive_sel_1v8(lval1);
	pcr->sd30_drive_sel_3v3 = rts5261_reg_to_sd30_drive_sel_3v3(lval1);

	if (setting_reg1 == PCR_SETTING_REG1) {
		/* store setting */
		rtsx_pci_write_register(pcr, 0xFF0C, 0xFF, (u8)(lval1 & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF0D, 0xFF, (u8)((lval1 >> 8) & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF0E, 0xFF, (u8)((lval1 >> 16) & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF0F, 0xFF, (u8)((lval1 >> 24) & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF10, 0xFF, (u8)(lval2 & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF11, 0xFF, (u8)((lval2 >> 8) & 0xFF));
		rtsx_pci_write_register(pcr, 0xFF12, 0xFF, (u8)((lval2 >> 16) & 0xFF));

		pci_write_config_dword(pdev, PCR_SETTING_REG4, lval1);
		lval2 = lval2 & 0x00FFFFFF;
		pci_write_config_dword(pdev, PCR_SETTING_REG5, lval2);
	}
}

static void rts5261_init_from_cfg(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;

	if (option->ltr_en) {
		if (option->ltr_enabled)
			rtsx_set_ltr_latency(pcr, option->ltr_active_latency);
	}
}

static int rts5261_extra_init_hw(struct rtsx_pcr *pcr)
{
	struct rtsx_cr_option *option = &pcr->option;
	u32 val;

	rtsx_pci_write_register(pcr, RTS5261_AUTOLOAD_CFG1,
			CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);

	rts5261_init_from_cfg(pcr);
	rts5261_init_from_hw(pcr);

	/* power off efuse */
	rtsx_pci_write_register(pcr, RTS5261_REG_PME_FORCE_CTL,
			REG_EFUSE_POWER_MASK, REG_EFUSE_POWEROFF);
	rtsx_pci_write_register(pcr, L1SUB_CONFIG1,
			AUX_CLK_ACTIVE_SEL_MASK, MAC_CKSW_DONE);
	rtsx_pci_write_register(pcr, L1SUB_CONFIG3, 0xFF, 0);

	if (is_version_higher_than(pcr, PID_5261, IC_VER_B)) {
		val = rtsx_pci_readl(pcr, RTSX_DUM_REG);
		rtsx_pci_writel(pcr, RTSX_DUM_REG, val | 0x1);
	}

Annotation

Implementation Notes