diff options
| author | Peter Meerwald <pmeerw@pmeerw.net> | 2013-06-23 17:30:00 -0400 |
|---|---|---|
| committer | Jonathan Cameron <jic23@kernel.org> | 2013-08-03 13:40:31 -0400 |
| commit | f17b77d6cfbc0d130ba9d57b89e8579ff43a3350 (patch) | |
| tree | 038ce0ba26ec59b53a3485b6c19014957b4c784d /drivers/iio/dac | |
| parent | 341673f1412cda87bcccb66f6ac4f01861657122 (diff) | |
iio: add store_eeprom to mcp4725 dac driver
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/dac')
| -rw-r--r-- | drivers/iio/dac/mcp4725.c | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/drivers/iio/dac/mcp4725.c b/drivers/iio/dac/mcp4725.c index a612ec766d96..cb9db90f0a21 100644 --- a/drivers/iio/dac/mcp4725.c +++ b/drivers/iio/dac/mcp4725.c | |||
| @@ -12,14 +12,13 @@ | |||
| 12 | * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC) | 12 | * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC) |
| 13 | * (7-bit I2C slave address 0x60, the three LSBs can be configured in | 13 | * (7-bit I2C slave address 0x60, the three LSBs can be configured in |
| 14 | * hardware) | 14 | * hardware) |
| 15 | * | ||
| 16 | * writing the DAC value to EEPROM is not supported | ||
| 17 | */ | 15 | */ |
| 18 | 16 | ||
| 19 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 20 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 21 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 22 | #include <linux/err.h> | 20 | #include <linux/err.h> |
| 21 | #include <linux/delay.h> | ||
| 23 | 22 | ||
| 24 | #include <linux/iio/iio.h> | 23 | #include <linux/iio/iio.h> |
| 25 | #include <linux/iio/sysfs.h> | 24 | #include <linux/iio/sysfs.h> |
| @@ -64,6 +63,66 @@ static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume); | |||
| 64 | #define MCP4725_PM_OPS NULL | 63 | #define MCP4725_PM_OPS NULL |
| 65 | #endif | 64 | #endif |
| 66 | 65 | ||
| 66 | static int mcp4725_store_eeprom(struct device *dev, | ||
| 67 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 68 | { | ||
| 69 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | ||
| 70 | struct mcp4725_data *data = iio_priv(indio_dev); | ||
| 71 | int tries = 20; | ||
| 72 | u8 inoutbuf[3]; | ||
| 73 | bool state; | ||
| 74 | int ret; | ||
| 75 | |||
| 76 | ret = strtobool(buf, &state); | ||
| 77 | if (ret < 0) | ||
| 78 | return ret; | ||
| 79 | |||
| 80 | if (!state) | ||
| 81 | return 0; | ||
| 82 | |||
| 83 | inoutbuf[0] = 0x60; /* write EEPROM */ | ||
| 84 | inoutbuf[1] = data->dac_value >> 4; | ||
| 85 | inoutbuf[2] = (data->dac_value & 0xf) << 4; | ||
| 86 | |||
| 87 | ret = i2c_master_send(data->client, inoutbuf, 3); | ||
| 88 | if (ret < 0) | ||
| 89 | return ret; | ||
| 90 | else if (ret != 3) | ||
| 91 | return -EIO; | ||
| 92 | |||
| 93 | /* wait for write complete, takes up to 50ms */ | ||
| 94 | while (tries--) { | ||
| 95 | msleep(20); | ||
| 96 | ret = i2c_master_recv(data->client, inoutbuf, 3); | ||
| 97 | if (ret < 0) | ||
| 98 | return ret; | ||
| 99 | else if (ret != 3) | ||
| 100 | return -EIO; | ||
| 101 | |||
| 102 | if (inoutbuf[0] & 0x80) | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (tries < 0) { | ||
| 107 | dev_err(&data->client->dev, | ||
| 108 | "mcp4725_store_eeprom() failed, incomplete\n"); | ||
| 109 | return -EIO; | ||
| 110 | } | ||
| 111 | |||
| 112 | return len; | ||
| 113 | } | ||
| 114 | |||
| 115 | static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0); | ||
| 116 | |||
| 117 | static struct attribute *mcp4725_attributes[] = { | ||
| 118 | &iio_dev_attr_store_eeprom.dev_attr.attr, | ||
| 119 | NULL, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static const struct attribute_group mcp4725_attribute_group = { | ||
| 123 | .attrs = mcp4725_attributes, | ||
| 124 | }; | ||
| 125 | |||
| 67 | static const struct iio_chan_spec mcp4725_channel = { | 126 | static const struct iio_chan_spec mcp4725_channel = { |
| 68 | .type = IIO_VOLTAGE, | 127 | .type = IIO_VOLTAGE, |
| 69 | .indexed = 1, | 128 | .indexed = 1, |
| @@ -138,6 +197,7 @@ static int mcp4725_write_raw(struct iio_dev *indio_dev, | |||
| 138 | static const struct iio_info mcp4725_info = { | 197 | static const struct iio_info mcp4725_info = { |
| 139 | .read_raw = mcp4725_read_raw, | 198 | .read_raw = mcp4725_read_raw, |
| 140 | .write_raw = mcp4725_write_raw, | 199 | .write_raw = mcp4725_write_raw, |
| 200 | .attrs = &mcp4725_attribute_group, | ||
| 141 | .driver_module = THIS_MODULE, | 201 | .driver_module = THIS_MODULE, |
| 142 | }; | 202 | }; |
| 143 | 203 | ||
