diff options
Diffstat (limited to 'drivers/iio/dac/m62332.c')
-rw-r--r-- | drivers/iio/dac/m62332.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c index c23d7fa88..76e8b044b 100644 --- a/drivers/iio/dac/m62332.c +++ b/drivers/iio/dac/m62332.c @@ -31,7 +31,6 @@ struct m62332_data { struct i2c_client *client; - u16 vref_mv; struct regulator *vcc; struct mutex mutex; u8 raw[M62332_CHANNELS]; @@ -40,8 +39,7 @@ struct m62332_data { #endif }; -static int m62332_set_value(struct iio_dev *indio_dev, - u8 val, int channel) +static int m62332_set_value(struct iio_dev *indio_dev, u8 val, int channel) { struct m62332_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; @@ -62,8 +60,8 @@ static int m62332_set_value(struct iio_dev *indio_dev, goto out; } - res = i2c_master_send(client, outbuf, 2); - if (res >= 0 && res != 2) + res = i2c_master_send(client, outbuf, ARRAY_SIZE(outbuf)); + if (res >= 0 && res != ARRAY_SIZE(outbuf)) res = -EIO; if (res < 0) goto out; @@ -87,46 +85,52 @@ static int m62332_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, - long m) + long mask) { struct m62332_data *data = iio_priv(indio_dev); + int ret; - switch (m) { + switch (mask) { case IIO_CHAN_INFO_SCALE: /* Corresponds to Vref / 2^(bits) */ - *val = data->vref_mv; + ret = regulator_get_voltage(data->vcc); + if (ret < 0) + return ret; + + *val = ret / 1000; /* mV */ *val2 = 8; + return IIO_VAL_FRACTIONAL_LOG2; case IIO_CHAN_INFO_RAW: *val = data->raw[chan->channel]; + return IIO_VAL_INT; case IIO_CHAN_INFO_OFFSET: *val = 1; + return IIO_VAL_INT; default: break; } + return -EINVAL; } static int m62332_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, int val, int val2, long mask) + struct iio_chan_spec const *chan, int val, int val2, + long mask) { - int ret; - switch (mask) { case IIO_CHAN_INFO_RAW: if (val < 0 || val > 255) return -EINVAL; - ret = m62332_set_value(indio_dev, val, chan->channel); - break; + return m62332_set_value(indio_dev, val, chan->channel); default: - ret = -EINVAL; break; } - return ret; + return -EINVAL; } #ifdef CONFIG_PM_SLEEP @@ -173,15 +177,15 @@ static const struct iio_info m62332_info = { .driver_module = THIS_MODULE, }; -#define M62332_CHANNEL(chan) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .output = 1, \ - .channel = (chan), \ - .datasheet_name = "CH" #chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_OFFSET), \ +#define M62332_CHANNEL(chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (chan), \ + .datasheet_name = "CH" #chan, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_OFFSET), \ } static const struct iio_chan_spec m62332_channels[M62332_CHANNELS] = { @@ -199,6 +203,7 @@ static int m62332_probe(struct i2c_client *client, indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; + data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; @@ -212,16 +217,11 @@ static int m62332_probe(struct i2c_client *client, /* establish that the iio_dev is a child of the i2c device */ indio_dev->dev.parent = &client->dev; - indio_dev->num_channels = M62332_CHANNELS; + indio_dev->num_channels = ARRAY_SIZE(m62332_channels); indio_dev->channels = m62332_channels; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &m62332_info; - ret = regulator_get_voltage(data->vcc); - if (ret < 0) - return ret; - data->vref_mv = ret / 1000; /* mV */ - ret = iio_map_array_register(indio_dev, client->dev.platform_data); if (ret < 0) return ret; @@ -234,6 +234,7 @@ static int m62332_probe(struct i2c_client *client, err: iio_map_array_unregister(indio_dev); + return ret; } @@ -243,6 +244,8 @@ static int m62332_remove(struct i2c_client *client) iio_device_unregister(indio_dev); iio_map_array_unregister(indio_dev); + m62332_set_value(indio_dev, 0, 0); + m62332_set_value(indio_dev, 0, 1); return 0; } |