Eu testei também aqui, o resultado foi o mesmo que você citou, então alterei algumas funções da api de gpio e também não deu certo, então externei as gpios para um driver em modulo separado;
#include
#include
#include
#include
#include
typedef struct {
int phy_reset_gpio;
int phy_power_gpio;
}phy_gpio;
static phy_gpio *global_data = NULL;
void eth_turn_on(void)
{
phy_gpio *data = global_data;
if (data)
{
gpio_set_value(data->phy_power_gpio, 1);
mdelay(150);//time for power up
gpio_set_value(data->phy_reset_gpio, 1);
mdelay(12);
gpio_set_value(data->phy_reset_gpio, 0);
mdelay(12);
gpio_set_value(data->phy_reset_gpio, 1);
mdelay(150);
pr_info("phy module turned on\n");
}
}
EXPORT_SYMBOL(eth_turn_on);
void eth_turn_off(void)
{
phy_gpio *data = global_data;
if (data)
{
gpio_set_value(data->phy_reset_gpio, 0);
gpio_set_value(data->phy_power_gpio, 0);
mdelay(15);
pr_info("phy module turned off\n");
}
}
EXPORT_SYMBOL(eth_turn_off);
static int __init eth_power_probe(struct platform_device * pdev)
{
phy_gpio *data = NULL;
struct device *dev = &pdev->dev;
int ret;
platform_set_drvdata(pdev, NULL);
data = devm_kzalloc(dev, sizeof(phy_gpio), GFP_KERNEL);
if (!data)
{
dev_err(dev, "could not alloc memory\n");
return -ENOMEM;
}
data->phy_power_gpio =
of_get_named_gpio(dev->of_node, "phy-power-gpio", 0);
if (!gpio_is_valid(data->phy_power_gpio))
{
dev_err(dev, "could not get phy power gpio\n");
return -ENODEV;
}
data->phy_reset_gpio =
of_get_named_gpio(dev->of_node, "phy-reset-gpio", 0);
if (!gpio_is_valid(data->phy_reset_gpio))
{
dev_err(dev, "could not get phy reset gpio\n");
return -ENODEV;
}
ret = devm_gpio_request(dev, data->phy_power_gpio, "phy_power");
if (ret)
{
dev_err(dev, "could not request wifi power gpio\n");
return ret;
}
ret = devm_gpio_request(dev, data->phy_reset_gpio, "phy_reset");
if (ret)
{
dev_err(dev, "could not request phy reset gpio\n");
return ret;
}
gpio_direction_output(data->phy_power_gpio, 0);
gpio_direction_output(data->phy_reset_gpio, 0);
mdelay(20);
global_data = data;
platform_set_drvdata(pdev, data);
eth_turn_on();
dev_info(dev, "eth power probe ok\n");
return 0;
}
static int __exit eth_power_remove(struct platform_device *pdev)
{
phy_gpio *data = platform_get_drvdata(pdev);
if (data)
{
eth_turn_off();
global_data = NULL;
dev_info(&pdev->dev, "driver remove ok\n");
}
return 0;
}
static const struct of_device_id eth_power_dt_match[] = {
{.compatible = “caninos,labrador-eth-power”},
{}
};
MODULE_DEVICE_TABLE(of, eth_power_dt_match);
static struct platform_driver __refdata eth_power_driver = {
.probe = eth_power_probe,
.remove = eth_power_remove,
.driver = {
.name = “labrador-eth-power”,
.owner = THIS_MODULE,
.of_match_table = eth_power_dt_match,
},
};
static int __init eth_power_init(void)
{
return platform_driver_register(ð_power_driver);
}
//device_initcall(eth_power_init);
module_platform_driver(eth_power_driver);
MODULE_LICENSE(“GPL”);
também não funcionou, vou olhar o datasheet e ver se tem algo multiplexado com esses pinos…