NOTE:Kernel version: 5.4.24
File Path:drivers/phy/xxxxxx/phy-xxx-pcie.c(省略返回值判断)
1、相关结构
struct xxx_pcie_phy {
struct phy *phy;
struct clk *clk;
void __iomem *base;
u32 flags;
};
2、phy驱动框架
NOTE: 下述代码凡是对返回值判断均用...代替;而......表示省略部分代码。
5)主要硬件配置函数xxx_pcie_phy_cal
static int xxx_pcie_phy_cal(struct phy *phy)
{
if (xxx_phy->flags & xxxMP_PCIE_PHY_FLAG_SYS_PLL) {
......
......
}else if (xxx_phy->flags & xxxMP_PCIE_PHY_FLAG_XO) {
......
......
}
......
......
return 0;
}
4)定义xxx_pcie_phy_ops
static struct phy_ops xxx_pcie_phy_ops = {
.init = xxx_pcie_phy_init,
.calibrate = xxx_pcie_phy_cal,
.power_on = xxx_pcie_phy_power_on,
.power_off = xxx_pcie_phy_power_off,
.owner = THIS_MODULE,
};
3)实现xxx_pcie_phy_probe
static int xxx_pcie_phy_probe(struct platform_device *pdev)
{
struct xxx_pcie_phy *xxx_phy;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
u32 val = 0;
struct resource *res;
xxx_phy = devm_kzalloc(dev, sizeof(*xxx_phy), GFP_KERNEL);
...
xxx_phy->flags &= ~xxxMP_PCIE_PHY_FLAG_CLK_MASK;
if (of_property_read_u32(np, "clk_mode", &val) < 0)
xxx_phy->flags |= xxxMP_PCIE_PHY_FLAG_EXT_OSC;
if (val == 1)
xxx_phy->flags |= xxxMP_PCIE_PHY_FLAG_XO;
else if (val == 2)
xxx_phy->flags |= xxxMP_PCIE_PHY_FLAG_EXT_OSC;
else if (val == 3)
xxx_phy->flags |= xxxMP_PCIE_PHY_FLAG_SYS_PLL;
xxx_phy->clk = devm_clk_get(dev, "phy");
...
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
xxx_phy->base = devm_ioremap_resource(dev, res);
...
xxx_phy->phy = devm_phy_create(dev, NULL, &xxx_pcie_phy_ops);
...
phy_set_drvdata(xxx_phy->phy, xxx_phy);
......
}
2)定义.driver.of_match_table
static const struct of_device_id xxx_pcie_phy_of_match[] = {
{.compatible = "fsl,xxxmp-pcie-phy",},
{ },
};
MODULE_DEVICE_TABLE(of, xxx_pcie_phy_of_match);
1)定义一个platform driver
static struct platform_driver xxx_pcie_phy_driver = {
.probe = xxx_pcie_phy_probe,
.driver = {
.name = "xxx-pcie-phy",
.of_match_table = xxx_pcie_phy_of_match,
}
};
module_platform_driver(xxx_pcie_phy_driver)