max5821.c (9155B)
1// SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * iio/dac/max5821.c 4 * Copyright (C) 2014 Philippe Reynes 5 */ 6 7#include <linux/kernel.h> 8#include <linux/module.h> 9#include <linux/i2c.h> 10#include <linux/iio/iio.h> 11#include <linux/regulator/consumer.h> 12 13#define MAX5821_MAX_DAC_CHANNELS 2 14 15/* command bytes */ 16#define MAX5821_LOAD_DAC_A_IN_REG_B 0x00 17#define MAX5821_LOAD_DAC_B_IN_REG_A 0x10 18#define MAX5821_EXTENDED_COMMAND_MODE 0xf0 19#define MAX5821_READ_DAC_A_COMMAND 0xf1 20#define MAX5821_READ_DAC_B_COMMAND 0xf2 21 22#define MAX5821_EXTENDED_POWER_UP 0x00 23#define MAX5821_EXTENDED_POWER_DOWN_MODE0 0x01 24#define MAX5821_EXTENDED_POWER_DOWN_MODE1 0x02 25#define MAX5821_EXTENDED_POWER_DOWN_MODE2 0x03 26#define MAX5821_EXTENDED_DAC_A 0x04 27#define MAX5821_EXTENDED_DAC_B 0x08 28 29enum max5821_device_ids { 30 ID_MAX5821, 31}; 32 33struct max5821_data { 34 struct i2c_client *client; 35 struct regulator *vref_reg; 36 unsigned short vref_mv; 37 bool powerdown[MAX5821_MAX_DAC_CHANNELS]; 38 u8 powerdown_mode[MAX5821_MAX_DAC_CHANNELS]; 39 struct mutex lock; 40}; 41 42static const char * const max5821_powerdown_modes[] = { 43 "three_state", 44 "1kohm_to_gnd", 45 "100kohm_to_gnd", 46}; 47 48enum { 49 MAX5821_THREE_STATE, 50 MAX5821_1KOHM_TO_GND, 51 MAX5821_100KOHM_TO_GND 52}; 53 54static int max5821_get_powerdown_mode(struct iio_dev *indio_dev, 55 const struct iio_chan_spec *chan) 56{ 57 struct max5821_data *st = iio_priv(indio_dev); 58 59 return st->powerdown_mode[chan->channel]; 60} 61 62static int max5821_set_powerdown_mode(struct iio_dev *indio_dev, 63 const struct iio_chan_spec *chan, 64 unsigned int mode) 65{ 66 struct max5821_data *st = iio_priv(indio_dev); 67 68 st->powerdown_mode[chan->channel] = mode; 69 70 return 0; 71} 72 73static const struct iio_enum max5821_powerdown_mode_enum = { 74 .items = max5821_powerdown_modes, 75 .num_items = ARRAY_SIZE(max5821_powerdown_modes), 76 .get = max5821_get_powerdown_mode, 77 .set = max5821_set_powerdown_mode, 78}; 79 80static ssize_t max5821_read_dac_powerdown(struct iio_dev *indio_dev, 81 uintptr_t private, 82 const struct iio_chan_spec *chan, 83 char *buf) 84{ 85 struct max5821_data *st = iio_priv(indio_dev); 86 87 return sysfs_emit(buf, "%d\n", st->powerdown[chan->channel]); 88} 89 90static int max5821_sync_powerdown_mode(struct max5821_data *data, 91 const struct iio_chan_spec *chan) 92{ 93 u8 outbuf[2]; 94 95 outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE; 96 97 if (chan->channel == 0) 98 outbuf[1] = MAX5821_EXTENDED_DAC_A; 99 else 100 outbuf[1] = MAX5821_EXTENDED_DAC_B; 101 102 if (data->powerdown[chan->channel]) 103 outbuf[1] |= data->powerdown_mode[chan->channel] + 1; 104 else 105 outbuf[1] |= MAX5821_EXTENDED_POWER_UP; 106 107 return i2c_master_send(data->client, outbuf, 2); 108} 109 110static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, 111 uintptr_t private, 112 const struct iio_chan_spec *chan, 113 const char *buf, size_t len) 114{ 115 struct max5821_data *data = iio_priv(indio_dev); 116 bool powerdown; 117 int ret; 118 119 ret = kstrtobool(buf, &powerdown); 120 if (ret) 121 return ret; 122 123 data->powerdown[chan->channel] = powerdown; 124 125 ret = max5821_sync_powerdown_mode(data, chan); 126 if (ret < 0) 127 return ret; 128 129 return len; 130} 131 132static const struct iio_chan_spec_ext_info max5821_ext_info[] = { 133 { 134 .name = "powerdown", 135 .read = max5821_read_dac_powerdown, 136 .write = max5821_write_dac_powerdown, 137 .shared = IIO_SEPARATE, 138 }, 139 IIO_ENUM("powerdown_mode", IIO_SEPARATE, &max5821_powerdown_mode_enum), 140 IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &max5821_powerdown_mode_enum), 141 { }, 142}; 143 144#define MAX5821_CHANNEL(chan) { \ 145 .type = IIO_VOLTAGE, \ 146 .indexed = 1, \ 147 .output = 1, \ 148 .channel = (chan), \ 149 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 150 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ 151 .ext_info = max5821_ext_info, \ 152} 153 154static const struct iio_chan_spec max5821_channels[] = { 155 MAX5821_CHANNEL(0), 156 MAX5821_CHANNEL(1) 157}; 158 159static const u8 max5821_read_dac_command[] = { 160 MAX5821_READ_DAC_A_COMMAND, 161 MAX5821_READ_DAC_B_COMMAND 162}; 163 164static const u8 max5821_load_dac_command[] = { 165 MAX5821_LOAD_DAC_A_IN_REG_B, 166 MAX5821_LOAD_DAC_B_IN_REG_A 167}; 168 169static int max5821_get_value(struct iio_dev *indio_dev, 170 int *val, int channel) 171{ 172 struct max5821_data *data = iio_priv(indio_dev); 173 struct i2c_client *client = data->client; 174 u8 outbuf[1]; 175 u8 inbuf[2]; 176 int ret; 177 178 if ((channel != 0) && (channel != 1)) 179 return -EINVAL; 180 181 outbuf[0] = max5821_read_dac_command[channel]; 182 183 mutex_lock(&data->lock); 184 185 ret = i2c_master_send(client, outbuf, 1); 186 if (ret < 0) { 187 mutex_unlock(&data->lock); 188 return ret; 189 } else if (ret != 1) { 190 mutex_unlock(&data->lock); 191 return -EIO; 192 } 193 194 ret = i2c_master_recv(client, inbuf, 2); 195 if (ret < 0) { 196 mutex_unlock(&data->lock); 197 return ret; 198 } else if (ret != 2) { 199 mutex_unlock(&data->lock); 200 return -EIO; 201 } 202 203 mutex_unlock(&data->lock); 204 205 *val = ((inbuf[0] & 0x0f) << 6) | (inbuf[1] >> 2); 206 207 return IIO_VAL_INT; 208} 209 210static int max5821_set_value(struct iio_dev *indio_dev, 211 int val, int channel) 212{ 213 struct max5821_data *data = iio_priv(indio_dev); 214 struct i2c_client *client = data->client; 215 u8 outbuf[2]; 216 int ret; 217 218 if ((val < 0) || (val > 1023)) 219 return -EINVAL; 220 221 if ((channel != 0) && (channel != 1)) 222 return -EINVAL; 223 224 outbuf[0] = max5821_load_dac_command[channel]; 225 outbuf[0] |= val >> 6; 226 outbuf[1] = (val & 0x3f) << 2; 227 228 ret = i2c_master_send(client, outbuf, 2); 229 if (ret < 0) 230 return ret; 231 else if (ret != 2) 232 return -EIO; 233 else 234 return 0; 235} 236 237static int max5821_read_raw(struct iio_dev *indio_dev, 238 struct iio_chan_spec const *chan, 239 int *val, int *val2, long mask) 240{ 241 struct max5821_data *data = iio_priv(indio_dev); 242 243 switch (mask) { 244 case IIO_CHAN_INFO_RAW: 245 return max5821_get_value(indio_dev, val, chan->channel); 246 case IIO_CHAN_INFO_SCALE: 247 *val = data->vref_mv; 248 *val2 = 10; 249 return IIO_VAL_FRACTIONAL_LOG2; 250 default: 251 return -EINVAL; 252 } 253} 254 255static int max5821_write_raw(struct iio_dev *indio_dev, 256 struct iio_chan_spec const *chan, 257 int val, int val2, long mask) 258{ 259 if (val2 != 0) 260 return -EINVAL; 261 262 switch (mask) { 263 case IIO_CHAN_INFO_RAW: 264 return max5821_set_value(indio_dev, val, chan->channel); 265 default: 266 return -EINVAL; 267 } 268} 269 270static int __maybe_unused max5821_suspend(struct device *dev) 271{ 272 u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, 273 MAX5821_EXTENDED_DAC_A | 274 MAX5821_EXTENDED_DAC_B | 275 MAX5821_EXTENDED_POWER_DOWN_MODE2 }; 276 277 return i2c_master_send(to_i2c_client(dev), outbuf, 2); 278} 279 280static int __maybe_unused max5821_resume(struct device *dev) 281{ 282 u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, 283 MAX5821_EXTENDED_DAC_A | 284 MAX5821_EXTENDED_DAC_B | 285 MAX5821_EXTENDED_POWER_UP }; 286 287 return i2c_master_send(to_i2c_client(dev), outbuf, 2); 288} 289 290static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume); 291 292static const struct iio_info max5821_info = { 293 .read_raw = max5821_read_raw, 294 .write_raw = max5821_write_raw, 295}; 296 297static void max5821_regulator_disable(void *reg) 298{ 299 regulator_disable(reg); 300} 301 302static int max5821_probe(struct i2c_client *client, 303 const struct i2c_device_id *id) 304{ 305 struct max5821_data *data; 306 struct iio_dev *indio_dev; 307 u32 tmp; 308 int ret; 309 310 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 311 if (!indio_dev) 312 return -ENOMEM; 313 data = iio_priv(indio_dev); 314 data->client = client; 315 mutex_init(&data->lock); 316 317 /* max5821 start in powerdown mode 100Kohm to ground */ 318 for (tmp = 0; tmp < MAX5821_MAX_DAC_CHANNELS; tmp++) { 319 data->powerdown[tmp] = true; 320 data->powerdown_mode[tmp] = MAX5821_100KOHM_TO_GND; 321 } 322 323 data->vref_reg = devm_regulator_get(&client->dev, "vref"); 324 if (IS_ERR(data->vref_reg)) 325 return dev_err_probe(&client->dev, PTR_ERR(data->vref_reg), 326 "Failed to get vref regulator\n"); 327 328 ret = regulator_enable(data->vref_reg); 329 if (ret) { 330 dev_err(&client->dev, 331 "Failed to enable vref regulator: %d\n", ret); 332 return ret; 333 } 334 335 ret = devm_add_action_or_reset(&client->dev, max5821_regulator_disable, 336 data->vref_reg); 337 if (ret) { 338 dev_err(&client->dev, 339 "Failed to add action to managed regulator: %d\n", ret); 340 return ret; 341 } 342 343 ret = regulator_get_voltage(data->vref_reg); 344 if (ret < 0) { 345 dev_err(&client->dev, 346 "Failed to get voltage on regulator: %d\n", ret); 347 return ret; 348 } 349 350 data->vref_mv = ret / 1000; 351 352 indio_dev->name = id->name; 353 indio_dev->num_channels = ARRAY_SIZE(max5821_channels); 354 indio_dev->channels = max5821_channels; 355 indio_dev->modes = INDIO_DIRECT_MODE; 356 indio_dev->info = &max5821_info; 357 358 return devm_iio_device_register(&client->dev, indio_dev); 359} 360 361static const struct i2c_device_id max5821_id[] = { 362 { "max5821", ID_MAX5821 }, 363 { } 364}; 365MODULE_DEVICE_TABLE(i2c, max5821_id); 366 367static const struct of_device_id max5821_of_match[] = { 368 { .compatible = "maxim,max5821" }, 369 { } 370}; 371MODULE_DEVICE_TABLE(of, max5821_of_match); 372 373static struct i2c_driver max5821_driver = { 374 .driver = { 375 .name = "max5821", 376 .of_match_table = max5821_of_match, 377 .pm = &max5821_pm_ops, 378 }, 379 .probe = max5821_probe, 380 .id_table = max5821_id, 381}; 382module_i2c_driver(max5821_driver); 383 384MODULE_AUTHOR("Philippe Reynes <tremyfr@yahoo.fr>"); 385MODULE_DESCRIPTION("MAX5821 DAC"); 386MODULE_LICENSE("GPL v2");