aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2015-12-26 07:17:22 -0500
committerJonathan Cameron <jic23@kernel.org>2016-01-03 12:42:59 -0500
commit35f739679a18d7a9680960c9cfc472ef012682dd (patch)
tree00d9976ea2b8559ad04c5bb825fa28b0d4659386
parent505abf99c7315f2229b873cca7a0514481a118e6 (diff)
iio: dac: mcp4725: Add basic support for MCP4726
MCP4726 is a single channel 12-bit DAC. We can support MCP4726 with a little changes to mcp4725 driver. In power-down mode, they have different selection of VOUT pull-down registers. MCP4726 also has features: - Output gain options: 1x, 2x - Voltage reference selection: VDD, VREF (Unbuffered or Buffered) But these are not supported in this change. (1x gain, VDD is selected) datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/22272C.pdf Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Cc: Jonathan Cameron <jic23@kernel.org> Cc: Hartmut Knaack <knaack.h@gmx.de> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: Peter Meerwald <pmeerw@pmeerw.net> Cc: linux-iio@vger.kernel.org Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio2
-rw-r--r--drivers/iio/dac/Kconfig4
-rw-r--r--drivers/iio/dac/mcp4725.c87
3 files changed, 71 insertions, 22 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 0439c2aaf741..8fadd272ad8a 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -497,7 +497,9 @@ Description:
497 6kohm_to_gnd: connected to ground via a 6kOhm resistor, 497 6kohm_to_gnd: connected to ground via a 6kOhm resistor,
498 20kohm_to_gnd: connected to ground via a 20kOhm resistor, 498 20kohm_to_gnd: connected to ground via a 20kOhm resistor,
499 100kohm_to_gnd: connected to ground via an 100kOhm resistor, 499 100kohm_to_gnd: connected to ground via an 100kOhm resistor,
500 125kohm_to_gnd: connected to ground via an 125kOhm resistor,
500 500kohm_to_gnd: connected to ground via a 500kOhm resistor, 501 500kohm_to_gnd: connected to ground via a 500kOhm resistor,
502 640kohm_to_gnd: connected to ground via a 640kOhm resistor,
501 three_state: left floating. 503 three_state: left floating.
502 For a list of available output power down options read 504 For a list of available output power down options read
503 outX_powerdown_mode_available. If Y is not present the 505 outX_powerdown_mode_available. If Y is not present the
diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
index e701e28fb1cd..5263c5125fbb 100644
--- a/drivers/iio/dac/Kconfig
+++ b/drivers/iio/dac/Kconfig
@@ -176,11 +176,11 @@ config MAX5821
176 10 bits DAC. 176 10 bits DAC.
177 177
178config MCP4725 178config MCP4725
179 tristate "MCP4725 DAC driver" 179 tristate "MCP4725/6 DAC driver"
180 depends on I2C 180 depends on I2C
181 ---help--- 181 ---help---
182 Say Y here if you want to build a driver for the Microchip 182 Say Y here if you want to build a driver for the Microchip
183 MCP 4725 12-bit digital-to-analog converter (DAC) with I2C 183 MCP 4725/6 12-bit digital-to-analog converter (DAC) with I2C
184 interface. 184 interface.
185 185
186 To compile this driver as a module, choose M here: the module 186 To compile this driver as a module, choose M here: the module
diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c
index 43d14588448d..fb4b3364d8e0 100644
--- a/drivers/iio/dac/mcp4725.c
+++ b/drivers/iio/dac/mcp4725.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * mcp4725.c - Support for Microchip MCP4725 2 * mcp4725.c - Support for Microchip MCP4725/6
3 * 3 *
4 * Copyright (C) 2012 Peter Meerwald <pmeerw@pmeerw.net> 4 * Copyright (C) 2012 Peter Meerwald <pmeerw@pmeerw.net>
5 * 5 *
@@ -134,6 +134,12 @@ static const char * const mcp4725_powerdown_modes[] = {
134 "500kohm_to_gnd" 134 "500kohm_to_gnd"
135}; 135};
136 136
137static const char * const mcp4726_powerdown_modes[] = {
138 "1kohm_to_gnd",
139 "125kohm_to_gnd",
140 "640kohm_to_gnd"
141};
142
137static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev, 143static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
138 const struct iio_chan_spec *chan) 144 const struct iio_chan_spec *chan)
139{ 145{
@@ -182,11 +188,24 @@ static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
182 return len; 188 return len;
183} 189}
184 190
185static const struct iio_enum mcp4725_powerdown_mode_enum = { 191enum {
186 .items = mcp4725_powerdown_modes, 192 MCP4725,
187 .num_items = ARRAY_SIZE(mcp4725_powerdown_modes), 193 MCP4726,
188 .get = mcp4725_get_powerdown_mode, 194};
189 .set = mcp4725_set_powerdown_mode, 195
196static const struct iio_enum mcp472x_powerdown_mode_enum[] = {
197 [MCP4725] = {
198 .items = mcp4725_powerdown_modes,
199 .num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
200 .get = mcp4725_get_powerdown_mode,
201 .set = mcp4725_set_powerdown_mode,
202 },
203 [MCP4726] = {
204 .items = mcp4726_powerdown_modes,
205 .num_items = ARRAY_SIZE(mcp4726_powerdown_modes),
206 .get = mcp4725_get_powerdown_mode,
207 .set = mcp4725_set_powerdown_mode,
208 },
190}; 209};
191 210
192static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = { 211static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
@@ -196,19 +215,46 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
196 .write = mcp4725_write_powerdown, 215 .write = mcp4725_write_powerdown,
197 .shared = IIO_SEPARATE, 216 .shared = IIO_SEPARATE,
198 }, 217 },
199 IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum), 218 IIO_ENUM("powerdown_mode", IIO_SEPARATE,
200 IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum), 219 &mcp472x_powerdown_mode_enum[MCP4725]),
220 IIO_ENUM_AVAILABLE("powerdown_mode",
221 &mcp472x_powerdown_mode_enum[MCP4725]),
222 { },
223};
224
225static const struct iio_chan_spec_ext_info mcp4726_ext_info[] = {
226 {
227 .name = "powerdown",
228 .read = mcp4725_read_powerdown,
229 .write = mcp4725_write_powerdown,
230 .shared = IIO_SEPARATE,
231 },
232 IIO_ENUM("powerdown_mode", IIO_SEPARATE,
233 &mcp472x_powerdown_mode_enum[MCP4726]),
234 IIO_ENUM_AVAILABLE("powerdown_mode",
235 &mcp472x_powerdown_mode_enum[MCP4726]),
201 { }, 236 { },
202}; 237};
203 238
204static const struct iio_chan_spec mcp4725_channel = { 239static const struct iio_chan_spec mcp472x_channel[] = {
205 .type = IIO_VOLTAGE, 240 [MCP4725] = {
206 .indexed = 1, 241 .type = IIO_VOLTAGE,
207 .output = 1, 242 .indexed = 1,
208 .channel = 0, 243 .output = 1,
209 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 244 .channel = 0,
210 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 245 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
211 .ext_info = mcp4725_ext_info, 246 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
247 .ext_info = mcp4725_ext_info,
248 },
249 [MCP4726] = {
250 .type = IIO_VOLTAGE,
251 .indexed = 1,
252 .output = 1,
253 .channel = 0,
254 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
255 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
256 .ext_info = mcp4726_ext_info,
257 },
212}; 258};
213 259
214static int mcp4725_set_value(struct iio_dev *indio_dev, int val) 260static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
@@ -301,7 +347,7 @@ static int mcp4725_probe(struct i2c_client *client,
301 347
302 indio_dev->dev.parent = &client->dev; 348 indio_dev->dev.parent = &client->dev;
303 indio_dev->info = &mcp4725_info; 349 indio_dev->info = &mcp4725_info;
304 indio_dev->channels = &mcp4725_channel; 350 indio_dev->channels = &mcp472x_channel[id->driver_data];
305 indio_dev->num_channels = 1; 351 indio_dev->num_channels = 1;
306 indio_dev->modes = INDIO_DIRECT_MODE; 352 indio_dev->modes = INDIO_DIRECT_MODE;
307 353
@@ -315,7 +361,7 @@ static int mcp4725_probe(struct i2c_client *client,
315 } 361 }
316 pd = (inbuf[0] >> 1) & 0x3; 362 pd = (inbuf[0] >> 1) & 0x3;
317 data->powerdown = pd > 0 ? true : false; 363 data->powerdown = pd > 0 ? true : false;
318 data->powerdown_mode = pd ? pd-1 : 2; /* 500kohm_to_gnd */ 364 data->powerdown_mode = pd ? pd - 1 : 2; /* largest register to gnd */
319 data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4); 365 data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
320 366
321 return iio_device_register(indio_dev); 367 return iio_device_register(indio_dev);
@@ -328,7 +374,8 @@ static int mcp4725_remove(struct i2c_client *client)
328} 374}
329 375
330static const struct i2c_device_id mcp4725_id[] = { 376static const struct i2c_device_id mcp4725_id[] = {
331 { "mcp4725", 0 }, 377 { "mcp4725", MCP4725 },
378 { "mcp4726", MCP4726 },
332 { } 379 { }
333}; 380};
334MODULE_DEVICE_TABLE(i2c, mcp4725_id); 381MODULE_DEVICE_TABLE(i2c, mcp4725_id);
@@ -345,5 +392,5 @@ static struct i2c_driver mcp4725_driver = {
345module_i2c_driver(mcp4725_driver); 392module_i2c_driver(mcp4725_driver);
346 393
347MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); 394MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
348MODULE_DESCRIPTION("MCP4725 12-bit DAC"); 395MODULE_DESCRIPTION("MCP4725/6 12-bit DAC");
349MODULE_LICENSE("GPL"); 396MODULE_LICENSE("GPL");