FILE
max34408.c
File preview with syntax highlighting.
linux-6.19.14/drivers/iio/adc/max34408.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * IIO driver for Maxim MAX34409/34408 ADC, 4-Channels/2-Channels, 8bits, I2C 4 * 5 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX34408-MAX34409.pdf 6 * 7 * TODO: ALERT interrupt, Overcurrent delay, Shutdown delay 8 */ 9 10#include <linux/bitfield.h> 11#include <linux/cleanup.h> 12#include <linux/init.h> 13#include <linux/i2c.h> 14#include <linux/module.h> 15#include <linux/mod_devicetable.h> 16#include <linux/property.h> 17#include <linux/regmap.h> 18 19#include <linux/iio/iio.h> 20#include <linux/iio/types.h> 21 22#define MAX34408_STATUS_REG 0x0 23#define MAX34408_CONTROL_REG 0x1 24#define MAX34408_OCDELAY_REG 0x2 25#define MAX34408_SDDELAY_REG 0x3 26 27#define MAX34408_ADC1_REG 0x4 28#define MAX34408_ADC2_REG 0x5 29/* ADC3 & ADC4 always returns 0x0 on 34408 */ 30#define MAX34409_ADC3_REG 0x6 31#define MAX34409_ADC4_REG 0x7 32 33#define MAX34408_OCT1_REG 0x8 34#define MAX34408_OCT2_REG 0x9 35#define MAX34409_OCT3_REG 0xA 36#define MAX34409_OCT4_REG 0xB 37 38#define MAX34408_DID_REG 0xC 39#define MAX34408_DCYY_REG 0xD 40#define MAX34408_DCWW_REG 0xE 41 42/* Bit masks for status register */ 43#define MAX34408_STATUS_OC_MSK GENMASK(1, 0) 44#define MAX34409_STATUS_OC_MSK GENMASK(3, 0) 45#define MAX34408_STATUS_SHTDN BIT(4) 46#define MAX34408_STATUS_ENA BIT(5) 47 48/* Bit masks for control register */ 49#define MAX34408_CONTROL_AVG0 BIT(0) 50#define MAX34408_CONTROL_AVG1 BIT(1) 51#define MAX34408_CONTROL_AVG2 BIT(2) 52#define MAX34408_CONTROL_ALERT BIT(3) 53 54#define MAX34408_DEFAULT_AVG 0x4 55 56/* Bit masks for over current delay */ 57#define MAX34408_OCDELAY_OCD_MSK GENMASK(6, 0) 58#define MAX34408_OCDELAY_RESET BIT(7) 59 60/* Bit masks for shutdown delay */ 61#define MAX34408_SDDELAY_SHD_MSK GENMASK(6, 0) 62#define MAX34408_SDDELAY_RESET BIT(7) 63 64#define MAX34408_DEFAULT_RSENSE 1000 65 66/** 67 * struct max34408_data - max34408/max34409 specific data. 68 * @regmap: device register map. 69 * @dev: max34408 device. 70 * @lock: lock for protecting access to device hardware registers, mostly 71 * for read modify write cycles for control registers. 72 * @input_rsense: Rsense values in uOhm, will be overwritten by 73 * values from channel nodes. 74 */ 75struct max34408_data { 76 struct regmap *regmap; 77 struct device *dev; 78 struct mutex lock; 79 u32 input_rsense[4]; 80}; 81 82static const struct regmap_config max34408_regmap_config = { 83 .reg_bits = 8, 84 .val_bits = 8, 85 .max_register = MAX34408_DCWW_REG, 86}; 87 88struct max34408_adc_model_data { 89 const char *model_name; 90 const struct iio_chan_spec *channels; 91 const int num_channels; 92}; 93 94#define MAX34008_CHANNEL(_index, _address) \ 95 { \ 96 .type = IIO_CURRENT, \ 97 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 98 BIT(IIO_CHAN_INFO_SCALE) | \ 99 BIT(IIO_CHAN_INFO_OFFSET), \ 100 .channel = (_index), \ 101 .address = (_address), \ 102 .indexed = 1, \ 103 } 104 105static const struct iio_chan_spec max34408_channels[] = { 106 MAX34008_CHANNEL(0, MAX34408_ADC1_REG), 107 MAX34008_CHANNEL(1, MAX34408_ADC2_REG), 108}; 109 110static const struct iio_chan_spec max34409_channels[] = { 111 MAX34008_CHANNEL(0, MAX34408_ADC1_REG), 112 MAX34008_CHANNEL(1, MAX34408_ADC2_REG), 113 MAX34008_CHANNEL(2, MAX34409_ADC3_REG), 114 MAX34008_CHANNEL(3, MAX34409_ADC4_REG), 115}; 116 117static int max34408_read_adc_avg(struct max34408_data *max34408, 118 const struct iio_chan_spec *chan, int *val) 119{ 120 unsigned int ctrl; 121 int rc; 122 123 guard(mutex)(&max34408->lock); 124 rc = regmap_read(max34408->regmap, MAX34408_CONTROL_REG, (u32 *)&ctrl); 125 if (rc) 126 return rc; 127 128 /* set averaging (0b100) default values*/ 129 rc = regmap_write(max34408->regmap, MAX34408_CONTROL_REG, 130 MAX34408_DEFAULT_AVG); 131 if (rc) { 132 dev_err(max34408->dev, 133 "Error (%d) writing control register\n", rc); 134 return rc; 135 } 136 137 rc = regmap_read(max34408->regmap, chan->address, val); 138 if (rc) 139 return rc; 140 141 /* back to old values */ 142 rc = regmap_write(max34408->regmap, MAX34408_CONTROL_REG, ctrl); 143 if (rc) 144 dev_err(max34408->dev, 145 "Error (%d) writing control register\n", rc); 146 147 return rc; 148} 149 150static int max34408_read_raw(struct iio_dev *indio_dev, 151 struct iio_chan_spec const *chan, 152 int *val, int *val2, long mask) 153{ 154 struct max34408_data *max34408 = iio_priv(indio_dev); 155 int rc; 156 157 switch (mask) { 158 case IIO_CHAN_INFO_RAW: 159 rc = max34408_read_adc_avg(max34408, chan, val); 160 if (rc) 161 return rc; 162 return IIO_VAL_INT; 163 case IIO_CHAN_INFO_SCALE: 164 /* 165 * calculate current for 8bit ADC with Rsense 166 * value. 167 * 10 mV * 1000 / Rsense uOhm = max current 168 * (max current * adc val * 1000) / (2^8 - 1) mA 169 */ 170 *val = 10000 / max34408->input_rsense[chan->channel]; 171 *val2 = 8; 172 return IIO_VAL_FRACTIONAL_LOG2; 173 default: 174 return -EINVAL; 175 } 176} 177 178static const struct iio_info max34408_info = { 179 .read_raw = max34408_read_raw, 180}; 181 182static const struct max34408_adc_model_data max34408_model_data = { 183 .model_name = "max34408", 184 .channels = max34408_channels, 185 .num_channels = 2, 186}; 187 188static const struct max34408_adc_model_data max34409_model_data = { 189 .model_name = "max34409", 190 .channels = max34409_channels, 191 .num_channels = 4, 192}; 193 194static int max34408_probe(struct i2c_client *client) 195{ 196 const struct max34408_adc_model_data *model_data; 197 struct device *dev = &client->dev; 198 struct max34408_data *max34408; 199 struct fwnode_handle *node; 200 struct iio_dev *indio_dev; 201 struct regmap *regmap; 202 int rc, i = 0; 203 204 model_data = i2c_get_match_data(client); 205 if (!model_data) 206 return -EINVAL; 207 208 regmap = devm_regmap_init_i2c(client, &max34408_regmap_config); 209 if (IS_ERR(regmap)) { 210 dev_err_probe(dev, PTR_ERR(regmap), 211 "regmap_init failed\n"); 212 return PTR_ERR(regmap); 213 } 214 215 indio_dev = devm_iio_device_alloc(dev, sizeof(*max34408)); 216 if (!indio_dev) 217 return -ENOMEM; 218 219 max34408 = iio_priv(indio_dev); 220 max34408->regmap = regmap; 221 max34408->dev = dev; 222 mutex_init(&max34408->lock); 223 224 device_for_each_child_node(dev, node) { 225 fwnode_property_read_u32(node, "maxim,rsense-val-micro-ohms", 226 &max34408->input_rsense[i]); 227 i++; 228 } 229 230 /* disable ALERT and averaging */ 231 rc = regmap_write(max34408->regmap, MAX34408_CONTROL_REG, 0x0); 232 if (rc) 233 return rc; 234 235 indio_dev->channels = model_data->channels; 236 indio_dev->num_channels = model_data->num_channels; 237 indio_dev->name = model_data->model_name; 238 239 indio_dev->info = &max34408_info; 240 indio_dev->modes = INDIO_DIRECT_MODE; 241 242 return devm_iio_device_register(dev, indio_dev); 243} 244 245static const struct of_device_id max34408_of_match[] = { 246 { 247 .compatible = "maxim,max34408", 248 .data = &max34408_model_data, 249 }, 250 { 251 .compatible = "maxim,max34409", 252 .data = &max34409_model_data, 253 }, 254 { } 255}; 256MODULE_DEVICE_TABLE(of, max34408_of_match); 257 258static const struct i2c_device_id max34408_id[] = { 259 { "max34408", (kernel_ulong_t)&max34408_model_data }, 260 { "max34409", (kernel_ulong_t)&max34409_model_data }, 261 { } 262}; 263MODULE_DEVICE_TABLE(i2c, max34408_id); 264 265static struct i2c_driver max34408_driver = { 266 .driver = { 267 .name = "max34408", 268 .of_match_table = max34408_of_match, 269 }, 270 .probe = max34408_probe, 271 .id_table = max34408_id, 272}; 273module_i2c_driver(max34408_driver); 274 275MODULE_AUTHOR("Ivan Mikhaylov <fr0st61te@gmail.com>"); 276MODULE_DESCRIPTION("Maxim MAX34408/34409 ADC driver"); 277MODULE_LICENSE("GPL");
~/
Read-only file preview.