1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2023, Linaro Limited 4 */ 5 6 #include <linux/module.h> 7 #include <linux/platform_device.h> 8 #include <linux/regulator/consumer.h> 9 #include <linux/regmap.h> 10 #include <linux/of.h> 11 #include <linux/phy/phy.h> 12 13 /* eUSB2 status registers */ 14 #define EUSB2_RPTR_STATUS 0x08 15 #define RPTR_OK BIT(7) 16 17 /* eUSB2 control registers */ 18 #define EUSB2_EN_CTL1 0x46 19 #define EUSB2_RPTR_EN BIT(7) 20 21 #define EUSB2_FORCE_EN_5 0xe8 22 #define F_CLK_19P2M_EN BIT(6) 23 24 #define EUSB2_FORCE_VAL_5 0xeD 25 #define V_CLK_19P2M_EN BIT(6) 26 27 #define EUSB2_TUNE_USB2_CROSSOVER 0x50 28 #define EUSB2_TUNE_IUSB2 0x51 29 #define EUSB2_TUNE_RES_FSDIF 0x52 30 #define EUSB2_TUNE_HSDISC 0x53 31 #define EUSB2_TUNE_SQUELCH_U 0x54 32 #define EUSB2_TUNE_USB2_SLEW 0x55 33 #define EUSB2_TUNE_USB2_EQU 0x56 34 #define EUSB2_TUNE_USB2_PREEM 0x57 35 #define EUSB2_TUNE_USB2_HS_COMP_CUR 0x58 36 #define EUSB2_TUNE_EUSB_SLEW 0x59 37 #define EUSB2_TUNE_EUSB_EQU 0x5A 38 #define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B 39 40 struct eusb2_repeater_init_tbl_reg { 41 unsigned int reg; 42 unsigned int value; 43 }; 44 45 struct eusb2_repeater_cfg { 46 const struct eusb2_repeater_init_tbl_reg *init_tbl; 47 int init_tbl_num; 48 const char * const *vreg_list; 49 int num_vregs; 50 }; 51 52 struct eusb2_repeater { 53 struct device *dev; 54 struct regmap *regmap; 55 struct phy *phy; 56 struct regulator_bulk_data *vregs; 57 const struct eusb2_repeater_cfg *cfg; 58 u32 base; 59 enum phy_mode mode; 60 }; 61 62 static const char * const pm8550b_vreg_l[] = { 63 "vdd18", "vdd3", 64 }; 65 66 static const struct eusb2_repeater_init_tbl_reg pm8550b_init_tbl[] = { 67 { EUSB2_TUNE_IUSB2, 0x8 }, 68 { EUSB2_TUNE_SQUELCH_U, 0x3 }, 69 { EUSB2_TUNE_USB2_PREEM, 0x5 }, 70 }; 71 72 static const struct eusb2_repeater_init_tbl_reg smb2360_init_tbl[] = { 73 { EUSB2_TUNE_IUSB2, 0x5 }, 74 { EUSB2_TUNE_SQUELCH_U, 0x3 }, 75 { EUSB2_TUNE_USB2_PREEM, 0x2 }, 76 }; 77 78 static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { 79 .init_tbl = pm8550b_init_tbl, 80 .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl), 81 .vreg_list = pm8550b_vreg_l, 82 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 83 }; 84 85 static const struct eusb2_repeater_cfg pmiv0104_eusb2_cfg = { 86 /* No PMIC-specific init sequence, only board level tuning via DT */ 87 .init_tbl = (struct eusb2_repeater_init_tbl_reg[]) {}, 88 .init_tbl_num = 0, 89 .vreg_list = pm8550b_vreg_l, 90 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 91 }; 92 93 static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { 94 .init_tbl = smb2360_init_tbl, 95 .init_tbl_num = ARRAY_SIZE(smb2360_init_tbl), 96 .vreg_list = pm8550b_vreg_l, 97 .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), 98 }; 99 100 static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) 101 { 102 int num = rptr->cfg->num_vregs; 103 struct device *dev = rptr->dev; 104 int i; 105 106 rptr->vregs = devm_kcalloc(dev, num, sizeof(*rptr->vregs), GFP_KERNEL); 107 if (!rptr->vregs) 108 return -ENOMEM; 109 110 for (i = 0; i < num; i++) 111 rptr->vregs[i].supply = rptr->cfg->vreg_list[i]; 112 113 return devm_regulator_bulk_get(dev, num, rptr->vregs); 114 } 115 116 static int eusb2_repeater_init(struct phy *phy) 117 { 118 struct eusb2_repeater *rptr = phy_get_drvdata(phy); 119 struct device_node *np = rptr->dev->of_node; 120 struct regmap *regmap = rptr->regmap; 121 u32 base = rptr->base; 122 u32 poll_val; 123 int ret; 124 u8 val; 125 126 ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs); 127 if (ret) 128 return ret; 129 130 regmap_write(regmap, base + EUSB2_EN_CTL1, EUSB2_RPTR_EN); 131 132 /* Write registers from init table */ 133 for (int i = 0; i < rptr->cfg->init_tbl_num; i++) 134 regmap_write(regmap, base + rptr->cfg->init_tbl[i].reg, 135 rptr->cfg->init_tbl[i].value); 136 137 /* Override registers from devicetree values */ 138 if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val)) 139 regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, val); 140 141 if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &val)) 142 regmap_write(regmap, base + EUSB2_TUNE_HSDISC, val); 143 144 if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val)) 145 regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val); 146 147 if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val)) 148 regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val); 149 150 /* Wait for status OK */ 151 ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, 152 poll_val & RPTR_OK, 10, 5); 153 if (ret) 154 dev_err(rptr->dev, "initialization timed-out\n"); 155 156 return ret; 157 } 158 159 static int eusb2_repeater_set_mode(struct phy *phy, 160 enum phy_mode mode, int submode) 161 { 162 struct eusb2_repeater *rptr = phy_get_drvdata(phy); 163 struct regmap *regmap = rptr->regmap; 164 u32 base = rptr->base; 165 166 switch (mode) { 167 case PHY_MODE_USB_HOST: 168 /* 169 * CM.Lx is prohibited when repeater is already into Lx state as 170 * per eUSB 1.2 Spec. Below implement software workaround until 171 * PHY and controller is fixing seen observation. 172 */ 173 regmap_write(regmap, base + EUSB2_FORCE_EN_5, F_CLK_19P2M_EN); 174 regmap_write(regmap, base + EUSB2_FORCE_VAL_5, V_CLK_19P2M_EN); 175 break; 176 case PHY_MODE_USB_DEVICE: 177 /* 178 * In device mode clear host mode related workaround as there 179 * is no repeater reset available, and enable/disable of 180 * repeater doesn't clear previous value due to shared 181 * regulators (say host <-> device mode switch). 182 */ 183 regmap_write(regmap, base + EUSB2_FORCE_EN_5, 0); 184 regmap_write(regmap, base + EUSB2_FORCE_VAL_5, 0); 185 break; 186 default: 187 return -EINVAL; 188 } 189 190 return 0; 191 } 192 193 static int eusb2_repeater_exit(struct phy *phy) 194 { 195 struct eusb2_repeater *rptr = phy_get_drvdata(phy); 196 197 return regulator_bulk_disable(rptr->cfg->num_vregs, rptr->vregs); 198 } 199 200 static const struct phy_ops eusb2_repeater_ops = { 201 .init = eusb2_repeater_init, 202 .exit = eusb2_repeater_exit, 203 .set_mode = eusb2_repeater_set_mode, 204 .owner = THIS_MODULE, 205 }; 206 207 static int eusb2_repeater_probe(struct platform_device *pdev) 208 { 209 struct eusb2_repeater *rptr; 210 struct device *dev = &pdev->dev; 211 struct phy_provider *phy_provider; 212 struct device_node *np = dev->of_node; 213 u32 res; 214 int ret; 215 216 rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL); 217 if (!rptr) 218 return -ENOMEM; 219 220 rptr->dev = dev; 221 dev_set_drvdata(dev, rptr); 222 223 rptr->cfg = of_device_get_match_data(dev); 224 if (!rptr->cfg) 225 return -EINVAL; 226 227 rptr->regmap = dev_get_regmap(dev->parent, NULL); 228 if (!rptr->regmap) 229 return -ENODEV; 230 231 ret = of_property_read_u32(np, "reg", &res); 232 if (ret < 0) 233 return ret; 234 235 rptr->base = res; 236 237 ret = eusb2_repeater_init_vregs(rptr); 238 if (ret < 0) { 239 dev_err(dev, "unable to get supplies\n"); 240 return ret; 241 } 242 243 rptr->phy = devm_phy_create(dev, np, &eusb2_repeater_ops); 244 if (IS_ERR(rptr->phy)) { 245 dev_err(dev, "failed to create PHY: %d\n", ret); 246 return PTR_ERR(rptr->phy); 247 } 248 249 phy_set_drvdata(rptr->phy, rptr); 250 251 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); 252 if (IS_ERR(phy_provider)) 253 return PTR_ERR(phy_provider); 254 255 return 0; 256 } 257 258 static void eusb2_repeater_remove(struct platform_device *pdev) 259 { 260 struct eusb2_repeater *rptr = platform_get_drvdata(pdev); 261 262 if (!rptr) 263 return; 264 265 eusb2_repeater_exit(rptr->phy); 266 } 267 268 static const struct of_device_id eusb2_repeater_of_match_table[] = { 269 { 270 .compatible = "qcom,pm8550b-eusb2-repeater", 271 .data = &pm8550b_eusb2_cfg, 272 }, 273 { 274 .compatible = "qcom,pmiv0104-eusb2-repeater", 275 .data = &pmiv0104_eusb2_cfg, 276 }, 277 { 278 .compatible = "qcom,smb2360-eusb2-repeater", 279 .data = &smb2360_eusb2_cfg, 280 }, 281 { }, 282 }; 283 MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table); 284 285 static struct platform_driver eusb2_repeater_driver = { 286 .probe = eusb2_repeater_probe, 287 .remove = eusb2_repeater_remove, 288 .driver = { 289 .name = "qcom-eusb2-repeater", 290 .of_match_table = eusb2_repeater_of_match_table, 291 }, 292 }; 293 294 module_platform_driver(eusb2_repeater_driver); 295 296 MODULE_DESCRIPTION("Qualcomm PMIC eUSB2 Repeater driver"); 297 MODULE_LICENSE("GPL"); 298