drivers/net/ethernet/arc/emac_rockchip.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/arc/emac_rockchip.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/arc/emac_rockchip.c
Extension
.c
Size
6988 bytes
Lines
279
Domain
Driver Families
Bucket
drivers/net
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

struct emac_rockchip_soc_data {
	unsigned int grf_offset;
	unsigned int grf_mode_offset;
	unsigned int grf_speed_offset;
	bool need_div_macclk;
};

struct rockchip_priv_data {
	struct arc_emac_priv emac;
	struct regmap *grf;
	const struct emac_rockchip_soc_data *soc_data;
	struct regulator *regulator;
	struct clk *refclk;
	struct clk *macclk;
};

static void emac_rockchip_set_mac_speed(void *priv, unsigned int speed)
{
	struct rockchip_priv_data *emac = priv;
	u32 speed_offset = emac->soc_data->grf_speed_offset;
	u32 data;
	int err = 0;

	switch (speed) {
	case 10:
		data = (1 << (speed_offset + 16)) | (0 << speed_offset);
		break;
	case 100:
		data = (1 << (speed_offset + 16)) | (1 << speed_offset);
		break;
	default:
		pr_err("speed %u not supported\n", speed);
		return;
	}

	err = regmap_write(emac->grf, emac->soc_data->grf_offset, data);
	if (err)
		pr_err("unable to apply speed %u to grf (%d)\n", speed, err);
}

static const struct emac_rockchip_soc_data emac_rk3036_emac_data = {
	.grf_offset = 0x140,   .grf_mode_offset = 8,
	.grf_speed_offset = 9, .need_div_macclk = 1,
};

static const struct emac_rockchip_soc_data emac_rk3066_emac_data = {
	.grf_offset = 0x154,   .grf_mode_offset = 0,
	.grf_speed_offset = 1, .need_div_macclk = 0,
};

static const struct emac_rockchip_soc_data emac_rk3188_emac_data = {
	.grf_offset = 0x0a4,   .grf_mode_offset = 0,
	.grf_speed_offset = 1, .need_div_macclk = 0,
};

static const struct of_device_id emac_rockchip_dt_ids[] = {
	{
		.compatible = "rockchip,rk3036-emac",
		.data = &emac_rk3036_emac_data,
	},
	{
		.compatible = "rockchip,rk3066-emac",
		.data = &emac_rk3066_emac_data,
	},
	{
		.compatible = "rockchip,rk3188-emac",
		.data = &emac_rk3188_emac_data,
	},
	{ /* Sentinel */ }
};

MODULE_DEVICE_TABLE(of, emac_rockchip_dt_ids);

static int emac_rockchip_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct net_device *ndev;
	struct rockchip_priv_data *priv;
	const struct of_device_id *match;
	phy_interface_t interface;
	u32 data;
	int err;

	if (!pdev->dev.of_node)
		return -ENODEV;

	ndev = alloc_etherdev(sizeof(struct rockchip_priv_data));
	if (!ndev)
		return -ENOMEM;
	platform_set_drvdata(pdev, ndev);

Annotation

Implementation Notes