Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

phy: add NXP PTN3222 eUSB2 to USB2 redriver

The NXP PTN3222 is the single-port eUSB2 to USB2 redriver that performs
translation between eUSB2 and USB2 signalling schemes. It supports all
three data rates: Low Speed, Full Speed and High Speed.

The reset state enables autonegotiation of the PHY role and of the data
rate, so no additional programming is required.

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Tested-by: Konrad Dybcio <konradybcio@kernel.org>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Stephan Gerhold <stephan.gerhold@linaro.org>
Tested-by: Stephan Gerhold <stephan.gerhold@linaro.org>
Link: https://lore.kernel.org/r/20240830-nxp-ptn3222-v2-2-4c6d8535cf6c@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Dmitry Baryshkov and committed by
Vinod Koul
c9be539e 2df490e7

+135
+11
drivers/phy/Kconfig
··· 82 82 This driver create the basic PHY instance and provides initialize 83 83 callback for PCIe GEN3 port. 84 84 85 + config PHY_NXP_PTN3222 86 + tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver" 87 + depends on I2C 88 + depends on OF 89 + select GENERIC_PHY 90 + help 91 + Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver. 92 + This redriver performs translation between eUSB2 and USB2 signalling 93 + schemes. It supports all three USB 2.0 data rates: Low Speed, Full 94 + Speed and High Speed. 95 + 85 96 source "drivers/phy/allwinner/Kconfig" 86 97 source "drivers/phy/amlogic/Kconfig" 87 98 source "drivers/phy/broadcom/Kconfig"
+1
drivers/phy/Makefile
··· 11 11 obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o 12 12 obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o 13 13 obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o 14 + obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o 14 15 obj-y += allwinner/ \ 15 16 amlogic/ \ 16 17 broadcom/ \
+123
drivers/phy/phy-nxp-ptn3222.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2024, Linaro Limited 4 + */ 5 + 6 + #include <linux/gpio/consumer.h> 7 + #include <linux/i2c.h> 8 + #include <linux/module.h> 9 + #include <linux/of.h> 10 + #include <linux/phy/phy.h> 11 + #include <linux/regmap.h> 12 + #include <linux/regulator/consumer.h> 13 + 14 + #define NUM_SUPPLIES 2 15 + 16 + struct ptn3222 { 17 + struct i2c_client *client; 18 + struct phy *phy; 19 + struct gpio_desc *reset_gpio; 20 + struct regulator_bulk_data *supplies; 21 + }; 22 + 23 + static int ptn3222_init(struct phy *phy) 24 + { 25 + struct ptn3222 *ptn3222 = phy_get_drvdata(phy); 26 + int ret; 27 + 28 + ret = regulator_bulk_enable(NUM_SUPPLIES, ptn3222->supplies); 29 + if (ret) 30 + return ret; 31 + 32 + gpiod_set_value_cansleep(ptn3222->reset_gpio, 0); 33 + 34 + return 0; 35 + } 36 + 37 + static int ptn3222_exit(struct phy *phy) 38 + { 39 + struct ptn3222 *ptn3222 = phy_get_drvdata(phy); 40 + 41 + gpiod_set_value_cansleep(ptn3222->reset_gpio, 1); 42 + 43 + return regulator_bulk_disable(NUM_SUPPLIES, ptn3222->supplies); 44 + } 45 + 46 + static const struct phy_ops ptn3222_ops = { 47 + .init = ptn3222_init, 48 + .exit = ptn3222_exit, 49 + .owner = THIS_MODULE, 50 + }; 51 + 52 + static const struct regulator_bulk_data ptn3222_supplies[NUM_SUPPLIES] = { 53 + { 54 + .supply = "vdd3v3", 55 + .init_load_uA = 11000, 56 + }, { 57 + .supply = "vdd1v8", 58 + .init_load_uA = 55000, 59 + } 60 + }; 61 + 62 + static int ptn3222_probe(struct i2c_client *client) 63 + { 64 + struct device *dev = &client->dev; 65 + struct phy_provider *phy_provider; 66 + struct ptn3222 *ptn3222; 67 + int ret; 68 + 69 + ptn3222 = devm_kzalloc(dev, sizeof(*ptn3222), GFP_KERNEL); 70 + if (!ptn3222) 71 + return -ENOMEM; 72 + 73 + ptn3222->client = client; 74 + 75 + ptn3222->reset_gpio = devm_gpiod_get_optional(dev, "reset", 76 + GPIOD_OUT_HIGH); 77 + if (IS_ERR(ptn3222->reset_gpio)) 78 + return dev_err_probe(dev, PTR_ERR(ptn3222->reset_gpio), 79 + "unable to acquire reset gpio\n"); 80 + 81 + ret = devm_regulator_bulk_get_const(dev, NUM_SUPPLIES, ptn3222_supplies, 82 + &ptn3222->supplies); 83 + if (ret) 84 + return ret; 85 + 86 + ptn3222->phy = devm_phy_create(dev, dev->of_node, &ptn3222_ops); 87 + if (IS_ERR(ptn3222->phy)) { 88 + dev_err(dev, "failed to create PHY: %d\n", ret); 89 + return PTR_ERR(ptn3222->phy); 90 + } 91 + 92 + phy_set_drvdata(ptn3222->phy, ptn3222); 93 + 94 + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 95 + 96 + return PTR_ERR_OR_ZERO(phy_provider); 97 + } 98 + 99 + static const struct i2c_device_id ptn3222_table[] = { 100 + { "ptn3222" }, 101 + { } 102 + }; 103 + MODULE_DEVICE_TABLE(i2c, ptn3222_table); 104 + 105 + static const struct of_device_id ptn3222_of_table[] = { 106 + { .compatible = "nxp,ptn3222" }, 107 + { } 108 + }; 109 + MODULE_DEVICE_TABLE(of, ptn3222_of_table); 110 + 111 + static struct i2c_driver ptn3222_driver = { 112 + .driver = { 113 + .name = "ptn3222", 114 + .of_match_table = ptn3222_of_table, 115 + }, 116 + .probe = ptn3222_probe, 117 + .id_table = ptn3222_table, 118 + }; 119 + 120 + module_i2c_driver(ptn3222_driver); 121 + 122 + MODULE_DESCRIPTION("NXP PTN3222 eUSB2 Redriver driver"); 123 + MODULE_LICENSE("GPL");