diff options
Diffstat (limited to 'drivers/iio/adc/ad7380.c')
-rw-r--r-- | drivers/iio/adc/ad7380.c | 136 |
1 files changed, 78 insertions, 58 deletions
diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c index e8bddfb0d07d..fb728570debe 100644 --- a/drivers/iio/adc/ad7380.c +++ b/drivers/iio/adc/ad7380.c @@ -75,6 +75,7 @@ #define T_CONVERT_NS 190 /* conversion time */ #define T_CONVERT_0_NS 10 /* 1st conversion start time (oversampling) */ #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ +#define T_POWERUP_US 5000 /* Power up */ struct ad7380_timing_specs { const unsigned int t_csh_ns; /* CS minimum high time */ @@ -86,6 +87,9 @@ struct ad7380_chip_info { unsigned int num_channels; unsigned int num_simult_channels; bool has_mux; + const char * const *supplies; + unsigned int num_supplies; + bool external_ref_only; const char * const *vcm_supplies; unsigned int num_vcm_supplies; const unsigned long *available_scan_masks; @@ -243,6 +247,10 @@ DEFINE_AD7380_8_CHANNEL(ad7386_4_channels, 16, 0, u); DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u); +static const char * const ad7380_supplies[] = { + "vcc", "vlogic", +}; + static const char * const ad7380_2_channel_vcm_supplies[] = { "aina", "ainb", }; @@ -338,6 +346,8 @@ static const struct ad7380_chip_info ad7380_chip_info = { .channels = ad7380_channels, .num_channels = ARRAY_SIZE(ad7380_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, .timing_specs = &ad7380_timing, }; @@ -347,6 +357,8 @@ static const struct ad7380_chip_info ad7381_chip_info = { .channels = ad7381_channels, .num_channels = ARRAY_SIZE(ad7381_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, .timing_specs = &ad7380_timing, }; @@ -356,6 +368,8 @@ static const struct ad7380_chip_info ad7383_chip_info = { .channels = ad7383_channels, .num_channels = ARRAY_SIZE(ad7383_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_2_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, @@ -367,6 +381,8 @@ static const struct ad7380_chip_info ad7384_chip_info = { .channels = ad7384_channels, .num_channels = ARRAY_SIZE(ad7384_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_2_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), .available_scan_masks = ad7380_2_channel_scan_masks, @@ -378,6 +394,8 @@ static const struct ad7380_chip_info ad7386_chip_info = { .channels = ad7386_channels, .num_channels = ARRAY_SIZE(ad7386_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -388,6 +406,8 @@ static const struct ad7380_chip_info ad7387_chip_info = { .channels = ad7387_channels, .num_channels = ARRAY_SIZE(ad7387_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -398,6 +418,8 @@ static const struct ad7380_chip_info ad7388_chip_info = { .channels = ad7388_channels, .num_channels = ARRAY_SIZE(ad7388_channels), .num_simult_channels = 2, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x2_channel_scan_masks, .timing_specs = &ad7380_timing, @@ -408,6 +430,9 @@ static const struct ad7380_chip_info ad7380_4_chip_info = { .channels = ad7380_4_channels, .num_channels = ARRAY_SIZE(ad7380_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), + .external_ref_only = true, .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, }; @@ -417,6 +442,8 @@ static const struct ad7380_chip_info ad7381_4_chip_info = { .channels = ad7381_4_channels, .num_channels = ARRAY_SIZE(ad7381_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, }; @@ -426,6 +453,8 @@ static const struct ad7380_chip_info ad7383_4_chip_info = { .channels = ad7383_4_channels, .num_channels = ARRAY_SIZE(ad7383_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_4_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, @@ -437,6 +466,8 @@ static const struct ad7380_chip_info ad7384_4_chip_info = { .channels = ad7384_4_channels, .num_channels = ARRAY_SIZE(ad7384_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .vcm_supplies = ad7380_4_channel_vcm_supplies, .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), .available_scan_masks = ad7380_4_channel_scan_masks, @@ -448,6 +479,8 @@ static const struct ad7380_chip_info ad7386_4_chip_info = { .channels = ad7386_4_channels, .num_channels = ARRAY_SIZE(ad7386_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -458,6 +491,8 @@ static const struct ad7380_chip_info ad7387_4_chip_info = { .channels = ad7387_4_channels, .num_channels = ARRAY_SIZE(ad7387_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -468,6 +503,8 @@ static const struct ad7380_chip_info ad7388_4_chip_info = { .channels = ad7388_4_channels, .num_channels = ARRAY_SIZE(ad7388_4_channels), .num_simult_channels = 4, + .supplies = ad7380_supplies, + .num_supplies = ARRAY_SIZE(ad7380_supplies), .has_mux = true, .available_scan_masks = ad7380_2x4_channel_scan_masks, .timing_specs = &ad7380_4_timing, @@ -956,7 +993,7 @@ static const struct iio_info ad7380_info = { .debugfs_reg_access = &ad7380_debugfs_reg_access, }; -static int ad7380_init(struct ad7380_state *st, struct regulator *vref) +static int ad7380_init(struct ad7380_state *st, bool external_ref_en) { int ret; @@ -968,13 +1005,13 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) if (ret < 0) return ret; - /* select internal or external reference voltage */ - ret = regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, - AD7380_CONFIG1_REFSEL, - FIELD_PREP(AD7380_CONFIG1_REFSEL, - vref ? 1 : 0)); - if (ret < 0) - return ret; + if (external_ref_en) { + /* select external reference voltage */ + ret = regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, + AD7380_CONFIG1_REFSEL); + if (ret < 0) + return ret; + } /* This is the default value after reset. */ st->oversampling_ratio = 1; @@ -987,16 +1024,11 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) FIELD_PREP(AD7380_CONFIG2_SDO, 1)); } -static void ad7380_regulator_disable(void *p) -{ - regulator_disable(p); -} - static int ad7380_probe(struct spi_device *spi) { struct iio_dev *indio_dev; struct ad7380_state *st; - struct regulator *vref; + bool external_ref_en; int ret, i; indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); @@ -1009,36 +1041,38 @@ static int ad7380_probe(struct spi_device *spi) if (!st->chip_info) return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); - vref = devm_regulator_get_optional(&spi->dev, "refio"); - if (IS_ERR(vref)) { - if (PTR_ERR(vref) != -ENODEV) - return dev_err_probe(&spi->dev, PTR_ERR(vref), - "Failed to get refio regulator\n"); - - vref = NULL; - } + ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies, + st->chip_info->supplies); - /* - * If there is no REFIO supply, then it means that we are using - * the internal 2.5V reference, otherwise REFIO is reference voltage. - */ - if (vref) { - ret = regulator_enable(vref); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, - ad7380_regulator_disable, vref); - if (ret) - return ret; + if (ret) + return dev_err_probe(&spi->dev, ret, + "Failed to enable power supplies\n"); + fsleep(T_POWERUP_US); - ret = regulator_get_voltage(vref); + if (st->chip_info->external_ref_only) { + ret = devm_regulator_get_enable_read_voltage(&spi->dev, + "refin"); if (ret < 0) - return ret; + return dev_err_probe(&spi->dev, ret, + "Failed to get refin regulator\n"); st->vref_mv = ret / 1000; + + /* these chips don't have a register bit for this */ + external_ref_en = false; } else { - st->vref_mv = AD7380_INTERNAL_REF_MV; + /* + * If there is no REFIO supply, then it means that we are using + * the internal reference, otherwise REFIO is reference voltage. + */ + ret = devm_regulator_get_enable_read_voltage(&spi->dev, + "refio"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(&spi->dev, ret, + "Failed to get refio regulator\n"); + + external_ref_en = ret != -ENODEV; + st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV; } if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) @@ -1050,27 +1084,13 @@ static int ad7380_probe(struct spi_device *spi) * input pin. */ for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { - struct regulator *vcm; - - vcm = devm_regulator_get(&spi->dev, - st->chip_info->vcm_supplies[i]); - if (IS_ERR(vcm)) - return dev_err_probe(&spi->dev, PTR_ERR(vcm), - "Failed to get %s regulator\n", - st->chip_info->vcm_supplies[i]); + const char *vcm = st->chip_info->vcm_supplies[i]; - ret = regulator_enable(vcm); - if (ret) - return ret; - - ret = devm_add_action_or_reset(&spi->dev, - ad7380_regulator_disable, vcm); - if (ret) - return ret; - - ret = regulator_get_voltage(vcm); + ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm); if (ret < 0) - return ret; + return dev_err_probe(&spi->dev, ret, + "Failed to get %s regulator\n", + vcm); st->vcm_mv[i] = ret / 1000; } @@ -1135,7 +1155,7 @@ static int ad7380_probe(struct spi_device *spi) if (ret) return ret; - ret = ad7380_init(st, vref); + ret = ad7380_init(st, external_ref_en); if (ret) return ret; |