214 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * max517.c - Support for Maxim MAX517, MAX518 and MAX5194 *5 * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>6 */7 8#include <linux/module.h>9#include <linux/slab.h>10#include <linux/jiffies.h>11#include <linux/i2c.h>12#include <linux/err.h>13 14#include <linux/iio/iio.h>15#include <linux/iio/sysfs.h>16#include <linux/iio/dac/max517.h>17 18#define MAX517_DRV_NAME "max517"19 20/* Commands */21#define COMMAND_CHANNEL0 0x0022#define COMMAND_CHANNEL1 0x01 /* for MAX518 and MAX519 */23#define COMMAND_PD 0x08 /* Power Down */24 25enum max517_device_ids {26 ID_MAX517,27 ID_MAX518,28 ID_MAX519,29 ID_MAX520,30 ID_MAX521,31};32 33struct max517_data {34 struct i2c_client *client;35 unsigned short vref_mv[8];36};37 38/*39 * channel: bit 0: channel 140 * bit 1: channel 241 * (this way, it's possible to set both channels at once)42 */43static int max517_set_value(struct iio_dev *indio_dev,44 long val, int channel)45{46 struct max517_data *data = iio_priv(indio_dev);47 struct i2c_client *client = data->client;48 u8 outbuf[2];49 int res;50 51 if (val < 0 || val > 255)52 return -EINVAL;53 54 outbuf[0] = channel;55 outbuf[1] = val;56 57 res = i2c_master_send(client, outbuf, 2);58 if (res < 0)59 return res;60 else if (res != 2)61 return -EIO;62 else63 return 0;64}65 66static int max517_read_raw(struct iio_dev *indio_dev,67 struct iio_chan_spec const *chan,68 int *val,69 int *val2,70 long m)71{72 struct max517_data *data = iio_priv(indio_dev);73 74 switch (m) {75 case IIO_CHAN_INFO_SCALE:76 /* Corresponds to Vref / 2^(bits) */77 *val = data->vref_mv[chan->channel];78 *val2 = 8;79 return IIO_VAL_FRACTIONAL_LOG2;80 default:81 break;82 }83 return -EINVAL;84}85 86static int max517_write_raw(struct iio_dev *indio_dev,87 struct iio_chan_spec const *chan, int val, int val2, long mask)88{89 int ret;90 91 switch (mask) {92 case IIO_CHAN_INFO_RAW:93 ret = max517_set_value(indio_dev, val, chan->channel);94 break;95 default:96 ret = -EINVAL;97 break;98 }99 100 return ret;101}102 103static int max517_suspend(struct device *dev)104{105 u8 outbuf = COMMAND_PD;106 107 return i2c_master_send(to_i2c_client(dev), &outbuf, 1);108}109 110static int max517_resume(struct device *dev)111{112 u8 outbuf = 0;113 114 return i2c_master_send(to_i2c_client(dev), &outbuf, 1);115}116 117static DEFINE_SIMPLE_DEV_PM_OPS(max517_pm_ops, max517_suspend, max517_resume);118 119static const struct iio_info max517_info = {120 .read_raw = max517_read_raw,121 .write_raw = max517_write_raw,122};123 124#define MAX517_CHANNEL(chan) { \125 .type = IIO_VOLTAGE, \126 .indexed = 1, \127 .output = 1, \128 .channel = (chan), \129 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \130 BIT(IIO_CHAN_INFO_SCALE), \131}132 133static const struct iio_chan_spec max517_channels[] = {134 MAX517_CHANNEL(0),135 MAX517_CHANNEL(1),136 MAX517_CHANNEL(2),137 MAX517_CHANNEL(3),138 MAX517_CHANNEL(4),139 MAX517_CHANNEL(5),140 MAX517_CHANNEL(6),141 MAX517_CHANNEL(7),142};143 144static int max517_probe(struct i2c_client *client)145{146 const struct i2c_device_id *id = i2c_client_get_device_id(client);147 struct max517_data *data;148 struct iio_dev *indio_dev;149 struct max517_platform_data *platform_data = client->dev.platform_data;150 int chan;151 152 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));153 if (!indio_dev)154 return -ENOMEM;155 data = iio_priv(indio_dev);156 data->client = client;157 158 switch (id->driver_data) {159 case ID_MAX521:160 indio_dev->num_channels = 8;161 break;162 case ID_MAX520:163 indio_dev->num_channels = 4;164 break;165 case ID_MAX519:166 case ID_MAX518:167 indio_dev->num_channels = 2;168 break;169 default: /* single channel for MAX517 */170 indio_dev->num_channels = 1;171 break;172 }173 indio_dev->channels = max517_channels;174 indio_dev->modes = INDIO_DIRECT_MODE;175 indio_dev->info = &max517_info;176 177 /*178 * Reference voltage on MAX518 and default is 5V, else take vref_mv179 * from platform_data180 */181 for (chan = 0; chan < indio_dev->num_channels; chan++) {182 if (id->driver_data == ID_MAX518 || !platform_data)183 data->vref_mv[chan] = 5000; /* mV */184 else185 data->vref_mv[chan] = platform_data->vref_mv[chan];186 }187 188 return devm_iio_device_register(&client->dev, indio_dev);189}190 191static const struct i2c_device_id max517_id[] = {192 { "max517", ID_MAX517 },193 { "max518", ID_MAX518 },194 { "max519", ID_MAX519 },195 { "max520", ID_MAX520 },196 { "max521", ID_MAX521 },197 { }198};199MODULE_DEVICE_TABLE(i2c, max517_id);200 201static struct i2c_driver max517_driver = {202 .driver = {203 .name = MAX517_DRV_NAME,204 .pm = pm_sleep_ptr(&max517_pm_ops),205 },206 .probe = max517_probe,207 .id_table = max517_id,208};209module_i2c_driver(max517_driver);210 211MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");212MODULE_DESCRIPTION("MAX517/518/519/520/521 8-bit DAC");213MODULE_LICENSE("GPL");214