Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions arch/arm/boot/dts/overlays/README
Original file line number Diff line number Diff line change
Expand Up @@ -2247,10 +2247,6 @@ Params: addr Sets the address for the fan controller. Note
i2c-bus Supports all the standard I2C bus selection
parameters - see "dtoverlay -h i2c-bus"

minpwm PWM setting for the fan when the SoC is below
mintemp (range 0-255. default 0)
maxpwm PWM setting for the fan when the SoC is above
maxtemp (range 0-255. default 255)
midtemp Temperature (in millicelsius) at which the fan
begins to speed up (default 50000)

Expand Down
19 changes: 12 additions & 7 deletions arch/arm/boot/dts/overlays/i2c-fan-overlay.dts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@
emc2301: emc2301@2f {
compatible = "microchip,emc2301", "microchip,emc2305";
reg = <0x2f>;
#cooling-cells = <0x02>;
#pwm-cells = <3>;

fan0: fan@0 {
reg = <0x0>;
pwms = <&emc2301 26000 0 1>;
#cooling-cells = <2>;
};

};
};
};
Expand Down Expand Up @@ -52,26 +59,24 @@
__overlay__ {
map0: map0 {
trip = <&fanmid0>;
cooling-device = <&emc2301 2 6>;
cooling-device = <&fan0 2 6>;
};
map1: map1 {
trip = <&fanmax0>;
cooling-device = <&emc2301 7 THERMAL_NO_LIMIT>;
cooling-device = <&fan0 7 THERMAL_NO_LIMIT>;
};
};
};

__overrides__ {
addr = <&emc2301>,"reg:0";
minpwm = <&emc2301>,"emc2305,pwm-min.0";
maxpwm = <&emc2301>,"emc2305,pwm-max.0";
midtemp = <&fanmid0>,"temperature:0";
midtemp_hyst = <&fanmid0>,"hysteresis:0";
maxtemp = <&fanmax0>,"temperature:0";
maxtemp_hyst = <&fanmax0>,"hysteresis:0";

emc2301 = <0>,"+0",
<&map0>,"cooling-device:0=",<&emc2301>,
<&map1>,"cooling-device:0=",<&emc2301>;
<&map0>,"cooling-device:0=",<&fan0>,
<&map1>,"cooling-device:0=",<&fan0>;
};
};
104 changes: 6 additions & 98 deletions drivers/hwmon/emc2305.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ struct emc2305_data {
bool pwm_separate;
s16 pwm_shutdown[EMC2305_PWM_MAX];
u8 pwm_min[EMC2305_PWM_MAX];
u8 pwm_max;
u16 pwm_freq[EMC2305_PWM_MAX];
struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
};
Expand Down Expand Up @@ -294,7 +293,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
struct i2c_client *client = data->client;
int ret;

if (val < data->pwm_min[channel] || val > data->pwm_max)
if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
return -EINVAL;

ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
Expand All @@ -305,49 +304,6 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
return 0;
}

static int emc2305_get_tz_of(struct device *dev)
{
struct device_node *np = dev->of_node;
struct emc2305_data *data = dev_get_drvdata(dev);
int ret = 0;
u8 val;
int i;

/* OF parameters are optional - overwrite default setting
* if some of them are provided.
*/

ret = of_property_read_u8(np, "emc2305,cooling-levels", &val);
if (!ret)
data->max_state = val;
else if (ret != -EINVAL)
return ret;

ret = of_property_read_u8(np, "emc2305,pwm-max", &val);
if (!ret)
data->pwm_max = val;
else if (ret != -EINVAL)
return ret;

ret = of_property_read_u8(np, "emc2305,pwm-min", &val);
if (!ret)
for (i = 0; i < EMC2305_PWM_MAX; i++)
data->pwm_min[i] = val;
else if (ret != -EINVAL)
return ret;

/* Not defined or 0 means one thermal zone over all cooling devices.
* Otherwise - separated thermal zones for each PWM channel.
*/
ret = of_property_read_u8(np, "emc2305,pwm-channel", &val);
if (!ret)
data->pwm_separate = (val != 0);
else if (ret != -EINVAL)
return ret;

return 0;
}

static int emc2305_set_single_tz(struct device *dev, struct device_node *fan_node, int idx)
{
struct emc2305_data *data = dev_get_drvdata(dev);
Expand All @@ -357,16 +313,10 @@ static int emc2305_set_single_tz(struct device *dev, struct device_node *fan_nod
cdev_idx = (idx) ? idx - 1 : 0;
pwm = data->pwm_min[cdev_idx];

if (dev->of_node)
data->cdev_data[cdev_idx].cdev =
devm_thermal_of_child_cooling_device_register(dev, fan_node,
emc2305_fan_name[idx], data,
&emc2305_cooling_ops);
else
data->cdev_data[cdev_idx].cdev =
thermal_cooling_device_register(emc2305_fan_name[idx],
data,
&emc2305_cooling_ops);
data->cdev_data[cdev_idx].cdev =
devm_thermal_of_child_cooling_device_register(dev, fan_node,
emc2305_fan_name[idx], data,
&emc2305_cooling_ops);

if (IS_ERR(data->cdev_data[cdev_idx].cdev)) {
dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]);
Expand Down Expand Up @@ -399,19 +349,6 @@ static int emc2305_set_single_tz(struct device *dev, struct device_node *fan_nod
return 0;
}

static void emc2305_unset_tz(struct device *dev)
{
struct emc2305_data *data = dev_get_drvdata(dev);
int i;

/* Unregister cooling device. */
if (!dev->of_node) {
for (i = 0; i < EMC2305_PWM_MAX; i++)
if (data->cdev_data[i].cdev)
thermal_cooling_device_unregister(data->cdev_data[i].cdev);
}
}

static int emc2305_set_tz(struct device *dev)
{
struct emc2305_data *data = dev_get_drvdata(dev);
Expand All @@ -423,13 +360,9 @@ static int emc2305_set_tz(struct device *dev)
for (i = 0; i < data->pwm_num; i++) {
ret = emc2305_set_single_tz(dev, dev->of_node, i + 1);
if (ret)
goto thermal_cooling_device_register_fail;
return ret;
}
return 0;

thermal_cooling_device_register_fail:
emc2305_unset_tz(dev);
return ret;
}

static umode_t
Expand Down Expand Up @@ -748,7 +681,6 @@ static int emc2305_probe(struct i2c_client *client)
data->pwm_min[i] = pdata->pwm_min[i];
data->pwm_freq[i] = pdata->pwm_freq[i];
}
data->pwm_max = EMC2305_FAN_MAX;
} else {
data->max_state = EMC2305_FAN_MAX_STATE;
data->pwm_separate = false;
Expand All @@ -758,24 +690,12 @@ static int emc2305_probe(struct i2c_client *client)
data->pwm_min[i] = EMC2305_FAN_MIN;
data->pwm_freq[i] = base_freq_table[3];
}
data->pwm_max = EMC2305_FAN_MAX;
if (dev->of_node) {
ret = emc2305_get_tz_of(dev);
if (ret < 0)
return ret;
}
}
} else {
data->max_state = EMC2305_FAN_MAX_STATE;
data->pwm_separate = false;
for (i = 0; i < EMC2305_PWM_MAX; i++)
data->pwm_min[i] = EMC2305_FAN_MIN;
data->pwm_max = EMC2305_FAN_MAX;
if (dev->of_node) {
ret = emc2305_get_tz_of(dev);
if (ret < 0)
return ret;
}
}

data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
Expand Down Expand Up @@ -851,29 +771,17 @@ static void emc2305_shutdown(struct i2c_client *client)

static const struct of_device_id of_emc2305_match_table[] = {
{ .compatible = "microchip,emc2305", },
{ .compatible = "microchip,emc2303", },
{ .compatible = "microchip,emc2302", },
{ .compatible = "microchip,emc2301", },
{},
};
MODULE_DEVICE_TABLE(of, of_emc2305_match_table);

static void emc2305_remove(struct i2c_client *client)
{
struct device *dev = &client->dev;

if (IS_REACHABLE(CONFIG_THERMAL))
emc2305_unset_tz(dev);
}

static struct i2c_driver emc2305_driver = {
.driver = {
.name = "emc2305",
.of_match_table = of_emc2305_match_table,
},
.probe = emc2305_probe,
.shutdown = emc2305_shutdown,
.remove = emc2305_remove,
.id_table = emc2305_ids,
};

Expand Down
Loading