[PATCH 1/4] iio: adc: add support for Berlin

Antoine Tenart antoine.tenart at free-electrons.com
Wed Apr 1 06:06:08 PDT 2015


Peter,

On Fri, Mar 20, 2015 at 06:43:15PM +0100, Peter Meerwald wrote:
>
> probably these regmap_read() / _write() pairs could be MACRO()'d away 
> somehow

Sure.

> 
> the prefix SYSCTL prefix is unexpected, couldn't you use BERLIN_ or 
> something?

I'll use BERLIN2_ instead of SYSCTL_

> 
> > +#define SYSCTL_SM_CTRL				0x14
> > +#define  SYSCTL_SM_CTRL_SM_SOC_INT		BIT(1)
> 
> whitespace issue?

I added a whitespace to put the bit definitions of a register together,
so that the reading is easier.

> 
> > +#define  SYSCTL_SM_CTRL_SOC_SM_INT		BIT(2)
> > +#define  SYSCTL_SM_CTRL_ADC_SEL(x)		(BIT(x) << 5)	/* 0-15 */
> > +#define  SYSCTL_SM_CTRL_ADC_SEL_MASK		(0xf << 5)
> > +#define  SYSCTL_SM_CTRL_ADC_POWER		BIT(9)
> > +#define  SYSCTL_SM_CTRL_ADC_CLKSEL_DIV2		(0x0 << 10)
> > +#define  SYSCTL_SM_CTRL_ADC_CLKSEL_DIV3		(0x1 << 10)
> > +#define  SYSCTL_SM_CTRL_ADC_CLKSEL_DIV4		(0x2 << 10)
> > +#define  SYSCTL_SM_CTRL_ADC_CLKSEL_DIV8		(0x3 << 10)
> > +#define  SYSCTL_SM_CTRL_ADC_CLKSEL_MASK		(0x3 << 10)
> > +#define  SYSCTL_SM_CTRL_ADC_START		BIT(12)
> > +#define  SYSCTL_SM_CTRL_ADC_RESET		BIT(13)
> > +#define  SYSCTL_SM_CTRL_ADC_BANDGAP_RDY		BIT(14)
> > +#define  SYSCTL_SM_CTRL_ADC_CONT_SINGLE		(0x0 << 15)
> > +#define  SYSCTL_SM_CTRL_ADC_CONT_CONTINUOUS	(0x1 << 15)
> > +#define  SYSCTL_SM_CTRL_ADC_BUFFER_EN		BIT(16)
> > +#define  SYSCTL_SM_CTRL_ADC_VREF_EXT		(0x0 << 17)
> > +#define  SYSCTL_SM_CTRL_ADC_VREF_INT		(0x1 << 17)
> > +#define  SYSCTL_SM_CTRL_ADC_ROTATE		BIT(19)
> > +#define  SYSCTL_SM_CTRL_TSEN_EN			BIT(20)
> > +#define  SYSCTL_SM_CTRL_TSEN_CLK_SEL_125	(0x0 << 21)	/* 1.25 MHz */
> > +#define  SYSCTL_SM_CTRL_TSEN_CLK_SEL_250	(0x1 << 21)	/* 2.5 MHz */
> > +#define  SYSCTL_SM_CTRL_TSEN_MODE_0_125		(0x0 << 22)	/* 0-125 C */
> > +#define  SYSCTL_SM_CTRL_TSEN_MODE_10_50		(0x1 << 22)	/* 10-50 C */

> > +		{							\
> > +			.channel	= n,				\
> > +			.datasheet_name	= "channel"#n,			\
> > +			.type		= t,				\
> > +			.indexed	= 1,				\
> > +			.scan_index	= n,				\
> > +			.scan_type	= {				\
> > +				.sign		= 'u',			\
> > +				.realbits	= 64,			\
> > +				.storagebits	= 64,			\
> > +			},						\
> 
> the data read is not 64 bit I think
> 
> the driver does not seem to support buffered reads, so scan_type and 
> scan_index can be removed

OK.

> > +			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
> > +		}
> > +
> > +#define N_CHANNELS		8
> 
> not prefixed; would be good if you could do with ARRAY_SIZE over 
> _adc_channels instead

OK.

> 
> > +	BERLIN2_ADC_CHANNEL(0, IIO_VOLTAGE),	/* external input */
> > +	BERLIN2_ADC_CHANNEL(1, IIO_VOLTAGE),	/* external input */
> > +	BERLIN2_ADC_CHANNEL(2, IIO_VOLTAGE),	/* external input */
> > +	BERLIN2_ADC_CHANNEL(3, IIO_VOLTAGE),	/* external input */
> > +	BERLIN2_ADC_CHANNEL(4, IIO_VOLTAGE),	/* reserved */
> > +	BERLIN2_ADC_CHANNEL(5, IIO_VOLTAGE),	/* reserved */
> > +	BERLIN2_ADC_CHANNEL(6, IIO_TEMP),	/* temperature sensor */
> 
> the temperature channel is not indexed (there is only one)

I'll update.

> 
> > +	BERLIN2_ADC_CHANNEL(7, IIO_VOLTAGE),	/* reserved */
> > +	{					/* timestamp */
> 
> 
> use IIO_CHAN_SOFT_TIMESTAMP(N_CHANNELS) here

Oh, nice! I'll update.

> > +
> > +	switch (mask) {
> > +	case IIO_CHAN_INFO_RAW:
> > +		if (chan->type == IIO_VOLTAGE) {
> > +			*val = berlin2_adc_read(idev, chan->channel);
> > +			if (*val < 0)
> > +				return *val;
> 
> is this milli-Volts?

Good question. I think so, but I do not have much information about
the !tsen channels.

> 
> > +
> > +			return IIO_VAL_INT;
> > +		} else if (chan->type == IIO_TEMP) {
> > +			temp = berlin2_adc_tsen_read(idev);
> > +			if (temp < 0)
> > +				return temp;
> > +
> > +			if (temp > 2047)
> > +				temp = -(4096 - temp);
> > +
> > +			/* Convert to Celsius */
> > +			*val = (temp * 100) / 264 - 270;
> 
> use SCALE and OFFSET IIO_CHAN_INFO_s to that the temperature can be 
> interpreted as milli-Celsius (or use _PROCESSED, not _RAW)

I'll fix that.

> > +
> > +static int berlin2_adc_probe(struct platform_device *pdev)
> > +{
> > +	struct iio_dev *idev;
> 
> people prefer indio_dev instead of idev

OK.

> 
> > +	struct berlin2_adc_priv *priv;
> > +	struct device_node *parent_np = of_get_parent(pdev->dev.of_node);
> > +	int ret, val;
> > +
> > +	idev = iio_device_alloc(sizeof(struct berlin2_adc_priv));
> 
> devm_iio_device_alloc?

Yep, that's better.

> > +
> > +	ret = iio_device_register(idev);
> 
> devm_iio_device_register?

Ditto.

> 
> > +	if (ret) {
> > +		dev_err(&pdev->dev,  "Failed to register the IIO device: %d\n",
> > +			ret);
> 
> probably not the most useful error msg and about the only logging; drop 
> it?
> 
> and just do 
> return devm_iio_device_register(idev);

OK.


Thanks for the review!

Antoine

-- 
Antoine Ténart, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com



More information about the linux-arm-kernel mailing list