Skip to content

Commit f7e1588

Browse files
dlechjic23
authored andcommitted
iio: resolver: ad2s1210: add support for adi,fixed-mode
It is possible to use the AD2S1210 with hardwired mode pins (A0 and A1). According to the devicetree bindings, in this case the adi,fixed-mode property will specify which of the 3 possible modes the mode pins are hardwired for and the gpio-modes property is not allowed. This adds support for the case where the mode pins are hardwired for config mode. In this configuration, the position and value must be read from the config register. The case of hardwired position or velocity mode is not supported as there would be no way to configure the device. Signed-off-by: David Lechner <dlechner@baylibre.com> Reviewed-by: Nuno Sa <nuno.sa@analog.com> Link: https://lore.kernel.org/r/20231016135423.16808-1-dlechner@baylibre.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent b512c76 commit f7e1588

1 file changed

Lines changed: 119 additions & 31 deletions

File tree

drivers/iio/resolver/ad2s1210.c

Lines changed: 119 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,16 @@ struct ad2s1210_state {
141141
struct spi_device *sdev;
142142
/** GPIO pin connected to SAMPLE line. */
143143
struct gpio_desc *sample_gpio;
144-
/** GPIO pins connected to A0 and A1 lines. */
144+
/** GPIO pins connected to A0 and A1 lines (optional). */
145145
struct gpio_descs *mode_gpios;
146146
/** Used to access config registers. */
147147
struct regmap *regmap;
148148
/** The external oscillator frequency in Hz. */
149149
unsigned long clkin_hz;
150150
/** Available raw hysteresis values based on resolution. */
151151
int hysteresis_available[2];
152+
/* adi,fixed-mode property - only valid when mode_gpios == NULL. */
153+
enum ad2s1210_mode fixed_mode;
152154
/** The selected resolution */
153155
enum ad2s1210_resolution resolution;
154156
/** Copy of fault register from the previous read. */
@@ -175,6 +177,9 @@ static int ad2s1210_set_mode(struct ad2s1210_state *st, enum ad2s1210_mode mode)
175177
struct gpio_descs *gpios = st->mode_gpios;
176178
DECLARE_BITMAP(bitmap, 2);
177179

180+
if (!gpios)
181+
return mode == st->fixed_mode ? 0 : -EOPNOTSUPP;
182+
178183
bitmap[0] = mode;
179184

180185
return gpiod_set_array_value(gpios->ndescs, gpios->desc, gpios->info,
@@ -276,7 +281,8 @@ static int ad2s1210_regmap_reg_read(void *context, unsigned int reg,
276281
* parity error. The fault register is read-only and the D7 bit means
277282
* something else there.
278283
*/
279-
if (reg != AD2S1210_REG_FAULT && st->rx[1] & AD2S1210_ADDRESS_DATA)
284+
if ((reg > AD2S1210_REG_VELOCITY_LSB && reg != AD2S1210_REG_FAULT)
285+
&& st->rx[1] & AD2S1210_ADDRESS_DATA)
280286
return -EBADMSG;
281287

282288
*val = st->rx[1];
@@ -450,21 +456,53 @@ static int ad2s1210_single_conversion(struct iio_dev *indio_dev,
450456
ad2s1210_toggle_sample_line(st);
451457
timestamp = iio_get_time_ns(indio_dev);
452458

453-
switch (chan->type) {
454-
case IIO_ANGL:
455-
ret = ad2s1210_set_mode(st, MOD_POS);
456-
break;
457-
case IIO_ANGL_VEL:
458-
ret = ad2s1210_set_mode(st, MOD_VEL);
459-
break;
460-
default:
461-
return -EINVAL;
459+
if (st->fixed_mode == MOD_CONFIG) {
460+
unsigned int reg_val;
461+
462+
switch (chan->type) {
463+
case IIO_ANGL:
464+
ret = regmap_bulk_read(st->regmap,
465+
AD2S1210_REG_POSITION_MSB,
466+
&st->sample.raw, 2);
467+
if (ret < 0)
468+
return ret;
469+
470+
break;
471+
case IIO_ANGL_VEL:
472+
ret = regmap_bulk_read(st->regmap,
473+
AD2S1210_REG_VELOCITY_MSB,
474+
&st->sample.raw, 2);
475+
if (ret < 0)
476+
return ret;
477+
478+
break;
479+
default:
480+
return -EINVAL;
481+
}
482+
483+
ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
484+
if (ret < 0)
485+
return ret;
486+
487+
st->sample.fault = reg_val;
488+
} else {
489+
switch (chan->type) {
490+
case IIO_ANGL:
491+
ret = ad2s1210_set_mode(st, MOD_POS);
492+
break;
493+
case IIO_ANGL_VEL:
494+
ret = ad2s1210_set_mode(st, MOD_VEL);
495+
break;
496+
default:
497+
return -EINVAL;
498+
}
499+
if (ret < 0)
500+
return ret;
501+
502+
ret = spi_read(st->sdev, &st->sample, 3);
503+
if (ret < 0)
504+
return ret;
462505
}
463-
if (ret < 0)
464-
return ret;
465-
ret = spi_read(st->sdev, &st->sample, 3);
466-
if (ret < 0)
467-
return ret;
468506

469507
switch (chan->type) {
470508
case IIO_ANGL:
@@ -1252,27 +1290,53 @@ static irqreturn_t ad2s1210_trigger_handler(int irq, void *p)
12521290
ad2s1210_toggle_sample_line(st);
12531291

12541292
if (test_bit(0, indio_dev->active_scan_mask)) {
1255-
ret = ad2s1210_set_mode(st, MOD_POS);
1256-
if (ret < 0)
1257-
goto error_ret;
1258-
1259-
ret = spi_read(st->sdev, &st->sample, 3);
1260-
if (ret < 0)
1261-
goto error_ret;
1293+
if (st->fixed_mode == MOD_CONFIG) {
1294+
ret = regmap_bulk_read(st->regmap,
1295+
AD2S1210_REG_POSITION_MSB,
1296+
&st->sample.raw, 2);
1297+
if (ret < 0)
1298+
goto error_ret;
1299+
} else {
1300+
ret = ad2s1210_set_mode(st, MOD_POS);
1301+
if (ret < 0)
1302+
goto error_ret;
1303+
1304+
ret = spi_read(st->sdev, &st->sample, 3);
1305+
if (ret < 0)
1306+
goto error_ret;
1307+
}
12621308

12631309
memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
12641310
}
12651311

12661312
if (test_bit(1, indio_dev->active_scan_mask)) {
1267-
ret = ad2s1210_set_mode(st, MOD_VEL);
1268-
if (ret < 0)
1269-
goto error_ret;
1313+
if (st->fixed_mode == MOD_CONFIG) {
1314+
ret = regmap_bulk_read(st->regmap,
1315+
AD2S1210_REG_VELOCITY_MSB,
1316+
&st->sample.raw, 2);
1317+
if (ret < 0)
1318+
goto error_ret;
1319+
} else {
1320+
ret = ad2s1210_set_mode(st, MOD_VEL);
1321+
if (ret < 0)
1322+
goto error_ret;
1323+
1324+
ret = spi_read(st->sdev, &st->sample, 3);
1325+
if (ret < 0)
1326+
goto error_ret;
1327+
}
12701328

1271-
ret = spi_read(st->sdev, &st->sample, 3);
1329+
memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
1330+
}
1331+
1332+
if (st->fixed_mode == MOD_CONFIG) {
1333+
unsigned int reg_val;
1334+
1335+
ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
12721336
if (ret < 0)
1273-
goto error_ret;
1337+
return ret;
12741338

1275-
memcpy(&st->scan.chan[chan++], &st->sample.raw, 2);
1339+
st->sample.fault = reg_val;
12761340
}
12771341

12781342
ad2s1210_push_events(indio_dev, st->sample.fault, pf->timestamp);
@@ -1299,9 +1363,24 @@ static const struct iio_info ad2s1210_info = {
12991363
static int ad2s1210_setup_properties(struct ad2s1210_state *st)
13001364
{
13011365
struct device *dev = &st->sdev->dev;
1366+
const char *str_val;
13021367
u32 val;
13031368
int ret;
13041369

1370+
ret = device_property_read_string(dev, "adi,fixed-mode", &str_val);
1371+
if (ret == -EINVAL)
1372+
st->fixed_mode = -1;
1373+
else if (ret < 0)
1374+
return dev_err_probe(dev, ret,
1375+
"failed to read adi,fixed-mode property\n");
1376+
else {
1377+
if (strcmp(str_val, "config"))
1378+
return dev_err_probe(dev, -EINVAL,
1379+
"only adi,fixed-mode=\"config\" is supported\n");
1380+
1381+
st->fixed_mode = MOD_CONFIG;
1382+
}
1383+
13051384
ret = device_property_read_u32(dev, "assigned-resolution-bits", &val);
13061385
if (ret < 0)
13071386
return dev_err_probe(dev, ret,
@@ -1357,12 +1436,21 @@ static int ad2s1210_setup_gpios(struct ad2s1210_state *st)
13571436
"failed to request sample GPIO\n");
13581437

13591438
/* both pins high means that we start in config mode */
1360-
st->mode_gpios = devm_gpiod_get_array(dev, "mode", GPIOD_OUT_HIGH);
1439+
st->mode_gpios = devm_gpiod_get_array_optional(dev, "mode",
1440+
GPIOD_OUT_HIGH);
13611441
if (IS_ERR(st->mode_gpios))
13621442
return dev_err_probe(dev, PTR_ERR(st->mode_gpios),
13631443
"failed to request mode GPIOs\n");
13641444

1365-
if (st->mode_gpios->ndescs != 2)
1445+
if (!st->mode_gpios && st->fixed_mode == -1)
1446+
return dev_err_probe(dev, -EINVAL,
1447+
"must specify either adi,fixed-mode or mode-gpios\n");
1448+
1449+
if (st->mode_gpios && st->fixed_mode != -1)
1450+
return dev_err_probe(dev, -EINVAL,
1451+
"must specify only one of adi,fixed-mode or mode-gpios\n");
1452+
1453+
if (st->mode_gpios && st->mode_gpios->ndescs != 2)
13661454
return dev_err_probe(dev, -EINVAL,
13671455
"requires exactly 2 mode-gpios\n");
13681456

0 commit comments

Comments
 (0)