mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
hwmon: emc2305: fixups for driver submitted to mailing lists
The driver had a number of issues, checkpatch warnings/errors, and other limitations, so fix these up to make it usable. Signed-off-by: Phil Elwell <phil@raspberrypi.com> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
This commit is contained in:
@@ -15,12 +15,13 @@
|
|||||||
static const unsigned short
|
static const unsigned short
|
||||||
emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END };
|
emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_END };
|
||||||
|
|
||||||
|
#define EMC2305_REG_FAN_STATUS 0x24
|
||||||
|
#define EMC2305_REG_FAN_STALL_STATUS 0x25
|
||||||
#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
|
#define EMC2305_REG_DRIVE_FAIL_STATUS 0x27
|
||||||
#define EMC2305_REG_VENDOR 0xfe
|
#define EMC2305_REG_VENDOR 0xfe
|
||||||
#define EMC2305_FAN_MAX 0xff
|
#define EMC2305_FAN_MAX 0xff
|
||||||
#define EMC2305_FAN_MIN 0x00
|
#define EMC2305_FAN_MIN 0x00
|
||||||
#define EMC2305_FAN_MAX_STATE 10
|
#define EMC2305_FAN_MAX_STATE 10
|
||||||
#define EMC2305_DEVICE 0x34
|
|
||||||
#define EMC2305_VENDOR 0x5d
|
#define EMC2305_VENDOR 0x5d
|
||||||
#define EMC2305_REG_PRODUCT_ID 0xfd
|
#define EMC2305_REG_PRODUCT_ID 0xfd
|
||||||
#define EMC2305_TACH_REGS_UNUSE_BITS 3
|
#define EMC2305_TACH_REGS_UNUSE_BITS 3
|
||||||
@@ -39,6 +40,7 @@ emc2305_normal_i2c[] = { 0x27, 0x2c, 0x2d, 0x2e, 0x2f, 0x4c, 0x4d, I2C_CLIENT_EN
|
|||||||
#define EMC2305_RPM_FACTOR 3932160
|
#define EMC2305_RPM_FACTOR 3932160
|
||||||
|
|
||||||
#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
|
#define EMC2305_REG_FAN_DRIVE(n) (0x30 + 0x10 * (n))
|
||||||
|
#define EMC2305_REG_FAN_CFG(n) (0x32 + 0x10 * (n))
|
||||||
#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
|
#define EMC2305_REG_FAN_MIN_DRIVE(n) (0x38 + 0x10 * (n))
|
||||||
#define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
|
#define EMC2305_REG_FAN_TACH(n) (0x3e + 0x10 * (n))
|
||||||
|
|
||||||
@@ -58,6 +60,15 @@ static const struct i2c_device_id emc2305_ids[] = {
|
|||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, emc2305_ids);
|
MODULE_DEVICE_TABLE(i2c, emc2305_ids);
|
||||||
|
|
||||||
|
static const struct of_device_id emc2305_dt_ids[] = {
|
||||||
|
{ .compatible = "microchip,emc2305" },
|
||||||
|
{ .compatible = "microchip,emc2303" },
|
||||||
|
{ .compatible = "microchip,emc2302" },
|
||||||
|
{ .compatible = "microchip,emc2301" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, emc2305_dt_ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @cdev: cooling device;
|
* @cdev: cooling device;
|
||||||
* @curr_state: cooling current state;
|
* @curr_state: cooling current state;
|
||||||
@@ -101,6 +112,7 @@ struct emc2305_data {
|
|||||||
u8 pwm_num;
|
u8 pwm_num;
|
||||||
bool pwm_separate;
|
bool pwm_separate;
|
||||||
u8 pwm_min[EMC2305_PWM_MAX];
|
u8 pwm_min[EMC2305_PWM_MAX];
|
||||||
|
u8 pwm_max;
|
||||||
struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
|
struct emc2305_cdev_data cdev_data[EMC2305_PWM_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -273,7 +285,7 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
|
|||||||
struct i2c_client *client = data->client;
|
struct i2c_client *client = data->client;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (val < data->pwm_min[channel] || val > EMC2305_FAN_MAX)
|
if (val < data->pwm_min[channel] || val > data->pwm_max)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
|
ret = i2c_smbus_write_byte_data(client, EMC2305_REG_FAN_DRIVE(channel), val);
|
||||||
@@ -284,6 +296,49 @@ static int emc2305_set_pwm(struct device *dev, long val, int channel)
|
|||||||
return 0;
|
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;
|
||||||
|
u32 val;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* OF parameters are optional - overwrite default setting
|
||||||
|
* if some of them are provided.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "emc2305,cooling-levels", &val);
|
||||||
|
if (!ret)
|
||||||
|
data->max_state = (u8)val;
|
||||||
|
else if (ret != -EINVAL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "emc2305,pwm-max", &val);
|
||||||
|
if (!ret)
|
||||||
|
data->pwm_max = (u8)val;
|
||||||
|
else if (ret != -EINVAL)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "emc2305,pwm-min", &val);
|
||||||
|
if (!ret)
|
||||||
|
for (i = 0; i < EMC2305_PWM_MAX; i++)
|
||||||
|
data->pwm_min[i] = (u8)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_u32(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, int idx)
|
static int emc2305_set_single_tz(struct device *dev, int idx)
|
||||||
{
|
{
|
||||||
struct emc2305_data *data = dev_get_drvdata(dev);
|
struct emc2305_data *data = dev_get_drvdata(dev);
|
||||||
@@ -572,11 +627,18 @@ static int emc2305_probe(struct i2c_client *client, const struct i2c_device_id *
|
|||||||
data->pwm_separate = pdata->pwm_separate;
|
data->pwm_separate = pdata->pwm_separate;
|
||||||
for (i = 0; i < EMC2305_PWM_MAX; i++)
|
for (i = 0; i < EMC2305_PWM_MAX; i++)
|
||||||
data->pwm_min[i] = pdata->pwm_min[i];
|
data->pwm_min[i] = pdata->pwm_min[i];
|
||||||
|
data->pwm_max = EMC2305_FAN_MAX;
|
||||||
} else {
|
} else {
|
||||||
data->max_state = EMC2305_FAN_MAX_STATE;
|
data->max_state = EMC2305_FAN_MAX_STATE;
|
||||||
data->pwm_separate = false;
|
data->pwm_separate = false;
|
||||||
for (i = 0; i < EMC2305_PWM_MAX; i++)
|
for (i = 0; i < EMC2305_PWM_MAX; i++)
|
||||||
data->pwm_min[i] = EMC2305_FAN_MIN;
|
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,
|
data->hwmon_dev = devm_hwmon_device_register_with_info(dev, "emc2305", data,
|
||||||
@@ -597,6 +659,12 @@ static int emc2305_probe(struct i2c_client *client, const struct i2c_device_id *
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Acknowledge any existing faults. Stops the device responding on the
|
||||||
|
* SMBus alert address.
|
||||||
|
*/
|
||||||
|
i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STALL_STATUS);
|
||||||
|
i2c_smbus_read_byte_data(client, EMC2305_REG_FAN_STATUS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -612,6 +680,7 @@ static struct i2c_driver emc2305_driver = {
|
|||||||
.class = I2C_CLASS_HWMON,
|
.class = I2C_CLASS_HWMON,
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "emc2305",
|
.name = "emc2305",
|
||||||
|
.of_match_table = emc2305_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = emc2305_probe,
|
.probe = emc2305_probe,
|
||||||
.remove = emc2305_remove,
|
.remove = emc2305_remove,
|
||||||
|
|||||||
Reference in New Issue
Block a user