in adc/rcar-gyroadc.c [314:442]
static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev)
{
const struct of_device_id *of_id;
const struct iio_chan_spec *channels;
struct rcar_gyroadc *priv = iio_priv(indio_dev);
struct device *dev = priv->dev;
struct device_node *np = dev->of_node;
struct device_node *child;
struct regulator *vref;
unsigned int reg;
unsigned int adcmode = -1, childmode;
unsigned int sample_width;
unsigned int num_channels;
int ret, first = 1;
for_each_child_of_node(np, child) {
of_id = of_match_node(rcar_gyroadc_child_match, child);
if (!of_id) {
dev_err(dev, "Ignoring unsupported ADC \"%pOFn\".",
child);
continue;
}
childmode = (uintptr_t)of_id->data;
switch (childmode) {
case RCAR_GYROADC_MODE_SELECT_1_MB88101A:
sample_width = 12;
channels = rcar_gyroadc_iio_channels_1;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_1);
break;
case RCAR_GYROADC_MODE_SELECT_2_ADCS7476:
sample_width = 15;
channels = rcar_gyroadc_iio_channels_2;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_2);
break;
case RCAR_GYROADC_MODE_SELECT_3_MAX1162:
sample_width = 16;
channels = rcar_gyroadc_iio_channels_3;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3);
break;
default:
goto err_e_inval;
}
/*
* MB88101 is special in that it's only a single chip taking
* up all the CHS lines. Thus, the DT binding is also special
* and has no reg property. If we run into such ADC, handle
* it here.
*/
if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) {
reg = 0;
} else {
ret = of_property_read_u32(child, "reg", ®);
if (ret) {
dev_err(dev,
"Failed to get child reg property of ADC \"%pOFn\".\n",
child);
goto err_of_node_put;
}
/* Channel number is too high. */
if (reg >= num_channels) {
dev_err(dev,
"Only %i channels supported with %pOFn, but reg = <%i>.\n",
num_channels, child, reg);
goto err_e_inval;
}
}
/* Child node selected different mode than the rest. */
if (!first && (adcmode != childmode)) {
dev_err(dev,
"Channel %i uses different ADC mode than the rest.\n",
reg);
goto err_e_inval;
}
/* Channel is valid, grab the regulator. */
dev->of_node = child;
vref = devm_regulator_get(dev, "vref");
dev->of_node = np;
if (IS_ERR(vref)) {
dev_dbg(dev, "Channel %i 'vref' supply not connected.\n",
reg);
ret = PTR_ERR(vref);
goto err_of_node_put;
}
priv->vref[reg] = vref;
if (!first)
continue;
/* First child node which passed sanity tests. */
adcmode = childmode;
first = 0;
priv->num_channels = num_channels;
priv->mode = childmode;
priv->sample_width = sample_width;
indio_dev->channels = channels;
indio_dev->num_channels = num_channels;
/*
* MB88101 is special and we only have one such device
* attached to the GyroADC at a time, so if we found it,
* we can stop parsing here.
*/
if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) {
of_node_put(child);
break;
}
}
if (first) {
dev_err(dev, "No valid ADC channels found, aborting.\n");
return -EINVAL;
}
return 0;
err_e_inval:
ret = -EINVAL;
err_of_node_put:
of_node_put(child);
return ret;
}