Mnemoc, have you checked and merged this yet?
Olliver On 01/27/14 20:25, Patrick Wood wrote:
Enable the internal thermal monitoring support of AXP20X chips Cherry-picked from: https://github.com/cubieboard/linux-sunxi/commit/e4144b3ce62b1d7014fee36b84bc65c812469822 Creates the sysfs file temp1_input in the sunxi-i2c tree that reports the AXP's temperature in degrees C. According to the AXP202's datasheet, this port outputs a 12-bit value where 0x000 == -144.7C and 0xfff == 264.8C in 0.1 degree C increments. Signed-off-by: LABBE Corentin <clabbe.montj...@gmail.com> Signed-off-by: Hans de Goede <hdego...@redhat.com> Signed-off-by: Patrick Wood <patrickhw...@gmail.com> --- drivers/power/axp_power/Kconfig | 5 ++ drivers/power/axp_power/axp-mfd.c | 7 +++ drivers/power/axp_power/axp20-mfd.h | 112 +++++++++++++++++++++++++++++++++++ include/linux/mfd/axp-mfd.h | 7 +++ 4 files changed, 130 insertions(+) diff --git a/drivers/power/axp_power/Kconfig b/drivers/power/axp_power/Kconfig index 039679f..b76f517 100644 --- a/drivers/power/axp_power/Kconfig +++ b/drivers/power/axp_power/Kconfig @@ -36,4 +36,9 @@ config AXP_CHGCHANGE bool "AXP charging current set when suspend\resume\shutdown" default y +config AXP_HWMON + depends on HWMON + bool "Enable the internal thermal monitoring support of AXP20X chips" + default y + endif # !AW_AXP diff --git a/drivers/power/axp_power/axp-mfd.c b/drivers/power/axp_power/axp-mfd.c index 9af0257..cfa894a 100644 --- a/drivers/power/axp_power/axp-mfd.c +++ b/drivers/power/axp_power/axp-mfd.c @@ -363,6 +363,13 @@ static int __devexit axp_mfd_remove(struct i2c_client *client) pm_power_off = NULL; axp = NULL; +#ifdef CONFIG_AXP_HWMON + if (chip->itm_enabled == 1) { + hwmon_device_unregister(chip->hwmon_dev); + sysfs_remove_group(&client->dev.kobj, &axp20_group); + } +#endif + axp_mfd_remove_subdevs(chip); kfree(chip); return 0; diff --git a/drivers/power/axp_power/axp20-mfd.h b/drivers/power/axp_power/axp20-mfd.h index 1c7a41b..214856e 100644 --- a/drivers/power/axp_power/axp20-mfd.h +++ b/drivers/power/axp_power/axp20-mfd.h @@ -22,6 +22,83 @@ #include "axp-rw.h" +#ifdef CONFIG_AXP_HWMON + +#include <linux/hwmon-sysfs.h> +#include <linux/hwmon.h> +#include <linux/err.h> + +static struct axp_mfd_chip *axp20_update_device(struct device *dev); + +static ssize_t +show_temp(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); + struct axp_mfd_chip *data = axp20_update_device(dev); + if (attr->index == 1) + return sprintf(buf, "264800\n"); + if (attr->index == 2) + return sprintf(buf, "-144700\n"); + return sprintf(buf, "%d\n", data->temperature * 100); +} + + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); +static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, 1); +static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO, show_temp, NULL, 2); + +static struct attribute *axp20_attributes[] = { + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_min.dev_attr.attr, + &sensor_dev_attr_temp1_max.dev_attr.attr, + NULL +}; + +static const struct attribute_group axp20_group = { + .attrs = axp20_attributes, +}; + + +/* + * * function that update the status of the chips (temperature) + * */ +static struct axp_mfd_chip *axp20_update_device(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct axp_mfd_chip *data = i2c_get_clientdata(client); + int err; + u8 high, low; + + mutex_lock(&data->lock); + + if (time_after(jiffies, data->last_updated + HZ * 2) + || !data->valid) { + dev_dbg(&client->dev, "Updating axp20 data\n"); + /* AXP202 datasheet page 25, 0x000 means -144.7, + * 0xfff means 264.8, 4096 steps of 0.1 degress */ + err = __axp_read(client, 0x5E, &high); + if (err) { + dev_err(dev, "AXP Error while reading high\n"); + high = 0; + } + + err = __axp_read(client, 0x5F, &low); + if (err) { + dev_err(dev, "AXP Error while reading low\n"); + low = 0; + } + + data->temperature = -1447 + ((high << 4) + (low && 0x0F)); + data->last_updated = jiffies; + data->valid = 1; + } + + mutex_unlock(&data->lock); + return data; +} + +#endif + static int __devinit axp20_init_chip(struct axp_mfd_chip *chip) { @@ -33,6 +110,9 @@ static int __devinit axp20_init_chip(struct axp_mfd_chip *chip) POWER20_INTSTS3, 0xff, POWER20_INTSTS4, 0xff, POWER20_INTSTS5, 0xff }; int err; +#ifdef CONFIG_AXP_HWMON + u8 enabled; +#endif /*read chip id*/ err = __axp_read(chip->client, POWER20_IC_TYPE, &chip_id); if (err) { @@ -51,7 +131,39 @@ static int __devinit axp20_init_chip(struct axp_mfd_chip *chip) dev_info(chip->dev, "AXP (CHIP ID: 0x%02x) detected\n", chip_id); chip->type = AXP20; +#ifdef CONFIG_AXP_HWMON + err = __axp_read(chip->client, 0x83, &enabled); + if (err) { + dev_info(chip->dev, "AXP Cannot get internal temperature monitoring status\n"); + return err; + } + if ((enabled & 0x80) > 0) { + chip->itm_enabled = 1; + dev_info(chip->dev, "AXP internal temperature monitoring enabled\n"); + + /* Register sysfs hooks */ + err = sysfs_create_group(&chip->client->dev.kobj, &axp20_group); + if (err) + return err; + + chip->hwmon_dev = hwmon_device_register(&chip->client->dev); + if (IS_ERR(chip->hwmon_dev)) { + err = PTR_ERR(chip->hwmon_dev); + goto exit_remove_files; + } + } else { + dev_info(chip->dev, "AXP internal temperature monitoring disabled\n"); + /* TODO enable it ?*/ + chip->itm_enabled = 0; + } +#endif + return 0; +#ifdef CONFIG_AXP_HWMON +exit_remove_files: + sysfs_remove_group(&chip->client->dev.kobj, &axp20_group); + return err; +#endif } static int axp20_disable_irqs(struct axp_mfd_chip *chip, uint64_t irqs) diff --git a/include/linux/mfd/axp-mfd.h b/include/linux/mfd/axp-mfd.h index 2511473..6e6843d 100644 --- a/include/linux/mfd/axp-mfd.h +++ b/include/linux/mfd/axp-mfd.h @@ -131,6 +131,13 @@ struct axp_mfd_chip { struct work_struct irq_work; struct blocking_notifier_head notifier_list; +#ifdef CONFIG_AXP_HWMON + s16 temperature; /* range from -1447 to 2648 */ + unsigned long last_updated; /* in jiffies */ + char valid; /* zero until following fields are valid */ + struct device *hwmon_dev; + char itm_enabled; +#endif }; struct axp_mfd_chip_ops {
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.