Commit 445e0bc7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'hwmon-for-v6.0-rc5' of...

Merge tag 'hwmon-for-v6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon fixes from Guenter Roeck:

 - Fix severe regression in asus-ec-sensors driver
   which resulted in EC driver failures

 - Fix various bugs in mr75203 driver

 - Fix byte order bug in tps23861 driver

* tag 'hwmon-for-v6.0-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging:
  hwmon: (asus-ec-sensors) autoload module via DMI data
  hwmon: (mr75203) enable polling for all VM channels
  hwmon: (mr75203) fix multi-channel voltage reading
  hwmon: (mr75203) fix voltage equation for negative source input
  hwmon: (mr75203) update pvt->v_num and vm_num to the actual number of used sensors
  hwmon: (mr75203) fix VM sensor allocation when "intel,vm-map" not defined
  dt-bindings: hwmon: (mr75203) fix "intel,vm-map" property to be optional
  hwmon: (tps23861) fix byte order in resistance register
parents 16547b21 88700d13
...@@ -48,7 +48,6 @@ required: ...@@ -48,7 +48,6 @@ required:
- compatible - compatible
- reg - reg
- reg-names - reg-names
- intel,vm-map
- clocks - clocks
- resets - resets
- "#thermal-sensor-cells" - "#thermal-sensor-cells"
......
This diff is collapsed.
...@@ -68,8 +68,9 @@ ...@@ -68,8 +68,9 @@
/* VM Individual Macro Register */ /* VM Individual Macro Register */
#define VM_COM_REG_SIZE 0x200 #define VM_COM_REG_SIZE 0x200
#define VM_SDIF_DONE(n) (VM_COM_REG_SIZE + 0x34 + 0x200 * (n)) #define VM_SDIF_DONE(vm) (VM_COM_REG_SIZE + 0x34 + 0x200 * (vm))
#define VM_SDIF_DATA(n) (VM_COM_REG_SIZE + 0x40 + 0x200 * (n)) #define VM_SDIF_DATA(vm, ch) \
(VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch))
/* SDA Slave Register */ /* SDA Slave Register */
#define IP_CTRL 0x00 #define IP_CTRL 0x00
...@@ -115,6 +116,7 @@ struct pvt_device { ...@@ -115,6 +116,7 @@ struct pvt_device {
u32 t_num; u32 t_num;
u32 p_num; u32 p_num;
u32 v_num; u32 v_num;
u32 c_num;
u32 ip_freq; u32 ip_freq;
u8 *vm_idx; u8 *vm_idx;
}; };
...@@ -178,14 +180,15 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) ...@@ -178,14 +180,15 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
{ {
struct pvt_device *pvt = dev_get_drvdata(dev); struct pvt_device *pvt = dev_get_drvdata(dev);
struct regmap *v_map = pvt->v_map; struct regmap *v_map = pvt->v_map;
u8 vm_idx, ch_idx;
u32 n, stat; u32 n, stat;
u8 vm_idx;
int ret; int ret;
if (channel >= pvt->v_num) if (channel >= pvt->v_num * pvt->c_num)
return -EINVAL; return -EINVAL;
vm_idx = pvt->vm_idx[channel]; vm_idx = pvt->vm_idx[channel / pvt->c_num];
ch_idx = channel % pvt->c_num;
switch (attr) { switch (attr) {
case hwmon_in_input: case hwmon_in_input:
...@@ -196,13 +199,23 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) ...@@ -196,13 +199,23 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val)
if (ret) if (ret)
return ret; return ret;
ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n); ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n);
if(ret < 0) if(ret < 0)
return ret; return ret;
n &= SAMPLE_DATA_MSK; n &= SAMPLE_DATA_MSK;
/* Convert the N bitstream count into voltage */ /*
*val = (PVT_N_CONST * n - PVT_R_CONST) >> PVT_CONV_BITS; * Convert the N bitstream count into voltage.
* To support negative voltage calculation for 64bit machines
* n must be cast to long, since n and *val differ both in
* signedness and in size.
* Division is used instead of right shift, because for signed
* numbers, the sign bit is used to fill the vacated bit
* positions, and if the number is negative, 1 is used.
* BIT(x) may not be used instead of (1 << x) because it's
* unsigned.
*/
*val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS);
return 0; return 0;
default: default:
...@@ -375,6 +388,19 @@ static int pvt_init(struct pvt_device *pvt) ...@@ -375,6 +388,19 @@ static int pvt_init(struct pvt_device *pvt)
if (ret) if (ret)
return ret; return ret;
val = (BIT(pvt->c_num) - 1) | VM_CH_INIT |
IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG;
ret = regmap_write(v_map, SDIF_W, val);
if (ret < 0)
return ret;
ret = regmap_read_poll_timeout(v_map, SDIF_STAT,
val, !(val & SDIF_BUSY),
PVT_POLL_DELAY_US,
PVT_POLL_TIMEOUT_US);
if (ret)
return ret;
val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT | val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT |
CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT | CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT |
SDIF_WRN_W | SDIF_PROG; SDIF_WRN_W | SDIF_PROG;
...@@ -489,8 +515,8 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt ...@@ -489,8 +515,8 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt
static int mr75203_probe(struct platform_device *pdev) static int mr75203_probe(struct platform_device *pdev)
{ {
u32 ts_num, vm_num, pd_num, ch_num, val, index, i;
const struct hwmon_channel_info **pvt_info; const struct hwmon_channel_info **pvt_info;
u32 ts_num, vm_num, pd_num, val, index, i;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
u32 *temp_config, *in_config; u32 *temp_config, *in_config;
struct device *hwmon_dev; struct device *hwmon_dev;
...@@ -531,9 +557,11 @@ static int mr75203_probe(struct platform_device *pdev) ...@@ -531,9 +557,11 @@ static int mr75203_probe(struct platform_device *pdev)
ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT; ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT;
pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT; pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT;
vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT; vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT;
ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT;
pvt->t_num = ts_num; pvt->t_num = ts_num;
pvt->p_num = pd_num; pvt->p_num = pd_num;
pvt->v_num = vm_num; pvt->v_num = vm_num;
pvt->c_num = ch_num;
val = 0; val = 0;
if (ts_num) if (ts_num)
val++; val++;
...@@ -570,7 +598,7 @@ static int mr75203_probe(struct platform_device *pdev) ...@@ -570,7 +598,7 @@ static int mr75203_probe(struct platform_device *pdev)
} }
if (vm_num) { if (vm_num) {
u32 num = vm_num; u32 total_ch;
ret = pvt_get_regmap(pdev, "vm", pvt); ret = pvt_get_regmap(pdev, "vm", pvt);
if (ret) if (ret)
...@@ -584,30 +612,30 @@ static int mr75203_probe(struct platform_device *pdev) ...@@ -584,30 +612,30 @@ static int mr75203_probe(struct platform_device *pdev)
ret = device_property_read_u8_array(dev, "intel,vm-map", ret = device_property_read_u8_array(dev, "intel,vm-map",
pvt->vm_idx, vm_num); pvt->vm_idx, vm_num);
if (ret) { if (ret) {
num = 0; /*
* Incase intel,vm-map property is not defined, we
* assume incremental channel numbers.
*/
for (i = 0; i < vm_num; i++)
pvt->vm_idx[i] = i;
} else { } else {
for (i = 0; i < vm_num; i++) for (i = 0; i < vm_num; i++)
if (pvt->vm_idx[i] >= vm_num || if (pvt->vm_idx[i] >= vm_num ||
pvt->vm_idx[i] == 0xff) { pvt->vm_idx[i] == 0xff) {
num = i; pvt->v_num = i;
vm_num = i;
break; break;
} }
} }
/* total_ch = ch_num * vm_num;
* Incase intel,vm-map property is not defined, we assume in_config = devm_kcalloc(dev, total_ch + 1,
* incremental channel numbers.
*/
for (i = num; i < vm_num; i++)
pvt->vm_idx[i] = i;
in_config = devm_kcalloc(dev, num + 1,
sizeof(*in_config), GFP_KERNEL); sizeof(*in_config), GFP_KERNEL);
if (!in_config) if (!in_config)
return -ENOMEM; return -ENOMEM;
memset32(in_config, HWMON_I_INPUT, num); memset32(in_config, HWMON_I_INPUT, total_ch);
in_config[num] = 0; in_config[total_ch] = 0;
pvt_in.config = in_config; pvt_in.config = in_config;
pvt_info[index++] = &pvt_in; pvt_info[index++] = &pvt_in;
......
...@@ -493,18 +493,20 @@ static char *tps23861_port_poe_plus_status(struct tps23861_data *data, int port) ...@@ -493,18 +493,20 @@ static char *tps23861_port_poe_plus_status(struct tps23861_data *data, int port)
static int tps23861_port_resistance(struct tps23861_data *data, int port) static int tps23861_port_resistance(struct tps23861_data *data, int port)
{ {
u16 regval; unsigned int raw_val;
__le16 regval;
regmap_bulk_read(data->regmap, regmap_bulk_read(data->regmap,
PORT_1_RESISTANCE_LSB + PORT_N_RESISTANCE_LSB_OFFSET * (port - 1), PORT_1_RESISTANCE_LSB + PORT_N_RESISTANCE_LSB_OFFSET * (port - 1),
&regval, &regval,
2); 2);
switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, regval)) { raw_val = le16_to_cpu(regval);
switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, raw_val)) {
case PORT_RESISTANCE_RSN_OTHER: case PORT_RESISTANCE_RSN_OTHER:
return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB) / 10000; return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB) / 10000;
case PORT_RESISTANCE_RSN_LOW: case PORT_RESISTANCE_RSN_LOW:
return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB_LOW) / 10000; return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB_LOW) / 10000;
case PORT_RESISTANCE_RSN_SHORT: case PORT_RESISTANCE_RSN_SHORT:
case PORT_RESISTANCE_RSN_OPEN: case PORT_RESISTANCE_RSN_OPEN:
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment