1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2021 Emil Renner Berthing <kernel@esmil.dk> 4 * Copyright (C) 2021 Samin Guo <samin.guo@starfivetech.com> 5 */ 6 7 #include <linux/bits.h> 8 #include <linux/clk.h> 9 #include <linux/delay.h> 10 #include <linux/hwmon.h> 11 #include <linux/io.h> 12 #include <linux/module.h> 13 #include <linux/of.h> 14 #include <linux/platform_device.h> 15 #include <linux/reset.h> 16 17 /* 18 * TempSensor reset. The RSTN can be de-asserted once the analog core has 19 * powered up. Trst(min 100ns) 20 * 0:reset 1:de-assert 21 */ 22 #define SFCTEMP_RSTN BIT(0) 23 24 /* 25 * TempSensor analog core power down. The analog core will be powered up 26 * Tpu(min 50us) after PD is de-asserted. RSTN should be held low until the 27 * analog core is powered up. 28 * 0:power up 1:power down 29 */ 30 #define SFCTEMP_PD BIT(1) 31 32 /* 33 * TempSensor start conversion enable. 34 * 0:disable 1:enable 35 */ 36 #define SFCTEMP_RUN BIT(2) 37 38 /* 39 * TempSensor conversion value output. 40 * Temp(C)=DOUT*Y/4094 - K 41 */ 42 #define SFCTEMP_DOUT_POS 16 43 #define SFCTEMP_DOUT_MSK GENMASK(27, 16) 44 45 /* DOUT to Celcius conversion constants */ 46 #define SFCTEMP_Y1000 237500L 47 #define SFCTEMP_Z 4094L 48 #define SFCTEMP_K1000 81100L 49 50 struct sfctemp { 51 void __iomem *regs; 52 struct clk *clk_sense; 53 struct clk *clk_bus; 54 struct reset_control *rst_sense; 55 struct reset_control *rst_bus; 56 bool enabled; 57 }; 58 59 static void sfctemp_power_up(struct sfctemp *sfctemp) 60 { 61 /* make sure we're powered down first */ 62 writel(SFCTEMP_PD, sfctemp->regs); 63 udelay(1); 64 65 writel(0, sfctemp->regs); 66 /* wait t_pu(50us) + t_rst(100ns) */ 67 usleep_range(60, 200); 68 69 /* de-assert reset */ 70 writel(SFCTEMP_RSTN, sfctemp->regs); 71 udelay(1); /* wait t_su(500ps) */ 72 } 73 74 static void sfctemp_power_down(struct sfctemp *sfctemp) 75 { 76 writel(SFCTEMP_PD, sfctemp->regs); 77 } 78 79 static void sfctemp_run(struct sfctemp *sfctemp) 80 { 81 writel(SFCTEMP_RSTN | SFCTEMP_RUN, sfctemp->regs); 82 udelay(1); 83 } 84 85 static void sfctemp_stop(struct sfctemp *sfctemp) 86 { 87 writel(SFCTEMP_RSTN, sfctemp->regs); 88 } 89 90 static int sfctemp_enable(struct sfctemp *sfctemp) 91 { 92 int ret; 93 94 if (sfctemp->enabled) 95 return 0; 96 97 ret = clk_prepare_enable(sfctemp->clk_bus); 98 if (ret) 99 return ret; 100 ret = reset_control_deassert(sfctemp->rst_bus); 101 if (ret) 102 goto err_disable_bus; 103 104 ret = clk_prepare_enable(sfctemp->clk_sense); 105 if (ret) 106 goto err_assert_bus; 107 ret = reset_control_deassert(sfctemp->rst_sense); 108 if (ret) 109 goto err_disable_sense; 110 111 sfctemp_power_up(sfctemp); 112 sfctemp_run(sfctemp); 113 sfctemp->enabled = true; 114 return 0; 115 116 err_disable_sense: 117 clk_disable_unprepare(sfctemp->clk_sense); 118 err_assert_bus: 119 reset_control_assert(sfctemp->rst_bus); 120 err_disable_bus: 121 clk_disable_unprepare(sfctemp->clk_bus); 122 return ret; 123 } 124 125 static int sfctemp_disable(struct sfctemp *sfctemp) 126 { 127 if (!sfctemp->enabled) 128 return 0; 129 130 sfctemp_stop(sfctemp); 131 sfctemp_power_down(sfctemp); 132 reset_control_assert(sfctemp->rst_sense); 133 clk_disable_unprepare(sfctemp->clk_sense); 134 reset_control_assert(sfctemp->rst_bus); 135 clk_disable_unprepare(sfctemp->clk_bus); 136 sfctemp->enabled = false; 137 return 0; 138 } 139 140 static void sfctemp_disable_action(void *data) 141 { 142 sfctemp_disable(data); 143 } 144 145 static int sfctemp_convert(struct sfctemp *sfctemp, long *val) 146 { 147 if (!sfctemp->enabled) 148 return -ENODATA; 149 150 /* calculate temperature in milli Celcius */ 151 *val = (long)((readl(sfctemp->regs) & SFCTEMP_DOUT_MSK) >> SFCTEMP_DOUT_POS) 152 * SFCTEMP_Y1000 / SFCTEMP_Z - SFCTEMP_K1000; 153 154 return 0; 155 } 156 157 static umode_t sfctemp_is_visible(const void *data, enum hwmon_sensor_types type, 158 u32 attr, int channel) 159 { 160 switch (type) { 161 case hwmon_temp: 162 switch (attr) { 163 case hwmon_temp_enable: 164 return 0644; 165 case hwmon_temp_input: 166 return 0444; 167 default: 168 return 0; 169 } 170 default: 171 return 0; 172 } 173 } 174 175 static int sfctemp_read(struct device *dev, enum hwmon_sensor_types type, 176 u32 attr, int channel, long *val) 177 { 178 struct sfctemp *sfctemp = dev_get_drvdata(dev); 179 180 switch (type) { 181 case hwmon_temp: 182 switch (attr) { 183 case hwmon_temp_enable: 184 *val = sfctemp->enabled; 185 return 0; 186 case hwmon_temp_input: 187 return sfctemp_convert(sfctemp, val); 188 default: 189 return -EINVAL; 190 } 191 default: 192 return -EINVAL; 193 } 194 } 195 196 static int sfctemp_write(struct device *dev, enum hwmon_sensor_types type, 197 u32 attr, int channel, long val) 198 { 199 struct sfctemp *sfctemp = dev_get_drvdata(dev); 200 201 switch (type) { 202 case hwmon_temp: 203 switch (attr) { 204 case hwmon_temp_enable: 205 if (val == 0) 206 return sfctemp_disable(sfctemp); 207 if (val == 1) 208 return sfctemp_enable(sfctemp); 209 return -EINVAL; 210 default: 211 return -EINVAL; 212 } 213 default: 214 return -EINVAL; 215 } 216 } 217 218 static const struct hwmon_channel_info *sfctemp_info[] = { 219 HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), 220 HWMON_CHANNEL_INFO(temp, HWMON_T_ENABLE | HWMON_T_INPUT), 221 NULL 222 }; 223 224 static const struct hwmon_ops sfctemp_hwmon_ops = { 225 .is_visible = sfctemp_is_visible, 226 .read = sfctemp_read, 227 .write = sfctemp_write, 228 }; 229 230 static const struct hwmon_chip_info sfctemp_chip_info = { 231 .ops = &sfctemp_hwmon_ops, 232 .info = sfctemp_info, 233 }; 234 235 static int sfctemp_probe(struct platform_device *pdev) 236 { 237 struct device *dev = &pdev->dev; 238 struct device *hwmon_dev; 239 struct sfctemp *sfctemp; 240 int ret; 241 242 sfctemp = devm_kzalloc(dev, sizeof(*sfctemp), GFP_KERNEL); 243 if (!sfctemp) 244 return -ENOMEM; 245 246 dev_set_drvdata(dev, sfctemp); 247 248 sfctemp->regs = devm_platform_ioremap_resource(pdev, 0); 249 if (IS_ERR(sfctemp->regs)) 250 return PTR_ERR(sfctemp->regs); 251 252 sfctemp->clk_sense = devm_clk_get(dev, "sense"); 253 if (IS_ERR(sfctemp->clk_sense)) 254 return dev_err_probe(dev, PTR_ERR(sfctemp->clk_sense), 255 "error getting sense clock\n"); 256 257 sfctemp->clk_bus = devm_clk_get(dev, "bus"); 258 if (IS_ERR(sfctemp->clk_bus)) 259 return dev_err_probe(dev, PTR_ERR(sfctemp->clk_bus), 260 "error getting bus clock\n"); 261 262 sfctemp->rst_sense = devm_reset_control_get_exclusive(dev, "sense"); 263 if (IS_ERR(sfctemp->rst_sense)) 264 return dev_err_probe(dev, PTR_ERR(sfctemp->rst_sense), 265 "error getting sense reset\n"); 266 267 sfctemp->rst_bus = devm_reset_control_get_exclusive(dev, "bus"); 268 if (IS_ERR(sfctemp->rst_bus)) 269 return dev_err_probe(dev, PTR_ERR(sfctemp->rst_bus), 270 "error getting busreset\n"); 271 272 ret = reset_control_assert(sfctemp->rst_sense); 273 if (ret) 274 return dev_err_probe(dev, ret, "error asserting sense reset\n"); 275 276 ret = reset_control_assert(sfctemp->rst_bus); 277 if (ret) 278 return dev_err_probe(dev, ret, "error asserting bus reset\n"); 279 280 ret = devm_add_action(dev, sfctemp_disable_action, sfctemp); 281 if (ret) 282 return ret; 283 284 ret = sfctemp_enable(sfctemp); 285 if (ret) 286 return dev_err_probe(dev, ret, "error enabling temperature sensor\n"); 287 288 hwmon_dev = devm_hwmon_device_register_with_info(dev, "sfctemp", sfctemp, 289 &sfctemp_chip_info, NULL); 290 return PTR_ERR_OR_ZERO(hwmon_dev); 291 } 292 293 static const struct of_device_id sfctemp_of_match[] = { 294 { .compatible = "starfive,jh7100-temp" }, 295 { .compatible = "starfive,jh7110-temp" }, 296 { /* sentinel */ } 297 }; 298 MODULE_DEVICE_TABLE(of, sfctemp_of_match); 299 300 static struct platform_driver sfctemp_driver = { 301 .probe = sfctemp_probe, 302 .driver = { 303 .name = "sfctemp", 304 .of_match_table = sfctemp_of_match, 305 }, 306 }; 307 module_platform_driver(sfctemp_driver); 308 309 MODULE_AUTHOR("Emil Renner Berthing"); 310 MODULE_DESCRIPTION("StarFive JH71x0 temperature sensor driver"); 311 MODULE_LICENSE("GPL"); 312