brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 5f7d344 Raw
181 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2020 NovaTech LLC4 * George McCollister <george.mccollister@gmail.com>5 */6 7#include <linux/bitfield.h>8#include <linux/bits.h>9#include <linux/mdio.h>10#include <linux/module.h>11#include <linux/phy.h>12#include <linux/if_vlan.h>13#include <linux/of.h>14#include "xrs700x.h"15#include "xrs700x_reg.h"16 17#define XRS_MDIO_IBA0	0x1018#define XRS_MDIO_IBA1	0x1119#define XRS_MDIO_IBD	0x1420 21#define XRS_IB_READ	0x022#define XRS_IB_WRITE	0x123 24static int xrs700x_mdio_reg_read(void *context, unsigned int reg,25				 unsigned int *val)26{27	struct mdio_device *mdiodev = context;28	struct device *dev = &mdiodev->dev;29	u16 uval;30	int ret;31 32	uval = (u16)FIELD_GET(GENMASK(31, 16), reg);33 34	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA1, uval);35	if (ret < 0) {36		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);37		return ret;38	}39 40	uval = (u16)((reg & GENMASK(15, 1)) | XRS_IB_READ);41 42	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA0, uval);43	if (ret < 0) {44		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);45		return ret;46	}47 48	ret = mdiodev_read(mdiodev, XRS_MDIO_IBD);49	if (ret < 0) {50		dev_err(dev, "xrs mdiobus_read returned %d\n", ret);51		return ret;52	}53 54	*val = (unsigned int)ret;55 56	return 0;57}58 59static int xrs700x_mdio_reg_write(void *context, unsigned int reg,60				  unsigned int val)61{62	struct mdio_device *mdiodev = context;63	struct device *dev = &mdiodev->dev;64	u16 uval;65	int ret;66 67	ret = mdiodev_write(mdiodev, XRS_MDIO_IBD, (u16)val);68	if (ret < 0) {69		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);70		return ret;71	}72 73	uval = (u16)FIELD_GET(GENMASK(31, 16), reg);74 75	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA1, uval);76	if (ret < 0) {77		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);78		return ret;79	}80 81	uval = (u16)((reg & GENMASK(15, 1)) | XRS_IB_WRITE);82 83	ret = mdiodev_write(mdiodev, XRS_MDIO_IBA0, uval);84	if (ret < 0) {85		dev_err(dev, "xrs mdiobus_write returned %d\n", ret);86		return ret;87	}88 89	return 0;90}91 92static const struct regmap_config xrs700x_mdio_regmap_config = {93	.val_bits = 16,94	.reg_stride = 2,95	.reg_bits = 32,96	.pad_bits = 0,97	.write_flag_mask = 0,98	.read_flag_mask = 0,99	.reg_read = xrs700x_mdio_reg_read,100	.reg_write = xrs700x_mdio_reg_write,101	.max_register = XRS_VLAN(VLAN_N_VID - 1),102	.cache_type = REGCACHE_NONE,103	.reg_format_endian = REGMAP_ENDIAN_BIG,104	.val_format_endian = REGMAP_ENDIAN_BIG105};106 107static int xrs700x_mdio_probe(struct mdio_device *mdiodev)108{109	struct xrs700x *priv;110	int ret;111 112	priv = xrs700x_switch_alloc(&mdiodev->dev, mdiodev);113	if (!priv)114		return -ENOMEM;115 116	priv->regmap = devm_regmap_init(&mdiodev->dev, NULL, mdiodev,117					&xrs700x_mdio_regmap_config);118	if (IS_ERR(priv->regmap)) {119		ret = PTR_ERR(priv->regmap);120		dev_err(&mdiodev->dev, "Failed to initialize regmap: %d\n", ret);121		return ret;122	}123 124	dev_set_drvdata(&mdiodev->dev, priv);125 126	ret = xrs700x_switch_register(priv);127 128	/* Main DSA driver may not be started yet. */129	if (ret)130		return ret;131 132	return 0;133}134 135static void xrs700x_mdio_remove(struct mdio_device *mdiodev)136{137	struct xrs700x *priv = dev_get_drvdata(&mdiodev->dev);138 139	if (!priv)140		return;141 142	xrs700x_switch_remove(priv);143}144 145static void xrs700x_mdio_shutdown(struct mdio_device *mdiodev)146{147	struct xrs700x *priv = dev_get_drvdata(&mdiodev->dev);148 149	if (!priv)150		return;151 152	xrs700x_switch_shutdown(priv);153 154	dev_set_drvdata(&mdiodev->dev, NULL);155}156 157static const struct of_device_id __maybe_unused xrs700x_mdio_dt_ids[] = {158	{ .compatible = "arrow,xrs7003e", .data = &xrs7003e_info },159	{ .compatible = "arrow,xrs7003f", .data = &xrs7003f_info },160	{ .compatible = "arrow,xrs7004e", .data = &xrs7004e_info },161	{ .compatible = "arrow,xrs7004f", .data = &xrs7004f_info },162	{},163};164MODULE_DEVICE_TABLE(of, xrs700x_mdio_dt_ids);165 166static struct mdio_driver xrs700x_mdio_driver = {167	.mdiodrv.driver = {168		.name	= "xrs700x-mdio",169		.of_match_table = of_match_ptr(xrs700x_mdio_dt_ids),170	},171	.probe	= xrs700x_mdio_probe,172	.remove	= xrs700x_mdio_remove,173	.shutdown = xrs700x_mdio_shutdown,174};175 176mdio_module_driver(xrs700x_mdio_driver);177 178MODULE_AUTHOR("George McCollister <george.mccollister@gmail.com>");179MODULE_DESCRIPTION("Arrow SpeedChips XRS700x DSA MDIO driver");180MODULE_LICENSE("GPL v2");181