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

phy: phy-can-transceiver: Support TJA1048/TJA1051

Peng Fan <peng.fan@nxp.com> says:

TJA1048 is a Dual channel can transceiver with Sleep mode supported.
TJA105{1,7} is a Single Channel can transceiver with Sleep mode supported.

Link: https://patch.msgid.link/20251001-can-v7-0-fad29efc3884@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

+184 -45
+66 -3
Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml
··· 23 23 - enum: 24 24 - ti,tcan1042 25 25 - ti,tcan1043 26 + - nxp,tja1048 27 + - nxp,tja1051 28 + - nxp,tja1057 26 29 - nxp,tjr1443 27 30 28 31 '#phy-cells': 29 - const: 0 32 + enum: [0, 1] 33 + 34 + silent-gpios: 35 + description: 36 + gpio node to toggle silent signal on transceiver 37 + maxItems: 1 30 38 31 39 standby-gpios: 32 40 description: 33 - gpio node to toggle standby signal on transceiver 34 - maxItems: 1 41 + gpio node to toggle standby signal on transceiver. For two Items, item 1 42 + is for stbn1, item 2 is for stbn2. 43 + minItems: 1 44 + maxItems: 2 35 45 36 46 enable-gpios: 37 47 description: ··· 63 53 required: 64 54 - compatible 65 55 - '#phy-cells' 56 + 57 + allOf: 58 + - if: 59 + properties: 60 + compatible: 61 + enum: 62 + - nxp,tjr1443 63 + - ti,tcan1042 64 + - ti,tcan1043 65 + then: 66 + properties: 67 + '#phy-cells': 68 + const: 0 69 + silent-gpios: false 70 + standby-gpios: 71 + maxItems: 1 72 + 73 + - if: 74 + properties: 75 + compatible: 76 + contains: 77 + const: nxp,tja1048 78 + then: 79 + properties: 80 + '#phy-cells': 81 + const: 1 82 + enable-gpios: false 83 + silent-gpios: false 84 + standby-gpios: 85 + minItems: 2 86 + 87 + - if: 88 + properties: 89 + compatible: 90 + contains: 91 + const: nxp,tja1051 92 + then: 93 + properties: 94 + '#phy-cells': 95 + const: 0 96 + standby-gpios: false 97 + 98 + - if: 99 + properties: 100 + compatible: 101 + contains: 102 + const: nxp,tja1057 103 + then: 104 + properties: 105 + '#phy-cells': 106 + const: 0 107 + enable-gpios: false 108 + standby-gpios: false 66 109 67 110 additionalProperties: false 68 111
+118 -42
drivers/phy/phy-can-transceiver.c
··· 17 17 u32 flags; 18 18 #define CAN_TRANSCEIVER_STB_PRESENT BIT(0) 19 19 #define CAN_TRANSCEIVER_EN_PRESENT BIT(1) 20 + #define CAN_TRANSCEIVER_DUAL_CH BIT(2) 21 + #define CAN_TRANSCEIVER_SILENT_PRESENT BIT(3) 20 22 }; 21 23 22 24 struct can_transceiver_phy { 23 25 struct phy *generic_phy; 26 + struct gpio_desc *silent_gpio; 24 27 struct gpio_desc *standby_gpio; 25 28 struct gpio_desc *enable_gpio; 29 + struct can_transceiver_priv *priv; 30 + }; 31 + 32 + struct can_transceiver_priv { 26 33 struct mux_state *mux_state; 34 + int num_ch; 35 + struct can_transceiver_phy can_transceiver_phy[] __counted_by(num_ch); 27 36 }; 28 37 29 38 /* Power on function */ 30 39 static int can_transceiver_phy_power_on(struct phy *phy) 31 40 { 32 41 struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy); 42 + struct can_transceiver_priv *priv = can_transceiver_phy->priv; 33 43 int ret; 34 44 35 - if (can_transceiver_phy->mux_state) { 36 - ret = mux_state_select(can_transceiver_phy->mux_state); 45 + if (priv->mux_state) { 46 + ret = mux_state_select(priv->mux_state); 37 47 if (ret) { 38 48 dev_err(&phy->dev, "Failed to select CAN mux: %d\n", ret); 39 49 return ret; 40 50 } 41 51 } 42 - if (can_transceiver_phy->standby_gpio) 43 - gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 0); 44 - if (can_transceiver_phy->enable_gpio) 45 - gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 1); 52 + gpiod_set_value_cansleep(can_transceiver_phy->silent_gpio, 0); 53 + gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 0); 54 + gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 1); 46 55 47 56 return 0; 48 57 } ··· 60 51 static int can_transceiver_phy_power_off(struct phy *phy) 61 52 { 62 53 struct can_transceiver_phy *can_transceiver_phy = phy_get_drvdata(phy); 54 + struct can_transceiver_priv *priv = can_transceiver_phy->priv; 63 55 64 - if (can_transceiver_phy->standby_gpio) 65 - gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1); 66 - if (can_transceiver_phy->enable_gpio) 67 - gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0); 68 - if (can_transceiver_phy->mux_state) 69 - mux_state_deselect(can_transceiver_phy->mux_state); 56 + gpiod_set_value_cansleep(can_transceiver_phy->silent_gpio, 1); 57 + gpiod_set_value_cansleep(can_transceiver_phy->standby_gpio, 1); 58 + gpiod_set_value_cansleep(can_transceiver_phy->enable_gpio, 0); 59 + if (priv->mux_state) 60 + mux_state_deselect(priv->mux_state); 70 61 71 62 return 0; 72 63 } ··· 85 76 .flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_EN_PRESENT, 86 77 }; 87 78 79 + static const struct can_transceiver_data tja1048_drvdata = { 80 + .flags = CAN_TRANSCEIVER_STB_PRESENT | CAN_TRANSCEIVER_DUAL_CH, 81 + }; 82 + 83 + static const struct can_transceiver_data tja1051_drvdata = { 84 + .flags = CAN_TRANSCEIVER_SILENT_PRESENT | CAN_TRANSCEIVER_EN_PRESENT, 85 + }; 86 + 87 + static const struct can_transceiver_data tja1057_drvdata = { 88 + .flags = CAN_TRANSCEIVER_SILENT_PRESENT, 89 + }; 90 + 88 91 static const struct of_device_id can_transceiver_phy_ids[] = { 89 92 { 90 93 .compatible = "ti,tcan1042", ··· 105 84 { 106 85 .compatible = "ti,tcan1043", 107 86 .data = &tcan1043_drvdata 87 + }, 88 + { 89 + .compatible = "nxp,tja1048", 90 + .data = &tja1048_drvdata 91 + }, 92 + { 93 + .compatible = "nxp,tja1051", 94 + .data = &tja1051_drvdata 95 + }, 96 + { 97 + .compatible = "nxp,tja1057", 98 + .data = &tja1057_drvdata 108 99 }, 109 100 { 110 101 .compatible = "nxp,tjr1443", ··· 136 103 return devm_mux_state_get(dev, mux_name); 137 104 } 138 105 106 + static struct phy *can_transceiver_phy_xlate(struct device *dev, 107 + const struct of_phandle_args *args) 108 + { 109 + struct can_transceiver_priv *priv = dev_get_drvdata(dev); 110 + u32 idx; 111 + 112 + if (priv->num_ch == 1) 113 + return priv->can_transceiver_phy[0].generic_phy; 114 + 115 + if (args->args_count != 1) 116 + return ERR_PTR(-EINVAL); 117 + 118 + idx = args->args[0]; 119 + if (idx >= priv->num_ch) 120 + return ERR_PTR(-EINVAL); 121 + 122 + return priv->can_transceiver_phy[idx].generic_phy; 123 + } 124 + 139 125 static int can_transceiver_phy_probe(struct platform_device *pdev) 140 126 { 141 127 struct phy_provider *phy_provider; 142 128 struct device *dev = &pdev->dev; 143 129 struct can_transceiver_phy *can_transceiver_phy; 130 + struct can_transceiver_priv *priv; 144 131 const struct can_transceiver_data *drvdata; 145 132 const struct of_device_id *match; 146 133 struct phy *phy; 134 + struct gpio_desc *silent_gpio; 147 135 struct gpio_desc *standby_gpio; 148 136 struct gpio_desc *enable_gpio; 149 137 struct mux_state *mux_state; 150 138 u32 max_bitrate = 0; 151 - int err; 152 - 153 - can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL); 154 - if (!can_transceiver_phy) 155 - return -ENOMEM; 139 + int err, i, num_ch = 1; 156 140 157 141 match = of_match_node(can_transceiver_phy_ids, pdev->dev.of_node); 158 142 drvdata = match->data; 143 + if (drvdata->flags & CAN_TRANSCEIVER_DUAL_CH) 144 + num_ch = 2; 145 + 146 + priv = devm_kzalloc(dev, struct_size(priv, can_transceiver_phy, num_ch), GFP_KERNEL); 147 + if (!priv) 148 + return -ENOMEM; 149 + 150 + priv->num_ch = num_ch; 151 + platform_set_drvdata(pdev, priv); 159 152 160 153 mux_state = devm_mux_state_get_optional(dev, NULL); 161 154 if (IS_ERR(mux_state)) 162 155 return PTR_ERR(mux_state); 163 156 164 - can_transceiver_phy->mux_state = mux_state; 165 - 166 - phy = devm_phy_create(dev, dev->of_node, 167 - &can_transceiver_phy_ops); 168 - if (IS_ERR(phy)) { 169 - dev_err(dev, "failed to create can transceiver phy\n"); 170 - return PTR_ERR(phy); 171 - } 157 + priv->mux_state = mux_state; 172 158 173 159 err = device_property_read_u32(dev, "max-bitrate", &max_bitrate); 174 160 if ((err != -EINVAL) && !max_bitrate) 175 161 dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n"); 176 - phy->attrs.max_link_rate = max_bitrate; 177 162 178 - can_transceiver_phy->generic_phy = phy; 163 + for (i = 0; i < num_ch; i++) { 164 + can_transceiver_phy = &priv->can_transceiver_phy[i]; 165 + can_transceiver_phy->priv = priv; 179 166 180 - if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) { 181 - standby_gpio = devm_gpiod_get_optional(dev, "standby", GPIOD_OUT_HIGH); 182 - if (IS_ERR(standby_gpio)) 183 - return PTR_ERR(standby_gpio); 184 - can_transceiver_phy->standby_gpio = standby_gpio; 167 + phy = devm_phy_create(dev, dev->of_node, &can_transceiver_phy_ops); 168 + if (IS_ERR(phy)) { 169 + dev_err(dev, "failed to create can transceiver phy\n"); 170 + return PTR_ERR(phy); 171 + } 172 + 173 + phy->attrs.max_link_rate = max_bitrate; 174 + 175 + can_transceiver_phy->generic_phy = phy; 176 + can_transceiver_phy->priv = priv; 177 + 178 + if (drvdata->flags & CAN_TRANSCEIVER_STB_PRESENT) { 179 + standby_gpio = devm_gpiod_get_index_optional(dev, "standby", i, 180 + GPIOD_OUT_HIGH); 181 + if (IS_ERR(standby_gpio)) 182 + return PTR_ERR(standby_gpio); 183 + can_transceiver_phy->standby_gpio = standby_gpio; 184 + } 185 + 186 + if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) { 187 + enable_gpio = devm_gpiod_get_index_optional(dev, "enable", i, 188 + GPIOD_OUT_LOW); 189 + if (IS_ERR(enable_gpio)) 190 + return PTR_ERR(enable_gpio); 191 + can_transceiver_phy->enable_gpio = enable_gpio; 192 + } 193 + 194 + if (drvdata->flags & CAN_TRANSCEIVER_SILENT_PRESENT) { 195 + silent_gpio = devm_gpiod_get_index_optional(dev, "silent", i, 196 + GPIOD_OUT_LOW); 197 + if (IS_ERR(silent_gpio)) 198 + return PTR_ERR(silent_gpio); 199 + can_transceiver_phy->silent_gpio = silent_gpio; 200 + } 201 + 202 + phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy); 203 + 185 204 } 186 205 187 - if (drvdata->flags & CAN_TRANSCEIVER_EN_PRESENT) { 188 - enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); 189 - if (IS_ERR(enable_gpio)) 190 - return PTR_ERR(enable_gpio); 191 - can_transceiver_phy->enable_gpio = enable_gpio; 192 - } 193 - 194 - phy_set_drvdata(can_transceiver_phy->generic_phy, can_transceiver_phy); 195 - 196 - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 206 + phy_provider = devm_of_phy_provider_register(dev, can_transceiver_phy_xlate); 197 207 198 208 return PTR_ERR_OR_ZERO(phy_provider); 199 209 }