brintos

brintos / linux-shallow public Read only

0
0
Text · 29.7 KiB · 6c1a5d1 Raw
1223 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* ADC driver for AXP20X and AXP22X PMICs3 *4 * Copyright (c) 2016 Free Electrons NextThing Co.5 *	Quentin Schulz <quentin.schulz@free-electrons.com>6 */7 8#include <linux/unaligned.h>9#include <linux/bitfield.h>10#include <linux/completion.h>11#include <linux/interrupt.h>12#include <linux/io.h>13#include <linux/module.h>14#include <linux/mod_devicetable.h>15#include <linux/platform_device.h>16#include <linux/pm_runtime.h>17#include <linux/property.h>18#include <linux/regmap.h>19#include <linux/thermal.h>20 21#include <linux/iio/iio.h>22#include <linux/iio/driver.h>23#include <linux/iio/machine.h>24#include <linux/mfd/axp20x.h>25 26#define AXP192_ADC_EN1_MASK			GENMASK(7, 0)27#define AXP192_ADC_EN2_MASK			(GENMASK(3, 0) | BIT(7))28 29#define AXP20X_ADC_EN1_MASK			GENMASK(7, 0)30#define AXP20X_ADC_EN2_MASK			(GENMASK(3, 2) | BIT(7))31 32#define AXP22X_ADC_EN1_MASK			(GENMASK(7, 5) | BIT(0))33 34#define AXP717_ADC_EN1_MASK			GENMASK(7, 0)35 36#define AXP192_GPIO30_IN_RANGE_GPIO0		BIT(0)37#define AXP192_GPIO30_IN_RANGE_GPIO1		BIT(1)38#define AXP192_GPIO30_IN_RANGE_GPIO2		BIT(2)39#define AXP192_GPIO30_IN_RANGE_GPIO3		BIT(3)40 41#define AXP20X_GPIO10_IN_RANGE_GPIO0		BIT(0)42#define AXP20X_GPIO10_IN_RANGE_GPIO1		BIT(1)43 44#define AXP20X_ADC_RATE_MASK			GENMASK(7, 6)45#define AXP20X_ADC_RATE_HZ(x)			((ilog2((x) / 25) << 6) & AXP20X_ADC_RATE_MASK)46 47#define AXP22X_ADC_RATE_HZ(x)			((ilog2((x) / 100) << 6) & AXP20X_ADC_RATE_MASK)48 49#define AXP717_ADC_DATA_TS			0x0050#define AXP717_ADC_DATA_TEMP			0x0151#define AXP717_ADC_DATA_VMID			0x0252#define AXP717_ADC_DATA_BKUP_BATT		0x0353 54#define AXP717_ADC_DATA_MASK			GENMASK(13, 0)55 56#define AXP813_V_I_ADC_RATE_MASK		GENMASK(5, 4)57#define AXP813_ADC_RATE_MASK			(AXP20X_ADC_RATE_MASK | AXP813_V_I_ADC_RATE_MASK)58#define AXP813_TS_GPIO0_ADC_RATE_HZ(x)		AXP20X_ADC_RATE_HZ(x)59#define AXP813_V_I_ADC_RATE_HZ(x)		((ilog2((x) / 100) << 4) & AXP813_V_I_ADC_RATE_MASK)60#define AXP813_ADC_RATE_HZ(x)			(AXP20X_ADC_RATE_HZ(x) | AXP813_V_I_ADC_RATE_HZ(x))61 62#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg)	\63	{							\64		.type = _type,					\65		.indexed = 1,					\66		.channel = _channel,				\67		.address = _reg,				\68		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\69				      BIT(IIO_CHAN_INFO_SCALE),	\70		.datasheet_name = _name,			\71	}72 73#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \74	{							\75		.type = _type,					\76		.indexed = 1,					\77		.channel = _channel,				\78		.address = _reg,				\79		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\80				      BIT(IIO_CHAN_INFO_SCALE) |\81				      BIT(IIO_CHAN_INFO_OFFSET),\82		.datasheet_name = _name,			\83	}84 85struct axp_data;86 87struct axp20x_adc_iio {88	struct regmap		*regmap;89	const struct axp_data	*data;90};91 92enum axp192_adc_channel_v {93	AXP192_ACIN_V = 0,94	AXP192_VBUS_V,95	AXP192_TS_IN,96	AXP192_GPIO0_V,97	AXP192_GPIO1_V,98	AXP192_GPIO2_V,99	AXP192_GPIO3_V,100	AXP192_IPSOUT_V,101	AXP192_BATT_V,102};103 104enum axp192_adc_channel_i {105	AXP192_ACIN_I = 0,106	AXP192_VBUS_I,107	AXP192_BATT_CHRG_I,108	AXP192_BATT_DISCHRG_I,109};110 111enum axp20x_adc_channel_v {112	AXP20X_ACIN_V = 0,113	AXP20X_VBUS_V,114	AXP20X_TS_IN,115	AXP20X_GPIO0_V,116	AXP20X_GPIO1_V,117	AXP20X_IPSOUT_V,118	AXP20X_BATT_V,119};120 121enum axp20x_adc_channel_i {122	AXP20X_ACIN_I = 0,123	AXP20X_VBUS_I,124	AXP20X_BATT_CHRG_I,125	AXP20X_BATT_DISCHRG_I,126};127 128enum axp22x_adc_channel_v {129	AXP22X_TS_IN = 0,130	AXP22X_BATT_V,131};132 133enum axp22x_adc_channel_i {134	AXP22X_BATT_CHRG_I = 1,135	AXP22X_BATT_DISCHRG_I,136};137 138enum axp717_adc_channel_v {139	AXP717_BATT_V = 0,140	AXP717_TS_IN,141	AXP717_VBUS_V,142	AXP717_VSYS_V,143	AXP717_DIE_TEMP_V,144	AXP717_VMID_V = 6,145	AXP717_BKUP_BATT_V,146};147 148enum axp717_adc_channel_i {149	AXP717_BATT_CHRG_I = 5,150};151 152enum axp813_adc_channel_v {153	AXP813_TS_IN = 0,154	AXP813_GPIO0_V,155	AXP813_BATT_V,156};157 158static struct iio_map axp20x_maps[] = {159	{160		.consumer_dev_name = "axp20x-usb-power-supply",161		.consumer_channel = "vbus_v",162		.adc_channel_label = "vbus_v",163	}, {164		.consumer_dev_name = "axp20x-usb-power-supply",165		.consumer_channel = "vbus_i",166		.adc_channel_label = "vbus_i",167	}, {168		.consumer_dev_name = "axp20x-ac-power-supply",169		.consumer_channel = "acin_v",170		.adc_channel_label = "acin_v",171	}, {172		.consumer_dev_name = "axp20x-ac-power-supply",173		.consumer_channel = "acin_i",174		.adc_channel_label = "acin_i",175	}, {176		.consumer_dev_name = "axp20x-battery-power-supply",177		.consumer_channel = "batt_v",178		.adc_channel_label = "batt_v",179	}, {180		.consumer_dev_name = "axp20x-battery-power-supply",181		.consumer_channel = "batt_chrg_i",182		.adc_channel_label = "batt_chrg_i",183	}, {184		.consumer_dev_name = "axp20x-battery-power-supply",185		.consumer_channel = "batt_dischrg_i",186		.adc_channel_label = "batt_dischrg_i",187	}, { /* sentinel */ }188};189 190static struct iio_map axp22x_maps[] = {191	{192		.consumer_dev_name = "axp20x-battery-power-supply",193		.consumer_channel = "batt_v",194		.adc_channel_label = "batt_v",195	}, {196		.consumer_dev_name = "axp20x-battery-power-supply",197		.consumer_channel = "batt_chrg_i",198		.adc_channel_label = "batt_chrg_i",199	}, {200		.consumer_dev_name = "axp20x-battery-power-supply",201		.consumer_channel = "batt_dischrg_i",202		.adc_channel_label = "batt_dischrg_i",203	}, { /* sentinel */ }204};205 206static struct iio_map axp717_maps[] = {207	{208		.consumer_dev_name = "axp20x-usb-power-supply",209		.consumer_channel = "vbus_v",210		.adc_channel_label = "vbus_v",211	}, {212		.consumer_dev_name = "axp20x-battery-power-supply",213		.consumer_channel = "batt_v",214		.adc_channel_label = "batt_v",215	}, {216		.consumer_dev_name = "axp20x-battery-power-supply",217		.consumer_channel = "batt_chrg_i",218		.adc_channel_label = "batt_chrg_i",219	},220};221 222/*223 * Channels are mapped by physical system. Their channels share the same index.224 * i.e. acin_i is in_current0_raw and acin_v is in_voltage0_raw.225 * The only exception is for the battery. batt_v will be in_voltage6_raw and226 * charge current in_current6_raw and discharge current will be in_current7_raw.227 */228static const struct iio_chan_spec axp192_adc_channels[] = {229	AXP20X_ADC_CHANNEL(AXP192_ACIN_V, "acin_v", IIO_VOLTAGE,230			   AXP20X_ACIN_V_ADC_H),231	AXP20X_ADC_CHANNEL(AXP192_ACIN_I, "acin_i", IIO_CURRENT,232			   AXP20X_ACIN_I_ADC_H),233	AXP20X_ADC_CHANNEL(AXP192_VBUS_V, "vbus_v", IIO_VOLTAGE,234			   AXP20X_VBUS_V_ADC_H),235	AXP20X_ADC_CHANNEL(AXP192_VBUS_I, "vbus_i", IIO_CURRENT,236			   AXP20X_VBUS_I_ADC_H),237	{238		.type = IIO_TEMP,239		.address = AXP20X_TEMP_ADC_H,240		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |241				      BIT(IIO_CHAN_INFO_SCALE) |242				      BIT(IIO_CHAN_INFO_OFFSET),243		.datasheet_name = "pmic_temp",244	},245	AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO0_V, "gpio0_v", IIO_VOLTAGE,246				  AXP20X_GPIO0_V_ADC_H),247	AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO1_V, "gpio1_v", IIO_VOLTAGE,248				  AXP20X_GPIO1_V_ADC_H),249	AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO2_V, "gpio2_v", IIO_VOLTAGE,250				  AXP192_GPIO2_V_ADC_H),251	AXP20X_ADC_CHANNEL_OFFSET(AXP192_GPIO3_V, "gpio3_v", IIO_VOLTAGE,252				  AXP192_GPIO3_V_ADC_H),253	AXP20X_ADC_CHANNEL(AXP192_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,254			   AXP20X_IPSOUT_V_HIGH_H),255	AXP20X_ADC_CHANNEL(AXP192_BATT_V, "batt_v", IIO_VOLTAGE,256			   AXP20X_BATT_V_H),257	AXP20X_ADC_CHANNEL(AXP192_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,258			   AXP20X_BATT_CHRG_I_H),259	AXP20X_ADC_CHANNEL(AXP192_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,260			   AXP20X_BATT_DISCHRG_I_H),261	AXP20X_ADC_CHANNEL(AXP192_TS_IN, "ts_v", IIO_VOLTAGE,262			   AXP20X_TS_IN_H),263};264 265static const struct iio_chan_spec axp20x_adc_channels[] = {266	AXP20X_ADC_CHANNEL(AXP20X_ACIN_V, "acin_v", IIO_VOLTAGE,267			   AXP20X_ACIN_V_ADC_H),268	AXP20X_ADC_CHANNEL(AXP20X_ACIN_I, "acin_i", IIO_CURRENT,269			   AXP20X_ACIN_I_ADC_H),270	AXP20X_ADC_CHANNEL(AXP20X_VBUS_V, "vbus_v", IIO_VOLTAGE,271			   AXP20X_VBUS_V_ADC_H),272	AXP20X_ADC_CHANNEL(AXP20X_VBUS_I, "vbus_i", IIO_CURRENT,273			   AXP20X_VBUS_I_ADC_H),274	{275		.type = IIO_TEMP,276		.address = AXP20X_TEMP_ADC_H,277		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |278				      BIT(IIO_CHAN_INFO_SCALE) |279				      BIT(IIO_CHAN_INFO_OFFSET),280		.datasheet_name = "pmic_temp",281	},282	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO0_V, "gpio0_v", IIO_VOLTAGE,283				  AXP20X_GPIO0_V_ADC_H),284	AXP20X_ADC_CHANNEL_OFFSET(AXP20X_GPIO1_V, "gpio1_v", IIO_VOLTAGE,285				  AXP20X_GPIO1_V_ADC_H),286	AXP20X_ADC_CHANNEL(AXP20X_IPSOUT_V, "ipsout_v", IIO_VOLTAGE,287			   AXP20X_IPSOUT_V_HIGH_H),288	AXP20X_ADC_CHANNEL(AXP20X_BATT_V, "batt_v", IIO_VOLTAGE,289			   AXP20X_BATT_V_H),290	AXP20X_ADC_CHANNEL(AXP20X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,291			   AXP20X_BATT_CHRG_I_H),292	AXP20X_ADC_CHANNEL(AXP20X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,293			   AXP20X_BATT_DISCHRG_I_H),294	AXP20X_ADC_CHANNEL(AXP20X_TS_IN, "ts_v", IIO_VOLTAGE,295			   AXP20X_TS_IN_H),296};297 298static const struct iio_chan_spec axp22x_adc_channels[] = {299	{300		.type = IIO_TEMP,301		.address = AXP22X_PMIC_TEMP_H,302		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |303				      BIT(IIO_CHAN_INFO_SCALE) |304				      BIT(IIO_CHAN_INFO_OFFSET),305		.datasheet_name = "pmic_temp",306	},307	AXP20X_ADC_CHANNEL(AXP22X_BATT_V, "batt_v", IIO_VOLTAGE,308			   AXP20X_BATT_V_H),309	AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,310			   AXP20X_BATT_CHRG_I_H),311	AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,312			   AXP20X_BATT_DISCHRG_I_H),313	AXP20X_ADC_CHANNEL(AXP22X_TS_IN, "ts_v", IIO_VOLTAGE,314			   AXP22X_TS_ADC_H),315};316 317/*318 * Scale and offset is unknown for temp, ts, batt_chrg_i, vmid_v, and319 * bkup_batt_v channels. Leaving scale and offset undefined for now.320 */321static const struct iio_chan_spec axp717_adc_channels[] = {322	AXP20X_ADC_CHANNEL(AXP717_BATT_V, "batt_v", IIO_VOLTAGE,323			   AXP717_BATT_V_H),324	AXP20X_ADC_CHANNEL(AXP717_TS_IN, "ts_v", IIO_VOLTAGE,325			   AXP717_ADC_DATA_H),326	AXP20X_ADC_CHANNEL(AXP717_VBUS_V, "vbus_v", IIO_VOLTAGE,327			   AXP717_VBUS_V_H),328	AXP20X_ADC_CHANNEL(AXP717_VSYS_V, "vsys_v", IIO_VOLTAGE,329			   AXP717_VSYS_V_H),330	AXP20X_ADC_CHANNEL(AXP717_DIE_TEMP_V, "pmic_temp", IIO_TEMP,331			   AXP717_ADC_DATA_H),332	AXP20X_ADC_CHANNEL(AXP717_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,333			   AXP717_BATT_CHRG_I_H),334	AXP20X_ADC_CHANNEL(AXP717_VMID_V, "vmid_v", IIO_VOLTAGE,335			   AXP717_ADC_DATA_H),336	AXP20X_ADC_CHANNEL(AXP717_BKUP_BATT_V, "bkup_batt_v", IIO_VOLTAGE,337			   AXP717_ADC_DATA_H),338};339 340static const struct iio_chan_spec axp813_adc_channels[] = {341	{342		.type = IIO_TEMP,343		.address = AXP22X_PMIC_TEMP_H,344		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |345				      BIT(IIO_CHAN_INFO_SCALE) |346				      BIT(IIO_CHAN_INFO_OFFSET),347		.datasheet_name = "pmic_temp",348	},349	AXP20X_ADC_CHANNEL(AXP813_GPIO0_V, "gpio0_v", IIO_VOLTAGE,350			   AXP288_GP_ADC_H),351	AXP20X_ADC_CHANNEL(AXP813_BATT_V, "batt_v", IIO_VOLTAGE,352			   AXP20X_BATT_V_H),353	AXP20X_ADC_CHANNEL(AXP22X_BATT_CHRG_I, "batt_chrg_i", IIO_CURRENT,354			   AXP20X_BATT_CHRG_I_H),355	AXP20X_ADC_CHANNEL(AXP22X_BATT_DISCHRG_I, "batt_dischrg_i", IIO_CURRENT,356			   AXP20X_BATT_DISCHRG_I_H),357	AXP20X_ADC_CHANNEL(AXP813_TS_IN, "ts_v", IIO_VOLTAGE,358			   AXP288_TS_ADC_H),359};360 361static int axp192_adc_raw(struct iio_dev *indio_dev,362			  struct iio_chan_spec const *chan, int *val)363{364	struct axp20x_adc_iio *info = iio_priv(indio_dev);365	int ret, size;366 367	if (chan->type == IIO_CURRENT &&368	    (chan->channel == AXP192_BATT_CHRG_I ||369	     chan->channel == AXP192_BATT_DISCHRG_I))370		size = 13;371	else372		size = 12;373 374	ret = axp20x_read_variable_width(info->regmap, chan->address, size);375	if (ret < 0)376		return ret;377 378	*val = ret;379	return IIO_VAL_INT;380}381 382static int axp20x_adc_raw(struct iio_dev *indio_dev,383			  struct iio_chan_spec const *chan, int *val)384{385	struct axp20x_adc_iio *info = iio_priv(indio_dev);386	int ret, size;387 388	/*389	 * N.B.:  Unlike the Chinese datasheets tell, the charging current is390	 * stored on 12 bits, not 13 bits. Only discharging current is on 13391	 * bits.392	 */393	if (chan->type == IIO_CURRENT && chan->channel == AXP20X_BATT_DISCHRG_I)394		size = 13;395	else396		size = 12;397 398	ret = axp20x_read_variable_width(info->regmap, chan->address, size);399	if (ret < 0)400		return ret;401 402	*val = ret;403	return IIO_VAL_INT;404}405 406static int axp22x_adc_raw(struct iio_dev *indio_dev,407			  struct iio_chan_spec const *chan, int *val)408{409	struct axp20x_adc_iio *info = iio_priv(indio_dev);410	int ret;411 412	ret = axp20x_read_variable_width(info->regmap, chan->address, 12);413	if (ret < 0)414		return ret;415 416	*val = ret;417	return IIO_VAL_INT;418}419 420static int axp717_adc_raw(struct iio_dev *indio_dev,421			  struct iio_chan_spec const *chan, int *val)422{423	struct axp20x_adc_iio *info = iio_priv(indio_dev);424	u8 bulk_reg[2];425	int ret;426 427	/*428	 * A generic "ADC data" channel is used for TS, tdie, vmid,429	 * and vbackup. This channel must both first be enabled and430	 * also selected before it can be read.431	 */432	switch (chan->channel) {433	case AXP717_TS_IN:434		regmap_write(info->regmap, AXP717_ADC_DATA_SEL,435			     AXP717_ADC_DATA_TS);436		break;437	case AXP717_DIE_TEMP_V:438		regmap_write(info->regmap, AXP717_ADC_DATA_SEL,439			     AXP717_ADC_DATA_TEMP);440		break;441	case AXP717_VMID_V:442		regmap_write(info->regmap, AXP717_ADC_DATA_SEL,443			     AXP717_ADC_DATA_VMID);444		break;445	case AXP717_BKUP_BATT_V:446		regmap_write(info->regmap, AXP717_ADC_DATA_SEL,447			     AXP717_ADC_DATA_BKUP_BATT);448		break;449	default:450		break;451	}452 453	/*454	 * All channels are 14 bits, with the first 2 bits on the high455	 * register reserved and the remaining bits as the ADC value.456	 */457	ret = regmap_bulk_read(info->regmap, chan->address, bulk_reg, 2);458	if (ret < 0)459		return ret;460 461	*val = FIELD_GET(AXP717_ADC_DATA_MASK, get_unaligned_be16(bulk_reg));462	return IIO_VAL_INT;463}464 465static int axp813_adc_raw(struct iio_dev *indio_dev,466			  struct iio_chan_spec const *chan, int *val)467{468	struct axp20x_adc_iio *info = iio_priv(indio_dev);469	int ret;470 471	ret = axp20x_read_variable_width(info->regmap, chan->address, 12);472	if (ret < 0)473		return ret;474 475	*val = ret;476	return IIO_VAL_INT;477}478 479static int axp192_adc_scale_voltage(int channel, int *val, int *val2)480{481	switch (channel) {482	case AXP192_ACIN_V:483	case AXP192_VBUS_V:484		*val = 1;485		*val2 = 700000;486		return IIO_VAL_INT_PLUS_MICRO;487 488	case AXP192_GPIO0_V:489	case AXP192_GPIO1_V:490	case AXP192_GPIO2_V:491	case AXP192_GPIO3_V:492		*val = 0;493		*val2 = 500000;494		return IIO_VAL_INT_PLUS_MICRO;495 496	case AXP192_BATT_V:497		*val = 1;498		*val2 = 100000;499		return IIO_VAL_INT_PLUS_MICRO;500 501	case AXP192_IPSOUT_V:502		*val = 1;503		*val2 = 400000;504		return IIO_VAL_INT_PLUS_MICRO;505 506	case AXP192_TS_IN:507		/* 0.8 mV per LSB */508		*val = 0;509		*val2 = 800000;510		return IIO_VAL_INT_PLUS_MICRO;511 512	default:513		return -EINVAL;514	}515}516 517static int axp20x_adc_scale_voltage(int channel, int *val, int *val2)518{519	switch (channel) {520	case AXP20X_ACIN_V:521	case AXP20X_VBUS_V:522		*val = 1;523		*val2 = 700000;524		return IIO_VAL_INT_PLUS_MICRO;525 526	case AXP20X_GPIO0_V:527	case AXP20X_GPIO1_V:528		*val = 0;529		*val2 = 500000;530		return IIO_VAL_INT_PLUS_MICRO;531 532	case AXP20X_BATT_V:533		*val = 1;534		*val2 = 100000;535		return IIO_VAL_INT_PLUS_MICRO;536 537	case AXP20X_IPSOUT_V:538		*val = 1;539		*val2 = 400000;540		return IIO_VAL_INT_PLUS_MICRO;541 542	case AXP20X_TS_IN:543		/* 0.8 mV per LSB */544		*val = 0;545		*val2 = 800000;546		return IIO_VAL_INT_PLUS_MICRO;547 548	default:549		return -EINVAL;550	}551}552 553static int axp22x_adc_scale_voltage(int channel, int *val, int *val2)554{555	switch (channel) {556	case AXP22X_BATT_V:557		/* 1.1 mV per LSB */558		*val = 1;559		*val2 = 100000;560		return IIO_VAL_INT_PLUS_MICRO;561 562	case AXP22X_TS_IN:563		/* 0.8 mV per LSB */564		*val = 0;565		*val2 = 800000;566		return IIO_VAL_INT_PLUS_MICRO;567 568	default:569		return -EINVAL;570	}571}572static int axp813_adc_scale_voltage(int channel, int *val, int *val2)573{574	switch (channel) {575	case AXP813_GPIO0_V:576		*val = 0;577		*val2 = 800000;578		return IIO_VAL_INT_PLUS_MICRO;579 580	case AXP813_BATT_V:581		*val = 1;582		*val2 = 100000;583		return IIO_VAL_INT_PLUS_MICRO;584 585	case AXP813_TS_IN:586		/* 0.8 mV per LSB */587		*val = 0;588		*val2 = 800000;589		return IIO_VAL_INT_PLUS_MICRO;590 591	default:592		return -EINVAL;593	}594}595 596static int axp20x_adc_scale_current(int channel, int *val, int *val2)597{598	switch (channel) {599	case AXP20X_ACIN_I:600		*val = 0;601		*val2 = 625000;602		return IIO_VAL_INT_PLUS_MICRO;603 604	case AXP20X_VBUS_I:605		*val = 0;606		*val2 = 375000;607		return IIO_VAL_INT_PLUS_MICRO;608 609	case AXP20X_BATT_DISCHRG_I:610	case AXP20X_BATT_CHRG_I:611		*val = 0;612		*val2 = 500000;613		return IIO_VAL_INT_PLUS_MICRO;614 615	default:616		return -EINVAL;617	}618}619 620static int axp192_adc_scale(struct iio_chan_spec const *chan, int *val,621			    int *val2)622{623	switch (chan->type) {624	case IIO_VOLTAGE:625		return axp192_adc_scale_voltage(chan->channel, val, val2);626 627	case IIO_CURRENT:628		/*629		 * AXP192 current channels are identical to the AXP20x,630		 * therefore we can re-use the scaling function.631		 */632		return axp20x_adc_scale_current(chan->channel, val, val2);633 634	case IIO_TEMP:635		*val = 100;636		return IIO_VAL_INT;637 638	default:639		return -EINVAL;640	}641}642 643static int axp20x_adc_scale(struct iio_chan_spec const *chan, int *val,644			    int *val2)645{646	switch (chan->type) {647	case IIO_VOLTAGE:648		return axp20x_adc_scale_voltage(chan->channel, val, val2);649 650	case IIO_CURRENT:651		return axp20x_adc_scale_current(chan->channel, val, val2);652 653	case IIO_TEMP:654		*val = 100;655		return IIO_VAL_INT;656 657	default:658		return -EINVAL;659	}660}661 662static int axp22x_adc_scale(struct iio_chan_spec const *chan, int *val,663			    int *val2)664{665	switch (chan->type) {666	case IIO_VOLTAGE:667		return axp22x_adc_scale_voltage(chan->channel, val, val2);668 669	case IIO_CURRENT:670		*val = 1;671		return IIO_VAL_INT;672 673	case IIO_TEMP:674		*val = 100;675		return IIO_VAL_INT;676 677	default:678		return -EINVAL;679	}680}681 682static int axp717_adc_scale(struct iio_chan_spec const *chan, int *val,683			    int *val2)684{685	switch (chan->type) {686	case IIO_VOLTAGE:687		*val = 1;688		return IIO_VAL_INT;689 690	case IIO_CURRENT:691		*val = 1;692		return IIO_VAL_INT;693 694	case IIO_TEMP:695		*val = 100;696		return IIO_VAL_INT;697 698	default:699		return -EINVAL;700	}701}702 703static int axp813_adc_scale(struct iio_chan_spec const *chan, int *val,704			    int *val2)705{706	switch (chan->type) {707	case IIO_VOLTAGE:708		return axp813_adc_scale_voltage(chan->channel, val, val2);709 710	case IIO_CURRENT:711		*val = 1;712		return IIO_VAL_INT;713 714	case IIO_TEMP:715		*val = 100;716		return IIO_VAL_INT;717 718	default:719		return -EINVAL;720	}721}722 723static int axp192_adc_offset_voltage(struct iio_dev *indio_dev, int channel,724				     int *val)725{726	struct axp20x_adc_iio *info = iio_priv(indio_dev);727	unsigned int regval;728	int ret;729 730	ret = regmap_read(info->regmap, AXP192_GPIO30_IN_RANGE, &regval);731	if (ret < 0)732		return ret;733 734	switch (channel) {735	case AXP192_GPIO0_V:736		regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO0, regval);737		break;738 739	case AXP192_GPIO1_V:740		regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO1, regval);741		break;742 743	case AXP192_GPIO2_V:744		regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO2, regval);745		break;746 747	case AXP192_GPIO3_V:748		regval = FIELD_GET(AXP192_GPIO30_IN_RANGE_GPIO3, regval);749		break;750 751	default:752		return -EINVAL;753	}754 755	*val = regval ? 700000 : 0;756	return IIO_VAL_INT;757}758 759static int axp20x_adc_offset_voltage(struct iio_dev *indio_dev, int channel,760				     int *val)761{762	struct axp20x_adc_iio *info = iio_priv(indio_dev);763	unsigned int regval;764	int ret;765 766	ret = regmap_read(info->regmap, AXP20X_GPIO10_IN_RANGE, &regval);767	if (ret < 0)768		return ret;769 770	switch (channel) {771	case AXP20X_GPIO0_V:772		regval = FIELD_GET(AXP20X_GPIO10_IN_RANGE_GPIO0, regval);773		break;774 775	case AXP20X_GPIO1_V:776		regval = FIELD_GET(AXP20X_GPIO10_IN_RANGE_GPIO1, regval);777		break;778 779	default:780		return -EINVAL;781	}782 783	*val = regval ? 700000 : 0;784	return IIO_VAL_INT;785}786 787static int axp192_adc_offset(struct iio_dev *indio_dev,788			     struct iio_chan_spec const *chan, int *val)789{790	switch (chan->type) {791	case IIO_VOLTAGE:792		return axp192_adc_offset_voltage(indio_dev, chan->channel, val);793 794	case IIO_TEMP:795		*val = -1447;796		return IIO_VAL_INT;797 798	default:799		return -EINVAL;800	}801}802 803static int axp20x_adc_offset(struct iio_dev *indio_dev,804			     struct iio_chan_spec const *chan, int *val)805{806	switch (chan->type) {807	case IIO_VOLTAGE:808		return axp20x_adc_offset_voltage(indio_dev, chan->channel, val);809 810	case IIO_TEMP:811		*val = -1447;812		return IIO_VAL_INT;813 814	default:815		return -EINVAL;816	}817}818 819static int axp192_read_raw(struct iio_dev *indio_dev,820			   struct iio_chan_spec const *chan, int *val,821			   int *val2, long mask)822{823	switch (mask) {824	case IIO_CHAN_INFO_OFFSET:825		return axp192_adc_offset(indio_dev, chan, val);826 827	case IIO_CHAN_INFO_SCALE:828		return axp192_adc_scale(chan, val, val2);829 830	case IIO_CHAN_INFO_RAW:831		return axp192_adc_raw(indio_dev, chan, val);832 833	default:834		return -EINVAL;835	}836}837 838static int axp20x_read_raw(struct iio_dev *indio_dev,839			   struct iio_chan_spec const *chan, int *val,840			   int *val2, long mask)841{842	switch (mask) {843	case IIO_CHAN_INFO_OFFSET:844		return axp20x_adc_offset(indio_dev, chan, val);845 846	case IIO_CHAN_INFO_SCALE:847		return axp20x_adc_scale(chan, val, val2);848 849	case IIO_CHAN_INFO_RAW:850		return axp20x_adc_raw(indio_dev, chan, val);851 852	default:853		return -EINVAL;854	}855}856 857static int axp22x_read_raw(struct iio_dev *indio_dev,858			   struct iio_chan_spec const *chan, int *val,859			   int *val2, long mask)860{861	switch (mask) {862	case IIO_CHAN_INFO_OFFSET:863		/* For PMIC temp only */864		*val = -2677;865		return IIO_VAL_INT;866 867	case IIO_CHAN_INFO_SCALE:868		return axp22x_adc_scale(chan, val, val2);869 870	case IIO_CHAN_INFO_RAW:871		return axp22x_adc_raw(indio_dev, chan, val);872 873	default:874		return -EINVAL;875	}876}877 878static int axp717_read_raw(struct iio_dev *indio_dev,879			   struct iio_chan_spec const *chan, int *val,880			   int *val2, long mask)881{882	switch (mask) {883	case IIO_CHAN_INFO_SCALE:884		return axp717_adc_scale(chan, val, val2);885 886	case IIO_CHAN_INFO_RAW:887		return axp717_adc_raw(indio_dev, chan, val);888 889	default:890		return -EINVAL;891	}892}893 894static int axp813_read_raw(struct iio_dev *indio_dev,895			   struct iio_chan_spec const *chan, int *val,896			   int *val2, long mask)897{898	switch (mask) {899	case IIO_CHAN_INFO_OFFSET:900		*val = -2667;901		return IIO_VAL_INT;902 903	case IIO_CHAN_INFO_SCALE:904		return axp813_adc_scale(chan, val, val2);905 906	case IIO_CHAN_INFO_RAW:907		return axp813_adc_raw(indio_dev, chan, val);908 909	default:910		return -EINVAL;911	}912}913 914static int axp192_write_raw(struct iio_dev *indio_dev,915			    struct iio_chan_spec const *chan, int val, int val2,916			    long mask)917{918	struct axp20x_adc_iio *info = iio_priv(indio_dev);919	unsigned int regmask, regval;920 921	/*922	 * The AXP192 PMIC allows the user to choose between 0V and 0.7V offsets923	 * for (independently) GPIO0-3 when in ADC mode.924	 */925	if (mask != IIO_CHAN_INFO_OFFSET)926		return -EINVAL;927 928	if (val != 0 && val != 700000)929		return -EINVAL;930 931	switch (chan->channel) {932	case AXP192_GPIO0_V:933		regmask = AXP192_GPIO30_IN_RANGE_GPIO0;934		regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO0, !!val);935		break;936 937	case AXP192_GPIO1_V:938		regmask = AXP192_GPIO30_IN_RANGE_GPIO1;939		regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO1, !!val);940		break;941 942	case AXP192_GPIO2_V:943		regmask = AXP192_GPIO30_IN_RANGE_GPIO2;944		regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO2, !!val);945		break;946 947	case AXP192_GPIO3_V:948		regmask = AXP192_GPIO30_IN_RANGE_GPIO3;949		regval = FIELD_PREP(AXP192_GPIO30_IN_RANGE_GPIO3, !!val);950		break;951 952	default:953		return -EINVAL;954	}955 956	return regmap_update_bits(info->regmap, AXP192_GPIO30_IN_RANGE, regmask, regval);957}958 959static int axp20x_write_raw(struct iio_dev *indio_dev,960			    struct iio_chan_spec const *chan, int val, int val2,961			    long mask)962{963	struct axp20x_adc_iio *info = iio_priv(indio_dev);964	unsigned int regmask, regval;965 966	/*967	 * The AXP20X PMIC allows the user to choose between 0V and 0.7V offsets968	 * for (independently) GPIO0 and GPIO1 when in ADC mode.969	 */970	if (mask != IIO_CHAN_INFO_OFFSET)971		return -EINVAL;972 973	if (val != 0 && val != 700000)974		return -EINVAL;975 976	switch (chan->channel) {977	case AXP20X_GPIO0_V:978		regmask = AXP20X_GPIO10_IN_RANGE_GPIO0;979		regval = FIELD_PREP(AXP20X_GPIO10_IN_RANGE_GPIO0, !!val);980		break;981 982	case AXP20X_GPIO1_V:983		regmask = AXP20X_GPIO10_IN_RANGE_GPIO1;984		regval = FIELD_PREP(AXP20X_GPIO10_IN_RANGE_GPIO1, !!val);985		break;986 987	default:988		return -EINVAL;989	}990 991	return regmap_update_bits(info->regmap, AXP20X_GPIO10_IN_RANGE, regmask, regval);992}993 994static const struct iio_info axp192_adc_iio_info = {995	.read_raw = axp192_read_raw,996	.write_raw = axp192_write_raw,997};998 999static const struct iio_info axp20x_adc_iio_info = {1000	.read_raw = axp20x_read_raw,1001	.write_raw = axp20x_write_raw,1002};1003 1004static const struct iio_info axp22x_adc_iio_info = {1005	.read_raw = axp22x_read_raw,1006};1007 1008static const struct iio_info axp717_adc_iio_info = {1009	.read_raw = axp717_read_raw,1010};1011 1012static const struct iio_info axp813_adc_iio_info = {1013	.read_raw = axp813_read_raw,1014};1015 1016static int axp20x_adc_rate(struct axp20x_adc_iio *info, int rate)1017{1018	return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,1019				  AXP20X_ADC_RATE_MASK,1020				  AXP20X_ADC_RATE_HZ(rate));1021}1022 1023static int axp22x_adc_rate(struct axp20x_adc_iio *info, int rate)1024{1025	return regmap_update_bits(info->regmap, AXP20X_ADC_RATE,1026				  AXP20X_ADC_RATE_MASK,1027				  AXP22X_ADC_RATE_HZ(rate));1028}1029 1030static int axp813_adc_rate(struct axp20x_adc_iio *info, int rate)1031{1032	return regmap_update_bits(info->regmap, AXP813_ADC_RATE,1033				 AXP813_ADC_RATE_MASK,1034				 AXP813_ADC_RATE_HZ(rate));1035}1036 1037struct axp_data {1038	const struct iio_info		*iio_info;1039	int				num_channels;1040	struct iio_chan_spec const	*channels;1041	unsigned long			adc_en1;1042	unsigned long			adc_en1_mask;1043	unsigned long			adc_en2;1044	unsigned long			adc_en2_mask;1045	int				(*adc_rate)(struct axp20x_adc_iio *info,1046						    int rate);1047	struct iio_map			*maps;1048};1049 1050static const struct axp_data axp192_data = {1051	.iio_info = &axp192_adc_iio_info,1052	.num_channels = ARRAY_SIZE(axp192_adc_channels),1053	.channels = axp192_adc_channels,1054	.adc_en1_mask = AXP192_ADC_EN1_MASK,1055	.adc_en2_mask = AXP192_ADC_EN2_MASK,1056	.adc_rate = axp20x_adc_rate,1057	.maps = axp20x_maps,1058};1059 1060static const struct axp_data axp20x_data = {1061	.iio_info = &axp20x_adc_iio_info,1062	.num_channels = ARRAY_SIZE(axp20x_adc_channels),1063	.channels = axp20x_adc_channels,1064	.adc_en1 = AXP20X_ADC_EN1,1065	.adc_en1_mask = AXP20X_ADC_EN1_MASK,1066	.adc_en2 = AXP20X_ADC_EN2,1067	.adc_en2_mask = AXP20X_ADC_EN2_MASK,1068	.adc_rate = axp20x_adc_rate,1069	.maps = axp20x_maps,1070};1071 1072static const struct axp_data axp22x_data = {1073	.iio_info = &axp22x_adc_iio_info,1074	.num_channels = ARRAY_SIZE(axp22x_adc_channels),1075	.channels = axp22x_adc_channels,1076	.adc_en1 = AXP20X_ADC_EN1,1077	.adc_en1_mask = AXP22X_ADC_EN1_MASK,1078	.adc_rate = axp22x_adc_rate,1079	.maps = axp22x_maps,1080};1081 1082static const struct axp_data axp717_data = {1083	.iio_info = &axp717_adc_iio_info,1084	.num_channels = ARRAY_SIZE(axp717_adc_channels),1085	.channels = axp717_adc_channels,1086	.adc_en1 = AXP717_ADC_CH_EN_CONTROL,1087	.adc_en1_mask = AXP717_ADC_EN1_MASK,1088	.maps = axp717_maps,1089};1090 1091static const struct axp_data axp813_data = {1092	.iio_info = &axp813_adc_iio_info,1093	.num_channels = ARRAY_SIZE(axp813_adc_channels),1094	.channels = axp813_adc_channels,1095	.adc_en1 = AXP20X_ADC_EN1,1096	.adc_en1_mask = AXP22X_ADC_EN1_MASK,1097	.adc_rate = axp813_adc_rate,1098	.maps = axp22x_maps,1099};1100 1101static const struct of_device_id axp20x_adc_of_match[] = {1102	{ .compatible = "x-powers,axp192-adc", .data = (void *)&axp192_data, },1103	{ .compatible = "x-powers,axp209-adc", .data = (void *)&axp20x_data, },1104	{ .compatible = "x-powers,axp221-adc", .data = (void *)&axp22x_data, },1105	{ .compatible = "x-powers,axp717-adc", .data = (void *)&axp717_data, },1106	{ .compatible = "x-powers,axp813-adc", .data = (void *)&axp813_data, },1107	{ /* sentinel */ }1108};1109MODULE_DEVICE_TABLE(of, axp20x_adc_of_match);1110 1111static const struct platform_device_id axp20x_adc_id_match[] = {1112	{ .name = "axp192-adc", .driver_data = (kernel_ulong_t)&axp192_data, },1113	{ .name = "axp20x-adc", .driver_data = (kernel_ulong_t)&axp20x_data, },1114	{ .name = "axp22x-adc", .driver_data = (kernel_ulong_t)&axp22x_data, },1115	{ .name = "axp717-adc", .driver_data = (kernel_ulong_t)&axp717_data, },1116	{ .name = "axp813-adc", .driver_data = (kernel_ulong_t)&axp813_data, },1117	{ /* sentinel */ },1118};1119MODULE_DEVICE_TABLE(platform, axp20x_adc_id_match);1120 1121static int axp20x_probe(struct platform_device *pdev)1122{1123	struct axp20x_adc_iio *info;1124	struct iio_dev *indio_dev;1125	struct axp20x_dev *axp20x_dev;1126	int ret;1127 1128	axp20x_dev = dev_get_drvdata(pdev->dev.parent);1129 1130	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));1131	if (!indio_dev)1132		return -ENOMEM;1133 1134	info = iio_priv(indio_dev);1135	platform_set_drvdata(pdev, indio_dev);1136 1137	info->regmap = axp20x_dev->regmap;1138	indio_dev->modes = INDIO_DIRECT_MODE;1139 1140	if (!dev_fwnode(&pdev->dev)) {1141		const struct platform_device_id *id;1142 1143		id = platform_get_device_id(pdev);1144		info->data = (const struct axp_data *)id->driver_data;1145	} else {1146		struct device *dev = &pdev->dev;1147 1148		info->data = device_get_match_data(dev);1149	}1150 1151	indio_dev->name = platform_get_device_id(pdev)->name;1152	indio_dev->info = info->data->iio_info;1153	indio_dev->num_channels = info->data->num_channels;1154	indio_dev->channels = info->data->channels;1155 1156	/* Enable the ADCs on IP */1157	regmap_write(info->regmap, info->data->adc_en1,1158		     info->data->adc_en1_mask);1159 1160	if (info->data->adc_en2_mask)1161		regmap_set_bits(info->regmap, info->data->adc_en2,1162				info->data->adc_en2_mask);1163 1164	/* Configure ADCs rate */1165	if (info->data->adc_rate)1166		info->data->adc_rate(info, 100);1167 1168	ret = iio_map_array_register(indio_dev, info->data->maps);1169	if (ret < 0) {1170		dev_err(&pdev->dev, "failed to register IIO maps: %d\n", ret);1171		goto fail_map;1172	}1173 1174	ret = iio_device_register(indio_dev);1175	if (ret < 0) {1176		dev_err(&pdev->dev, "could not register the device\n");1177		goto fail_register;1178	}1179 1180	return 0;1181 1182fail_register:1183	iio_map_array_unregister(indio_dev);1184 1185fail_map:1186	regmap_write(info->regmap, info->data->adc_en1, 0);1187 1188	if (info->data->adc_en2_mask)1189		regmap_write(info->regmap, info->data->adc_en2, 0);1190 1191	return ret;1192}1193 1194static void axp20x_remove(struct platform_device *pdev)1195{1196	struct iio_dev *indio_dev = platform_get_drvdata(pdev);1197	struct axp20x_adc_iio *info = iio_priv(indio_dev);1198 1199	iio_device_unregister(indio_dev);1200	iio_map_array_unregister(indio_dev);1201 1202	regmap_write(info->regmap, info->data->adc_en1, 0);1203 1204	if (info->data->adc_en2_mask)1205		regmap_write(info->regmap, info->data->adc_en2, 0);1206}1207 1208static struct platform_driver axp20x_adc_driver = {1209	.driver = {1210		.name = "axp20x-adc",1211		.of_match_table = axp20x_adc_of_match,1212	},1213	.id_table = axp20x_adc_id_match,1214	.probe = axp20x_probe,1215	.remove_new = axp20x_remove,1216};1217 1218module_platform_driver(axp20x_adc_driver);1219 1220MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");1221MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");1222MODULE_LICENSE("GPL");1223