drivers/misc/cardreader/rts5209.c

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

File Facts

System
Linux kernel
Corpus path
drivers/misc/cardreader/rts5209.c
Extension
.c
Size
7329 bytes
Lines
268
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

// SPDX-License-Identifier: GPL-2.0-or-later
/* Driver for Realtek PCI-Express card reader
 *
 * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
 *
 * Author:
 *   Wei WANG <wei_wang@realsil.com.cn>
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/rtsx_pci.h>

#include "rtsx_pcr.h"

static u8 rts5209_get_ic_version(struct rtsx_pcr *pcr)
{
	u8 val;

	val = rtsx_pci_readb(pcr, 0x1C);
	return val & 0x0F;
}

static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
{
	struct pci_dev *pdev = pcr->pci;
	u32 reg;

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

	if (rts5209_vendor_setting1_valid(reg)) {
		if (rts5209_reg_check_ms_pmos(reg))
			pcr->flags |= PCR_MS_PMOS;
		pcr->aspm_en = rts5209_reg_to_aspm(reg);
	}

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

	if (rts5209_vendor_setting2_valid(reg)) {
		pcr->sd30_drive_sel_1v8 =
			rts5209_reg_to_sd30_drive_sel_1v8(reg);
		pcr->sd30_drive_sel_3v3 =
			rts5209_reg_to_sd30_drive_sel_3v3(reg);
		pcr->card_drive_sel = rts5209_reg_to_card_drive_sel(reg);
	}
}

static void rts5209_force_power_down(struct rtsx_pcr *pcr, u8 pm_state, bool runtime)
{
	rtsx_pci_write_register(pcr, FPDCTL, 0x07, 0x07);
}

static int rts5209_extra_init_hw(struct rtsx_pcr *pcr)
{
	rtsx_pci_init_cmd(pcr);

	/* Turn off LED */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO, 0xFF, 0x03);
	/* Reset ASPM state to default value */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, ASPM_FORCE_CTL, 0x3F, 0);
	/* Force CLKREQ# PIN to drive 0 to request clock */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0x08, 0x08);
	/* Configure GPIO as output */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_GPIO_DIR, 0xFF, 0x03);
	/* Configure driving */
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD30_DRIVE_SEL,
			0xFF, pcr->sd30_drive_sel_3v3);

	return rtsx_pci_send_cmd(pcr, 100);
}

static int rts5209_optimize_phy(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_phy_register(pcr, 0x00, 0xB966);
}

static int rts5209_turn_on_led(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
}

static int rts5209_turn_off_led(struct rtsx_pcr *pcr)
{
	return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x01);
}

static int rts5209_enable_auto_blink(struct rtsx_pcr *pcr)
{

Annotation

Implementation Notes