Lines Matching +full:cpsw +full:- +full:switch

1 // SPDX-License-Identifier: GPL-2.0
3 * Texas Instruments CPSW Port's PHY Interface Mode selection Driver
5 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
7 * Based on cpsw-phy-sel.c driver created by Mugunthan V N <mugunthanvnm@ti.com>
61 const struct phy_gmii_sel_soc_data *soc_data = if_phy->priv->soc_data; in phy_gmii_sel_mode()
62 struct device *dev = if_phy->priv->dev; in phy_gmii_sel_mode()
68 return -EINVAL; in phy_gmii_sel_mode()
70 switch (submode) { in phy_gmii_sel_mode()
93 if_phy->id, phy_modes(submode)); in phy_gmii_sel_mode()
94 return -EINVAL; in phy_gmii_sel_mode()
97 if_phy->phy_if_mode = submode; in phy_gmii_sel_mode()
100 __func__, if_phy->id, submode, rgmii_id, in phy_gmii_sel_mode()
101 if_phy->rmii_clock_external); in phy_gmii_sel_mode()
103 regfield = if_phy->fields[PHY_GMII_SEL_PORT_MODE]; in phy_gmii_sel_mode()
106 dev_err(dev, "port%u: set mode fail %d", if_phy->id, ret); in phy_gmii_sel_mode()
110 if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE) && in phy_gmii_sel_mode()
111 if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE]) { in phy_gmii_sel_mode()
112 regfield = if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE]; in phy_gmii_sel_mode()
118 if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) && in phy_gmii_sel_mode()
119 if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN]) { in phy_gmii_sel_mode()
120 regfield = if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN]; in phy_gmii_sel_mode()
122 if_phy->rmii_clock_external); in phy_gmii_sel_mode()
193 .compatible = "ti,am3352-phy-gmii-sel",
197 .compatible = "ti,dra7xx-phy-gmii-sel",
201 .compatible = "ti,am43xx-phy-gmii-sel",
205 .compatible = "ti,dm814-phy-gmii-sel",
209 .compatible = "ti,am654-phy-gmii-sel",
225 int phy_id = args->args[0]; in phy_gmii_sel_of_xlate()
227 if (args->args_count < 1) in phy_gmii_sel_of_xlate()
228 return ERR_PTR(-EINVAL); in phy_gmii_sel_of_xlate()
229 if (!priv || !priv->if_phys) in phy_gmii_sel_of_xlate()
230 return ERR_PTR(-ENODEV); in phy_gmii_sel_of_xlate()
231 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN) && in phy_gmii_sel_of_xlate()
232 args->args_count < 2) in phy_gmii_sel_of_xlate()
233 return ERR_PTR(-EINVAL); in phy_gmii_sel_of_xlate()
234 if (phy_id > priv->num_ports) in phy_gmii_sel_of_xlate()
235 return ERR_PTR(-EINVAL); in phy_gmii_sel_of_xlate()
236 if (phy_id != priv->if_phys[phy_id - 1].id) in phy_gmii_sel_of_xlate()
237 return ERR_PTR(-EINVAL); in phy_gmii_sel_of_xlate()
239 phy_id--; in phy_gmii_sel_of_xlate()
240 if (priv->soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN)) in phy_gmii_sel_of_xlate()
241 priv->if_phys[phy_id].rmii_clock_external = args->args[1]; in phy_gmii_sel_of_xlate()
243 priv->if_phys[phy_id].id, args->args[1]); in phy_gmii_sel_of_xlate()
245 return priv->if_phys[phy_id].if_phy; in phy_gmii_sel_of_xlate()
251 const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data; in phy_gmii_init_phy()
252 struct device *dev = priv->dev; in phy_gmii_init_phy()
258 if_phy->id = port; in phy_gmii_init_phy()
259 if_phy->priv = priv; in phy_gmii_init_phy()
261 fields = soc_data->regfields[port - 1]; in phy_gmii_init_phy()
263 field.reg += priv->reg_offset; in phy_gmii_init_phy()
267 regfield = devm_regmap_field_alloc(dev, priv->regmap, field); in phy_gmii_init_phy()
270 if_phy->fields[PHY_GMII_SEL_PORT_MODE] = regfield; in phy_gmii_init_phy()
273 field.reg += priv->reg_offset; in phy_gmii_init_phy()
274 if (soc_data->features & BIT(PHY_GMII_SEL_RGMII_ID_MODE)) { in phy_gmii_init_phy()
276 priv->regmap, in phy_gmii_init_phy()
280 if_phy->fields[PHY_GMII_SEL_RGMII_ID_MODE] = regfield; in phy_gmii_init_phy()
286 field.reg += priv->reg_offset; in phy_gmii_init_phy()
287 if (soc_data->features & BIT(PHY_GMII_SEL_RMII_IO_CLK_EN)) { in phy_gmii_init_phy()
289 priv->regmap, in phy_gmii_init_phy()
293 if_phy->fields[PHY_GMII_SEL_RMII_IO_CLK_EN] = regfield; in phy_gmii_init_phy()
298 if_phy->if_phy = devm_phy_create(dev, in phy_gmii_init_phy()
299 priv->dev->of_node, in phy_gmii_init_phy()
301 if (IS_ERR(if_phy->if_phy)) { in phy_gmii_init_phy()
302 ret = PTR_ERR(if_phy->if_phy); in phy_gmii_init_phy()
306 phy_set_drvdata(if_phy->if_phy, if_phy); in phy_gmii_init_phy()
313 const struct phy_gmii_sel_soc_data *soc_data = priv->soc_data; in phy_gmii_sel_init_ports()
315 struct device *dev = priv->dev; in phy_gmii_sel_init_ports()
318 if (soc_data->use_of_data) { in phy_gmii_sel_init_ports()
322 offset = of_get_address(dev->of_node, 0, &size, NULL); in phy_gmii_sel_init_ports()
323 priv->num_ports = size / sizeof(u32); in phy_gmii_sel_init_ports()
324 if (!priv->num_ports) in phy_gmii_sel_init_ports()
325 return -EINVAL; in phy_gmii_sel_init_ports()
326 priv->reg_offset = __be32_to_cpu(*offset); in phy_gmii_sel_init_ports()
329 if_phys = devm_kcalloc(dev, priv->num_ports, in phy_gmii_sel_init_ports()
332 return -ENOMEM; in phy_gmii_sel_init_ports()
333 dev_dbg(dev, "%s %d\n", __func__, priv->num_ports); in phy_gmii_sel_init_ports()
335 for (i = 0; i < priv->num_ports; i++) { in phy_gmii_sel_init_ports()
341 priv->if_phys = if_phys; in phy_gmii_sel_init_ports()
347 struct device *dev = &pdev->dev; in phy_gmii_sel_probe()
348 struct device_node *node = dev->of_node; in phy_gmii_sel_probe()
353 of_id = of_match_node(phy_gmii_sel_id_table, pdev->dev.of_node); in phy_gmii_sel_probe()
355 return -EINVAL; in phy_gmii_sel_probe()
357 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in phy_gmii_sel_probe()
359 return -ENOMEM; in phy_gmii_sel_probe()
361 priv->dev = &pdev->dev; in phy_gmii_sel_probe()
362 priv->soc_data = of_id->data; in phy_gmii_sel_probe()
363 priv->num_ports = priv->soc_data->num_ports; in phy_gmii_sel_probe()
365 priv->regmap = syscon_node_to_regmap(node->parent); in phy_gmii_sel_probe()
366 if (IS_ERR(priv->regmap)) { in phy_gmii_sel_probe()
367 ret = PTR_ERR(priv->regmap); in phy_gmii_sel_probe()
376 dev_set_drvdata(&pdev->dev, priv); in phy_gmii_sel_probe()
378 priv->phy_provider = in phy_gmii_sel_probe()
381 if (IS_ERR(priv->phy_provider)) { in phy_gmii_sel_probe()
382 ret = PTR_ERR(priv->phy_provider); in phy_gmii_sel_probe()
393 .name = "phy-gmii-sel",
401 MODULE_DESCRIPTION("TI CPSW Port's PHY Interface Mode selection Driver");