diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2015-12-26 07:17:22 -0500 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2016-01-03 12:42:59 -0500 |
commit | 35f739679a18d7a9680960c9cfc472ef012682dd (patch) | |
tree | 00d9976ea2b8559ad04c5bb825fa28b0d4659386 | |
parent | 505abf99c7315f2229b873cca7a0514481a118e6 (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-iio | 2 | ||||
-rw-r--r-- | drivers/iio/dac/Kconfig | 4 | ||||
-rw-r--r-- | drivers/iio/dac/mcp4725.c | 87 |
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 | ||
178 | config MCP4725 | 178 | config 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 | ||
137 | static const char * const mcp4726_powerdown_modes[] = { | ||
138 | "1kohm_to_gnd", | ||
139 | "125kohm_to_gnd", | ||
140 | "640kohm_to_gnd" | ||
141 | }; | ||
142 | |||
137 | static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev, | 143 | static 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 | ||
185 | static const struct iio_enum mcp4725_powerdown_mode_enum = { | 191 | enum { |
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 | |
196 | static 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 | ||
192 | static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = { | 211 | static 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 | |||
225 | static 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 | ||
204 | static const struct iio_chan_spec mcp4725_channel = { | 239 | static 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 | ||
214 | static int mcp4725_set_value(struct iio_dev *indio_dev, int val) | 260 | static 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 | ||
330 | static const struct i2c_device_id mcp4725_id[] = { | 376 | static const struct i2c_device_id mcp4725_id[] = { |
331 | { "mcp4725", 0 }, | 377 | { "mcp4725", MCP4725 }, |
378 | { "mcp4726", MCP4726 }, | ||
332 | { } | 379 | { } |
333 | }; | 380 | }; |
334 | MODULE_DEVICE_TABLE(i2c, mcp4725_id); | 381 | MODULE_DEVICE_TABLE(i2c, mcp4725_id); |
@@ -345,5 +392,5 @@ static struct i2c_driver mcp4725_driver = { | |||
345 | module_i2c_driver(mcp4725_driver); | 392 | module_i2c_driver(mcp4725_driver); |
346 | 393 | ||
347 | MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); | 394 | MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>"); |
348 | MODULE_DESCRIPTION("MCP4725 12-bit DAC"); | 395 | MODULE_DESCRIPTION("MCP4725/6 12-bit DAC"); |
349 | MODULE_LICENSE("GPL"); | 396 | MODULE_LICENSE("GPL"); |