1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * m62332.c - Support for Mitsubishi m62332 DAC 4 * 5 * Copyright (c) 2014 Dmitry Eremin-Solenikov 6 * 7 * Based on max517 driver: 8 * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de> 9 */ 10 11 #include <linux/module.h> 12 #include <linux/slab.h> 13 #include <linux/i2c.h> 14 #include <linux/err.h> 15 16 #include <linux/iio/iio.h> 17 #include <linux/iio/driver.h> 18 19 #include <linux/regulator/consumer.h> 20 21 #define M62332_CHANNELS 2 22 23 struct m62332_data { 24 struct i2c_client *client; 25 struct regulator *vcc; 26 struct mutex mutex; 27 u8 raw[M62332_CHANNELS]; 28 u8 save[M62332_CHANNELS]; 29 }; 30 31 static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) 32 { 33 struct m62332_data *data = iio_priv(indio_dev); 34 struct i2c_client *client = data->client; 35 bool enabling, disabling; 36 u8 outbuf[2]; 37 int res; 38 39 if (val == data->raw[channel]) 40 return 0; 41 42 outbuf[0] = channel; 43 outbuf[1] = val; 44 45 mutex_lock(&data->mutex); 46 47 enabling = val && !data->raw[channel]; 48 disabling = !val && data->raw[channel]; 49 50 if (enabling) { 51 res = regulator_enable(data->vcc); 52 if (res) 53 goto out; 54 } 55 56 res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf)); 57 if (res >= 0 && res != ARRAY_SIZE(outbuf)) 58 res = -EIO; 59 if (res < 0) { 60 if (enabling) 61 regulator_disable(data->vcc); 62 goto out; 63 } 64 65 if (disabling) 66 regulator_disable(data->vcc); 67 68 data->raw[channel] = val; 69 70 mutex_unlock(&data->mutex); 71 72 return 0; 73 74 out: 75 mutex_unlock(&data->mutex); 76 77 return res; 78 } 79 80 static int m62332_read_raw(struct iio_dev *indio_dev, 81 struct iio_chan_spec const *chan, 82 int *val, 83 int *val2, 84 long mask) 85 { 86 struct m62332_data *data = iio_priv(indio_dev); 87 int ret; 88 89 switch (mask) { 90 case IIO_CHAN_INFO_SCALE: 91 /* Corresponds to Vref / 2^(bits) */ 92 ret = regulator_get_voltage(data->vcc); 93 if (ret < 0) 94 return ret; 95 96 *val = ret / 1000; /* mV */ 97 *val2 = 8; 98 99 return IIO_VAL_FRACTIONAL_LOG2; 100 case IIO_CHAN_INFO_RAW: 101 *val = data->raw[chan->channel]; 102 103 return IIO_VAL_INT; 104 case IIO_CHAN_INFO_OFFSET: 105 *val = 1; 106 107 return IIO_VAL_INT; 108 default: 109 break; 110 } 111 112 return -EINVAL; 113 } 114 115 static int m62332_write_raw(struct iio_dev *indio_dev, 116 struct iio_chan_spec const *chan, int val, int val2, 117 long mask) 118 { 119 switch (mask) { 120 case IIO_CHAN_INFO_RAW: 121 if (val < 0 || val > 255) 122 return -EINVAL; 123 124 return m62332_set_value(indio_dev, val, chan->channel); 125 default: 126 break; 127 } 128 129 return -EINVAL; 130 } 131 132 static int m62332_suspend(struct device *dev) 133 { 134 struct i2c_client *client = to_i2c_client(dev); 135 struct iio_dev *indio_dev = i2c_get_clientdata(client); 136 struct m62332_data *data = iio_priv(indio_dev); 137 int ret; 138 139 data->save[0] = data->raw[0]; 140 data->save[1] = data->raw[1]; 141 142 ret = m62332_set_value(indio_dev, 0, 0); 143 if (ret < 0) 144 return ret; 145 146 return m62332_set_value(indio_dev, 0, 1); 147 } 148 149 static int m62332_resume(struct device *dev) 150 { 151 struct i2c_client *client = to_i2c_client(dev); 152 struct iio_dev *indio_dev = i2c_get_clientdata(client); 153 struct m62332_data *data = iio_priv(indio_dev); 154 int ret; 155 156 ret = m62332_set_value(indio_dev, data->save[0], 0); 157 if (ret < 0) 158 return ret; 159 160 return m62332_set_value(indio_dev, data->save[1], 1); 161 } 162 163 static DEFINE_SIMPLE_DEV_PM_OPS(m62332_pm_ops, m62332_suspend, m62332_resume); 164 165 static const struct iio_info m62332_info = { 166 .read_raw = m62332_read_raw, 167 .write_raw = m62332_write_raw, 168 }; 169 170 #define M62332_CHANNEL(chan) { \ 171 .type = IIO_VOLTAGE, \ 172 .indexed = 1, \ 173 .output = 1, \ 174 .channel = (chan), \ 175 .datasheet_name = "CH" #chan, \ 176 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 177 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 178 BIT(IIO_CHAN_INFO_OFFSET), \ 179 } 180 181 static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = { 182 M62332_CHANNEL(0), 183 M62332_CHANNEL(1) 184 }; 185 186 static int m62332_probe(struct i2c_client *client) 187 { 188 struct m62332_data *data; 189 struct iio_dev *indio_dev; 190 int ret; 191 192 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 193 if (!indio_dev) 194 return -ENOMEM; 195 196 data = iio_priv(indio_dev); 197 i2c_set_clientdata(client, indio_dev); 198 data->client = client; 199 200 mutex_init(&data->mutex); 201 202 data->vcc = devm_regulator_get(&client->dev, "VCC"); 203 if (IS_ERR(data->vcc)) 204 return PTR_ERR(data->vcc); 205 206 indio_dev->num_channels = ARRAY_SIZE(m62332_channels); 207 indio_dev->channels = m62332_channels; 208 indio_dev->modes = INDIO_DIRECT_MODE; 209 indio_dev->info = &m62332_info; 210 211 ret = iio_map_array_register(indio_dev, dev_get_platdata(&client->dev)); 212 if (ret < 0) 213 return ret; 214 215 ret = iio_device_register(indio_dev); 216 if (ret < 0) 217 goto err; 218 219 return 0; 220 221 err: 222 iio_map_array_unregister(indio_dev); 223 224 return ret; 225 } 226 227 static void m62332_remove(struct i2c_client *client) 228 { 229 struct iio_dev *indio_dev = i2c_get_clientdata(client); 230 231 iio_device_unregister(indio_dev); 232 iio_map_array_unregister(indio_dev); 233 m62332_set_value(indio_dev, 0, 0); 234 m62332_set_value(indio_dev, 0, 1); 235 } 236 237 static const struct i2c_device_id m62332_id[] = { 238 { .name = "m62332" }, 239 { } 240 }; 241 MODULE_DEVICE_TABLE(i2c, m62332_id); 242 243 static struct i2c_driver m62332_driver = { 244 .driver = { 245 .name = "m62332", 246 .pm = pm_sleep_ptr(&m62332_pm_ops), 247 }, 248 .probe = m62332_probe, 249 .remove = m62332_remove, 250 .id_table = m62332_id, 251 }; 252 module_i2c_driver(m62332_driver); 253 254 MODULE_AUTHOR("Dmitry Eremin-Solenikov"); 255 MODULE_DESCRIPTION("M62332 8-bit DAC"); 256 MODULE_LICENSE("GPL v2"); 257