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: qualcomm: phy-qcom-eusb2-repeater: Use regmap_fields

Switch to regmap_fields, so that the values written into registers are
sanitized by their explicit sizes and the different registers are
structured in an iterable object to make external changes to the init
sequence simpler.

Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20230830-topic-eusb2_override-v2-2-7d8c893d93f6@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Konrad Dybcio and committed by
Vinod Koul
4ba2e527 c20b59b2

+61 -30
+61 -30
drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
··· 28 28 #define EUSB2_TUNE_SQUELCH_U 0x54 29 29 #define EUSB2_TUNE_USB2_PREEM 0x57 30 30 31 - #define QCOM_EUSB2_REPEATER_INIT_CFG(o, v) \ 31 + #define QCOM_EUSB2_REPEATER_INIT_CFG(r, v) \ 32 32 { \ 33 - .offset = o, \ 33 + .reg = r, \ 34 34 .val = v, \ 35 35 } 36 36 37 + enum reg_fields { 38 + F_TUNE_USB2_PREEM, 39 + F_TUNE_SQUELCH_U, 40 + F_TUNE_IUSB2, 41 + F_NUM_TUNE_FIELDS, 42 + 43 + F_FORCE_VAL_5 = F_NUM_TUNE_FIELDS, 44 + F_FORCE_EN_5, 45 + 46 + F_EN_CTL1, 47 + 48 + F_RPTR_STATUS, 49 + F_NUM_FIELDS, 50 + }; 51 + 52 + static struct reg_field eusb2_repeater_tune_reg_fields[F_NUM_FIELDS] = { 53 + [F_TUNE_USB2_PREEM] = REG_FIELD(EUSB2_TUNE_USB2_PREEM, 0, 2), 54 + [F_TUNE_SQUELCH_U] = REG_FIELD(EUSB2_TUNE_SQUELCH_U, 0, 2), 55 + [F_TUNE_IUSB2] = REG_FIELD(EUSB2_TUNE_IUSB2, 0, 3), 56 + 57 + [F_FORCE_VAL_5] = REG_FIELD(EUSB2_FORCE_VAL_5, 0, 7), 58 + [F_FORCE_EN_5] = REG_FIELD(EUSB2_FORCE_EN_5, 0, 7), 59 + 60 + [F_EN_CTL1] = REG_FIELD(EUSB2_EN_CTL1, 0, 7), 61 + 62 + [F_RPTR_STATUS] = REG_FIELD(EUSB2_RPTR_STATUS, 0, 7), 63 + }; 64 + 37 65 struct eusb2_repeater_init_tbl { 38 - unsigned int offset; 66 + unsigned int reg; 39 67 unsigned int val; 40 68 }; 41 69 ··· 76 48 77 49 struct eusb2_repeater { 78 50 struct device *dev; 79 - struct regmap *regmap; 51 + struct regmap_field *regs[F_NUM_FIELDS]; 80 52 struct phy *phy; 81 53 struct regulator_bulk_data *vregs; 82 54 const struct eusb2_repeater_cfg *cfg; 83 - u16 base; 84 55 enum phy_mode mode; 85 56 }; 86 57 ··· 88 61 }; 89 62 90 63 static const struct eusb2_repeater_init_tbl pm8550b_init_tbl[] = { 91 - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_IUSB2, 0x8), 92 - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_SQUELCH_U, 0x3), 93 - QCOM_EUSB2_REPEATER_INIT_CFG(EUSB2_TUNE_USB2_PREEM, 0x5), 64 + QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_IUSB2, 0x8), 65 + QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_SQUELCH_U, 0x3), 66 + QCOM_EUSB2_REPEATER_INIT_CFG(F_TUNE_USB2_PREEM, 0x5), 94 67 }; 95 68 96 69 static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { ··· 120 93 { 121 94 struct eusb2_repeater *rptr = phy_get_drvdata(phy); 122 95 const struct eusb2_repeater_init_tbl *init_tbl = rptr->cfg->init_tbl; 123 - int num = rptr->cfg->init_tbl_num; 124 96 u32 val; 125 97 int ret; 126 98 int i; ··· 128 102 if (ret) 129 103 return ret; 130 104 131 - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_EN_CTL1, 132 - EUSB2_RPTR_EN, EUSB2_RPTR_EN); 105 + regmap_field_update_bits(rptr->regs[F_EN_CTL1], EUSB2_RPTR_EN, EUSB2_RPTR_EN); 133 106 134 - for (i = 0; i < num; i++) 135 - regmap_update_bits(rptr->regmap, 136 - rptr->base + init_tbl[i].offset, 137 - init_tbl[i].val, init_tbl[i].val); 107 + for (i = 0; i < rptr->cfg->init_tbl_num; i++) 108 + regmap_field_update_bits(rptr->regs[init_tbl[i].reg], 109 + init_tbl[i].val, init_tbl[i].val); 138 110 139 - ret = regmap_read_poll_timeout(rptr->regmap, 140 - rptr->base + EUSB2_RPTR_STATUS, val, 141 - val & RPTR_OK, 10, 5); 111 + ret = regmap_field_read_poll_timeout(rptr->regs[F_RPTR_STATUS], 112 + val, val & RPTR_OK, 10, 5); 142 113 if (ret) 143 114 dev_err(rptr->dev, "initialization timed-out\n"); 144 115 ··· 154 131 * per eUSB 1.2 Spec. Below implement software workaround until 155 132 * PHY and controller is fixing seen observation. 156 133 */ 157 - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, 158 - F_CLK_19P2M_EN, F_CLK_19P2M_EN); 159 - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, 160 - V_CLK_19P2M_EN, V_CLK_19P2M_EN); 134 + regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], 135 + F_CLK_19P2M_EN, F_CLK_19P2M_EN); 136 + regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], 137 + V_CLK_19P2M_EN, V_CLK_19P2M_EN); 161 138 break; 162 139 case PHY_MODE_USB_DEVICE: 163 140 /* ··· 166 143 * repeater doesn't clear previous value due to shared 167 144 * regulators (say host <-> device mode switch). 168 145 */ 169 - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_EN_5, 170 - F_CLK_19P2M_EN, 0); 171 - regmap_update_bits(rptr->regmap, rptr->base + EUSB2_FORCE_VAL_5, 172 - V_CLK_19P2M_EN, 0); 146 + regmap_field_update_bits(rptr->regs[F_FORCE_EN_5], 147 + F_CLK_19P2M_EN, 0); 148 + regmap_field_update_bits(rptr->regs[F_FORCE_VAL_5], 149 + V_CLK_19P2M_EN, 0); 173 150 break; 174 151 default: 175 152 return -EINVAL; ··· 198 175 struct device *dev = &pdev->dev; 199 176 struct phy_provider *phy_provider; 200 177 struct device_node *np = dev->of_node; 178 + struct regmap *regmap; 179 + int i, ret; 201 180 u32 res; 202 - int ret; 203 181 204 182 rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL); 205 183 if (!rptr) ··· 213 189 if (!rptr->cfg) 214 190 return -EINVAL; 215 191 216 - rptr->regmap = dev_get_regmap(dev->parent, NULL); 217 - if (!rptr->regmap) 192 + regmap = dev_get_regmap(dev->parent, NULL); 193 + if (!regmap) 218 194 return -ENODEV; 219 195 220 196 ret = of_property_read_u32(np, "reg", &res); 221 197 if (ret < 0) 222 198 return ret; 223 199 224 - rptr->base = res; 200 + for (i = 0; i < F_NUM_FIELDS; i++) 201 + eusb2_repeater_tune_reg_fields[i].reg += res; 202 + 203 + ret = devm_regmap_field_bulk_alloc(dev, regmap, rptr->regs, 204 + eusb2_repeater_tune_reg_fields, 205 + F_NUM_FIELDS); 206 + if (ret) 207 + return ret; 225 208 226 209 ret = eusb2_repeater_init_vregs(rptr); 227 210 if (ret < 0) {