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