* [RFC V1 0/3] da9063: Addition of HWMON support for DA9063
@ 2014-03-23 20:37 Opensource [Steve Twiss]
2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss]
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Opensource [Steve Twiss] @ 2014-03-23 20:37 UTC (permalink / raw)
To: Guenter Roeck, Jean Delvare, Lee Jones, Rob Landley, Samuel Ortiz
Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown,
Philipp Zabel
From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com>
This patch series covers hardware monitoring support for the DA9063 PMIC.
There are three patches in this set:
- Add a new HWMON driver component
- Minor MFD core and platform data changes for HWMON
- Documentation
Thank you,
Steve Twiss, Dialog Semiconductor Ltd.
S Twiss (3):
hwmon: da9063: HWMON driver
mfd: da9063: Add HWMON dependencies
Documentation: hwmon: New information for DA9063
Documentation/hwmon/da9063 | 67 +++++
drivers/hwmon/Kconfig | 10 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/da9063-hwmon.c | 456 ++++++++++++++++++++++++++++++++++
drivers/mfd/da9063-core.c | 13 +-
include/linux/mfd/da9063/core.h | 3 +
include/linux/mfd/da9063/pdata.h | 18 ++
include/linux/mfd/da9063/registers.h | 34 +++
8 files changed, 601 insertions(+), 1 deletion(-)
create mode 100644 Documentation/hwmon/da9063
create mode 100644 drivers/hwmon/da9063-hwmon.c
--
end-of-patch for RFC V1
^ permalink raw reply [flat|nested] 12+ messages in thread* [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-23 20:37 [RFC V1 0/3] da9063: Addition of HWMON support for DA9063 Opensource [Steve Twiss] @ 2014-03-23 20:37 ` Opensource [Steve Twiss] 2014-03-24 3:27 ` Guenter Roeck ` (2 more replies) 2014-03-23 20:37 ` [RFC V1 2/3] mfd: da9063: Add HWMON dependencies Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 3/3] Documentation: hwmon: New information for DA9063 Opensource [Steve Twiss] 2 siblings, 3 replies; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-23 20:37 UTC (permalink / raw) To: Guenter Roeck, Jean Delvare Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Lee Jones, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> Add the HWMON driver for DA9063 Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> --- Checks performed with linux-next/next-20140321/scripts/checkpatch.pl da9063-hwmon.c total: 0 errors, 0 warnings, 456 lines checked Kconfig total: 1 errors, 3 warnings, 1643 lines checked Makefile total: 0 errors, 0 warnings, 154 lines checked registers.h total: 0 errors, 0 warnings, 1066 lines checked There are errors and warning in Kconfig, however they are not caused by this patch. This is the hardware monitor driver component for DA9063 PMIC. The manual measurement allows monitoring of the system voltage VSYS, the auxiliary channels ADCIN1, ADCIN2 and ADCIN3, VBBAT measures of the backup battery voltage and a Tjunc value for the internal junction temperature sensor. This patch also includes the necessary register changes, especially the definitions for ADC_CFG (addr=0xC9) to allow settings for the current sources. Dependencies: The patch in this set titled: "mfd: da9063: Add HWMON dependencies" - The da9063-core.c changes allows for reading the temperature trimming offset value from the PMIC. This used by HWMON in its calculation of the internal junction temperature. - Changes to platform data definitions so that ADCIN[123]_CUR values may be set from outside the driver. This patch applies against linux-next and next-20140321 Regards, Steve Twiss, Dialog Semiconductor Ltd. drivers/hwmon/Kconfig | 10 + drivers/hwmon/Makefile | 1 + drivers/hwmon/da9063-hwmon.c | 456 ++++++++++++++++++++++++++++++++++ include/linux/mfd/da9063/registers.h | 34 +++ 4 files changed, 501 insertions(+) create mode 100644 drivers/hwmon/da9063-hwmon.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index f288b60..68aa886 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -391,6 +391,16 @@ config SENSORS_DA9055 This driver can also be built as a module. If so, the module will be called da9055-hwmon. +config SENSORS_DA9063 + tristate "Dialog Semiconductor DA9063" + depends on MFD_DA9063 + help + If you say yes here you get support for the hardware + monitoring features of the DA9063 Power Management IC. + + This driver can also be built as a module. If so, the module + will be called da9063-hwmon. + config SENSORS_I5K_AMB tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" depends on PCI diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index c48f987..4174b07 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o +obj-$(CONFIG_SENSORS_DA9063) += da9063-hwmon.o obj-$(CONFIG_SENSORS_DME1737) += dme1737.o obj-$(CONFIG_SENSORS_DS620) += ds620.o obj-$(CONFIG_SENSORS_DS1621) += ds1621.o diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c new file mode 100644 index 0000000..7756cb2 --- /dev/null +++ b/drivers/hwmon/da9063-hwmon.c @@ -0,0 +1,456 @@ +/* da9063-hwmon.c - Hardware monitor support for DA9063 + * Copyright (C) 2014 Dialog Semiconductor Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/hwmon.h> +#include <linux/hwmon-sysfs.h> +#include <linux/regmap.h> +#include <linux/mfd/da9063/core.h> +#include <linux/mfd/da9063/pdata.h> + +#define DA9063_ADC_RES (1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS)) +#define DA9063_ADC_MAX (DA9063_ADC_RES - 1) +#define DA9063_2V5 2500 +#define DA9063_5V0 5000 +#define DA9063_5V5 5500 +#define DA9063_TJUNC_M -420 +#define DA9063_TJUNC_C -812 +#define DA9063_VBBAT_M 2048 + +enum da9063_adc { + DA9063_CHAN_VSYS = DA9063_ADC_MUX_VSYS, + DA9063_CHAN_ADCIN1 = DA9063_ADC_MUX_ADCIN1, + DA9063_CHAN_ADCIN2 = DA9063_ADC_MUX_ADCIN2, + DA9063_CHAN_ADCIN3 = DA9063_ADC_MUX_ADCIN3, + DA9063_CHAN_TJUNC = DA9063_ADC_MUX_T_SENSE, + DA9063_CHAN_VBBAT = DA9063_ADC_MUX_VBBAT, + DA9063_CHAN_LDO_G1 = DA9063_ADC_MUX_LDO_G1, + DA9063_CHAN_LDO_G2 = DA9063_ADC_MUX_LDO_G2, + DA9063_CHAN_LDO_G3 = DA9063_ADC_MUX_LDO_G3 +}; + +struct da9063_hwmon { + struct da9063 *da9063; + struct device *classdev; + struct mutex hwmon_mutex; + struct completion adc_ready; + signed char tjunc_offset; + int irq; +}; + +static int da9063_adc_convert(struct da9063_hwmon *hwmon, int channel, + int *value) +{ + int val = *value; + int ret = 0; + + switch (channel) { + case DA9063_CHAN_ADCIN1: + case DA9063_CHAN_ADCIN2: + case DA9063_CHAN_ADCIN3: + val = (DA9063_2V5 * val) / DA9063_ADC_MAX; + break; + case DA9063_CHAN_VSYS: + val = ((DA9063_5V5 - DA9063_2V5) * val) / DA9063_ADC_MAX + + DA9063_2V5; + break; + case DA9063_CHAN_TJUNC: + val -= hwmon->tjunc_offset; + val = (DA9063_TJUNC_M * (val + DA9063_TJUNC_C)) >> 10; + break; + case DA9063_CHAN_VBBAT: + val = (DA9063_5V0 * val) / DA9063_ADC_MAX; + break; + default: + ret = -EINVAL; + goto err_convert; + } + + *value = val; +err_convert: + return ret; +} + +static int da9063_adc_current_switch(struct da9063_hwmon *hwmon, int channel, + bool on) +{ + int ret; + unsigned int val; + unsigned int mask; + + switch (channel) { + case DA9063_CHAN_ADCIN1: + mask = DA9063_ADC_AD1_ISRC_EN; + break; + case DA9063_CHAN_ADCIN2: + mask = DA9063_ADC_AD2_ISRC_EN; + break; + case DA9063_CHAN_ADCIN3: + mask = DA9063_ADC_AD3_ISRC_EN; + break; + default: + ret = -EINVAL; + goto err_switch; + } + + if (on) + val = mask; + else + val = ~mask; + + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CONT, + mask, val); +err_switch: + return ret; + +} + +static int da9063_adc_manual_read(struct da9063_hwmon *hwmon, int channel) +{ + int ret; + unsigned char val; + unsigned char data[2]; + int adc_man; + + mutex_lock(&hwmon->hwmon_mutex); + + init_completion(&hwmon->adc_ready); + + val = (channel & DA9063_ADC_MUX_MASK) | DA9063_ADC_MAN; + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, + DA9063_ADC_MUX_MASK | DA9063_ADC_MAN, val); + if (ret < 0) + goto err_mread; + + ret = wait_for_completion_timeout(&hwmon->adc_ready, + msecs_to_jiffies(1000)); + if (ret == 0) { + ret = -ETIMEDOUT; + goto err_mread; + } + + ret = regmap_read(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, &adc_man); + if (ret < 0) + goto err_mread; + + /* data value is not ready */ + if (adc_man & DA9063_ADC_MAN == 0) { + ret = -EINVAL; + goto err_mread; + } + + ret = regmap_bulk_read(hwmon->da9063->regmap, + DA9063_REG_ADC_RES_L, data, 2); + if (ret < 0) + goto err_mread; + + ret = (data[0] & DA9063_ADC_RES_L_MASK) >> DA9063_ADC_RES_L_SHIFT; + ret |= data[1] << DA9063_ADC_RES_L_BITS; +err_mread: + mutex_unlock(&hwmon->hwmon_mutex); + return ret; +} + +static irqreturn_t da9063_hwmon_irq_handler(int irq, void *irq_data) +{ + struct da9063_hwmon *hwmon = irq_data; + complete(&hwmon->adc_ready); + return IRQ_HANDLED; +} + +static ssize_t da9063_adc_read(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct da9063_hwmon *hwmon = dev_get_drvdata(dev); + int channel = to_sensor_dev_attr(devattr)->index; + int val; + int ret; + + switch (channel) { + case DA9063_CHAN_ADCIN1: + case DA9063_CHAN_ADCIN2: + case DA9063_CHAN_ADCIN3: + /* fallthrough for ADC measures */ + ret = da9063_adc_current_switch(hwmon, channel, true); + if (ret < 0) + goto err_read; + + val = da9063_adc_manual_read(hwmon, channel); + if (val < 0) { + ret = val; + if (ret == -EINVAL) + dev_err(dev, "Conversion was not completed\n"); + else + dev_err(dev, "ADC read error %d\n", ret); + goto err_read; + } + + ret = da9063_adc_current_switch(hwmon, channel, false); + if (ret < 0) { + dev_err(dev, "Could not switch current\n"); + goto err_read; + } + break; + + case DA9063_CHAN_VSYS: + case DA9063_CHAN_TJUNC: + case DA9063_CHAN_VBBAT: + /* fallthrough for internal measures */ + val = da9063_adc_manual_read(hwmon, channel); + if (val < 0) { + dev_err(dev, "ADC read error %d\n", val); + return val; + } + break; + + default: + /* error case */ + ret = -EINVAL; + goto err_read; + } + + ret = da9063_adc_convert(hwmon, channel, &val); + if (ret < 0) { + dev_err(dev, "Failed to convert ADC value %d\n", ret); + goto err_read; + } + + return sprintf(buf, "%d\n", val); +err_read: + return ret; +} + +static ssize_t da9063_show_name(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, DA9063_DRVNAME_HWMON "\n"); +} + +static ssize_t da9063_show_label(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + int channel = to_sensor_dev_attr(devattr)->index; + char *label; + + switch (channel) { + case DA9063_CHAN_VSYS: + label = "VSYS"; + break; + case DA9063_CHAN_ADCIN1: + label = "ADCIN1"; + break; + case DA9063_CHAN_ADCIN2: + label = "ADCIN2"; + break; + case DA9063_CHAN_ADCIN3: + label = "ADCIN3"; + break; + case DA9063_CHAN_TJUNC: + label = "TJUNC"; + break; + case DA9063_CHAN_VBBAT: + label = "VBBAT"; + break; + default: + label = "UNKNOWN"; + } + + return sprintf(buf, "%s\n", label); +} + +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_VSYS); +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_VSYS); + +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_ADCIN1); +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_ADCIN1); + +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_ADCIN2); +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_ADCIN2); + +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_ADCIN3); +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_ADCIN3); + +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_VBBAT); +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_VBBAT); + +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, + da9063_adc_read, NULL, DA9063_CHAN_TJUNC); + +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, + da9063_show_label, NULL, DA9063_CHAN_TJUNC); + +static DEVICE_ATTR(name, S_IRUGO, da9063_show_name, NULL); + +static struct attribute *da9063_attributes[] = { + &dev_attr_name.attr, + &sensor_dev_attr_in0_input.dev_attr.attr, + &sensor_dev_attr_in0_label.dev_attr.attr, + &sensor_dev_attr_in1_input.dev_attr.attr, + &sensor_dev_attr_in1_label.dev_attr.attr, + &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_label.dev_attr.attr, + &sensor_dev_attr_in3_input.dev_attr.attr, + &sensor_dev_attr_in3_label.dev_attr.attr, + &sensor_dev_attr_in4_input.dev_attr.attr, + &sensor_dev_attr_in4_label.dev_attr.attr, + &sensor_dev_attr_temp1_input.dev_attr.attr, + &sensor_dev_attr_temp1_label.dev_attr.attr, + NULL +}; + +static const struct attribute_group da9063_attr_group = { + .attrs = da9063_attributes, +}; + +static int da9063_hwmon_probe(struct platform_device *pdev) +{ + struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); + struct da9063_pdata *pdata = da9063->dev->platform_data; + struct da9063_hwmon *hwmon; + int ret; + unsigned int val; + + hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9063_hwmon), + GFP_KERNEL); + if (!hwmon) + return -ENOMEM; + + mutex_init(&hwmon->hwmon_mutex); + init_completion(&hwmon->adc_ready); + hwmon->da9063 = da9063; + + /* enable the ADC functions for GPIO 0,1,2 */ + val = (DA9063_GPIO0_PIN_ADCIN1 << DA9063_GPIO0_PIN_MASK_SHIFT | + DA9063_GPIO1_PIN_ADCIN2_COMP << DA9063_GPIO1_PIN_MASK_SHIFT); + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_0_1, + (DA9063_GPIO0_PIN_MASK | + DA9063_GPIO1_PIN_MASK), val); + if (ret < 0) { + dev_err(&pdev->dev, + "Failed to alter the ADCIN 1,2 bits for the GPIO 0,1 register\n"); + return -EIO; + } + + val = DA9063_GPIO2_PIN_ADCIN3 << DA9063_GPIO2_PIN_MASK_SHIFT; + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_2_3, + DA9063_GPIO2_PIN_MASK, val); + if (ret < 0) { + dev_err(&pdev->dev, + "Failed to alter the ADCIN 3 bits for the GPIO 2,3 register\n"); + return -EIO; + } + + /* debounce ADC I settings */ + val = (DA9063_ADCIN1_DEB_ON << DA9063_REG_ADCIN1_DEB_SHIFT | + DA9063_ADCIN2_DEB_ON << DA9063_REG_ADCIN2_DEB_SHIFT | + DA9063_ADCIN3_DEB_ON << DA9063_REG_ADCIN3_DEB_SHIFT); + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, + (DA9063_REG_ADCIN1_DEB_MASK | + DA9063_REG_ADCIN2_DEB_MASK | + DA9063_REG_ADCIN3_DEB_MASK), val); + if (ret < 0) { + dev_err(&pdev->dev, + "Failed to alter the ADC configuration register\n"); + return -EIO; + } + + /* set up the current configurations */ + val = (pdata->hwmon_pdata->adcin1_cur << DA9063_REG_ADCIN1_CUR_SHIFT | + pdata->hwmon_pdata->adcin2_cur << DA9063_REG_ADCIN2_CUR_SHIFT | + pdata->hwmon_pdata->adcin3_cur << DA9063_REG_ADCIN3_CUR_SHIFT); + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, + (DA9063_REG_ADCIN1_CUR_MASK | + DA9063_REG_ADCIN2_CUR_MASK | + DA9063_REG_ADCIN3_CUR_MASK), val); + + ret = regmap_read(da9063->regmap, DA9063_REG_ADC_CFG, &val); + if (ret < 0) { + dev_err(&pdev->dev, + "Failed to read read the ADC configuration register\n"); + return -EIO; + } + + hwmon->irq = platform_get_irq_byname(pdev, DA9063_DRVNAME_HWMON); + if (hwmon->irq < 0) + return hwmon->irq; + + ret = devm_request_threaded_irq(&pdev->dev, hwmon->irq, NULL, + da9063_hwmon_irq_handler, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "HWMON", hwmon); + if (ret) { + dev_err(&pdev->dev, "Failed to request IRQ.\n"); + return ret; + } + + platform_set_drvdata(pdev, hwmon); + + /* set trim temperature offset to value read at startup */ + hwmon->tjunc_offset = (signed char)hwmon->da9063->t_offset; + + ret = sysfs_create_group(&pdev->dev.kobj, &da9063_attr_group); + if (ret) + return ret; + + hwmon->classdev = hwmon_device_register(&pdev->dev); + if (IS_ERR(hwmon->classdev)) { + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); + return PTR_ERR(hwmon->classdev); + } + + return 0; +} + +static int da9063_hwmon_remove(struct platform_device *pdev) +{ + struct da9063_hwmon *hwmon = platform_get_drvdata(pdev); + + hwmon_device_unregister(hwmon->classdev); + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); + + return 0; +} + +static struct platform_driver da9063_hwmon_driver = { + .probe = da9063_hwmon_probe, + .remove = da9063_hwmon_remove, + .driver = { + .name = DA9063_DRVNAME_HWMON, + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(da9063_hwmon_driver); + +MODULE_DESCRIPTION("Hardware monitor support device driver for Dialog DA9063"); +MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DA9063_DRVNAME_HWMON); diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h index 09a85c6..922371b 100644 --- a/include/linux/mfd/da9063/registers.h +++ b/include/linux/mfd/da9063/registers.h @@ -474,6 +474,7 @@ /* DA9063_REG_GPIO_0_1 (addr=0x15) */ #define DA9063_GPIO0_PIN_MASK 0x03 +#define DA9063_GPIO0_PIN_MASK_SHIFT 0 #define DA9063_GPIO0_PIN_ADCIN1 0x00 #define DA9063_GPIO0_PIN_GPI 0x01 #define DA9063_GPIO0_PIN_GPO_OD 0x02 @@ -485,6 +486,7 @@ #define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04 #define DA9063_GPIO0_NO_WAKEUP 0x08 #define DA9063_GPIO1_PIN_MASK 0x30 +#define DA9063_GPIO1_PIN_MASK_SHIFT 4 #define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00 #define DA9063_GPIO1_PIN_GPI 0x10 #define DA9063_GPIO1_PIN_GPO_OD 0x20 @@ -498,6 +500,7 @@ /* DA9063_REG_GPIO_2_3 (addr=0x16) */ #define DA9063_GPIO2_PIN_MASK 0x03 +#define DA9063_GPIO2_PIN_MASK_SHIFT 0 #define DA9063_GPIO2_PIN_ADCIN3 0x00 #define DA9063_GPIO2_PIN_GPI 0x01 #define DA9063_GPIO2_PIN_GPO_PSS 0x02 @@ -813,6 +816,7 @@ #define DA9063_VSYS_VAL_BASE 0x00 /* DA9063_REG_ADC_RES_L (addr=0x37) */ +#define DA9063_ADC_RES_L_SHIFT 6 #define DA9063_ADC_RES_L_BITS 2 #define DA9063_ADC_RES_L_MASK 0xC0 @@ -979,6 +983,36 @@ #define DA9063_GPIO_DIM 0x80 #define DA9063_GPIO_PWM_MASK 0x7F +/* DA9063_REG_ADC_CFG (addr=0xC9) */ +#define DA9063_REG_ADCIN1_CUR_MASK 0x03 +#define DA9063_REG_ADCIN1_CUR_SHIFT 0 +#define DA9063_ADCIN1_CUR_1UA 0x00 +#define DA9063_ADCIN1_CUR_2UA 0x01 +#define DA9063_ADCIN1_CUR_10UA 0x02 +#define DA9063_ADCIN1_CUR_40UA 0x03 +#define DA9063_REG_ADCIN2_CUR_MASK 0x0C +#define DA9063_REG_ADCIN2_CUR_SHIFT 2 +#define DA9063_ADCIN2_CUR_1UA 0x00 +#define DA9063_ADCIN2_CUR_2UA 0x01 +#define DA9063_ADCIN2_CUR_10UA 0x02 +#define DA9063_ADCIN2_CUR_40UA 0x03 +#define DA9063_REG_ADCIN3_CUR_MASK 0x10 +#define DA9063_REG_ADCIN3_CUR_SHIFT 4 +#define DA9063_ADCIN3_CUR_10UA 0x00 +#define DA9063_ADCIN3_CUR_40UA 0x01 +#define DA9063_REG_ADCIN1_DEB_MASK 0x20 +#define DA9063_REG_ADCIN1_DEB_SHIFT 5 +#define DA9063_ADCIN1_DEB_OFF 0x00 +#define DA9063_ADCIN1_DEB_ON 0x01 +#define DA9063_REG_ADCIN2_DEB_MASK 0x40 +#define DA9063_REG_ADCIN2_DEB_SHIFT 6 +#define DA9063_ADCIN2_DEB_OFF 0x00 +#define DA9063_ADCIN2_DEB_ON 0x01 +#define DA9063_REG_ADCIN3_DEB_MASK 0x80 +#define DA9063_REG_ADCIN3_DEB_SHIFT 7 +#define DA9063_ADCIN3_DEB_OFF 0x00 +#define DA9063_ADCIN3_DEB_ON 0x01 + /* DA9063_REG_CONFIG_H (addr=0x10D) */ #define DA9063_PWM_CLK_MASK 0x01 #define DA9063_PWM_CLK_PWM2MHZ 0x00 -- end-of-patch for RFC V1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] @ 2014-03-24 3:27 ` Guenter Roeck 2014-03-24 3:39 ` Guenter Roeck 2014-03-24 7:52 ` Lee Jones 2 siblings, 0 replies; 12+ messages in thread From: Guenter Roeck @ 2014-03-24 3:27 UTC (permalink / raw) To: Opensource [Steve Twiss], Jean Delvare Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Lee Jones, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz On 03/23/2014 01:37 PM, Opensource [Steve Twiss] wrote: > From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > > Add the HWMON driver for DA9063 > > Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > --- > + > + ret = sysfs_create_group(&pdev->dev.kobj, &da9063_attr_group); > + if (ret) > + return ret; > + > + hwmon->classdev = hwmon_device_register(&pdev->dev); > + if (IS_ERR(hwmon->classdev)) { > + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); > + return PTR_ERR(hwmon->classdev); > + } > + Hi Steve, This looks like an ideal candidate for devm_hwmon_device_register_with_groups(). Can you use that API, please ? Thanks, Guenter ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] 2014-03-24 3:27 ` Guenter Roeck @ 2014-03-24 3:39 ` Guenter Roeck 2014-03-24 7:48 ` Opensource [Steve Twiss] 2014-03-24 7:52 ` Lee Jones 2 siblings, 1 reply; 12+ messages in thread From: Guenter Roeck @ 2014-03-24 3:39 UTC (permalink / raw) To: Opensource [Steve Twiss], Jean Delvare Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Lee Jones, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz On 03/23/2014 01:37 PM, Opensource [Steve Twiss] wrote: > From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > > Add the HWMON driver for DA9063 > > Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > --- > Checks performed with linux-next/next-20140321/scripts/checkpatch.pl > da9063-hwmon.c total: 0 errors, 0 warnings, 456 lines checked > Kconfig total: 1 errors, 3 warnings, 1643 lines checked > Makefile total: 0 errors, 0 warnings, 154 lines checked > registers.h total: 0 errors, 0 warnings, 1066 lines checked > There are errors and warning in Kconfig, however they are not caused > by this patch. > > This is the hardware monitor driver component for DA9063 PMIC. > > The manual measurement allows monitoring of the system voltage > VSYS, the auxiliary channels ADCIN1, ADCIN2 and ADCIN3, VBBAT > measures of the backup battery voltage and a Tjunc value for the > internal junction temperature sensor. > At least this part belongs into the summary. After browsing through patch 2/3, I got suspicious and tried to compile the driver after applying this patch. Here is the result: drivers/hwmon/da9063-hwmon.c: In function 'da9063_adc_manual_read': drivers/hwmon/da9063-hwmon.c:155:2: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses] drivers/hwmon/da9063-hwmon.c: In function 'da9063_hwmon_probe': drivers/hwmon/da9063-hwmon.c:386:14: error: 'struct da9063_pdata' has no member named 'hwmon_pdata' drivers/hwmon/da9063-hwmon.c:387:14: error: 'struct da9063_pdata' has no member named 'hwmon_pdata' drivers/hwmon/da9063-hwmon.c:388:14: error: 'struct da9063_pdata' has no member named 'hwmon_pdata' drivers/hwmon/da9063-hwmon.c:417:50: error: 'struct da9063' has no member named 't_offset' make[1]: *** [drivers/hwmon/da9063-hwmon.o] Error 1 make: *** [drivers/hwmon/da9063-hwmon.ko] Error 2 Please make sure that each patch, if applied one after another, compiles. Patch 1/3 must not depend on patch 2/3. Thanks, Guenter ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-24 3:39 ` Guenter Roeck @ 2014-03-24 7:48 ` Opensource [Steve Twiss] 2014-03-24 9:24 ` Lee Jones 0 siblings, 1 reply; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-24 7:48 UTC (permalink / raw) To: Guenter Roeck, Jean Delvare Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Lee Jones, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz On 24 March 2014 03:39, Guenter Roeck wrote: >On 03/23/2014 01:37 PM, Opensource [Steve Twiss] wrote: >> From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> >> Add the HWMON driver for DA9063 >> >> Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> --- >> Checks performed with linux-next/next-20140321/scripts/checkpatch.pl >> da9063-hwmon.c total: 0 errors, 0 warnings, 456 lines checked >> Kconfig total: 1 errors, 3 warnings, 1643 lines checked >> Makefile total: 0 errors, 0 warnings, 154 lines checked >> registers.h total: 0 errors, 0 warnings, 1066 lines checked >> There are errors and warning in Kconfig, however they are not caused >> by this patch. >> >> This is the hardware monitor driver component for DA9063 PMIC. >> >> The manual measurement allows monitoring of the system voltage >> VSYS, the auxiliary channels ADCIN1, ADCIN2 and ADCIN3, VBBAT >> measures of the backup battery voltage and a Tjunc value for the >> internal junction temperature sensor. >> > >At least this part belongs into the summary. > >After browsing through patch 2/3, I got suspicious and tried to compile >the driver after applying this patch. > >Here is the result: > >drivers/hwmon/da9063-hwmon.c: In function 'da9063_adc_manual_read': >drivers/hwmon/da9063-hwmon.c:155:2: warning: suggest parentheses around >comparison in operand of '&' [-Wparentheses] >drivers/hwmon/da9063-hwmon.c: In function 'da9063_hwmon_probe': >drivers/hwmon/da9063-hwmon.c:386:14: error: 'struct da9063_pdata' has no >member named 'hwmon_pdata' >drivers/hwmon/da9063-hwmon.c:387:14: error: 'struct da9063_pdata' has no >member named 'hwmon_pdata' >drivers/hwmon/da9063-hwmon.c:388:14: error: 'struct da9063_pdata' has no >member named 'hwmon_pdata' >drivers/hwmon/da9063-hwmon.c:417:50: error: 'struct da9063' has no member >named 't_offset' >make[1]: *** [drivers/hwmon/da9063-hwmon.o] Error 1 >make: *** [drivers/hwmon/da9063-hwmon.ko] Error 2 > >Please make sure that each patch, if applied one after another, compiles. >Patch 1/3 must not depend on patch 2/3. Hi Guenter, Thank you for this fast response. Ah, the dependencies were not in order. I will check for that in future. I will also look into using the API with devm_hwmon_device_register_with_groups and will resubmit with a RFC V2 later. Thank you, Steve > >Thanks, >Guenter ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-24 7:48 ` Opensource [Steve Twiss] @ 2014-03-24 9:24 ` Lee Jones 0 siblings, 0 replies; 12+ messages in thread From: Lee Jones @ 2014-03-24 9:24 UTC (permalink / raw) To: Opensource [Steve Twiss] Cc: Guenter Roeck, Jean Delvare, David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz [...] > >Please make sure that each patch, if applied one after another, compiles. > >Patch 1/3 must not depend on patch 2/3. > > Hi Guenter, > > Thank you for this fast response. > > Ah, the dependencies were not in order. I will check for that in future. > > I will also look into using the API with devm_hwmon_device_register_with_groups > and will resubmit with a RFC V2 later. If there are inter-{patch,subsystem} dependencies within a patch-set you need to let us know so we can ensure the patches are kept together. If not they are likely to be sucked into their respective subsystem trees and will break bisectability when they hit Mainline. -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] 2014-03-24 3:27 ` Guenter Roeck 2014-03-24 3:39 ` Guenter Roeck @ 2014-03-24 7:52 ` Lee Jones 2014-03-24 8:12 ` Opensource [Steve Twiss] 2 siblings, 1 reply; 12+ messages in thread From: Lee Jones @ 2014-03-24 7:52 UTC (permalink / raw) To: Opensource [Steve Twiss] Cc: Guenter Roeck, Jean Delvare, David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz > From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > > Add the HWMON driver for DA9063 > > Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > --- > > drivers/hwmon/Kconfig | 10 + > drivers/hwmon/Makefile | 1 + > drivers/hwmon/da9063-hwmon.c | 456 ++++++++++++++++++++++++++++++++++ > include/linux/mfd/da9063/registers.h | 34 +++ I'd prefer to see all values in hex, but this probably a preference thing rather than something which would prevent acceptance. For the MFD header changes: Acked-by: Lee Jones <lee.jones@linaro.org> > 4 files changed, 501 insertions(+) > create mode 100644 drivers/hwmon/da9063-hwmon.c > > diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig > index f288b60..68aa886 100644 > --- a/drivers/hwmon/Kconfig > +++ b/drivers/hwmon/Kconfig > @@ -391,6 +391,16 @@ config SENSORS_DA9055 > This driver can also be built as a module. If so, the module > will be called da9055-hwmon. > > +config SENSORS_DA9063 > + tristate "Dialog Semiconductor DA9063" > + depends on MFD_DA9063 > + help > + If you say yes here you get support for the hardware > + monitoring features of the DA9063 Power Management IC. > + > + This driver can also be built as a module. If so, the module > + will be called da9063-hwmon. > + > config SENSORS_I5K_AMB > tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" > depends on PCI > diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile > index c48f987..4174b07 100644 > --- a/drivers/hwmon/Makefile > +++ b/drivers/hwmon/Makefile > @@ -49,6 +49,7 @@ obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o > obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o > obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o > obj-$(CONFIG_SENSORS_DA9055)+= da9055-hwmon.o > +obj-$(CONFIG_SENSORS_DA9063) += da9063-hwmon.o > obj-$(CONFIG_SENSORS_DME1737) += dme1737.o > obj-$(CONFIG_SENSORS_DS620) += ds620.o > obj-$(CONFIG_SENSORS_DS1621) += ds1621.o > diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c > new file mode 100644 > index 0000000..7756cb2 > --- /dev/null > +++ b/drivers/hwmon/da9063-hwmon.c > @@ -0,0 +1,456 @@ > +/* da9063-hwmon.c - Hardware monitor support for DA9063 > + * Copyright (C) 2014 Dialog Semiconductor Ltd. > + * > + * This library is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Library General Public > + * License as published by the Free Software Foundation; either > + * version 2 of the License, or (at your option) any later version. > + * > + * This library is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Library General Public License for more details. > + */ > + > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/err.h> > +#include <linux/delay.h> > +#include <linux/init.h> > +#include <linux/slab.h> > +#include <linux/string.h> > +#include <linux/platform_device.h> > +#include <linux/hwmon.h> > +#include <linux/hwmon-sysfs.h> > +#include <linux/regmap.h> > +#include <linux/mfd/da9063/core.h> > +#include <linux/mfd/da9063/pdata.h> > + > +#define DA9063_ADC_RES (1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS)) > +#define DA9063_ADC_MAX (DA9063_ADC_RES - 1) > +#define DA9063_2V5 2500 > +#define DA9063_5V0 5000 > +#define DA9063_5V5 5500 > +#define DA9063_TJUNC_M -420 > +#define DA9063_TJUNC_C -812 > +#define DA9063_VBBAT_M 2048 > + > +enum da9063_adc { > + DA9063_CHAN_VSYS = DA9063_ADC_MUX_VSYS, > + DA9063_CHAN_ADCIN1 = DA9063_ADC_MUX_ADCIN1, > + DA9063_CHAN_ADCIN2 = DA9063_ADC_MUX_ADCIN2, > + DA9063_CHAN_ADCIN3 = DA9063_ADC_MUX_ADCIN3, > + DA9063_CHAN_TJUNC = DA9063_ADC_MUX_T_SENSE, > + DA9063_CHAN_VBBAT = DA9063_ADC_MUX_VBBAT, > + DA9063_CHAN_LDO_G1 = DA9063_ADC_MUX_LDO_G1, > + DA9063_CHAN_LDO_G2 = DA9063_ADC_MUX_LDO_G2, > + DA9063_CHAN_LDO_G3 = DA9063_ADC_MUX_LDO_G3 > +}; > + > +struct da9063_hwmon { > + struct da9063 *da9063; > + struct device *classdev; > + struct mutex hwmon_mutex; > + struct completion adc_ready; > + signed char tjunc_offset; > + int irq; > +}; > + > +static int da9063_adc_convert(struct da9063_hwmon *hwmon, int channel, > + int *value) > +{ > + int val = *value; > + int ret = 0; > + > + switch (channel) { > + case DA9063_CHAN_ADCIN1: > + case DA9063_CHAN_ADCIN2: > + case DA9063_CHAN_ADCIN3: > + val = (DA9063_2V5 * val) / DA9063_ADC_MAX; > + break; > + case DA9063_CHAN_VSYS: > + val = ((DA9063_5V5 - DA9063_2V5) * val) / DA9063_ADC_MAX + > + DA9063_2V5; > + break; > + case DA9063_CHAN_TJUNC: > + val -= hwmon->tjunc_offset; > + val = (DA9063_TJUNC_M * (val + DA9063_TJUNC_C)) >> 10; > + break; > + case DA9063_CHAN_VBBAT: > + val = (DA9063_5V0 * val) / DA9063_ADC_MAX; > + break; > + default: > + ret = -EINVAL; > + goto err_convert; > + } > + > + *value = val; > +err_convert: > + return ret; > +} > + > +static int da9063_adc_current_switch(struct da9063_hwmon *hwmon, int channel, > + bool on) > +{ > + int ret; > + unsigned int val; > + unsigned int mask; > + > + switch (channel) { > + case DA9063_CHAN_ADCIN1: > + mask = DA9063_ADC_AD1_ISRC_EN; > + break; > + case DA9063_CHAN_ADCIN2: > + mask = DA9063_ADC_AD2_ISRC_EN; > + break; > + case DA9063_CHAN_ADCIN3: > + mask = DA9063_ADC_AD3_ISRC_EN; > + break; > + default: > + ret = -EINVAL; > + goto err_switch; > + } > + > + if (on) > + val = mask; > + else > + val = ~mask; > + > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CONT, > + mask, val); > +err_switch: > + return ret; > + > +} > + > +static int da9063_adc_manual_read(struct da9063_hwmon *hwmon, int channel) > +{ > + int ret; > + unsigned char val; > + unsigned char data[2]; > + int adc_man; > + > + mutex_lock(&hwmon->hwmon_mutex); > + > + init_completion(&hwmon->adc_ready); > + > + val = (channel & DA9063_ADC_MUX_MASK) | DA9063_ADC_MAN; > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, > + DA9063_ADC_MUX_MASK | DA9063_ADC_MAN, val); > + if (ret < 0) > + goto err_mread; > + > + ret = wait_for_completion_timeout(&hwmon->adc_ready, > + msecs_to_jiffies(1000)); > + if (ret == 0) { > + ret = -ETIMEDOUT; > + goto err_mread; > + } > + > + ret = regmap_read(hwmon->da9063->regmap, DA9063_REG_ADC_MAN, &adc_man); > + if (ret < 0) > + goto err_mread; > + > + /* data value is not ready */ > + if (adc_man & DA9063_ADC_MAN == 0) { > + ret = -EINVAL; > + goto err_mread; > + } > + > + ret = regmap_bulk_read(hwmon->da9063->regmap, > + DA9063_REG_ADC_RES_L, data, 2); > + if (ret < 0) > + goto err_mread; > + > + ret = (data[0] & DA9063_ADC_RES_L_MASK) >> DA9063_ADC_RES_L_SHIFT; > + ret |= data[1] << DA9063_ADC_RES_L_BITS; > +err_mread: > + mutex_unlock(&hwmon->hwmon_mutex); > + return ret; > +} > + > +static irqreturn_t da9063_hwmon_irq_handler(int irq, void *irq_data) > +{ > + struct da9063_hwmon *hwmon = irq_data; > + complete(&hwmon->adc_ready); > + return IRQ_HANDLED; > +} > + > +static ssize_t da9063_adc_read(struct device *dev, > + struct device_attribute *devattr, char *buf) > +{ > + struct da9063_hwmon *hwmon = dev_get_drvdata(dev); > + int channel = to_sensor_dev_attr(devattr)->index; > + int val; > + int ret; > + > + switch (channel) { > + case DA9063_CHAN_ADCIN1: > + case DA9063_CHAN_ADCIN2: > + case DA9063_CHAN_ADCIN3: > + /* fallthrough for ADC measures */ > + ret = da9063_adc_current_switch(hwmon, channel, true); > + if (ret < 0) > + goto err_read; > + > + val = da9063_adc_manual_read(hwmon, channel); > + if (val < 0) { > + ret = val; > + if (ret == -EINVAL) > + dev_err(dev, "Conversion was not completed\n"); > + else > + dev_err(dev, "ADC read error %d\n", ret); > + goto err_read; > + } > + > + ret = da9063_adc_current_switch(hwmon, channel, false); > + if (ret < 0) { > + dev_err(dev, "Could not switch current\n"); > + goto err_read; > + } > + break; > + > + case DA9063_CHAN_VSYS: > + case DA9063_CHAN_TJUNC: > + case DA9063_CHAN_VBBAT: > + /* fallthrough for internal measures */ > + val = da9063_adc_manual_read(hwmon, channel); > + if (val < 0) { > + dev_err(dev, "ADC read error %d\n", val); > + return val; > + } > + break; > + > + default: > + /* error case */ > + ret = -EINVAL; > + goto err_read; > + } > + > + ret = da9063_adc_convert(hwmon, channel, &val); > + if (ret < 0) { > + dev_err(dev, "Failed to convert ADC value %d\n", ret); > + goto err_read; > + } > + > + return sprintf(buf, "%d\n", val); > +err_read: > + return ret; > +} > + > +static ssize_t da9063_show_name(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + return sprintf(buf, DA9063_DRVNAME_HWMON "\n"); > +} > + > +static ssize_t da9063_show_label(struct device *dev, > + struct device_attribute *devattr, char *buf) > +{ > + int channel = to_sensor_dev_attr(devattr)->index; > + char *label; > + > + switch (channel) { > + case DA9063_CHAN_VSYS: > + label = "VSYS"; > + break; > + case DA9063_CHAN_ADCIN1: > + label = "ADCIN1"; > + break; > + case DA9063_CHAN_ADCIN2: > + label = "ADCIN2"; > + break; > + case DA9063_CHAN_ADCIN3: > + label = "ADCIN3"; > + break; > + case DA9063_CHAN_TJUNC: > + label = "TJUNC"; > + break; > + case DA9063_CHAN_VBBAT: > + label = "VBBAT"; > + break; > + default: > + label = "UNKNOWN"; > + } > + > + return sprintf(buf, "%s\n", label); > +} > + > +static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_VSYS); > +static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_VSYS); > + > +static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_ADCIN1); > +static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_ADCIN1); > + > +static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_ADCIN2); > +static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_ADCIN2); > + > +static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_ADCIN3); > +static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_ADCIN3); > + > +static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_VBBAT); > +static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_VBBAT); > + > +static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, > + da9063_adc_read, NULL, DA9063_CHAN_TJUNC); > + > +static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, > + da9063_show_label, NULL, DA9063_CHAN_TJUNC); > + > +static DEVICE_ATTR(name, S_IRUGO, da9063_show_name, NULL); > + > +static struct attribute *da9063_attributes[] = { > + &dev_attr_name.attr, > + &sensor_dev_attr_in0_input.dev_attr.attr, > + &sensor_dev_attr_in0_label.dev_attr.attr, > + &sensor_dev_attr_in1_input.dev_attr.attr, > + &sensor_dev_attr_in1_label.dev_attr.attr, > + &sensor_dev_attr_in2_input.dev_attr.attr, > + &sensor_dev_attr_in2_label.dev_attr.attr, > + &sensor_dev_attr_in3_input.dev_attr.attr, > + &sensor_dev_attr_in3_label.dev_attr.attr, > + &sensor_dev_attr_in4_input.dev_attr.attr, > + &sensor_dev_attr_in4_label.dev_attr.attr, > + &sensor_dev_attr_temp1_input.dev_attr.attr, > + &sensor_dev_attr_temp1_label.dev_attr.attr, > + NULL > +}; > + > +static const struct attribute_group da9063_attr_group = { > + .attrs = da9063_attributes, > +}; > + > +static int da9063_hwmon_probe(struct platform_device *pdev) > +{ > + struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); > + struct da9063_pdata *pdata = da9063->dev->platform_data; > + struct da9063_hwmon *hwmon; > + int ret; > + unsigned int val; > + > + hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9063_hwmon), > + GFP_KERNEL); > + if (!hwmon) > + return -ENOMEM; > + > + mutex_init(&hwmon->hwmon_mutex); > + init_completion(&hwmon->adc_ready); > + hwmon->da9063 = da9063; > + > + /* enable the ADC functions for GPIO 0,1,2 */ > + val = (DA9063_GPIO0_PIN_ADCIN1 << DA9063_GPIO0_PIN_MASK_SHIFT | > + DA9063_GPIO1_PIN_ADCIN2_COMP << DA9063_GPIO1_PIN_MASK_SHIFT); > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_0_1, > + (DA9063_GPIO0_PIN_MASK | > + DA9063_GPIO1_PIN_MASK), val); > + if (ret < 0) { > + dev_err(&pdev->dev, > + "Failed to alter the ADCIN 1,2 bits for the GPIO 0,1 register\n"); > + return -EIO; > + } > + > + val = DA9063_GPIO2_PIN_ADCIN3 << DA9063_GPIO2_PIN_MASK_SHIFT; > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_GPIO_2_3, > + DA9063_GPIO2_PIN_MASK, val); > + if (ret < 0) { > + dev_err(&pdev->dev, > + "Failed to alter the ADCIN 3 bits for the GPIO 2,3 register\n"); > + return -EIO; > + } > + > + /* debounce ADC I settings */ > + val = (DA9063_ADCIN1_DEB_ON << DA9063_REG_ADCIN1_DEB_SHIFT | > + DA9063_ADCIN2_DEB_ON << DA9063_REG_ADCIN2_DEB_SHIFT | > + DA9063_ADCIN3_DEB_ON << DA9063_REG_ADCIN3_DEB_SHIFT); > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, > + (DA9063_REG_ADCIN1_DEB_MASK | > + DA9063_REG_ADCIN2_DEB_MASK | > + DA9063_REG_ADCIN3_DEB_MASK), val); > + if (ret < 0) { > + dev_err(&pdev->dev, > + "Failed to alter the ADC configuration register\n"); > + return -EIO; > + } > + > + /* set up the current configurations */ > + val = (pdata->hwmon_pdata->adcin1_cur << DA9063_REG_ADCIN1_CUR_SHIFT | > + pdata->hwmon_pdata->adcin2_cur << DA9063_REG_ADCIN2_CUR_SHIFT | > + pdata->hwmon_pdata->adcin3_cur << DA9063_REG_ADCIN3_CUR_SHIFT); > + ret = regmap_update_bits(hwmon->da9063->regmap, DA9063_REG_ADC_CFG, > + (DA9063_REG_ADCIN1_CUR_MASK | > + DA9063_REG_ADCIN2_CUR_MASK | > + DA9063_REG_ADCIN3_CUR_MASK), val); > + > + ret = regmap_read(da9063->regmap, DA9063_REG_ADC_CFG, &val); > + if (ret < 0) { > + dev_err(&pdev->dev, > + "Failed to read read the ADC configuration register\n"); > + return -EIO; > + } > + > + hwmon->irq = platform_get_irq_byname(pdev, DA9063_DRVNAME_HWMON); > + if (hwmon->irq < 0) > + return hwmon->irq; > + > + ret = devm_request_threaded_irq(&pdev->dev, hwmon->irq, NULL, > + da9063_hwmon_irq_handler, > + IRQF_TRIGGER_LOW | IRQF_ONESHOT, > + "HWMON", hwmon); > + if (ret) { > + dev_err(&pdev->dev, "Failed to request IRQ.\n"); > + return ret; > + } > + > + platform_set_drvdata(pdev, hwmon); > + > + /* set trim temperature offset to value read at startup */ > + hwmon->tjunc_offset = (signed char)hwmon->da9063->t_offset; > + > + ret = sysfs_create_group(&pdev->dev.kobj, &da9063_attr_group); > + if (ret) > + return ret; > + > + hwmon->classdev = hwmon_device_register(&pdev->dev); > + if (IS_ERR(hwmon->classdev)) { > + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); > + return PTR_ERR(hwmon->classdev); > + } > + > + return 0; > +} > + > +static int da9063_hwmon_remove(struct platform_device *pdev) > +{ > + struct da9063_hwmon *hwmon = platform_get_drvdata(pdev); > + > + hwmon_device_unregister(hwmon->classdev); > + sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); > + > + return 0; > +} > + > +static struct platform_driver da9063_hwmon_driver = { > + .probe = da9063_hwmon_probe, > + .remove = da9063_hwmon_remove, > + .driver = { > + .name = DA9063_DRVNAME_HWMON, > + .owner = THIS_MODULE, > + }, > +}; > + > +module_platform_driver(da9063_hwmon_driver); > + > +MODULE_DESCRIPTION("Hardware monitor support device driver for Dialog DA9063"); > +MODULE_AUTHOR("S Twiss <stwiss.opensource@diasemi.com>"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:" DA9063_DRVNAME_HWMON); > diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h > index 09a85c6..922371b 100644 > --- a/include/linux/mfd/da9063/registers.h > +++ b/include/linux/mfd/da9063/registers.h > @@ -474,6 +474,7 @@ > > /* DA9063_REG_GPIO_0_1 (addr=0x15) */ > #define DA9063_GPIO0_PIN_MASK 0x03 > +#define DA9063_GPIO0_PIN_MASK_SHIFT 0 > #define DA9063_GPIO0_PIN_ADCIN1 0x00 > #define DA9063_GPIO0_PIN_GPI 0x01 > #define DA9063_GPIO0_PIN_GPO_OD 0x02 > @@ -485,6 +486,7 @@ > #define DA9063_GPIO0_TYPE_GPO_VDD_IO2 0x04 > #define DA9063_GPIO0_NO_WAKEUP 0x08 > #define DA9063_GPIO1_PIN_MASK 0x30 > +#define DA9063_GPIO1_PIN_MASK_SHIFT 4 > #define DA9063_GPIO1_PIN_ADCIN2_COMP 0x00 > #define DA9063_GPIO1_PIN_GPI 0x10 > #define DA9063_GPIO1_PIN_GPO_OD 0x20 > @@ -498,6 +500,7 @@ > > /* DA9063_REG_GPIO_2_3 (addr=0x16) */ > #define DA9063_GPIO2_PIN_MASK 0x03 > +#define DA9063_GPIO2_PIN_MASK_SHIFT 0 > #define DA9063_GPIO2_PIN_ADCIN3 0x00 > #define DA9063_GPIO2_PIN_GPI 0x01 > #define DA9063_GPIO2_PIN_GPO_PSS 0x02 > @@ -813,6 +816,7 @@ > #define DA9063_VSYS_VAL_BASE 0x00 > > /* DA9063_REG_ADC_RES_L (addr=0x37) */ > +#define DA9063_ADC_RES_L_SHIFT 6 > #define DA9063_ADC_RES_L_BITS 2 > #define DA9063_ADC_RES_L_MASK 0xC0 > > @@ -979,6 +983,36 @@ > #define DA9063_GPIO_DIM 0x80 > #define DA9063_GPIO_PWM_MASK 0x7F > > +/* DA9063_REG_ADC_CFG (addr=0xC9) */ > +#define DA9063_REG_ADCIN1_CUR_MASK 0x03 > +#define DA9063_REG_ADCIN1_CUR_SHIFT 0 > +#define DA9063_ADCIN1_CUR_1UA 0x00 > +#define DA9063_ADCIN1_CUR_2UA 0x01 > +#define DA9063_ADCIN1_CUR_10UA 0x02 > +#define DA9063_ADCIN1_CUR_40UA 0x03 > +#define DA9063_REG_ADCIN2_CUR_MASK 0x0C > +#define DA9063_REG_ADCIN2_CUR_SHIFT 2 > +#define DA9063_ADCIN2_CUR_1UA 0x00 > +#define DA9063_ADCIN2_CUR_2UA 0x01 > +#define DA9063_ADCIN2_CUR_10UA 0x02 > +#define DA9063_ADCIN2_CUR_40UA 0x03 > +#define DA9063_REG_ADCIN3_CUR_MASK 0x10 > +#define DA9063_REG_ADCIN3_CUR_SHIFT 4 > +#define DA9063_ADCIN3_CUR_10UA 0x00 > +#define DA9063_ADCIN3_CUR_40UA 0x01 > +#define DA9063_REG_ADCIN1_DEB_MASK 0x20 > +#define DA9063_REG_ADCIN1_DEB_SHIFT 5 > +#define DA9063_ADCIN1_DEB_OFF 0x00 > +#define DA9063_ADCIN1_DEB_ON 0x01 > +#define DA9063_REG_ADCIN2_DEB_MASK 0x40 > +#define DA9063_REG_ADCIN2_DEB_SHIFT 6 > +#define DA9063_ADCIN2_DEB_OFF 0x00 > +#define DA9063_ADCIN2_DEB_ON 0x01 > +#define DA9063_REG_ADCIN3_DEB_MASK 0x80 > +#define DA9063_REG_ADCIN3_DEB_SHIFT 7 > +#define DA9063_ADCIN3_DEB_OFF 0x00 > +#define DA9063_ADCIN3_DEB_ON 0x01 > + > /* DA9063_REG_CONFIG_H (addr=0x10D) */ > #define DA9063_PWM_CLK_MASK 0x01 > #define DA9063_PWM_CLK_PWM2MHZ 0x00 -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [RFC V1 1/3] hwmon: da9063: HWMON driver 2014-03-24 7:52 ` Lee Jones @ 2014-03-24 8:12 ` Opensource [Steve Twiss] 0 siblings, 0 replies; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-24 8:12 UTC (permalink / raw) To: Lee Jones Cc: Guenter Roeck, Jean Delvare, David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley, Samuel Ortiz [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2230 bytes --] Hi Lee, Thank you for the fast reply. On 24 March 2014 07:52 Lee Jones wrote, >> From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> >> Add the HWMON driver for DA9063 >> >> Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> --- >> >> drivers/hwmon/Kconfig | 10 + >> drivers/hwmon/Makefile | 1 + >> drivers/hwmon/da9063-hwmon.c | 456 >++++++++++++++++++++++++++++++++++ >> include/linux/mfd/da9063/registers.h | 34 +++ > >I'd prefer to see all values in hex, but this probably a preference >thing rather than something which would prevent acceptance. > >For the MFD header changes: > Acked-by: Lee Jones <lee.jones@linaro.org> > Thanks for the Ack. <snip> > +#define DA9063_ADC_RES (1 << (DA9063_ADC_RES_L_BITS + DA9063_ADC_RES_M_BITS)) > +#define DA9063_ADC_MAX (DA9063_ADC_RES - 1) >> +#define DA9063_2V5 2500 >> +#define DA9063_5V0 5000 >> +#define DA9063_5V5 5500 >> +#define DA9063_TJUNC_M -420 >> +#define DA9063_TJUNC_C -812 >> +#define DA9063_VBBAT_M 2048 I am using these defines as part of the base-10 calculations in the conversion routines for voltage and temperature. I guess they do look weird .. and looking at it, I have mixed division by 1024 as a right shift 10 in the TJUNC calculation. I will re-format that part and put a comment in the defines to explain. Thanks. <snip> >> + case DA9063_CHAN_ADCIN1: >> + case DA9063_CHAN_ADCIN2: >> + case DA9063_CHAN_ADCIN3: >> + val = (DA9063_2V5 * val) / DA9063_ADC_MAX; >> + break; >> + case DA9063_CHAN_VSYS: >> + val = ((DA9063_5V5 - DA9063_2V5) * val) / DA9063_ADC_MAX + >> + DA9063_2V5; >> + break; >> + case DA9063_CHAN_TJUNC: >> + val -= hwmon->tjunc_offset; >> + val = (DA9063_TJUNC_M * (val + DA9063_TJUNC_C)) >> 10; >> + break; >> + case DA9063_CHAN_VBBAT: >> + val = (DA9063_5V0 * val) / DA9063_ADC_MAX; >> + break; <snip> > >-- >Lee Jones >Linaro STMicroelectronics Landing Team Lead >Linaro.org â Open source software for ARM SoCs >Follow Linaro: Facebook | Twitter | Blog Regards, Steve ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥ ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC V1 2/3] mfd: da9063: Add HWMON dependencies 2014-03-23 20:37 [RFC V1 0/3] da9063: Addition of HWMON support for DA9063 Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] @ 2014-03-23 20:37 ` Opensource [Steve Twiss] 2014-03-24 8:02 ` Lee Jones 2014-03-23 20:37 ` [RFC V1 3/3] Documentation: hwmon: New information for DA9063 Opensource [Steve Twiss] 2 siblings, 1 reply; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-23 20:37 UTC (permalink / raw) To: Lee Jones, Samuel Ortiz Cc: David Dajun Chen, Guenter Roeck, Jean Delvare, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> Dependencies required for DA9063 HWMON support. Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> --- Checks performed with linux-next/next-20140321/scripts/checkpatch.pl core.h total: 0 errors, 0 warnings, 100 lines checked pdata.h total: 0 errors, 0 warnings, 129 lines checked da9063-core.c total: 0 errors, 0 warnings, 199 lines checked This patch includes the following changes: There are small changes to da9063-core.c to allow reading the temperature trimming offset value from the PMIC register list. This value is passed to HWMON and is used during its calculations of the PMIC's internal junction temperature. There are also changes to the platform data definitions so that values may be set for the current sources ADCIN[123]_CUR. These are provided so that they may be configured outside the driver. This patch applies against linux-next and next-20140321 Regards, Steve Twiss, Dialog Semiconductor Ltd. drivers/mfd/da9063-core.c | 13 ++++++++++++- include/linux/mfd/da9063/core.h | 3 +++ include/linux/mfd/da9063/pdata.h | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c index e70ae31..24c1838 100644 --- a/drivers/mfd/da9063-core.c +++ b/drivers/mfd/da9063-core.c @@ -111,6 +111,7 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) { struct da9063_pdata *pdata = da9063->dev->platform_data; int model, variant_id, variant_code; + int t_offset = 0; int ret; if (pdata) { @@ -171,8 +172,18 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) ret = mfd_add_devices(da9063->dev, -1, da9063_devs, ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, NULL); - if (ret) + if (ret) { dev_err(da9063->dev, "Cannot add MFD cells\n"); + return ret; + } + + ret = regmap_read(da9063->regmap, DA9063_REG_T_OFFSET, &t_offset); + if (ret < 0) + dev_warn(da9063->dev, + "Temperature trimming value cannot be read (defaulting to 0)\n"); + + /* pass this on to the hwmon driver */ + da9063->t_offset = t_offset; return ret; } diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h index 00a9aac..7327d37 100644 --- a/include/linux/mfd/da9063/core.h +++ b/include/linux/mfd/da9063/core.h @@ -86,6 +86,9 @@ struct da9063 { int chip_irq; unsigned int irq_base; struct regmap_irq_chip_data *regmap_irq; + + /* Trimming */ + int t_offset; }; int da9063_device_init(struct da9063 *da9063, unsigned int irq); diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h index 95c8742..576033e 100644 --- a/include/linux/mfd/da9063/pdata.h +++ b/include/linux/mfd/da9063/pdata.h @@ -62,6 +62,23 @@ struct da9063_regulators_pdata { struct da9063_regulator_data *regulator_data; }; +/* HWMON platform data */ +#define DA9063_SET_ADCIN1_CUR_1UA 0x00 +#define DA9063_SET_ADCIN1_CUR_2UA 0x01 +#define DA9063_SET_ADCIN1_CUR_10UA 0x02 +#define DA9063_SET_ADCIN1_CUR_40UA 0x03 +#define DA9063_SET_ADCIN2_CUR_1UA 0x00 +#define DA9063_SET_ADCIN2_CUR_2UA 0x01 +#define DA9063_SET_ADCIN2_CUR_10UA 0x02 +#define DA9063_SET_ADCIN2_CUR_40UA 0x03 +#define DA9063_SET_ADCIN3_CUR_10UA 0x00 + +struct da9063_hwmon_pdata { + unsigned char adcin1_cur; + unsigned char adcin2_cur; + unsigned char adcin3_cur; +}; + /* * RGB LED configuration @@ -106,6 +123,7 @@ struct da9063_pdata { unsigned flags; struct da9063_regulators_pdata *regulators_pdata; struct led_platform_data *leds_pdata; + struct da9063_hwmon_pdata *hwmon_pdata; }; #endif /* __MFD_DA9063_PDATA_H__ */ -- end-of-patch for RFC V1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC V1 2/3] mfd: da9063: Add HWMON dependencies 2014-03-23 20:37 ` [RFC V1 2/3] mfd: da9063: Add HWMON dependencies Opensource [Steve Twiss] @ 2014-03-24 8:02 ` Lee Jones 2014-03-24 8:28 ` Opensource [Steve Twiss] 0 siblings, 1 reply; 12+ messages in thread From: Lee Jones @ 2014-03-24 8:02 UTC (permalink / raw) To: Opensource [Steve Twiss] Cc: Samuel Ortiz, David Dajun Chen, Guenter Roeck, Jean Delvare, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley On Sun, 23 Mar 2014, Opensource [Steve Twiss] wrote: > From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > > Dependencies required for DA9063 HWMON support. > > Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> > --- > > drivers/mfd/da9063-core.c | 13 ++++++++++++- > include/linux/mfd/da9063/core.h | 3 +++ > include/linux/mfd/da9063/pdata.h | 18 ++++++++++++++++++ > 3 files changed, 33 insertions(+), 1 deletion(-) > > diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c > index e70ae31..24c1838 100644 > --- a/drivers/mfd/da9063-core.c > +++ b/drivers/mfd/da9063-core.c > @@ -111,6 +111,7 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) > { > struct da9063_pdata *pdata = da9063->dev->platform_data; > int model, variant_id, variant_code; > + int t_offset = 0; > int ret; > > if (pdata) { > @@ -171,8 +172,18 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) > ret = mfd_add_devices(da9063->dev, -1, da9063_devs, > ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, > NULL); > - if (ret) > + if (ret) { > dev_err(da9063->dev, "Cannot add MFD cells\n"); > + return ret; > + } > + > + ret = regmap_read(da9063->regmap, DA9063_REG_T_OFFSET, &t_offset); > + if (ret < 0) > + dev_warn(da9063->dev, > + "Temperature trimming value cannot be read (defaulting to 0)\n"); > + > + /* pass this on to the hwmon driver */ > + da9063->t_offset = t_offset; What's the logic for using a local variable for this prior to setting the attribute in the shared container? > return ret; > } > diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h > index 00a9aac..7327d37 100644 > --- a/include/linux/mfd/da9063/core.h > +++ b/include/linux/mfd/da9063/core.h > @@ -86,6 +86,9 @@ struct da9063 { > int chip_irq; > unsigned int irq_base; > struct regmap_irq_chip_data *regmap_irq; > + > + /* Trimming */ > + int t_offset; > }; > > int da9063_device_init(struct da9063 *da9063, unsigned int irq); > diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h > index 95c8742..576033e 100644 > --- a/include/linux/mfd/da9063/pdata.h > +++ b/include/linux/mfd/da9063/pdata.h > @@ -62,6 +62,23 @@ struct da9063_regulators_pdata { > struct da9063_regulator_data *regulator_data; > }; > > +/* HWMON platform data */ > +#define DA9063_SET_ADCIN1_CUR_1UA 0x00 > +#define DA9063_SET_ADCIN1_CUR_2UA 0x01 > +#define DA9063_SET_ADCIN1_CUR_10UA 0x02 > +#define DA9063_SET_ADCIN1_CUR_40UA 0x03 > +#define DA9063_SET_ADCIN2_CUR_1UA 0x00 > +#define DA9063_SET_ADCIN2_CUR_2UA 0x01 > +#define DA9063_SET_ADCIN2_CUR_10UA 0x02 > +#define DA9063_SET_ADCIN2_CUR_40UA 0x03 > +#define DA9063_SET_ADCIN3_CUR_10UA 0x00 Why differentiate? More succinctly: /* HWMON platform data */ #define DA9063_SET_CUR_1UA 0x00 #define DA9063_SET_CUR_2UA 0x01 #define DA9063_SET_CUR_10UA 0x02 #define DA9063_SET_CUR_40UA 0x03 > +struct da9063_hwmon_pdata { > + unsigned char adcin1_cur; > + unsigned char adcin2_cur; > + unsigned char adcin3_cur; > +}; > + > Now there are two new lines here. > /* > * RGB LED configuration > @@ -106,6 +123,7 @@ struct da9063_pdata { > unsigned flags; > struct da9063_regulators_pdata *regulators_pdata; > struct led_platform_data *leds_pdata; > + struct da9063_hwmon_pdata *hwmon_pdata; > }; Does this device support Device Tree? > #endif /* __MFD_DA9063_PDATA_H__ */ -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [RFC V1 2/3] mfd: da9063: Add HWMON dependencies 2014-03-24 8:02 ` Lee Jones @ 2014-03-24 8:28 ` Opensource [Steve Twiss] 0 siblings, 0 replies; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-24 8:28 UTC (permalink / raw) To: Lee Jones Cc: Samuel Ortiz, David Dajun Chen, Guenter Roeck, Jean Delvare, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Mark Brown, Philipp Zabel, Rob Landley [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset="utf-8", Size: 4209 bytes --] Hi Lee, On 24 March 2014 08:03 Lee Jones wrote: >On Sun, 23 Mar 2014, Opensource [Steve Twiss] wrote: >> From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> >> Dependencies required for DA9063 HWMON support. >> >> Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> >> --- >> >> drivers/mfd/da9063-core.c | 13 ++++++++++++- >> include/linux/mfd/da9063/core.h | 3 +++ >> include/linux/mfd/da9063/pdata.h | 18 ++++++++++++++++++ >> 3 files changed, 33 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c >> index e70ae31..24c1838 100644 >> --- a/drivers/mfd/da9063-core.c >> +++ b/drivers/mfd/da9063-core.c >> @@ -111,6 +111,7 @@ int da9063_device_init(struct da9063 *da9063, unsigned >int irq) >> { >> struct da9063_pdata *pdata = da9063->dev->platform_data; >> int model, variant_id, variant_code; >> + int t_offset = 0; >> int ret; >> >> if (pdata) { >> @@ -171,8 +172,18 @@ int da9063_device_init(struct da9063 *da9063, unsigned >int irq) >> ret = mfd_add_devices(da9063->dev, -1, da9063_devs, >> ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, >> NULL); >> - if (ret) >> + if (ret) { >> dev_err(da9063->dev, "Cannot add MFD cells\n"); >> + return ret; >> + } >> + >> + ret = regmap_read(da9063->regmap, DA9063_REG_T_OFFSET, &t_offset); >> + if (ret < 0) >> + dev_warn(da9063->dev, >> + "Temperature trimming value cannot be read (defaulting >to 0)\n"); >> + >> + /* pass this on to the hwmon driver */ >> + da9063->t_offset = t_offset; > >What's the logic for using a local variable for this prior to setting >the attribute in the shared container? > Yep -- that's bad. I'll remove it. >> return ret; >> } >> diff --git a/include/linux/mfd/da9063/core.h >b/include/linux/mfd/da9063/core.h >> index 00a9aac..7327d37 100644 >> --- a/include/linux/mfd/da9063/core.h >> +++ b/include/linux/mfd/da9063/core.h >> @@ -86,6 +86,9 @@ struct da9063 { >> int chip_irq; >> unsigned int irq_base; >> struct regmap_irq_chip_data *regmap_irq; >> + >> + /* Trimming */ >> + int t_offset; >> }; >> >> int da9063_device_init(struct da9063 *da9063, unsigned int irq); >> diff --git a/include/linux/mfd/da9063/pdata.h >b/include/linux/mfd/da9063/pdata.h >> index 95c8742..576033e 100644 >> --- a/include/linux/mfd/da9063/pdata.h >> +++ b/include/linux/mfd/da9063/pdata.h >> @@ -62,6 +62,23 @@ struct da9063_regulators_pdata { >> struct da9063_regulator_data *regulator_data; >> }; >> >> +/* HWMON platform data */ >> +#define DA9063_SET_ADCIN1_CUR_1UA 0x00 >> +#define DA9063_SET_ADCIN1_CUR_2UA 0x01 >> +#define DA9063_SET_ADCIN1_CUR_10UA 0x02 >> +#define DA9063_SET_ADCIN1_CUR_40UA 0x03 >> +#define DA9063_SET_ADCIN2_CUR_1UA 0x00 >> +#define DA9063_SET_ADCIN2_CUR_2UA 0x01 >> +#define DA9063_SET_ADCIN2_CUR_10UA 0x02 >> +#define DA9063_SET_ADCIN2_CUR_40UA 0x03 >> +#define DA9063_SET_ADCIN3_CUR_10UA 0x00 > >Why differentiate? More succinctly: > >/* HWMON platform data */ >#define DA9063_SET_CUR_1UA 0x00 >#define DA9063_SET_CUR_2UA 0x01 >#define DA9063_SET_CUR_10UA 0x02 >#define DA9063_SET_CUR_40UA 0x03 > > Oh yeh... that makes much more sense. I should have thought of that :( Sorry you had to review that part. >> +struct da9063_hwmon_pdata { >> + unsigned char adcin1_cur; >> + unsigned char adcin2_cur; >> + unsigned char adcin3_cur; >> +}; >> + >> > >Now there are two new lines here. > Will erase them. >> /* >> * RGB LED configuration >> @@ -106,6 +123,7 @@ struct da9063_pdata { >> unsigned flags; >> struct da9063_regulators_pdata *regulators_pdata; >> struct led_platform_data *leds_pdata; >> + struct da9063_hwmon_pdata *hwmon_pdata; >> }; > >Does this device support Device Tree? > Ah, well no. I've not added any DT stuff. Is that an essential requirement now? >> #endif /* __MFD_DA9063_PDATA_H__ */ > >-- >Lee Jones >Linaro STMicroelectronics Landing Team Lead >Linaro.org â Open source software for ARM SoCs >Follow Linaro: Facebook | Twitter | Blog Thanks, Steve ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥ ^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC V1 3/3] Documentation: hwmon: New information for DA9063 2014-03-23 20:37 [RFC V1 0/3] da9063: Addition of HWMON support for DA9063 Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 2/3] mfd: da9063: Add HWMON dependencies Opensource [Steve Twiss] @ 2014-03-23 20:37 ` Opensource [Steve Twiss] 2 siblings, 0 replies; 12+ messages in thread From: Opensource [Steve Twiss] @ 2014-03-23 20:37 UTC (permalink / raw) To: Guenter Roeck, Jean Delvare, Rob Landley Cc: David Dajun Chen, LINUX-DOC, LINUX-KERNEL, LM-SENSORS, Lee Jones, Mark Brown, Philipp Zabel, Samuel Ortiz From: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> Addition of HWMON documentation for the DA9063 driver. Signed-off-by: Opensource [Steve Twiss] <stwiss.opensource@diasemi.com> --- Checks performed with linux-next/next-20140321/scripts/checkpatch.pl da9063 total: 0 errors, 0 warnings, 67 lines checked This is the documentation that goes along with the DA9063 HWMON driver and the associated changes to the DA9063 mfd core and platform data. Dependencies: - The two other patches in this patch set: These are the HWMON driver and the MFD core changes This patch applies against linux-next and next-20140321 Regards, Steve Twiss, Dialog Semiconductor Ltd. Documentation/hwmon/da9063 | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/hwmon/da9063 diff --git a/Documentation/hwmon/da9063 b/Documentation/hwmon/da9063 new file mode 100644 index 0000000..fa616bb --- /dev/null +++ b/Documentation/hwmon/da9063 @@ -0,0 +1,67 @@ + +Kernel driver da9063-hwmon +========================== + +Supported chips: + * Dialog Semiconductor DA9063 PMIC + Prefix: 'da9063' + Datasheet: + http://www.dialog-semiconductor.com/products/power-management/DA9063 + +Authors: S Twiss <stwiss.opensource@diasemi.com> + +Description +----------- + +The DA9063 PMIC provides a general purpose ADC with 10 bits of resolution. +It uses track and hold circuitry with an analogue input multiplexer which +allows the conversion of up to 9 different inputs. + + Channel 0: VSYS_RES measurement of the system VDD (2.5 - 5.5V) + Channel 1: ADCIN1_RES high impedance input (0 - 2.5V) + Channel 2: ADCIN2_RES high impedance input (0 - 2.5V) + Channel 3: ADCIN3_RES high impedance input (0 - 2.5V) + Channel 4: Tjunc measurement of internal temperature sensor + Channel 5: VBBAT measurement of the backup battery voltage (0 - 5.0V) + Channel 6: N/A Reserved + Channel 7: N/A Reserved + Channel 8: MON1_RES group 1 internal regulators voltage (0 - 5.0V) + Channel 9: MON2_RES group 2 internal regulators voltage (0 - 5.0V) + Channel 10: MON3_RES group 3 internal regulators voltage (0 - 5.0V) + +The MUX selects from and isolates the 9 inputs and presents the channel to +be measured to the ADC input. When selected, an input amplifier on the VSYS +channel subtracts the VDDCORE reference voltage and scales the signal to the +correct value for the ADC. + +The analog ADC includes current sources at ADC_IN1, ADC_IN2 and ADC_IN3 to +support resistive measurements. + +Channels 1, 2 and 3 current source capability can be set through the ADC +thresholds ADC_CFG register and values for ADCIN1_CUR, ADCIN2_CUR and +ADCIN3_CUR. Settings for ADCIN1_CUR and ADCIN2_CUR are 1.0, 2.0, 10 and +40 micro Amps. The setting for ADCIN3_CUR is 10 micro Amps. + +Voltage Monitoring +------------------ + +The manual measurement allows monitoring of the system voltage VSYS, the +auxiliary channels ADCIN1, ADCIN2 and ADCIN3, and a VBBAT measurement of +the backup battery voltage (0 - 5.0V). The manual measurements store 10 +bits of ADC resolution. + +The manual ADC measurements attributes described above are supported by +the driver. + +The automatic ADC measurement is not supported by the driver. + +Temperature Monitoring +---------------------- + +Channel 4 (Tjunc) will be used to measure the output of the internal +temperature sensor. The ADC measurement result and the T_OFFSET value can +be used by the host to calculate the internal junction temperature + + Tjunc = -0.41 * (ADC - T_OFFSET - 812.5); + +The junction temperature attribute is supported by the driver. -- end-of-patch for RFC V1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-03-24 9:24 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-03-23 20:37 [RFC V1 0/3] da9063: Addition of HWMON support for DA9063 Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 1/3] hwmon: da9063: HWMON driver Opensource [Steve Twiss] 2014-03-24 3:27 ` Guenter Roeck 2014-03-24 3:39 ` Guenter Roeck 2014-03-24 7:48 ` Opensource [Steve Twiss] 2014-03-24 9:24 ` Lee Jones 2014-03-24 7:52 ` Lee Jones 2014-03-24 8:12 ` Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 2/3] mfd: da9063: Add HWMON dependencies Opensource [Steve Twiss] 2014-03-24 8:02 ` Lee Jones 2014-03-24 8:28 ` Opensource [Steve Twiss] 2014-03-23 20:37 ` [RFC V1 3/3] Documentation: hwmon: New information for DA9063 Opensource [Steve Twiss]
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox