Received: by 10.223.176.46 with SMTP id f43csp1783225wra; Sun, 21 Jan 2018 04:27:42 -0800 (PST) X-Google-Smtp-Source: AH8x225a5VObaJkb2WXjwhqoi3zIgr4lPHbeyoLmPXRh62qlDiv0lcvLM6XjPfpm+su30tQLmlUq X-Received: by 10.99.139.195 with SMTP id j186mr4401464pge.188.1516537662799; Sun, 21 Jan 2018 04:27:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516537662; cv=none; d=google.com; s=arc-20160816; b=fUv5oss7GPkSSLMYbEluK8dlZ5S5/RkANq4HQZyd6J6d0AAjY5pYKVUxKRk06C0UWx Rc943b3ol6fzHz2Mh3DFW8wQSve8h9aZFwlmF7PKbFLPZSED32az8moUT6w7qho7Mfp5 dBjvKVCGa1c6XDyr5cxFkydPDQlRZl8CqwjfwB59+hv2hm1Hduc0QMfumlGJTX4gf+XN hRzhDan58hd758OMiT7AKnV2U5IcPJhW61Hagka94jEXSPcFq7kfk/+zQDfVKI0cCqBe 7yTcy2rhmLLm415pRS5tMQc+w249PR1JiUfDcSi9/0sBqWMkOChggVnTP8WUnCx4yjkQ v8Kw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :dmarc-filter:arc-authentication-results; bh=llEMjoaqEt+BrwrddEqKrAdoCmkMERkgTAzWYpmZ9WE=; b=KcwLccFbH44/LF6y5cUHvcJqeF6QmQGy961djsXM3ptyGrKxzUwcqlmVwmNNNfsW9G 9fDqz/f1FcqIyGdCoLZMO4S45oXbly2XzldcQenIOlJk9hjUk7lMRdZCpq9kZeJNeUA8 Xov1Y16UvepI/+2GCzP8ceCOcdwA4uotvkljxeRLBOO/1+7/rVBBBZUZs+7SRU+22QbM U+q9orp4fOWOZiOggz9Xec2JGDJ8mubXGrD7d4wPscdwZM6x08z/mfZrdYiGtQ1WSYMW OLNKBGXvtYB1HT4epqCm16RTQ0c0vhdHCmyX5VTFPv5fHVoXUPpn0TT93vzzA3sGAFaP vxig== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 43-v6si2524158plb.498.2018.01.21.04.27.28; Sun, 21 Jan 2018 04:27:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751233AbeAUM1E (ORCPT + 99 others); Sun, 21 Jan 2018 07:27:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:47006 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751019AbeAUM1C (ORCPT ); Sun, 21 Jan 2018 07:27:02 -0500 Received: from archlinux (cpc91196-cmbg18-2-0-cust659.5-4.cable.virginm.net [81.96.234.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E109220835; Sun, 21 Jan 2018 12:26:57 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E109220835 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=jic23@kernel.org Date: Sun, 21 Jan 2018 12:26:55 +0000 From: Jonathan Cameron To: Quentin Schulz Cc: knaack.h@gmx.de, lars@metafoo.de, pmeerw@pmeerw.net, robh+dt@kernel.org, mark.rutland@arm.com, wens@csie.org, sre@kernel.org, linux@armlinux.org.uk, maxime.ripard@free-electrons.com, lee.jones@linaro.org, linux-iio@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, thomas.petazzoni@free-electrons.com, linux-sunxi@googlegroups.com, julian.calaby@gmail.com Subject: Re: [PATCH v3 07/16] iio: adc: axp20x_adc: add support for AXP813 ADC Message-ID: <20180121122655.0efd9480@archlinux> In-Reply-To: References: X-Mailer: Claws Mail 3.16.0 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, 15 Jan 2018 11:33:41 +0100 Quentin Schulz wrote: > The X-Powers AXP813 PMIC is really close to what is already done for > AXP20X/AXP22X. > > There are two pairs of bits to set the rate (one for Voltage and Current > measurements and one for TS/GPIO0 voltage measurements) instead of one. > > The register to set the ADC rates is different from the one for > AXP20X/AXP22X. > > GPIO0 can be used as an ADC (measuring Volts) unlike for AXP22X. > > The scales to apply to the different inputs are unlike the ones from > AXP20X and AXP22X. > > Signed-off-by: Quentin Schulz > Acked-by: Jonathan Cameron Applied to the togreg branch of iio.git and pushed out as testing for the autobuilders to play with it. One thing that might be nice to tidy up in this driver though. CHECK drivers/iio/adc/axp20x_adc.c drivers/iio/adc/axp20x_adc.c:548:26: warning: dubious: !x & y drivers/iio/adc/axp20x_adc.c:553:26: warning: dubious: !x & y Those are 'interesting' code constructions. It may be worth being a little more verbose to keep sparse happy and suppress the warning. Thanks, Jonathan > --- > drivers/iio/adc/axp20x_adc.c | 123 ++++++++++++++++++++++++++++++++++++- > include/linux/mfd/axp20x.h | 2 +- > 2 files changed, 125 insertions(+) > > diff --git a/drivers/iio/adc/axp20x_adc.c b/drivers/iio/adc/axp20x_adc.c > index 3968053..7cdb8bc 100644 > --- a/drivers/iio/adc/axp20x_adc.c > +++ b/drivers/iio/adc/axp20x_adc.c > @@ -35,8 +35,13 @@ > #define AXP20X_GPIO10_IN_RANGE_GPIO1_VAL(x) (((x) & BIT(0)) << 1) > > #define AXP20X_ADC_RATE_MASK GENMASK(7, 6) > +#define AXP813_V_I_ADC_RATE_MASK GENMASK(5, 4) > +#define AXP813_ADC_RATE_MASK (AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK) > #define AXP20X_ADC_RATE_HZ(x) ((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK) > #define AXP22X_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK) > +#define AXP813_TS_GPIO0_ADC_RATE_HZ(x) AXP20X_ADC_RATE_HZ(x) > +#define AXP813_V_I_ADC_RATE_HZ(x) ((ilog2((x) / 100) << 4) & AXP813_V_I_ADC_RATE_MASK) > +#define AXP813_ADC_RATE_HZ(x) (AXP20X_ADC_RATE_HZ(x) | AXP813_V_I_ADC_RATE_HZ(x)) > > #define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \ > { \ > @@ -95,6 +100,12 @@ enum axp22x_adc_channel_i { > AXP22X_BATT_DISCHRG_I, > }; > > +enum axp813_adc_channel_v { > + AXP813_TS_IN = 0, > + AXP813_GPIO0_V, > + AXP813_BATT_V, > +}; > + > static struct iio_map axp20x_maps[] = { > { > .consumer_dev_name = "axp20x-usb-power-supply", > @@ -197,6 +208,25 @@ static const struct iio_chan_spec axp22x_adc_channels[] = { > AXP20X_BATT_DISCHRG_I_H), > }; > > +static const struct iio_chan_spec axp813_adc_channels[] = { > + { > + .type = IIO_TEMP, > + .address = AXP22X_PMIC_TEMP_H, > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | > + BIT(IIO_CHAN_INFO_SCALE) | > + BIT(IIO_CHAN_INFO_OFFSET), > + .datasheet_name = "pmic_temp", > + }, > + AXP20X_ADC_CHANNEL(AXP813_GPIO0_V, "gpio0_v", IIO_VOLTAGE, > + AXP288_GP_ADC_H), > + AXP20X_ADC_CHANNEL(AXP813_BATT_V, "batt_v", IIO_VOLTAGE, > + AXP20X_BATT_V_H), > + AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT, > + AXP20X_BATT_CHRG_I_H), > + AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT, > + AXP20X_BATT_DISCHRG_I_H), > +}; > + > static int axp20x_adc_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const *chan, int *val) > { > @@ -243,6 +273,18 @@ static int axp22x_adc_raw(struct iio_dev *indio_dev, > return IIO_VAL_INT; > } > > +static int axp813_adc_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, int *val) > +{ > + struct axp20x_adc_iio *info = iio_priv(indio_dev); > + > + *val = axp20x_read_variable_width(info->regmap, chan->address, 12); > + if (*val < 0) > + return *val; > + > + return IIO_VAL_INT; > +} > + > static int axp20x_adc_scale_voltage(int channel, int *val, int *val2) > { > switch (channel) { > @@ -273,6 +315,24 @@ static int axp20x_adc_scale_voltage(int channel, int *val, int *val2) > } > } > > +static int axp813_adc_scale_voltage(int channel, int *val, int *val2) > +{ > + switch (channel) { > + case AXP813_GPIO0_V: > + *val = 0; > + *val2 = 800000; > + return IIO_VAL_INT_PLUS_MICRO; > + > + case AXP813_BATT_V: > + *val = 1; > + *val2 = 100000; > + return IIO_VAL_INT_PLUS_MICRO; > + > + default: > + return -EINVAL; > + } > +} > + > static int axp20x_adc_scale_current(int channel, int *val, int *val2) > { > switch (channel) { > @@ -342,6 +402,26 @@ static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val, > } > } > > +static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val, > + int *val2) > +{ > + switch (chan->type) { > + case IIO_VOLTAGE: > + return axp813_adc_scale_voltage(chan->channel, val, val2); > + > + case IIO_CURRENT: > + *val = 1; > + return IIO_VAL_INT; > + > + case IIO_TEMP: > + *val = 100; > + return IIO_VAL_INT; > + > + default: > + return -EINVAL; > + } > +} > + > static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel, > int *val) > { > @@ -425,6 +505,26 @@ static int axp22x_read_raw(struct iio_dev *indio_dev, > } > } > > +static int axp813_read_raw(struct iio_dev *indio_dev, > + struct iio_chan_spec const *chan, int *val, > + int *val2, long mask) > +{ > + switch (mask) { > + case IIO_CHAN_INFO_OFFSET: > + *val = -2667; > + return IIO_VAL_INT; > + > + case IIO_CHAN_INFO_SCALE: > + return axp813_adc_scale(chan, val, val2); > + > + case IIO_CHAN_INFO_RAW: > + return axp813_adc_raw(indio_dev, chan, val); > + > + default: > + return -EINVAL; > + } > +} > + > static int axp20x_write_raw(struct iio_dev *indio_dev, > struct iio_chan_spec const *chan, int val, int val2, > long mask) > @@ -470,6 +570,10 @@ static const struct iio_info axp22x_adc_iio_info = { > .read_raw = axp22x_read_raw, > }; > > +static const struct iio_info axp813_adc_iio_info = { > + .read_raw = axp813_read_raw, > +}; > + > static int axp20x_adc_rate(struct axp20x_adc_iio *info, int rate) > { > return regmap_update_bits(info->regmap, AXP20X_ADC_RATE, > @@ -484,6 +588,13 @@ static int axp22x_adc_rate(struct axp20x_adc_iio *info, int rate) > AXP22X_ADC_RATE_HZ(rate)); > } > > +static int axp813_adc_rate(struct axp20x_adc_iio *info, int rate) > +{ > + return regmap_update_bits(info->regmap, AXP813_ADC_RATE, > + AXP813_ADC_RATE_MASK, > + AXP813_ADC_RATE_HZ(rate)); > +} > + > struct axp_data { > const struct iio_info *iio_info; > int num_channels; > @@ -515,9 +626,20 @@ static const struct axp_data axp22x_data = { > .maps = axp22x_maps, > }; > > +static const struct axp_data axp813_data = { > + .iio_info = &axp813_adc_iio_info, > + .num_channels = ARRAY_SIZE(axp813_adc_channels), > + .channels = axp813_adc_channels, > + .adc_en1_mask = AXP22X_ADC_EN1_MASK, > + .adc_rate = axp813_adc_rate, > + .adc_en2 = false, > + .maps = axp22x_maps, > +}; > + > static const struct of_device_id axp20x_adc_of_match[] = { > { .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, }, > { .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, }, > + { .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, }, > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, axp20x_adc_of_match); > @@ -525,6 +647,7 @@ MODULE_DEVICE_TABLE(of, axp20x_adc_of_match); > static const struct platform_device_id axp20x_adc_id_match[] = { > { .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, }, > { .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, }, > + { .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, }, > { /* sentinel */ }, > }; > MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match); > diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h > index 080798f..82bf774 100644 > --- a/include/linux/mfd/axp20x.h > +++ b/include/linux/mfd/axp20x.h > @@ -266,6 +266,8 @@ enum axp20x_variants { > #define AXP288_RT_BATT_V_H 0xa0 > #define AXP288_RT_BATT_V_L 0xa1 > > +#define AXP813_ADC_RATE 0x85 > + > /* Fuel Gauge */ > #define AXP288_FG_RDC1_REG 0xba > #define AXP288_FG_RDC0_REG 0xbb