Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (C) 2020 MaxLinear, Inc.
0004  *
0005  * This driver is a hardware monitoring driver for PVT controller
0006  * (MR75203) which is used to configure & control Moortec embedded
0007  * analog IP to enable multiple embedded temperature sensor(TS),
0008  * voltage monitor(VM) & process detector(PD) modules.
0009  */
0010 #include <linux/bits.h>
0011 #include <linux/clk.h>
0012 #include <linux/hwmon.h>
0013 #include <linux/module.h>
0014 #include <linux/mod_devicetable.h>
0015 #include <linux/mutex.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/property.h>
0018 #include <linux/regmap.h>
0019 #include <linux/reset.h>
0020 #include <linux/units.h>
0021 
0022 /* PVT Common register */
0023 #define PVT_IP_CONFIG   0x04
0024 #define TS_NUM_MSK  GENMASK(4, 0)
0025 #define TS_NUM_SFT  0
0026 #define PD_NUM_MSK  GENMASK(12, 8)
0027 #define PD_NUM_SFT  8
0028 #define VM_NUM_MSK  GENMASK(20, 16)
0029 #define VM_NUM_SFT  16
0030 #define CH_NUM_MSK  GENMASK(31, 24)
0031 #define CH_NUM_SFT  24
0032 
0033 /* Macro Common Register */
0034 #define CLK_SYNTH       0x00
0035 #define CLK_SYNTH_LO_SFT    0
0036 #define CLK_SYNTH_HI_SFT    8
0037 #define CLK_SYNTH_HOLD_SFT  16
0038 #define CLK_SYNTH_EN        BIT(24)
0039 #define CLK_SYS_CYCLES_MAX  514
0040 #define CLK_SYS_CYCLES_MIN  2
0041 
0042 #define SDIF_DISABLE    0x04
0043 
0044 #define SDIF_STAT   0x08
0045 #define SDIF_BUSY   BIT(0)
0046 #define SDIF_LOCK   BIT(1)
0047 
0048 #define SDIF_W      0x0c
0049 #define SDIF_PROG   BIT(31)
0050 #define SDIF_WRN_W  BIT(27)
0051 #define SDIF_WRN_R  0x00
0052 #define SDIF_ADDR_SFT   24
0053 
0054 #define SDIF_HALT   0x10
0055 #define SDIF_CTRL   0x14
0056 #define SDIF_SMPL_CTRL  0x20
0057 
0058 /* TS & PD Individual Macro Register */
0059 #define COM_REG_SIZE    0x40
0060 
0061 #define SDIF_DONE(n)    (COM_REG_SIZE + 0x14 + 0x40 * (n))
0062 #define SDIF_SMPL_DONE  BIT(0)
0063 
0064 #define SDIF_DATA(n)    (COM_REG_SIZE + 0x18 + 0x40 * (n))
0065 #define SAMPLE_DATA_MSK GENMASK(15, 0)
0066 
0067 #define HILO_RESET(n)   (COM_REG_SIZE + 0x2c + 0x40 * (n))
0068 
0069 /* VM Individual Macro Register */
0070 #define VM_COM_REG_SIZE 0x200
0071 #define VM_SDIF_DONE(vm)    (VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
0072 #define VM_SDIF_DATA(vm, ch)    \
0073     (VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))
0074 
0075 /* SDA Slave Register */
0076 #define IP_CTRL         0x00
0077 #define IP_RST_REL      BIT(1)
0078 #define IP_RUN_CONT     BIT(3)
0079 #define IP_AUTO         BIT(8)
0080 #define IP_VM_MODE      BIT(10)
0081 
0082 #define IP_CFG          0x01
0083 #define CFG0_MODE_2     BIT(0)
0084 #define CFG0_PARALLEL_OUT   0
0085 #define CFG0_12_BIT     0
0086 #define CFG1_VOL_MEAS_MODE  0
0087 #define CFG1_PARALLEL_OUT   0
0088 #define CFG1_14_BIT     0
0089 
0090 #define IP_DATA     0x03
0091 
0092 #define IP_POLL     0x04
0093 #define VM_CH_INIT  BIT(20)
0094 #define VM_CH_REQ   BIT(21)
0095 
0096 #define IP_TMR          0x05
0097 #define POWER_DELAY_CYCLE_256   0x100
0098 #define POWER_DELAY_CYCLE_64    0x40
0099 
0100 #define PVT_POLL_DELAY_US   20
0101 #define PVT_POLL_TIMEOUT_US 20000
0102 #define PVT_H_CONST     100000
0103 #define PVT_CAL5_CONST      2047
0104 #define PVT_G_CONST     40000
0105 #define PVT_CONV_BITS       10
0106 #define PVT_N_CONST     90
0107 #define PVT_R_CONST     245805
0108 
0109 struct pvt_device {
0110     struct regmap       *c_map;
0111     struct regmap       *t_map;
0112     struct regmap       *p_map;
0113     struct regmap       *v_map;
0114     struct clk      *clk;
0115     struct reset_control    *rst;
0116     u32         t_num;
0117     u32         p_num;
0118     u32         v_num;
0119     u32         c_num;
0120     u32         ip_freq;
0121     u8          *vm_idx;
0122 };
0123 
0124 static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type,
0125                   u32 attr, int channel)
0126 {
0127     switch (type) {
0128     case hwmon_temp:
0129         if (attr == hwmon_temp_input)
0130             return 0444;
0131         break;
0132     case hwmon_in:
0133         if (attr == hwmon_in_input)
0134             return 0444;
0135         break;
0136     default:
0137         break;
0138     }
0139     return 0;
0140 }
0141 
0142 static int pvt_read_temp(struct device *dev, u32 attr, int channel, long *val)
0143 {
0144     struct pvt_device *pvt = dev_get_drvdata(dev);
0145     struct regmap *t_map = pvt->t_map;
0146     u32 stat, nbs;
0147     int ret;
0148     u64 tmp;
0149 
0150     switch (attr) {
0151     case hwmon_temp_input:
0152         ret = regmap_read_poll_timeout(t_map, SDIF_DONE(channel),
0153                            stat, stat & SDIF_SMPL_DONE,
0154                            PVT_POLL_DELAY_US,
0155                            PVT_POLL_TIMEOUT_US);
0156         if (ret)
0157             return ret;
0158 
0159         ret = regmap_read(t_map, SDIF_DATA(channel), &nbs);
0160         if(ret < 0)
0161             return ret;
0162 
0163         nbs &= SAMPLE_DATA_MSK;
0164 
0165         /*
0166          * Convert the register value to
0167          * degrees centigrade temperature
0168          */
0169         tmp = nbs * PVT_H_CONST;
0170         do_div(tmp, PVT_CAL5_CONST);
0171         *val = tmp - PVT_G_CONST - pvt->ip_freq;
0172 
0173         return 0;
0174     default:
0175         return -EOPNOTSUPP;
0176     }
0177 }
0178 
0179 static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
0180 {
0181     struct pvt_device *pvt = dev_get_drvdata(dev);
0182     struct regmap *v_map = pvt->v_map;
0183     u8 vm_idx, ch_idx;
0184     u32 n, stat;
0185     int ret;
0186 
0187     if (channel >= pvt->v_num * pvt->c_num)
0188         return -EINVAL;
0189 
0190     vm_idx = pvt->vm_idx[channel / pvt->c_num];
0191     ch_idx = channel % pvt->c_num;
0192 
0193     switch (attr) {
0194     case hwmon_in_input:
0195         ret = regmap_read_poll_timeout(v_map, VM_SDIF_DONE(vm_idx),
0196                            stat, stat & SDIF_SMPL_DONE,
0197                            PVT_POLL_DELAY_US,
0198                            PVT_POLL_TIMEOUT_US);
0199         if (ret)
0200             return ret;
0201 
0202         ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
0203         if(ret < 0)
0204             return ret;
0205 
0206         n &= SAMPLE_DATA_MSK;
0207         /*
0208          * Convert the N bitstream count into voltage.
0209          * To support negative voltage calculation for 64bit machines
0210          * n must be cast to long, since n and *val differ both in
0211          * signedness and in size.
0212          * Division is used instead of right shift, because for signed
0213          * numbers, the sign bit is used to fill the vacated bit
0214          * positions, and if the number is negative, 1 is used.
0215          * BIT(x) may not be used instead of (1 << x) because it's
0216          * unsigned.
0217          */
0218         *val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS);
0219 
0220         return 0;
0221     default:
0222         return -EOPNOTSUPP;
0223     }
0224 }
0225 
0226 static int pvt_read(struct device *dev, enum hwmon_sensor_types type,
0227             u32 attr, int channel, long *val)
0228 {
0229     switch (type) {
0230     case hwmon_temp:
0231         return pvt_read_temp(dev, attr, channel, val);
0232     case hwmon_in:
0233         return pvt_read_in(dev, attr, channel, val);
0234     default:
0235         return -EOPNOTSUPP;
0236     }
0237 }
0238 
0239 static struct hwmon_channel_info pvt_temp = {
0240     .type = hwmon_temp,
0241 };
0242 
0243 static struct hwmon_channel_info pvt_in = {
0244     .type = hwmon_in,
0245 };
0246 
0247 static const struct hwmon_ops pvt_hwmon_ops = {
0248     .is_visible = pvt_is_visible,
0249     .read = pvt_read,
0250 };
0251 
0252 static struct hwmon_chip_info pvt_chip_info = {
0253     .ops = &pvt_hwmon_ops,
0254 };
0255 
0256 static int pvt_init(struct pvt_device *pvt)
0257 {
0258     u16 sys_freq, key, middle, low = 4, high = 8;
0259     struct regmap *t_map = pvt->t_map;
0260     struct regmap *p_map = pvt->p_map;
0261     struct regmap *v_map = pvt->v_map;
0262     u32 t_num = pvt->t_num;
0263     u32 p_num = pvt->p_num;
0264     u32 v_num = pvt->v_num;
0265     u32 clk_synth, val;
0266     int ret;
0267 
0268     sys_freq = clk_get_rate(pvt->clk) / HZ_PER_MHZ;
0269     while (high >= low) {
0270         middle = (low + high + 1) / 2;
0271         key = DIV_ROUND_CLOSEST(sys_freq, middle);
0272         if (key > CLK_SYS_CYCLES_MAX) {
0273             low = middle + 1;
0274             continue;
0275         } else if (key < CLK_SYS_CYCLES_MIN) {
0276             high = middle - 1;
0277             continue;
0278         } else {
0279             break;
0280         }
0281     }
0282 
0283     /*
0284      * The system supports 'clk_sys' to 'clk_ip' frequency ratios
0285      * from 2:1 to 512:1
0286      */
0287     key = clamp_val(key, CLK_SYS_CYCLES_MIN, CLK_SYS_CYCLES_MAX) - 2;
0288 
0289     clk_synth = ((key + 1) >> 1) << CLK_SYNTH_LO_SFT |
0290             (key >> 1) << CLK_SYNTH_HI_SFT |
0291             (key >> 1) << CLK_SYNTH_HOLD_SFT | CLK_SYNTH_EN;
0292 
0293     pvt->ip_freq = sys_freq * 100 / (key + 2);
0294 
0295     if (t_num) {
0296         ret = regmap_write(t_map, SDIF_SMPL_CTRL, 0x0);
0297         if(ret < 0)
0298             return ret;
0299 
0300         ret = regmap_write(t_map, SDIF_HALT, 0x0);
0301         if(ret < 0)
0302             return ret;
0303 
0304         ret = regmap_write(t_map, CLK_SYNTH, clk_synth);
0305         if(ret < 0)
0306             return ret;
0307 
0308         ret = regmap_write(t_map, SDIF_DISABLE, 0x0);
0309         if(ret < 0)
0310             return ret;
0311 
0312         ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
0313                            val, !(val & SDIF_BUSY),
0314                            PVT_POLL_DELAY_US,
0315                            PVT_POLL_TIMEOUT_US);
0316         if (ret)
0317             return ret;
0318 
0319         val = CFG0_MODE_2 | CFG0_PARALLEL_OUT | CFG0_12_BIT |
0320               IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
0321         ret = regmap_write(t_map, SDIF_W, val);
0322         if(ret < 0)
0323             return ret;
0324 
0325         ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
0326                            val, !(val & SDIF_BUSY),
0327                            PVT_POLL_DELAY_US,
0328                            PVT_POLL_TIMEOUT_US);
0329         if (ret)
0330             return ret;
0331 
0332         val = POWER_DELAY_CYCLE_256 | IP_TMR << SDIF_ADDR_SFT |
0333                   SDIF_WRN_W | SDIF_PROG;
0334         ret = regmap_write(t_map, SDIF_W, val);
0335         if(ret < 0)
0336             return ret;
0337 
0338         ret = regmap_read_poll_timeout(t_map, SDIF_STAT,
0339                            val, !(val & SDIF_BUSY),
0340                            PVT_POLL_DELAY_US,
0341                            PVT_POLL_TIMEOUT_US);
0342         if (ret)
0343             return ret;
0344 
0345         val = IP_RST_REL | IP_RUN_CONT | IP_AUTO |
0346               IP_CTRL << SDIF_ADDR_SFT |
0347               SDIF_WRN_W | SDIF_PROG;
0348         ret = regmap_write(t_map, SDIF_W, val);
0349         if(ret < 0)
0350             return ret;
0351     }
0352 
0353     if (p_num) {
0354         ret = regmap_write(p_map, SDIF_HALT, 0x0);
0355         if(ret < 0)
0356             return ret;
0357 
0358         ret = regmap_write(p_map, SDIF_DISABLE, BIT(p_num) - 1);
0359         if(ret < 0)
0360             return ret;
0361 
0362         ret = regmap_write(p_map, CLK_SYNTH, clk_synth);
0363         if(ret < 0)
0364             return ret;
0365     }
0366 
0367     if (v_num) {
0368         ret = regmap_write(v_map, SDIF_SMPL_CTRL, 0x0);
0369         if(ret < 0)
0370             return ret;
0371 
0372         ret = regmap_write(v_map, SDIF_HALT, 0x0);
0373         if(ret < 0)
0374             return ret;
0375 
0376         ret = regmap_write(v_map, CLK_SYNTH, clk_synth);
0377         if(ret < 0)
0378             return ret;
0379 
0380         ret = regmap_write(v_map, SDIF_DISABLE, 0x0);
0381         if(ret < 0)
0382             return ret;
0383 
0384         ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
0385                            val, !(val & SDIF_BUSY),
0386                            PVT_POLL_DELAY_US,
0387                            PVT_POLL_TIMEOUT_US);
0388         if (ret)
0389             return ret;
0390 
0391         val = (BIT(pvt->c_num) - 1) | VM_CH_INIT |
0392               IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
0393         ret = regmap_write(v_map, SDIF_W, val);
0394         if (ret < 0)
0395             return ret;
0396 
0397         ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
0398                            val, !(val & SDIF_BUSY),
0399                            PVT_POLL_DELAY_US,
0400                            PVT_POLL_TIMEOUT_US);
0401         if (ret)
0402             return ret;
0403 
0404         val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
0405               CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
0406               SDIF_WRN_W | SDIF_PROG;
0407         ret = regmap_write(v_map, SDIF_W, val);
0408         if(ret < 0)
0409             return ret;
0410 
0411         ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
0412                            val, !(val & SDIF_BUSY),
0413                            PVT_POLL_DELAY_US,
0414                            PVT_POLL_TIMEOUT_US);
0415         if (ret)
0416             return ret;
0417 
0418         val = POWER_DELAY_CYCLE_64 | IP_TMR << SDIF_ADDR_SFT |
0419               SDIF_WRN_W | SDIF_PROG;
0420         ret = regmap_write(v_map, SDIF_W, val);
0421         if(ret < 0)
0422             return ret;
0423 
0424         ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
0425                            val, !(val & SDIF_BUSY),
0426                            PVT_POLL_DELAY_US,
0427                            PVT_POLL_TIMEOUT_US);
0428         if (ret)
0429             return ret;
0430 
0431         val = IP_RST_REL | IP_RUN_CONT | IP_AUTO | IP_VM_MODE |
0432               IP_CTRL << SDIF_ADDR_SFT |
0433               SDIF_WRN_W | SDIF_PROG;
0434         ret = regmap_write(v_map, SDIF_W, val);
0435         if(ret < 0)
0436             return ret;
0437     }
0438 
0439     return 0;
0440 }
0441 
0442 static struct regmap_config pvt_regmap_config = {
0443     .reg_bits = 32,
0444     .reg_stride = 4,
0445     .val_bits = 32,
0446 };
0447 
0448 static int pvt_get_regmap(struct platform_device *pdev, char *reg_name,
0449               struct pvt_device *pvt)
0450 {
0451     struct device *dev = &pdev->dev;
0452     struct regmap **reg_map;
0453     void __iomem *io_base;
0454 
0455     if (!strcmp(reg_name, "common"))
0456         reg_map = &pvt->c_map;
0457     else if (!strcmp(reg_name, "ts"))
0458         reg_map = &pvt->t_map;
0459     else if (!strcmp(reg_name, "pd"))
0460         reg_map = &pvt->p_map;
0461     else if (!strcmp(reg_name, "vm"))
0462         reg_map = &pvt->v_map;
0463     else
0464         return -EINVAL;
0465 
0466     io_base = devm_platform_ioremap_resource_byname(pdev, reg_name);
0467     if (IS_ERR(io_base))
0468         return PTR_ERR(io_base);
0469 
0470     pvt_regmap_config.name = reg_name;
0471     *reg_map = devm_regmap_init_mmio(dev, io_base, &pvt_regmap_config);
0472     if (IS_ERR(*reg_map)) {
0473         dev_err(dev, "failed to init register map\n");
0474         return PTR_ERR(*reg_map);
0475     }
0476 
0477     return 0;
0478 }
0479 
0480 static void pvt_clk_disable(void *data)
0481 {
0482     struct pvt_device *pvt = data;
0483 
0484     clk_disable_unprepare(pvt->clk);
0485 }
0486 
0487 static int pvt_clk_enable(struct device *dev, struct pvt_device *pvt)
0488 {
0489     int ret;
0490 
0491     ret = clk_prepare_enable(pvt->clk);
0492     if (ret)
0493         return ret;
0494 
0495     return devm_add_action_or_reset(dev, pvt_clk_disable, pvt);
0496 }
0497 
0498 static void pvt_reset_control_assert(void *data)
0499 {
0500     struct pvt_device *pvt = data;
0501 
0502     reset_control_assert(pvt->rst);
0503 }
0504 
0505 static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt)
0506 {
0507     int ret;
0508 
0509     ret = reset_control_deassert(pvt->rst);
0510     if (ret)
0511         return ret;
0512 
0513     return devm_add_action_or_reset(dev, pvt_reset_control_assert, pvt);
0514 }
0515 
0516 static int mr75203_probe(struct platform_device *pdev)
0517 {
0518     u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
0519     const struct hwmon_channel_info **pvt_info;
0520     struct device *dev = &pdev->dev;
0521     u32 *temp_config, *in_config;
0522     struct device *hwmon_dev;
0523     struct pvt_device *pvt;
0524     int ret;
0525 
0526     pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL);
0527     if (!pvt)
0528         return -ENOMEM;
0529 
0530     ret = pvt_get_regmap(pdev, "common", pvt);
0531     if (ret)
0532         return ret;
0533 
0534     pvt->clk = devm_clk_get(dev, NULL);
0535     if (IS_ERR(pvt->clk))
0536         return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n");
0537 
0538     ret = pvt_clk_enable(dev, pvt);
0539     if (ret) {
0540         dev_err(dev, "failed to enable clock\n");
0541         return ret;
0542     }
0543 
0544     pvt->rst = devm_reset_control_get_exclusive(dev, NULL);
0545     if (IS_ERR(pvt->rst))
0546         return dev_err_probe(dev, PTR_ERR(pvt->rst),
0547                      "failed to get reset control\n");
0548 
0549     ret = pvt_reset_control_deassert(dev, pvt);
0550     if (ret)
0551         return dev_err_probe(dev, ret, "cannot deassert reset control\n");
0552 
0553     ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val);
0554     if(ret < 0)
0555         return ret;
0556 
0557     ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
0558     pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
0559     vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
0560     ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
0561     pvt->t_num = ts_num;
0562     pvt->p_num = pd_num;
0563     pvt->v_num = vm_num;
0564     pvt->c_num = ch_num;
0565     val = 0;
0566     if (ts_num)
0567         val++;
0568     if (vm_num)
0569         val++;
0570     if (!val)
0571         return -ENODEV;
0572 
0573     pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL);
0574     if (!pvt_info)
0575         return -ENOMEM;
0576     pvt_info[0] = HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ);
0577     index = 1;
0578 
0579     if (ts_num) {
0580         ret = pvt_get_regmap(pdev, "ts", pvt);
0581         if (ret)
0582             return ret;
0583 
0584         temp_config = devm_kcalloc(dev, ts_num + 1,
0585                        sizeof(*temp_config), GFP_KERNEL);
0586         if (!temp_config)
0587             return -ENOMEM;
0588 
0589         memset32(temp_config, HWMON_T_INPUT, ts_num);
0590         pvt_temp.config = temp_config;
0591         pvt_info[index++] = &pvt_temp;
0592     }
0593 
0594     if (pd_num) {
0595         ret = pvt_get_regmap(pdev, "pd", pvt);
0596         if (ret)
0597             return ret;
0598     }
0599 
0600     if (vm_num) {
0601         u32 total_ch;
0602 
0603         ret = pvt_get_regmap(pdev, "vm", pvt);
0604         if (ret)
0605             return ret;
0606 
0607         pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx),
0608                        GFP_KERNEL);
0609         if (!pvt->vm_idx)
0610             return -ENOMEM;
0611 
0612         ret = device_property_read_u8_array(dev, "intel,vm-map",
0613                             pvt->vm_idx, vm_num);
0614         if (ret) {
0615             /*
0616              * Incase intel,vm-map property is not defined, we
0617              * assume incremental channel numbers.
0618              */
0619             for (i = 0; i < vm_num; i++)
0620                 pvt->vm_idx[i] = i;
0621         } else {
0622             for (i = 0; i < vm_num; i++)
0623                 if (pvt->vm_idx[i] >= vm_num ||
0624                     pvt->vm_idx[i] == 0xff) {
0625                     pvt->v_num = i;
0626                     vm_num = i;
0627                     break;
0628                 }
0629         }
0630 
0631         total_ch = ch_num * vm_num;
0632         in_config = devm_kcalloc(dev, total_ch + 1,
0633                      sizeof(*in_config), GFP_KERNEL);
0634         if (!in_config)
0635             return -ENOMEM;
0636 
0637         memset32(in_config, HWMON_I_INPUT, total_ch);
0638         in_config[total_ch] = 0;
0639         pvt_in.config = in_config;
0640 
0641         pvt_info[index++] = &pvt_in;
0642     }
0643 
0644     ret = pvt_init(pvt);
0645     if (ret) {
0646         dev_err(dev, "failed to init pvt: %d\n", ret);
0647         return ret;
0648     }
0649 
0650     pvt_chip_info.info = pvt_info;
0651     hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt",
0652                              pvt,
0653                              &pvt_chip_info,
0654                              NULL);
0655 
0656     return PTR_ERR_OR_ZERO(hwmon_dev);
0657 }
0658 
0659 static const struct of_device_id moortec_pvt_of_match[] = {
0660     { .compatible = "moortec,mr75203" },
0661     { }
0662 };
0663 MODULE_DEVICE_TABLE(of, moortec_pvt_of_match);
0664 
0665 static struct platform_driver moortec_pvt_driver = {
0666     .driver = {
0667         .name = "moortec-pvt",
0668         .of_match_table = moortec_pvt_of_match,
0669     },
0670     .probe = mr75203_probe,
0671 };
0672 module_platform_driver(moortec_pvt_driver);
0673 
0674 MODULE_LICENSE("GPL v2");