Skip to content

Commit 91a9e06

Browse files
Eliav Farbergroeck
authored andcommitted
hwmon: (mr75203) fix multi-channel voltage reading
Fix voltage allocation and reading to support all channels in all VMs. Prior to this change allocation and reading were done only for the first channel in each VM. This change counts the total number of channels for allocation, and takes into account the channel offset when reading the sample data register. Fixes: 9d82335 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Guenter Roeck <[email protected]>
1 parent 227a3a2 commit 91a9e06

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

drivers/hwmon/mr75203.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@
6868

6969
/* VM Individual Macro Register */
7070
#define VM_COM_REG_SIZE 0x200
71-
#define VM_SDIF_DONE(n) (VM_COM_REG_SIZE + 0x34 + 0x200 * (n))
72-
#define VM_SDIF_DATA(n) (VM_COM_REG_SIZE + 0x40 + 0x200 * (n))
71+
#define VM_SDIF_DONE(vm) (VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
72+
#define VM_SDIF_DATA(vm, ch) \
73+
(VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))
7374

7475
/* SDA Slave Register */
7576
#define IP_CTRL 0x00
@@ -115,6 +116,7 @@ struct pvt_device {
115116
u32 t_num;
116117
u32 p_num;
117118
u32 v_num;
119+
u32 c_num;
118120
u32 ip_freq;
119121
u8 *vm_idx;
120122
};
@@ -178,14 +180,15 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
178180
{
179181
struct pvt_device *pvt = dev_get_drvdata(dev);
180182
struct regmap *v_map = pvt->v_map;
183+
u8 vm_idx, ch_idx;
181184
u32 n, stat;
182-
u8 vm_idx;
183185
int ret;
184186

185-
if (channel >= pvt->v_num)
187+
if (channel >= pvt->v_num * pvt->c_num)
186188
return -EINVAL;
187189

188-
vm_idx = pvt->vm_idx[channel];
190+
vm_idx = pvt->vm_idx[channel / pvt->c_num];
191+
ch_idx = channel % pvt->c_num;
189192

190193
switch (attr) {
191194
case hwmon_in_input:
@@ -196,7 +199,7 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
196199
if (ret)
197200
return ret;
198201

199-
ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n);
202+
ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
200203
if(ret < 0)
201204
return ret;
202205

@@ -499,8 +502,8 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt
499502

500503
static int mr75203_probe(struct platform_device *pdev)
501504
{
505+
u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
502506
const struct hwmon_channel_info **pvt_info;
503-
u32 ts_num, vm_num, pd_num, val, index, i;
504507
struct device *dev = &pdev->dev;
505508
u32 *temp_config, *in_config;
506509
struct device *hwmon_dev;
@@ -541,9 +544,11 @@ static int mr75203_probe(struct platform_device *pdev)
541544
ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
542545
pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
543546
vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
547+
ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
544548
pvt->t_num = ts_num;
545549
pvt->p_num = pd_num;
546550
pvt->v_num = vm_num;
551+
pvt->c_num = ch_num;
547552
val = 0;
548553
if (ts_num)
549554
val++;
@@ -580,7 +585,7 @@ static int mr75203_probe(struct platform_device *pdev)
580585
}
581586

582587
if (vm_num) {
583-
u32 num = vm_num;
588+
u32 total_ch;
584589

585590
ret = pvt_get_regmap(pdev, "vm", pvt);
586591
if (ret)
@@ -604,20 +609,20 @@ static int mr75203_probe(struct platform_device *pdev)
604609
for (i = 0; i < vm_num; i++)
605610
if (pvt->vm_idx[i] >= vm_num ||
606611
pvt->vm_idx[i] == 0xff) {
607-
num = i;
608612
pvt->v_num = i;
609613
vm_num = i;
610614
break;
611615
}
612616
}
613617

614-
in_config = devm_kcalloc(dev, num + 1,
618+
total_ch = ch_num * vm_num;
619+
in_config = devm_kcalloc(dev, total_ch + 1,
615620
sizeof(*in_config), GFP_KERNEL);
616621
if (!in_config)
617622
return -ENOMEM;
618623

619-
memset32(in_config, HWMON_I_INPUT, num);
620-
in_config[num] = 0;
624+
memset32(in_config, HWMON_I_INPUT, total_ch);
625+
in_config[total_ch] = 0;
621626
pvt_in.config = in_config;
622627

623628
pvt_info[index++] = &pvt_in;

0 commit comments

Comments
 (0)