drivers/misc/cardreader/rts5249.c

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

File Facts

System
Linux kernel
Corpus path
drivers/misc/cardreader/rts5249.c
Extension
.c
Size
25750 bytes
Lines
859
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 (val & RTS525A_LOAD_BIOS_FLAG) {
			rtsx_pci_write_register(pcr, RTS525A_BIOS_CFG,
				RTS525A_LOAD_BIOS_FLAG, RTS525A_CLEAR_BIOS_FLAG);

			rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL,
				REG_EFUSE_POWER_MASK, REG_EFUSE_POWERON);

			pcr_dbg(pcr, "Power ON efuse!");
			mdelay(1);
			rts52xa_save_content_from_efuse(pcr);
		} else {
			rtsx_pci_read_register(pcr, RTS524A_PME_FORCE_CTL, &val);
			if (!(val & 0x08))
				rts52xa_save_content_from_efuse(pcr);
		}
	} else {
		pcr_dbg(pcr, "Load from autoload");
		rtsx_pci_write_register(pcr, 0xFF00, 0xFF, 0x80);
		rtsx_pci_write_register(pcr, 0xFF04, 0xFF, (u8)PCI_VID(pcr));
		rtsx_pci_write_register(pcr, 0xFF05, 0xFF, (u8)(PCI_VID(pcr) >> 8));
		rtsx_pci_write_register(pcr, 0xFF06, 0xFF, (u8)PCI_PID(pcr));
		rtsx_pci_write_register(pcr, 0xFF07, 0xFF, (u8)(PCI_PID(pcr) >> 8));
	}
}

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

	rts5249_init_from_cfg(pcr);

	rtsx_pci_init_cmd(pcr);

	if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A))
		rts52xa_save_content_to_autoload_space(pcr);

	/* Rest L1SUB Config */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
	/* Configure GPIO as output */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
	/* Reset ASPM state to default value */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
	/* Switch LDO3318 source from DV33 to card_3v3 */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x00);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, LDO_PWR_SEL, 0x03, 0x01);
	/* LED shine disabled, set initial shine cycle period */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, OLT_LED_CTL, 0x0F, 0x02);
	/* Configure driving */
	rts5249_fill_driving(pcr, OUTPUT_3V3);
	if (pcr->flags & PCR_REVERSE_SOCKET)
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x30, 0x30);
	else {
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x20, option->sd_cd_reverse_en << 5);
		rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x10, option->sd_wp_reverse_en << 4);
	}

	rtsx_pci_send_cmd(pcr, CMD_TIMEOUT_DEF);

	if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) {
		rtsx_pci_write_register(pcr, REG_VREF, PWD_SUSPND_EN, PWD_SUSPND_EN);
		rtsx_pci_write_register(pcr, RTS524A_AUTOLOAD_CFG1,
			CD_RESUME_EN_MASK, CD_RESUME_EN_MASK);
	}

	if (pcr->rtd3_en) {
		if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) {
			rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, 0x01, 0x01);
			rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL, 0x30, 0x30);
		} else {
			rtsx_pci_write_register(pcr, PM_CTRL3, 0x01, 0x01);
			rtsx_pci_write_register(pcr, PME_FORCE_CTL, 0xFF, 0x33);
		}
	} else {
		if (CHK_PCI_PID(pcr, PID_524A) || CHK_PCI_PID(pcr, PID_525A)) {
			rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3, 0x01, 0x00);
			rtsx_pci_write_register(pcr, RTS524A_PME_FORCE_CTL, 0x30, 0x20);
		} else {
			rtsx_pci_write_register(pcr, PME_FORCE_CTL, 0xFF, 0x30);
			rtsx_pci_write_register(pcr, PM_CTRL3, 0x01, 0x00);
		}
	}


	/*
	 * If u_force_clkreq_0 is enabled, CLKREQ# PIN will be forced
	 * to drive low, and we forcibly request clock.
	 */
	if (option->force_clkreq_0)
		rtsx_pci_write_register(pcr, PETXCFG,
			FORCE_CLKREQ_DELINK_MASK, FORCE_CLKREQ_LOW);

Annotation

Implementation Notes