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