195 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (c) 2022 Analog Devices, Inc.4 * ADI MAX77541 ADC Driver with IIO interface5 */6 7#include <linux/bitfield.h>8#include <linux/iio/iio.h>9#include <linux/mod_devicetable.h>10#include <linux/platform_device.h>11#include <linux/regmap.h>12#include <linux/units.h>13 14#include <linux/mfd/max77541.h>15 16enum max77541_adc_range {17 LOW_RANGE,18 MID_RANGE,19 HIGH_RANGE,20};21 22enum max77541_adc_channel {23 MAX77541_ADC_VSYS_V,24 MAX77541_ADC_VOUT1_V,25 MAX77541_ADC_VOUT2_V,26 MAX77541_ADC_TEMP,27};28 29static int max77541_adc_offset(struct iio_dev *indio_dev,30 struct iio_chan_spec const *chan,31 int *val, int *val2)32{33 switch (chan->channel) {34 case MAX77541_ADC_TEMP:35 *val = DIV_ROUND_CLOSEST(ABSOLUTE_ZERO_MILLICELSIUS, 1725);36 return IIO_VAL_INT;37 default:38 return -EINVAL;39 }40}41 42static int max77541_adc_scale(struct iio_dev *indio_dev,43 struct iio_chan_spec const *chan,44 int *val, int *val2)45{46 struct regmap **regmap = iio_priv(indio_dev);47 unsigned int reg_val;48 int ret;49 50 switch (chan->channel) {51 case MAX77541_ADC_VSYS_V:52 *val = 25;53 return IIO_VAL_INT;54 case MAX77541_ADC_VOUT1_V:55 case MAX77541_ADC_VOUT2_V:56 ret = regmap_read(*regmap, MAX77541_REG_M2_CFG1, ®_val);57 if (ret)58 return ret;59 60 reg_val = FIELD_GET(MAX77541_BITS_MX_CFG1_RNG, reg_val);61 switch (reg_val) {62 case LOW_RANGE:63 *val = 6;64 *val2 = 250000;65 break;66 case MID_RANGE:67 *val = 12;68 *val2 = 500000;69 break;70 case HIGH_RANGE:71 *val = 25;72 return IIO_VAL_INT;73 default:74 return -EINVAL;75 }76 77 return IIO_VAL_INT_PLUS_MICRO;78 case MAX77541_ADC_TEMP:79 *val = 1725;80 return IIO_VAL_INT;81 default:82 return -EINVAL;83 }84}85 86static int max77541_adc_raw(struct iio_dev *indio_dev,87 struct iio_chan_spec const *chan,88 int *val)89{90 struct regmap **regmap = iio_priv(indio_dev);91 int ret;92 93 ret = regmap_read(*regmap, chan->address, val);94 if (ret)95 return ret;96 97 return IIO_VAL_INT;98}99 100#define MAX77541_ADC_CHANNEL_V(_channel, _name, _type, _reg) \101 { \102 .type = _type, \103 .indexed = 1, \104 .channel = _channel, \105 .address = _reg, \106 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \107 BIT(IIO_CHAN_INFO_SCALE), \108 .datasheet_name = _name, \109 }110 111#define MAX77541_ADC_CHANNEL_TEMP(_channel, _name, _type, _reg) \112 { \113 .type = _type, \114 .indexed = 1, \115 .channel = _channel, \116 .address = _reg, \117 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \118 BIT(IIO_CHAN_INFO_SCALE) |\119 BIT(IIO_CHAN_INFO_OFFSET),\120 .datasheet_name = _name, \121 }122 123static const struct iio_chan_spec max77541_adc_channels[] = {124 MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VSYS_V, "vsys_v", IIO_VOLTAGE,125 MAX77541_REG_ADC_DATA_CH1),126 MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VOUT1_V, "vout1_v", IIO_VOLTAGE,127 MAX77541_REG_ADC_DATA_CH2),128 MAX77541_ADC_CHANNEL_V(MAX77541_ADC_VOUT2_V, "vout2_v", IIO_VOLTAGE,129 MAX77541_REG_ADC_DATA_CH3),130 MAX77541_ADC_CHANNEL_TEMP(MAX77541_ADC_TEMP, "temp", IIO_TEMP,131 MAX77541_REG_ADC_DATA_CH6),132};133 134static int max77541_adc_read_raw(struct iio_dev *indio_dev,135 struct iio_chan_spec const *chan,136 int *val, int *val2, long mask)137{138 switch (mask) {139 case IIO_CHAN_INFO_OFFSET:140 return max77541_adc_offset(indio_dev, chan, val, val2);141 case IIO_CHAN_INFO_SCALE:142 return max77541_adc_scale(indio_dev, chan, val, val2);143 case IIO_CHAN_INFO_RAW:144 return max77541_adc_raw(indio_dev, chan, val);145 default:146 return -EINVAL;147 }148}149 150static const struct iio_info max77541_adc_info = {151 .read_raw = max77541_adc_read_raw,152};153 154static int max77541_adc_probe(struct platform_device *pdev)155{156 struct device *dev = &pdev->dev;157 struct iio_dev *indio_dev;158 struct regmap **regmap;159 160 indio_dev = devm_iio_device_alloc(dev, sizeof(*regmap));161 if (!indio_dev)162 return -ENOMEM;163 164 regmap = iio_priv(indio_dev);165 166 *regmap = dev_get_regmap(dev->parent, NULL);167 indio_dev->modes = INDIO_DIRECT_MODE;168 169 indio_dev->name = "max77541";170 indio_dev->info = &max77541_adc_info;171 indio_dev->channels = max77541_adc_channels;172 indio_dev->num_channels = ARRAY_SIZE(max77541_adc_channels);173 174 return devm_iio_device_register(dev, indio_dev);175}176 177static const struct platform_device_id max77541_adc_platform_id[] = {178 { "max77541-adc" },179 { /* sentinel */ }180};181MODULE_DEVICE_TABLE(platform, max77541_adc_platform_id);182 183static struct platform_driver max77541_adc_driver = {184 .driver = {185 .name = "max77541-adc",186 },187 .probe = max77541_adc_probe,188 .id_table = max77541_adc_platform_id,189};190module_platform_driver(max77541_adc_driver);191 192MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>");193MODULE_DESCRIPTION("MAX77541 ADC driver");194MODULE_LICENSE("GPL");195