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 struct regulator *vcc; 35 struct mutex mutex; 36 u8 raw[M62332_CHANNELS]; 37 #ifdef CONFIG_PM_SLEEP 38 u8 save[M62332_CHANNELS]; 39 #endif 40 }; 41 42 static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) 43 { 44 struct m62332_data *data = iio_priv(indio_dev); 45 struct i2c_client *client = data->client; 46 u8 outbuf[2]; 47 int res; 48 49 if (val == data->raw[channel]) 50 return 0; 51 52 outbuf[0] = channel; 53 outbuf[1] = val; 54 55 mutex_lock(&data->mutex); 56 57 if (val) { 58 res = regulator_enable(data->vcc); 59 if (res) 60 goto out; 61 } 62 63 res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf)); 64 if (res >= 0 && res != ARRAY_SIZE(outbuf)) 65 res = -EIO; 66 if (res < 0) 67 goto out; 68 69 data->raw[channel] = val; 70 71 if (!val) 72 regulator_disable(data->vcc); 73 74 mutex_unlock(&data->mutex); 75 76 return 0; 77 78 out: 79 mutex_unlock(&data->mutex); 80 81 return res; 82 } 83 84 static int m62332_read_raw(struct iio_dev *indio_dev, 85 struct iio_chan_spec const *chan, 86 int *val, 87 int *val2, 88 long mask) 89 { 90 struct m62332_data *data = iio_priv(indio_dev); 91 int ret; 92 93 switch (mask) { 94 case IIO_CHAN_INFO_SCALE: 95 /* Corresponds to Vref / 2^(bits) */ 96 ret = regulator_get_voltage(data->vcc); 97 if (ret < 0) 98 return ret; 99 100 *val = ret / 1000; /* mV */ 101 *val2 = 8; 102 103 return IIO_VAL_FRACTIONAL_LOG2; 104 case IIO_CHAN_INFO_RAW: 105 *val = data->raw[chan->channel]; 106 107 return IIO_VAL_INT; 108 case IIO_CHAN_INFO_OFFSET: 109 *val = 1; 110 111 return IIO_VAL_INT; 112 default: 113 break; 114 } 115 116 return -EINVAL; 117 } 118 119 static int m62332_write_raw(struct iio_dev *indio_dev, 120 struct iio_chan_spec const *chan, int val, int val2, 121 long mask) 122 { 123 switch (mask) { 124 case IIO_CHAN_INFO_RAW: 125 if (val < 0 || val > 255) 126 return -EINVAL; 127 128 return m62332_set_value(indio_dev, val, chan->channel); 129 default: 130 break; 131 } 132 133 return -EINVAL; 134 } 135 136 #ifdef CONFIG_PM_SLEEP 137 static int m62332_suspend(struct device *dev) 138 { 139 struct i2c_client *client = to_i2c_client(dev); 140 struct iio_dev *indio_dev = i2c_get_clientdata(client); 141 struct m62332_data *data = iio_priv(indio_dev); 142 int ret; 143 144 data->save[0] = data->raw[0]; 145 data->save[1] = data->raw[1]; 146 147 ret = m62332_set_value(indio_dev, 0, 0); 148 if (ret < 0) 149 return ret; 150 151 return m62332_set_value(indio_dev, 0, 1); 152 } 153 154 static int m62332_resume(struct device *dev) 155 { 156 struct i2c_client *client = to_i2c_client(dev); 157 struct iio_dev *indio_dev = i2c_get_clientdata(client); 158 struct m62332_data *data = iio_priv(indio_dev); 159 int ret; 160 161 ret = m62332_set_value(indio_dev, data->save[0], 0); 162 if (ret < 0) 163 return ret; 164 165 return m62332_set_value(indio_dev, data->save[1], 1); 166 } 167 168 static SIMPLE_DEV_PM_OPS(m62332_pm_ops, m62332_suspend, m62332_resume); 169 #define M62332_PM_OPS (&m62332_pm_ops) 170 #else 171 #define M62332_PM_OPS NULL 172 #endif 173 174 static const struct iio_info m62332_info = { 175 .read_raw = m62332_read_raw, 176 .write_raw = m62332_write_raw, 177 .driver_module = THIS_MODULE, 178 }; 179 180 #define M62332_CHANNEL(chan) { \ 181 .type = IIO_VOLTAGE, \ 182 .indexed = 1, \ 183 .output = 1, \ 184 .channel = (chan), \ 185 .datasheet_name = "CH" #chan, \ 186 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 187 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 188 BIT(IIO_CHAN_INFO_OFFSET), \ 189 } 190 191 static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = { 192 M62332_CHANNEL(0), 193 M62332_CHANNEL(1) 194 }; 195 196 static int m62332_probe(struct i2c_client *client, 197 const struct i2c_device_id *id) 198 { 199 struct m62332_data *data; 200 struct iio_dev *indio_dev; 201 int ret; 202 203 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); 204 if (!indio_dev) 205 return -ENOMEM; 206 207 data = iio_priv(indio_dev); 208 i2c_set_clientdata(client, indio_dev); 209 data->client = client; 210 211 mutex_init(&data->mutex); 212 213 data->vcc = devm_regulator_get(&client->dev, "VCC"); 214 if (IS_ERR(data->vcc)) 215 return PTR_ERR(data->vcc); 216 217 /* establish that the iio_dev is a child of the i2c device */ 218 indio_dev->dev.parent = &client->dev; 219 220 indio_dev->num_channels = ARRAY_SIZE(m62332_channels); 221 indio_dev->channels = m62332_channels; 222 indio_dev->modes = INDIO_DIRECT_MODE; 223 indio_dev->info = &m62332_info; 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 238 return ret; 239 } 240 241 static int m62332_remove(struct i2c_client *client) 242 { 243 struct iio_dev *indio_dev = i2c_get_clientdata(client); 244 245 iio_device_unregister(indio_dev); 246 iio_map_array_unregister(indio_dev); 247 m62332_set_value(indio_dev, 0, 0); 248 m62332_set_value(indio_dev, 0, 1); 249 250 return 0; 251 } 252 253 static const struct i2c_device_id m62332_id[] = { 254 { "m62332", }, 255 { } 256 }; 257 MODULE_DEVICE_TABLE(i2c, m62332_id); 258 259 static struct i2c_driver m62332_driver = { 260 .driver = { 261 .name = "m62332", 262 .pm = M62332_PM_OPS, 263 }, 264 .probe = m62332_probe, 265 .remove = m62332_remove, 266 .id_table = m62332_id, 267 }; 268 module_i2c_driver(m62332_driver); 269 270 MODULE_AUTHOR("Dmitry Eremin-Solenikov"); 271 MODULE_DESCRIPTION("M62332 8-bit DAC"); 272 MODULE_LICENSE("GPL v2"); 273