// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2024, Linaro Limited */ #include #include #include #include #include #include #include #define NUM_SUPPLIES 2 struct ptn3222 { struct i2c_client *client; struct phy *phy; struct gpio_desc *reset_gpio; struct regulator_bulk_data *supplies; }; static int ptn3222_init(struct phy *phy) { struct ptn3222 *ptn3222 = phy_get_drvdata(phy); int ret; ret = regulator_bulk_enable(NUM_SUPPLIES, ptn3222->supplies); if (ret) return ret; gpiod_set_value_cansleep(ptn3222->reset_gpio, 0); return 0; } static int ptn3222_exit(struct phy *phy) { struct ptn3222 *ptn3222 = phy_get_drvdata(phy); gpiod_set_value_cansleep(ptn3222->reset_gpio, 1); return regulator_bulk_disable(NUM_SUPPLIES, ptn3222->supplies); } static const struct phy_ops ptn3222_ops = { .init = ptn3222_init, .exit = ptn3222_exit, .owner = THIS_MODULE, }; static const struct regulator_bulk_data ptn3222_supplies[NUM_SUPPLIES] = { { .supply = "vdd3v3", .init_load_uA = 11000, }, { .supply = "vdd1v8", .init_load_uA = 55000, } }; static int ptn3222_probe(struct i2c_client *client) { struct device *dev = &client->dev; struct phy_provider *phy_provider; struct ptn3222 *ptn3222; int ret; ptn3222 = devm_kzalloc(dev, sizeof(*ptn3222), GFP_KERNEL); if (!ptn3222) return -ENOMEM; ptn3222->client = client; ptn3222->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(ptn3222->reset_gpio)) return dev_err_probe(dev, PTR_ERR(ptn3222->reset_gpio), "unable to acquire reset gpio\n"); ret = devm_regulator_bulk_get_const(dev, NUM_SUPPLIES, ptn3222_supplies, &ptn3222->supplies); if (ret) return ret; ptn3222->phy = devm_phy_create(dev, dev->of_node, &ptn3222_ops); if (IS_ERR(ptn3222->phy)) { dev_err(dev, "failed to create PHY: %d\n", ret); return PTR_ERR(ptn3222->phy); } phy_set_drvdata(ptn3222->phy, ptn3222); phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); return PTR_ERR_OR_ZERO(phy_provider); } static const struct i2c_device_id ptn3222_table[] = { { "ptn3222" }, { } }; MODULE_DEVICE_TABLE(i2c, ptn3222_table); static const struct of_device_id ptn3222_of_table[] = { { .compatible = "nxp,ptn3222" }, { } }; MODULE_DEVICE_TABLE(of, ptn3222_of_table); static struct i2c_driver ptn3222_driver = { .driver = { .name = "ptn3222", .of_match_table = ptn3222_of_table, }, .probe = ptn3222_probe, .id_table = ptn3222_table, }; module_i2c_driver(ptn3222_driver); MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver"); MODULE_LICENSE("GPL");