* [PATCH v4 5/8] iio: adc: add STMPE ADC driver using IIO framework [not found] <20181212130649.15146-1-dev@pschenker.ch> @ 2018-12-12 13:06 ` Philippe Schenker 2018-12-16 12:24 ` Jonathan Cameron 2018-12-12 13:06 ` [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings Philippe Schenker 1 sibling, 1 reply; 5+ messages in thread From: Philippe Schenker @ 2018-12-12 13:06 UTC (permalink / raw) To: jic23, marcel.ziswiler, stefan Cc: thierry.reding, Philippe Schenker, Max Krummenacher, Philippe Schenker, Arnd Bergmann, Arnaud Pouliquen, linux-iio, Mark Brown, Geert Uytterhoeven, William Breathitt Gray, linux-stm32, Baolin Wang, Randy Dunlap, Marcus Folkesson, Freeman Liu, Eugen Hristev, Peter Meerwald-Stadler, Maxime Coquelin, Hartmut Knaack, linux-arm-kernel, Alexandre Torgue, Siddartha Mohanadoss, linux-kernel, Lars-Peter Clausen, Kent Gustavsson This adds an ADC driver for the STMPE device using the industrial input/output interface. The driver supports raw reading of values. The driver depends on the MFD STMPE driver. If the touchscreen block is enabled too, only four of the 8 ADC channels are available. Signed-off-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com> --- Changes in v4: - Moved MFD changes to a precursor patch - Moved stmpe-ts changes to a precursor patch - Created stmpe_read_temp and stmpe_read_voltage functions to make read_raw more readable - Added local lock instead of using indio_dev's mlock - Use be16_to_cpu() macro instead of bitshifting - Added stmpe_enable again to stmpe_adc_init_hw - Use devm_add_action_or_reset to get rid of the remove function (I tested if that actually works) Changes in v3: - Removed COMPILE_TEST from dependings in Kconfig - Removed stmpe_adc_get_platform_info() function and integrated the few code lines in the other function Changes in v2: - Code formatting - Removed unused includes - Defined the macro STMPE_START_ONE_TEMP_CONV with other macros. - Added new macro that defines the channel of the temperature sensor. Took new name for STMPE_MAX_ADC->STMPE_ADC_LAST_NR and used it throughout the code for better readability. - Added mutex_unlock where missing. drivers/iio/adc/Kconfig | 7 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/stmpe-adc.c | 368 ++++++++++++++++++++++++++++++++++++ 3 files changed, 376 insertions(+) create mode 100644 drivers/iio/adc/stmpe-adc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index a52fea8749a9..224f2067494d 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -734,6 +734,13 @@ config STM32_DFSDM_ADC This driver can also be built as a module. If so, the module will be called stm32-dfsdm-adc. +config STMPE_ADC + tristate "STMicroelectronics STMPE ADC driver" + depends on OF && MFD_STMPE + help + Say yes here to build support for ST Microelectronics STMPE + built-in ADC block (stmpe811). + config STX104 tristate "Apex Embedded Systems STX104 driver" depends on PC104 && X86 diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index a6e6a0b659e2..cba889c30bf9 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -69,6 +69,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o obj-$(CONFIG_STM32_ADC) += stm32-adc.o obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o +obj-$(CONFIG_STMPE_ADC) += stmpe-adc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o diff --git a/drivers/iio/adc/stmpe-adc.c b/drivers/iio/adc/stmpe-adc.c new file mode 100644 index 000000000000..4333da19a097 --- /dev/null +++ b/drivers/iio/adc/stmpe-adc.c @@ -0,0 +1,368 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * STMicroelectronics STMPE811 IIO ADC Driver + * + * 4 channel, 10/12-bit ADC + * + * Copyright (C) 2013-2018 Toradex AG <stefan.agner@toradex.com> + */ + +#include <linux/completion.h> +#include <linux/err.h> +#include <linux/iio/iio.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mfd/stmpe.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/device.h> + +#define STMPE_REG_INT_STA 0x0B +#define STMPE_REG_ADC_INT_EN 0x0E +#define STMPE_REG_ADC_INT_STA 0x0F + +#define STMPE_REG_ADC_CTRL1 0x20 +#define STMPE_REG_ADC_CTRL2 0x21 +#define STMPE_REG_ADC_CAPT 0x22 +#define STMPE_REG_ADC_DATA_CH(channel) (0x30 + 2 * (channel)) + +#define STMPE_REG_TEMP_CTRL 0x60 +#define STMPE_TEMP_CTRL_ENABLE BIT(0) +#define STMPE_TEMP_CTRL_ACQ BIT(1) +#define STMPE_TEMP_CTRL_THRES_EN BIT(3) +#define STMPE_START_ONE_TEMP_CONV (STMPE_TEMP_CTRL_ENABLE | \ + STMPE_TEMP_CTRL_ACQ | \ + STMPE_TEMP_CTRL_THRES_EN) +#define STMPE_REG_TEMP_DATA 0x61 +#define STMPE_REG_TEMP_TH 0x63 +#define STMPE_ADC_LAST_NR 7 +#define STMPE_TEMP_CHANNEL (STMPE_ADC_LAST_NR + 1) + +#define STMPE_ADC_CH(channel) ((1 << (channel)) & 0xff) + +#define STMPE_ADC_TIMEOUT msecs_to_jiffies(1000) + +struct stmpe_adc { + struct stmpe *stmpe; + struct clk *clk; + struct device *dev; + struct mutex lock; + + /* We are allocating plus one for the temperature channel */ + struct iio_chan_spec stmpe_adc_iio_channels[STMPE_ADC_LAST_NR + 2]; + + struct completion completion; + + u8 channel; + u32 value; +}; + +static int stmpe_read_voltage(struct stmpe_adc *info, + struct iio_chan_spec const *chan, int *val) +{ + long ret; + + mutex_lock(&info->lock); + + info->channel = (u8)chan->channel; + + if (info->channel > STMPE_ADC_LAST_NR) { + mutex_unlock(&info->lock); + return -EINVAL; + } + + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN, + STMPE_ADC_CH(info->channel)); + + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT, + STMPE_ADC_CH(info->channel)); + + *val = info->value; + + ret = wait_for_completion_interruptible_timeout + (&info->completion, STMPE_ADC_TIMEOUT); + + if (ret <= 0) { + mutex_unlock(&info->lock); + if (ret == 0) + return -ETIMEDOUT; + else + return ret; + } + + *val = info->value; + + mutex_unlock(&info->lock); + + return 0; +} + +static int stmpe_read_temp(struct stmpe_adc *info, + struct iio_chan_spec const *chan, int *val) +{ + long ret; + + mutex_lock(&info->lock); + + info->channel = (u8)chan->channel; + + if (info->channel != STMPE_TEMP_CHANNEL) { + mutex_unlock(&info->lock); + return -EINVAL; + } + + stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL, + STMPE_START_ONE_TEMP_CONV); + + ret = wait_for_completion_interruptible_timeout + (&info->completion, STMPE_ADC_TIMEOUT); + + if (ret <= 0) { + mutex_unlock(&info->lock); + if (ret == 0) + return -ETIMEDOUT; + else + return ret; + } + + /* + * absolute temp = +V3.3 * value /7.51 [K] + * scale to [milli °C] + */ + *val = ((449960l * info->value) / 1024l) - 273150; + + mutex_unlock(&info->lock); + + return 0; +} + +static int stmpe_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct stmpe_adc *info = iio_priv(indio_dev); + long ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_PROCESSED: + + switch (chan->type) { + case IIO_VOLTAGE: + ret = stmpe_read_voltage(info, chan, val); + break; + + case IIO_TEMP: + ret = stmpe_read_temp(info, chan, val); + break; + default: + return -EINVAL; + } + + if (ret < 0) + return ret; + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = 3300; + *val2 = info->stmpe->mod_12b ? 12 : 10; + return IIO_VAL_FRACTIONAL_LOG2; + + default: + break; + } + + return -EINVAL; +} + +static irqreturn_t stmpe_adc_isr(int irq, void *dev_id) +{ + struct stmpe_adc *info = (struct stmpe_adc *)dev_id; + u16 data; + + if (info->channel > STMPE_TEMP_CHANNEL) + return IRQ_NONE; + + if (info->channel <= STMPE_ADC_LAST_NR) { + int int_sta; + + int_sta = stmpe_reg_read(info->stmpe, STMPE_REG_ADC_INT_STA); + + /* Is the interrupt relevant */ + if (!(int_sta & STMPE_ADC_CH(info->channel))) + return IRQ_NONE; + + /* Read value */ + stmpe_block_read(info->stmpe, + STMPE_REG_ADC_DATA_CH(info->channel), 2, (u8 *) &data); + + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, int_sta); + } else if (info->channel == STMPE_TEMP_CHANNEL) { + /* Read value */ + stmpe_block_read(info->stmpe, STMPE_REG_TEMP_DATA, 2, + (u8 *) &data); + } + + info->value = (u32) be16_to_cpu(data); + complete(&info->completion); + + return IRQ_HANDLED; +} + +static const struct iio_info stmpe_adc_iio_info = { + .read_raw = &stmpe_read_raw, +}; + +static void stmpe_adc_voltage_chan(struct iio_chan_spec *ics, int chan) +{ + ics->type = IIO_VOLTAGE; + ics->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); + ics->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); + ics->indexed = 1; + ics->channel = chan; +} + +static void stmpe_adc_temp_chan(struct iio_chan_spec *ics, int chan) +{ + ics->type = IIO_TEMP; + ics->info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED); + ics->indexed = 1; + ics->channel = chan; +} + +static int stmpe_adc_init_hw(struct stmpe_adc *adc) +{ + int ret; + struct stmpe *stmpe = adc->stmpe; + + ret = stmpe_enable(stmpe, STMPE_BLOCK_ADC); + if (ret) { + dev_err(stmpe->dev, "Could not enable clock for ADC\n"); + return ret; + } + + ret = stmpe811_adc_common_init(stmpe); + if (ret) { + stmpe_disable(stmpe, STMPE_BLOCK_ADC); + return ret; + } + + /* use temp irq for each conversion completion */ + stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH, 0); + stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH + 1, 0); + + return 0; +} + +static int stmpe_adc_probe(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = NULL; + struct stmpe_adc *info = NULL; + struct device_node *np; + u32 norequest_mask = 0; + int irq_temp, irq_adc; + int num_chan = 0; + int i = 0; + int ret; + + irq_adc = platform_get_irq_byname(pdev, "STMPE_ADC"); + if (irq_adc < 0) + return irq_adc; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct stmpe_adc)); + if (!indio_dev) { + dev_err(&pdev->dev, "failed allocating iio device\n"); + return -ENOMEM; + } + + info = iio_priv(indio_dev); + mutex_init(&info->lock); + + init_completion(&info->completion); + ret = devm_request_threaded_irq(&pdev->dev, irq_adc, NULL, + stmpe_adc_isr, IRQF_ONESHOT, + "stmpe-adc", info); + if (ret < 0) { + dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", + irq_adc); + return ret; + } + + irq_temp = platform_get_irq_byname(pdev, "STMPE_TEMP_SENS"); + if (irq_temp >= 0) { + ret = devm_request_threaded_irq(&pdev->dev, irq_temp, NULL, + stmpe_adc_isr, IRQF_ONESHOT, + "stmpe-adc", info); + if (ret < 0) + dev_warn(&pdev->dev, "failed requesting irq for" + " temp sensor, irq = %d\n", irq_temp); + } + + platform_set_drvdata(pdev, indio_dev); + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->info = &stmpe_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE; + + info->stmpe = dev_get_drvdata(pdev->dev.parent); + + np = pdev->dev.of_node; + + if (!np) + dev_err(&pdev->dev, "no device tree node found\n"); + + of_property_read_u32(np, "st,norequest-mask", &norequest_mask); + + for_each_clear_bit(i, (unsigned long *) &norequest_mask, + (STMPE_ADC_LAST_NR + 1)) { + stmpe_adc_voltage_chan(&info->stmpe_adc_iio_channels[num_chan], i); + num_chan++; + } + stmpe_adc_temp_chan(&info->stmpe_adc_iio_channels[num_chan], i); + num_chan++; + indio_dev->channels = info->stmpe_adc_iio_channels; + indio_dev->num_channels = num_chan; + + ret = stmpe_adc_init_hw(info); + if (ret) + return ret; + + ret = iio_device_register(indio_dev); + if (ret) + return ret; + + return devm_add_action_or_reset(&pdev->dev, + (void (*)(void *))iio_device_unregister, indio_dev); +} + +static int __maybe_unused stmpe_adc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct stmpe_adc *info = iio_priv(indio_dev); + + stmpe_adc_init_hw(info); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume); + +static struct platform_driver stmpe_adc_driver = { + .probe = stmpe_adc_probe, + .driver = { + .name = "stmpe-adc", + .pm = &stmpe_adc_pm_ops, + }, +}; + +module_platform_driver(stmpe_adc_driver); + +MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>"); +MODULE_DESCRIPTION("STMPEXXX ADC driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:stmpe-adc"); -- 2.19.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 5/8] iio: adc: add STMPE ADC driver using IIO framework 2018-12-12 13:06 ` [PATCH v4 5/8] iio: adc: add STMPE ADC driver using IIO framework Philippe Schenker @ 2018-12-16 12:24 ` Jonathan Cameron 0 siblings, 0 replies; 5+ messages in thread From: Jonathan Cameron @ 2018-12-16 12:24 UTC (permalink / raw) To: Philippe Schenker Cc: marcel.ziswiler, stefan, thierry.reding, Max Krummenacher, Philippe Schenker, Arnd Bergmann, Arnaud Pouliquen, linux-iio, Mark Brown, Geert Uytterhoeven, William Breathitt Gray, linux-stm32, Baolin Wang, Randy Dunlap, Marcus Folkesson, Freeman Liu, Eugen Hristev, Peter Meerwald-Stadler, Maxime Coquelin, Hartmut Knaack, linux-arm-kernel, Alexandre Torgue, Siddartha Mohanadoss, linux-kernel, Lars-Peter Clausen, Kent Gustavsson On Wed, 12 Dec 2018 14:06:46 +0100 Philippe Schenker <dev@pschenker.ch> wrote: > This adds an ADC driver for the STMPE device using the industrial > input/output interface. The driver supports raw reading of values. > The driver depends on the MFD STMPE driver. If the touchscreen > block is enabled too, only four of the 8 ADC channels are available. > > Signed-off-by: Stefan Agner <stefan@agner.ch> > Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com> Hi. A few trivial comments inline. Fix those up and you can add my Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Thanks, Jonathan > --- > > Changes in v4: > - Moved MFD changes to a precursor patch > - Moved stmpe-ts changes to a precursor patch > - Created stmpe_read_temp and stmpe_read_voltage functions to make > read_raw more readable > - Added local lock instead of using indio_dev's mlock > - Use be16_to_cpu() macro instead of bitshifting > - Added stmpe_enable again to stmpe_adc_init_hw > - Use devm_add_action_or_reset to get rid of the remove function > (I tested if that actually works) > > Changes in v3: > - Removed COMPILE_TEST from dependings in Kconfig > - Removed stmpe_adc_get_platform_info() function and integrated the > few code lines in the other function > > Changes in v2: > - Code formatting > - Removed unused includes > - Defined the macro STMPE_START_ONE_TEMP_CONV with other macros. > - Added new macro that defines the channel of the temperature sensor. > Took new name for STMPE_MAX_ADC->STMPE_ADC_LAST_NR and used it > throughout the code for better readability. > - Added mutex_unlock where missing. > > drivers/iio/adc/Kconfig | 7 + > drivers/iio/adc/Makefile | 1 + > drivers/iio/adc/stmpe-adc.c | 368 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 376 insertions(+) > create mode 100644 drivers/iio/adc/stmpe-adc.c > > diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig > index a52fea8749a9..224f2067494d 100644 > --- a/drivers/iio/adc/Kconfig > +++ b/drivers/iio/adc/Kconfig > @@ -734,6 +734,13 @@ config STM32_DFSDM_ADC > This driver can also be built as a module. If so, the module > will be called stm32-dfsdm-adc. > > +config STMPE_ADC > + tristate "STMicroelectronics STMPE ADC driver" > + depends on OF && MFD_STMPE > + help > + Say yes here to build support for ST Microelectronics STMPE > + built-in ADC block (stmpe811). > + > config STX104 > tristate "Apex Embedded Systems STX104 driver" > depends on PC104 && X86 > diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile > index a6e6a0b659e2..cba889c30bf9 100644 > --- a/drivers/iio/adc/Makefile > +++ b/drivers/iio/adc/Makefile > @@ -69,6 +69,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o > obj-$(CONFIG_STM32_ADC) += stm32-adc.o > obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o > obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o > +obj-$(CONFIG_STMPE_ADC) += stmpe-adc.o > obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o > obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o > obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o > diff --git a/drivers/iio/adc/stmpe-adc.c b/drivers/iio/adc/stmpe-adc.c > new file mode 100644 > index 000000000000..4333da19a097 > --- /dev/null > +++ b/drivers/iio/adc/stmpe-adc.c > @@ -0,0 +1,368 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * STMicroelectronics STMPE811 IIO ADC Driver > + * > + * 4 channel, 10/12-bit ADC > + * > + * Copyright (C) 2013-2018 Toradex AG <stefan.agner@toradex.com> > + */ > + > +#include <linux/completion.h> > +#include <linux/err.h> > +#include <linux/iio/iio.h> > +#include <linux/interrupt.h> > +#include <linux/kernel.h> > +#include <linux/mfd/stmpe.h> > +#include <linux/module.h> > +#include <linux/of_platform.h> > +#include <linux/platform_device.h> > +#include <linux/device.h> > + > +#define STMPE_REG_INT_STA 0x0B > +#define STMPE_REG_ADC_INT_EN 0x0E > +#define STMPE_REG_ADC_INT_STA 0x0F > + > +#define STMPE_REG_ADC_CTRL1 0x20 > +#define STMPE_REG_ADC_CTRL2 0x21 > +#define STMPE_REG_ADC_CAPT 0x22 > +#define STMPE_REG_ADC_DATA_CH(channel) (0x30 + 2 * (channel)) > + > +#define STMPE_REG_TEMP_CTRL 0x60 > +#define STMPE_TEMP_CTRL_ENABLE BIT(0) > +#define STMPE_TEMP_CTRL_ACQ BIT(1) > +#define STMPE_TEMP_CTRL_THRES_EN BIT(3) > +#define STMPE_START_ONE_TEMP_CONV (STMPE_TEMP_CTRL_ENABLE | \ > + STMPE_TEMP_CTRL_ACQ | \ > + STMPE_TEMP_CTRL_THRES_EN) > +#define STMPE_REG_TEMP_DATA 0x61 > +#define STMPE_REG_TEMP_TH 0x63 > +#define STMPE_ADC_LAST_NR 7 > +#define STMPE_TEMP_CHANNEL (STMPE_ADC_LAST_NR + 1) > + > +#define STMPE_ADC_CH(channel) ((1 << (channel)) & 0xff) > + > +#define STMPE_ADC_TIMEOUT msecs_to_jiffies(1000) > + > +struct stmpe_adc { > + struct stmpe *stmpe; > + struct clk *clk; > + struct device *dev; > + struct mutex lock; > + > + /* We are allocating plus one for the temperature channel */ > + struct iio_chan_spec stmpe_adc_iio_channels[STMPE_ADC_LAST_NR + 2]; > + > + struct completion completion; > + > + u8 channel; > + u32 value; > +}; > + > +static int stmpe_read_voltage(struct stmpe_adc *info, > + struct iio_chan_spec const *chan, int *val) > +{ > + long ret; > + > + mutex_lock(&info->lock); > + > + info->channel = (u8)chan->channel; > + > + if (info->channel > STMPE_ADC_LAST_NR) { > + mutex_unlock(&info->lock); > + return -EINVAL; > + } > + > + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN, > + STMPE_ADC_CH(info->channel)); > + > + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT, > + STMPE_ADC_CH(info->channel)); > + > + *val = info->value; > + > + ret = wait_for_completion_interruptible_timeout > + (&info->completion, STMPE_ADC_TIMEOUT); > + > + if (ret <= 0) { > + mutex_unlock(&info->lock); > + if (ret == 0) > + return -ETIMEDOUT; > + else > + return ret; > + } > + > + *val = info->value; > + > + mutex_unlock(&info->lock); > + > + return 0; > +} > + > +static int stmpe_read_temp(struct stmpe_adc *info, > + struct iio_chan_spec const *chan, int *val) > +{ > + long ret; > + > + mutex_lock(&info->lock); > + > + info->channel = (u8)chan->channel; > + > + if (info->channel != STMPE_TEMP_CHANNEL) { > + mutex_unlock(&info->lock); > + return -EINVAL; > + } > + > + stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL, > + STMPE_START_ONE_TEMP_CONV); > + > + ret = wait_for_completion_interruptible_timeout > + (&info->completion, STMPE_ADC_TIMEOUT); > + > + if (ret <= 0) { > + mutex_unlock(&info->lock); > + if (ret == 0) > + return -ETIMEDOUT; > + else > + return ret; > + } > + > + /* > + * absolute temp = +V3.3 * value /7.51 [K] > + * scale to [milli °C] > + */ > + *val = ((449960l * info->value) / 1024l) - 273150; > + > + mutex_unlock(&info->lock); > + > + return 0; > +} > + > +static int stmpe_read_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, > + int *val, > + int *val2, > + long mask) > +{ > + struct stmpe_adc *info = iio_priv(indio_dev); > + long ret; > + > + switch (mask) { > + case IIO_CHAN_INFO_RAW: > + case IIO_CHAN_INFO_PROCESSED: > + > + switch (chan->type) { > + case IIO_VOLTAGE: > + ret = stmpe_read_voltage(info, chan, val); > + break; > + > + case IIO_TEMP: > + ret = stmpe_read_temp(info, chan, val); > + break; > + default: > + return -EINVAL; > + } > + > + if (ret < 0) > + return ret; > + > + return IIO_VAL_INT; > + > + case IIO_CHAN_INFO_SCALE: > + *val = 3300; > + *val2 = info->stmpe->mod_12b ? 12 : 10; > + return IIO_VAL_FRACTIONAL_LOG2; > + > + default: > + break; > + } > + > + return -EINVAL; > +} > + > +static irqreturn_t stmpe_adc_isr(int irq, void *dev_id) > +{ > + struct stmpe_adc *info = (struct stmpe_adc *)dev_id; > + u16 data; > + > + if (info->channel > STMPE_TEMP_CHANNEL) > + return IRQ_NONE; > + > + if (info->channel <= STMPE_ADC_LAST_NR) { > + int int_sta; > + > + int_sta = stmpe_reg_read(info->stmpe, STMPE_REG_ADC_INT_STA); > + > + /* Is the interrupt relevant */ > + if (!(int_sta & STMPE_ADC_CH(info->channel))) > + return IRQ_NONE; > + > + /* Read value */ > + stmpe_block_read(info->stmpe, > + STMPE_REG_ADC_DATA_CH(info->channel), 2, (u8 *) &data); > + > + stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, int_sta); > + } else if (info->channel == STMPE_TEMP_CHANNEL) { > + /* Read value */ > + stmpe_block_read(info->stmpe, STMPE_REG_TEMP_DATA, 2, > + (u8 *) &data); > + } > + > + info->value = (u32) be16_to_cpu(data); > + complete(&info->completion); > + > + return IRQ_HANDLED; > +} > + > +static const struct iio_info stmpe_adc_iio_info = { > + .read_raw = &stmpe_read_raw, > +}; > + > +static void stmpe_adc_voltage_chan(struct iio_chan_spec *ics, int chan) > +{ > + ics->type = IIO_VOLTAGE; > + ics->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); > + ics->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); > + ics->indexed = 1; > + ics->channel = chan; > +} > + > +static void stmpe_adc_temp_chan(struct iio_chan_spec *ics, int chan) > +{ > + ics->type = IIO_TEMP; > + ics->info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED); > + ics->indexed = 1; > + ics->channel = chan; > +} > + > +static int stmpe_adc_init_hw(struct stmpe_adc *adc) > +{ > + int ret; > + struct stmpe *stmpe = adc->stmpe; > + > + ret = stmpe_enable(stmpe, STMPE_BLOCK_ADC); > + if (ret) { > + dev_err(stmpe->dev, "Could not enable clock for ADC\n"); > + return ret; > + } > + > + ret = stmpe811_adc_common_init(stmpe); > + if (ret) { > + stmpe_disable(stmpe, STMPE_BLOCK_ADC); > + return ret; > + } > + > + /* use temp irq for each conversion completion */ > + stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH, 0); > + stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH + 1, 0); > + > + return 0; > +} > + > +static int stmpe_adc_probe(struct platform_device *pdev) > +{ > + struct iio_dev *indio_dev = NULL; No need to initialize. It's set in all the paths where it can be used. > + struct stmpe_adc *info = NULL; Same with this one. > + struct device_node *np; > + u32 norequest_mask = 0; > + int irq_temp, irq_adc; > + int num_chan = 0; > + int i = 0; > + int ret; > + > + irq_adc = platform_get_irq_byname(pdev, "STMPE_ADC"); > + if (irq_adc < 0) > + return irq_adc; > + > + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct stmpe_adc)); > + if (!indio_dev) { > + dev_err(&pdev->dev, "failed allocating iio device\n"); > + return -ENOMEM; > + } > + > + info = iio_priv(indio_dev); > + mutex_init(&info->lock); > + > + init_completion(&info->completion); > + ret = devm_request_threaded_irq(&pdev->dev, irq_adc, NULL, > + stmpe_adc_isr, IRQF_ONESHOT, > + "stmpe-adc", info); > + if (ret < 0) { > + dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", > + irq_adc); > + return ret; > + } > + > + irq_temp = platform_get_irq_byname(pdev, "STMPE_TEMP_SENS"); > + if (irq_temp >= 0) { > + ret = devm_request_threaded_irq(&pdev->dev, irq_temp, NULL, > + stmpe_adc_isr, IRQF_ONESHOT, > + "stmpe-adc", info); > + if (ret < 0) > + dev_warn(&pdev->dev, "failed requesting irq for" > + " temp sensor, irq = %d\n", irq_temp); > + } > + > + platform_set_drvdata(pdev, indio_dev); > + > + indio_dev->name = dev_name(&pdev->dev); > + indio_dev->dev.parent = &pdev->dev; > + indio_dev->info = &stmpe_adc_iio_info; > + indio_dev->modes = INDIO_DIRECT_MODE; > + > + info->stmpe = dev_get_drvdata(pdev->dev.parent); > + > + np = pdev->dev.of_node; > + > + if (!np) > + dev_err(&pdev->dev, "no device tree node found\n"); > + > + of_property_read_u32(np, "st,norequest-mask", &norequest_mask); > + > + for_each_clear_bit(i, (unsigned long *) &norequest_mask, > + (STMPE_ADC_LAST_NR + 1)) { > + stmpe_adc_voltage_chan(&info->stmpe_adc_iio_channels[num_chan], i); > + num_chan++; > + } > + stmpe_adc_temp_chan(&info->stmpe_adc_iio_channels[num_chan], i); > + num_chan++; > + indio_dev->channels = info->stmpe_adc_iio_channels; > + indio_dev->num_channels = num_chan; > + > + ret = stmpe_adc_init_hw(info); > + if (ret) > + return ret; > + > + ret = iio_device_register(indio_dev); > + if (ret) > + return ret; > + > + return devm_add_action_or_reset(&pdev->dev, > + (void (*)(void *))iio_device_unregister, indio_dev); Why do this? devm_iio_device_register exists which is basically the same thing but more readable! > +} > + > +static int __maybe_unused stmpe_adc_resume(struct device *dev) > +{ > + struct iio_dev *indio_dev = dev_get_drvdata(dev); > + struct stmpe_adc *info = iio_priv(indio_dev); > + > + stmpe_adc_init_hw(info); > + > + return 0; > +} > + > +static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume); > + > +static struct platform_driver stmpe_adc_driver = { > + .probe = stmpe_adc_probe, > + .driver = { > + .name = "stmpe-adc", > + .pm = &stmpe_adc_pm_ops, > + }, > +}; > + > +module_platform_driver(stmpe_adc_driver); > + > +MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>"); > +MODULE_DESCRIPTION("STMPEXXX ADC driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:stmpe-adc"); ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings [not found] <20181212130649.15146-1-dev@pschenker.ch> 2018-12-12 13:06 ` [PATCH v4 5/8] iio: adc: add STMPE ADC driver using IIO framework Philippe Schenker @ 2018-12-12 13:06 ` Philippe Schenker 2018-12-16 12:28 ` Jonathan Cameron 2018-12-17 22:15 ` Rob Herring 1 sibling, 2 replies; 5+ messages in thread From: Philippe Schenker @ 2018-12-12 13:06 UTC (permalink / raw) To: jic23, marcel.ziswiler, stefan Cc: thierry.reding, Max Krummenacher, Philippe Schenker, devicetree, linux-iio, Hartmut Knaack, Alexandre Torgue, linux-input, linux-kernel, Rob Herring, Dmitry Torokhov, Lee Jones, Maxime Coquelin, Mark Rutland, Peter Meerwald-Stadler, linux-stm32, linux-arm-kernel, Lars-Peter Clausen From: Stefan Agner <stefan@agner.ch> This adds the devicetree bindings for the STMPE ADC. And corrects a typo in st,sample-time it is rather "6 -> 124 clocks" according to the datasheet and not 144. Signed-off-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com> --- Changes in v4: - Put reformatting in a separate precursor patch. Changes in v3: - Reformatted documentation for touchscreen to use tabs and have a better overview of the settings. - Added note which adc-settings will take precedence. - changed typo in sample-time setting from 144 clocks to 124 clocks, as stated in the datasheet. Changes in v2: - Moved the bindings for ADC to the overlying mfd. - Reformatted for better readability .../devicetree/bindings/iio/adc/stmpe-adc.txt | 21 ++++++++++++ .../bindings/input/touchscreen/stmpe.txt | 32 +++++++++---------- .../devicetree/bindings/mfd/stmpe.txt | 14 ++++++++ 3 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt new file mode 100644 index 000000000000..480e66422625 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt @@ -0,0 +1,21 @@ +STMPE ADC driver +---------------- + +Required properties: + - compatible: "st,stmpe-adc" + +Optional properties: +Note that the ADC is shared with the STMPE touchscreen. ADC related settings +have to be done in the mfd. +- st,norequest-mask: bitmask specifying which ADC channels should _not_ be + requestable due to different usage (e.g. touch) + +Node name must be stmpe_adc and should be child node of stmpe node to +which it belongs. + +Example: + + stmpe_adc { + compatible = "st,stmpe-adc"; + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt index 1d3f84308142..8e2b240882fa 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt @@ -5,18 +5,6 @@ Required properties: - compatible: "st,stmpe-ts" Optional properties: -- st,sample-time : ADC conversion time in number of clock. - 0 -> 36 clocks 4 -> 80 clocks (recommended) - 1 -> 44 clocks 5 -> 96 clocks - 2 -> 56 clocks 6 -> 144 clocks - 3 -> 64 clocks -- st,mod-12b : ADC Bit mode - 0 -> 10bit ADC 1 -> 12bit ADC -- st,ref-sel : ADC reference source - 0 -> internal 1 -> external -- st,adc-freq : ADC Clock speed - 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz - 1 -> 3.25 MHz - st,ave-ctrl : Sample average control 0 -> 1 sample 1 -> 2 samples @@ -40,17 +28,29 @@ Optional properties: 0 -> 20 mA (typical 35mA max) 1 -> 50 mA (typical 80 mA max) +Optional properties common with MFD (deprecated): + - st,sample-time : ADC conversion time in number of clock. + 0 -> 36 clocks 4 -> 80 clocks (recommended) + 1 -> 44 clocks 5 -> 96 clocks + 2 -> 56 clocks 6 -> 124 clocks + 3 -> 64 clocks + - st,mod-12b : ADC Bit mode + 0 -> 10bit ADC 1 -> 12bit ADC + - st,ref-sel : ADC reference source + 0 -> internal 1 -> external + - st,adc-freq : ADC Clock speed + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz + 1 -> 3.25 MHz + Node name must be stmpe_touchscreen and should be child node of stmpe node to which it belongs. +Note that common ADC settings of stmpe_touchscreen will take precedence. + Example: stmpe_touchscreen { compatible = "st,stmpe-ts"; - st,sample-time = <4>; - st,mod-12b = <1>; - st,ref-sel = <0>; - st,adc-freq = <1>; st,ave-ctrl = <1>; st,touch-det-delay = <2>; st,settling = <2>; diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt index a46e7177195d..d4408a417193 100644 --- a/Documentation/devicetree/bindings/mfd/stmpe.txt +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt @@ -14,6 +14,20 @@ Optional properties: - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024 - irq-gpio : If present, which GPIO to use for event IRQ +Optional properties for devices with touch and ADC (STMPE811|STMPE610): + - st,sample-time : ADC conversion time in number of clock. + 0 -> 36 clocks 4 -> 80 clocks (recommended) + 1 -> 44 clocks 5 -> 96 clocks + 2 -> 56 clocks 6 -> 124 clocks + 3 -> 64 clocks + - st,mod-12b : ADC Bit mode + 0 -> 10bit ADC 1 -> 12bit ADC + - st,ref-sel : ADC reference source + 0 -> internal 1 -> external + - st,adc-freq : ADC Clock speed + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz + 1 -> 3.25 MHz + Example: stmpe1601: stmpe1601@40 { -- 2.19.2 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings 2018-12-12 13:06 ` [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings Philippe Schenker @ 2018-12-16 12:28 ` Jonathan Cameron 2018-12-17 22:15 ` Rob Herring 1 sibling, 0 replies; 5+ messages in thread From: Jonathan Cameron @ 2018-12-16 12:28 UTC (permalink / raw) To: Philippe Schenker Cc: marcel.ziswiler, stefan, thierry.reding, Max Krummenacher, Philippe Schenker, devicetree, linux-iio, Hartmut Knaack, Alexandre Torgue, linux-input, linux-kernel, Rob Herring, Dmitry Torokhov, Lee Jones, Maxime Coquelin, Mark Rutland, Peter Meerwald-Stadler, linux-stm32, linux-arm-kernel, Lars-Peter Clausen On Wed, 12 Dec 2018 14:06:47 +0100 Philippe Schenker <dev@pschenker.ch> wrote: > From: Stefan Agner <stefan@agner.ch> > > This adds the devicetree bindings for the STMPE ADC. And corrects a > typo in st,sample-time it is rather "6 -> 124 clocks" according > to the datasheet and not 144. > > Signed-off-by: Stefan Agner <stefan@agner.ch> > Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com> This still conflates a couple of different things but we can argue about patch separation for ever so never mind. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > --- > > Changes in v4: > - Put reformatting in a separate precursor patch. > > Changes in v3: > - Reformatted documentation for touchscreen to use tabs and have a better > overview of the settings. > - Added note which adc-settings will take precedence. > - changed typo in sample-time setting from 144 clocks to 124 clocks, as stated > in the datasheet. > > Changes in v2: > - Moved the bindings for ADC to the overlying mfd. > - Reformatted for better readability > > .../devicetree/bindings/iio/adc/stmpe-adc.txt | 21 ++++++++++++ > .../bindings/input/touchscreen/stmpe.txt | 32 +++++++++---------- > .../devicetree/bindings/mfd/stmpe.txt | 14 ++++++++ > 3 files changed, 51 insertions(+), 16 deletions(-) > create mode 100644 Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > > diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > new file mode 100644 > index 000000000000..480e66422625 > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > @@ -0,0 +1,21 @@ > +STMPE ADC driver > +---------------- > + > +Required properties: > + - compatible: "st,stmpe-adc" > + > +Optional properties: > +Note that the ADC is shared with the STMPE touchscreen. ADC related settings > +have to be done in the mfd. > +- st,norequest-mask: bitmask specifying which ADC channels should _not_ be > + requestable due to different usage (e.g. touch) > + > +Node name must be stmpe_adc and should be child node of stmpe node to > +which it belongs. > + > +Example: > + > + stmpe_adc { > + compatible = "st,stmpe-adc"; > + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ > + }; > diff --git a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > index 1d3f84308142..8e2b240882fa 100644 > --- a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > +++ b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > @@ -5,18 +5,6 @@ Required properties: > - compatible: "st,stmpe-ts" > > Optional properties: > -- st,sample-time : ADC conversion time in number of clock. > - 0 -> 36 clocks 4 -> 80 clocks (recommended) > - 1 -> 44 clocks 5 -> 96 clocks > - 2 -> 56 clocks 6 -> 144 clocks > - 3 -> 64 clocks > -- st,mod-12b : ADC Bit mode > - 0 -> 10bit ADC 1 -> 12bit ADC > -- st,ref-sel : ADC reference source > - 0 -> internal 1 -> external > -- st,adc-freq : ADC Clock speed > - 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > - 1 -> 3.25 MHz > - st,ave-ctrl : Sample average control > 0 -> 1 sample > 1 -> 2 samples > @@ -40,17 +28,29 @@ Optional properties: > 0 -> 20 mA (typical 35mA max) > 1 -> 50 mA (typical 80 mA max) > > +Optional properties common with MFD (deprecated): > + - st,sample-time : ADC conversion time in number of clock. > + 0 -> 36 clocks 4 -> 80 clocks (recommended) > + 1 -> 44 clocks 5 -> 96 clocks > + 2 -> 56 clocks 6 -> 124 clocks > + 3 -> 64 clocks > + - st,mod-12b : ADC Bit mode > + 0 -> 10bit ADC 1 -> 12bit ADC > + - st,ref-sel : ADC reference source > + 0 -> internal 1 -> external > + - st,adc-freq : ADC Clock speed > + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > + 1 -> 3.25 MHz > + > Node name must be stmpe_touchscreen and should be child node of stmpe node to > which it belongs. > > +Note that common ADC settings of stmpe_touchscreen will take precedence. > + > Example: > > stmpe_touchscreen { > compatible = "st,stmpe-ts"; > - st,sample-time = <4>; > - st,mod-12b = <1>; > - st,ref-sel = <0>; > - st,adc-freq = <1>; > st,ave-ctrl = <1>; > st,touch-det-delay = <2>; > st,settling = <2>; > diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt > index a46e7177195d..d4408a417193 100644 > --- a/Documentation/devicetree/bindings/mfd/stmpe.txt > +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt > @@ -14,6 +14,20 @@ Optional properties: > - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024 > - irq-gpio : If present, which GPIO to use for event IRQ > > +Optional properties for devices with touch and ADC (STMPE811|STMPE610): > + - st,sample-time : ADC conversion time in number of clock. > + 0 -> 36 clocks 4 -> 80 clocks (recommended) > + 1 -> 44 clocks 5 -> 96 clocks > + 2 -> 56 clocks 6 -> 124 clocks > + 3 -> 64 clocks > + - st,mod-12b : ADC Bit mode > + 0 -> 10bit ADC 1 -> 12bit ADC > + - st,ref-sel : ADC reference source > + 0 -> internal 1 -> external > + - st,adc-freq : ADC Clock speed > + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > + 1 -> 3.25 MHz > + > Example: > > stmpe1601: stmpe1601@40 { ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings 2018-12-12 13:06 ` [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings Philippe Schenker 2018-12-16 12:28 ` Jonathan Cameron @ 2018-12-17 22:15 ` Rob Herring 1 sibling, 0 replies; 5+ messages in thread From: Rob Herring @ 2018-12-17 22:15 UTC (permalink / raw) To: Philippe Schenker Cc: jic23, marcel.ziswiler, stefan, thierry.reding, Max Krummenacher, Philippe Schenker, devicetree, linux-iio, Hartmut Knaack, Alexandre Torgue, linux-input, linux-kernel, Dmitry Torokhov, Lee Jones, Maxime Coquelin, Mark Rutland, Peter Meerwald-Stadler, linux-stm32, linux-arm-kernel, Lars-Peter Clausen On Wed, Dec 12, 2018 at 02:06:47PM +0100, Philippe Schenker wrote: > From: Stefan Agner <stefan@agner.ch> > > This adds the devicetree bindings for the STMPE ADC. And corrects a > typo in st,sample-time it is rather "6 -> 124 clocks" according > to the datasheet and not 144. > > Signed-off-by: Stefan Agner <stefan@agner.ch> > Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com> > Signed-off-by: Philippe Schenker <philippe.schenker@toradex.com> > --- > > Changes in v4: > - Put reformatting in a separate precursor patch. > > Changes in v3: > - Reformatted documentation for touchscreen to use tabs and have a better > overview of the settings. > - Added note which adc-settings will take precedence. > - changed typo in sample-time setting from 144 clocks to 124 clocks, as stated > in the datasheet. > > Changes in v2: > - Moved the bindings for ADC to the overlying mfd. > - Reformatted for better readability > > .../devicetree/bindings/iio/adc/stmpe-adc.txt | 21 ++++++++++++ > .../bindings/input/touchscreen/stmpe.txt | 32 +++++++++---------- > .../devicetree/bindings/mfd/stmpe.txt | 14 ++++++++ > 3 files changed, 51 insertions(+), 16 deletions(-) > create mode 100644 Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > > diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > new file mode 100644 > index 000000000000..480e66422625 > --- /dev/null > +++ b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt > @@ -0,0 +1,21 @@ > +STMPE ADC driver > +---------------- > + > +Required properties: > + - compatible: "st,stmpe-adc" > + > +Optional properties: > +Note that the ADC is shared with the STMPE touchscreen. ADC related settings > +have to be done in the mfd. > +- st,norequest-mask: bitmask specifying which ADC channels should _not_ be > + requestable due to different usage (e.g. touch) > + > +Node name must be stmpe_adc and should be child node of stmpe node to > +which it belongs. > + > +Example: > + > + stmpe_adc { > + compatible = "st,stmpe-adc"; > + st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ > + }; > diff --git a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > index 1d3f84308142..8e2b240882fa 100644 > --- a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > +++ b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt > @@ -5,18 +5,6 @@ Required properties: > - compatible: "st,stmpe-ts" > > Optional properties: > -- st,sample-time : ADC conversion time in number of clock. > - 0 -> 36 clocks 4 -> 80 clocks (recommended) > - 1 -> 44 clocks 5 -> 96 clocks > - 2 -> 56 clocks 6 -> 144 clocks > - 3 -> 64 clocks > -- st,mod-12b : ADC Bit mode > - 0 -> 10bit ADC 1 -> 12bit ADC > -- st,ref-sel : ADC reference source > - 0 -> internal 1 -> external > -- st,adc-freq : ADC Clock speed > - 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > - 1 -> 3.25 MHz > - st,ave-ctrl : Sample average control > 0 -> 1 sample > 1 -> 2 samples > @@ -40,17 +28,29 @@ Optional properties: > 0 -> 20 mA (typical 35mA max) > 1 -> 50 mA (typical 80 mA max) > > +Optional properties common with MFD (deprecated): > + - st,sample-time : ADC conversion time in number of clock. > + 0 -> 36 clocks 4 -> 80 clocks (recommended) > + 1 -> 44 clocks 5 -> 96 clocks > + 2 -> 56 clocks 6 -> 124 clocks > + 3 -> 64 clocks > + - st,mod-12b : ADC Bit mode > + 0 -> 10bit ADC 1 -> 12bit ADC > + - st,ref-sel : ADC reference source > + 0 -> internal 1 -> external > + - st,adc-freq : ADC Clock speed > + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > + 1 -> 3.25 MHz > + > Node name must be stmpe_touchscreen and should be child node of stmpe node to > which it belongs. > > +Note that common ADC settings of stmpe_touchscreen will take precedence. This isn't clear. The parent or child properties take precedence? > + > Example: > > stmpe_touchscreen { > compatible = "st,stmpe-ts"; > - st,sample-time = <4>; > - st,mod-12b = <1>; > - st,ref-sel = <0>; > - st,adc-freq = <1>; It would be nice to see an example with both ADC and touchscreen. > st,ave-ctrl = <1>; > st,touch-det-delay = <2>; > st,settling = <2>; > diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt > index a46e7177195d..d4408a417193 100644 > --- a/Documentation/devicetree/bindings/mfd/stmpe.txt > +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt > @@ -14,6 +14,20 @@ Optional properties: > - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024 > - irq-gpio : If present, which GPIO to use for event IRQ > > +Optional properties for devices with touch and ADC (STMPE811|STMPE610): > + - st,sample-time : ADC conversion time in number of clock. > + 0 -> 36 clocks 4 -> 80 clocks (recommended) > + 1 -> 44 clocks 5 -> 96 clocks > + 2 -> 56 clocks 6 -> 124 clocks > + 3 -> 64 clocks > + - st,mod-12b : ADC Bit mode > + 0 -> 10bit ADC 1 -> 12bit ADC > + - st,ref-sel : ADC reference source > + 0 -> internal 1 -> external > + - st,adc-freq : ADC Clock speed > + 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz > + 1 -> 3.25 MHz > + > Example: > > stmpe1601: stmpe1601@40 { > -- > 2.19.2 > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-12-17 22:15 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- [not found] <20181212130649.15146-1-dev@pschenker.ch> 2018-12-12 13:06 ` [PATCH v4 5/8] iio: adc: add STMPE ADC driver using IIO framework Philippe Schenker 2018-12-16 12:24 ` Jonathan Cameron 2018-12-12 13:06 ` [PATCH v4 6/8] iio: adc: add STMPE ADC devicetree bindings Philippe Schenker 2018-12-16 12:28 ` Jonathan Cameron 2018-12-17 22:15 ` Rob Herring
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).