155 lines · 3.6 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only//// Driver for the regulator based Ethernet Power Sourcing Equipment, without// auto classification support.//// Copyright (c) 2022 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>// #include <linux/module.h>#include <linux/of.h>#include <linux/platform_device.h>#include <linux/pse-pd/pse.h>#include <linux/regulator/consumer.h> struct pse_reg_priv {	struct pse_controller_dev pcdev;	struct regulator *ps; /*power source */	enum ethtool_podl_pse_admin_state admin_state;}; static struct pse_reg_priv *to_pse_reg(struct pse_controller_dev *pcdev){	return container_of(pcdev, struct pse_reg_priv, pcdev);} static intpse_reg_pi_enable(struct pse_controller_dev *pcdev, int id){	struct pse_reg_priv *priv = to_pse_reg(pcdev);	int ret; 	ret = regulator_enable(priv->ps);	if (ret)		return ret; 	priv->admin_state = ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED;	return 0;} static intpse_reg_pi_disable(struct pse_controller_dev *pcdev, int id){	struct pse_reg_priv *priv = to_pse_reg(pcdev);	int ret; 	ret = regulator_disable(priv->ps);	if (ret)		return ret; 	priv->admin_state = ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED;	return 0;} static intpse_reg_pi_get_admin_state(struct pse_controller_dev *pcdev, int id,			   struct pse_admin_state *admin_state){	struct pse_reg_priv *priv = to_pse_reg(pcdev); 	admin_state->podl_admin_state = priv->admin_state; 	return 0;} static intpse_reg_pi_get_pw_status(struct pse_controller_dev *pcdev, int id,			 struct pse_pw_status *pw_status){	struct pse_reg_priv *priv = to_pse_reg(pcdev);	int ret; 	ret = regulator_is_enabled(priv->ps);	if (ret < 0)		return ret; 	if (!ret)		pw_status->podl_pw_status =			ETHTOOL_PODL_PSE_PW_D_STATUS_DISABLED;	else		pw_status->podl_pw_status =			ETHTOOL_PODL_PSE_PW_D_STATUS_DELIVERING; 	return 0;} static const struct pse_controller_ops pse_reg_ops = {	.pi_get_admin_state = pse_reg_pi_get_admin_state,	.pi_get_pw_status = pse_reg_pi_get_pw_status,	.pi_enable = pse_reg_pi_enable,	.pi_disable = pse_reg_pi_disable,}; static intpse_reg_probe(struct platform_device *pdev){	struct device *dev = &pdev->dev;	struct pse_reg_priv *priv;	int ret; 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);	if (!priv)		return -ENOMEM; 	if (!pdev->dev.of_node)		return -ENOENT; 	priv->ps = devm_regulator_get_exclusive(dev, "pse");	if (IS_ERR(priv->ps))		return dev_err_probe(dev, PTR_ERR(priv->ps),				     "failed to get PSE regulator.\n"); 	platform_set_drvdata(pdev, priv); 	ret = regulator_is_enabled(priv->ps);	if (ret < 0)		return ret; 	if (ret)		priv->admin_state = ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED;	else		priv->admin_state = ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED; 	priv->pcdev.owner = THIS_MODULE;	priv->pcdev.ops = &pse_reg_ops;	priv->pcdev.dev = dev;	priv->pcdev.types = ETHTOOL_PSE_PODL;	ret = devm_pse_controller_register(dev, &priv->pcdev);	if (ret) {		dev_err(dev, "failed to register PSE controller (%pe)\n",			ERR_PTR(ret));		return ret;	} 	return 0;} static const __maybe_unused struct of_device_id pse_reg_of_match[] = {	{ .compatible = "podl-pse-regulator", },	{ },};MODULE_DEVICE_TABLE(of, pse_reg_of_match); static struct platform_driver pse_reg_driver = {	.probe		= pse_reg_probe,	.driver		= {		.name		= "PSE regulator",		.of_match_table = of_match_ptr(pse_reg_of_match),	},};module_platform_driver(pse_reg_driver); MODULE_AUTHOR("Oleksij Rempel <kernel@pengutronix.de>");MODULE_DESCRIPTION("regulator based Ethernet Power Sourcing Equipment");MODULE_LICENSE("GPL v2");MODULE_ALIAS("platform:pse-regulator");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t