Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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