On 05/11/2012 04:53 PM, Lars-Peter Clausen wrote: > Use extended channel attributes instead of raw sysfs files for the additional > channel attributes. This allows us to remove some boilerplate code. > Looks good. > Signed-off-by: Lars-Peter Clausen <lars@xxxxxxxxxx> Acked-by: Jonathan Cameron <jic23@xxxxxxxxxx> > --- > drivers/staging/iio/dac/ad5380.c | 250 ++++++++++++++++++-------------------- > 1 file changed, 116 insertions(+), 134 deletions(-) > > diff --git a/drivers/staging/iio/dac/ad5380.c b/drivers/staging/iio/dac/ad5380.c > index 1baaabe..5dfb445 100644 > --- a/drivers/staging/iio/dac/ad5380.c > +++ b/drivers/staging/iio/dac/ad5380.c > @@ -79,103 +79,18 @@ enum ad5380_type { > ID_AD5392_5, > }; > > -#define AD5380_CHANNEL(_bits) { \ > - .type = IIO_VOLTAGE, \ > - .indexed = 1, \ > - .output = 1, \ > - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ > - IIO_CHAN_INFO_SCALE_SHARED_BIT | \ > - IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ > - IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ > - .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)) \ > -} > - > -static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { > - [ID_AD5380_3] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 40, > - .int_vref = 1250000, > - }, > - [ID_AD5380_5] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 40, > - .int_vref = 2500000, > - }, > - [ID_AD5381_3] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 16, > - .int_vref = 1250000, > - }, > - [ID_AD5381_5] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 16, > - .int_vref = 2500000, > - }, > - [ID_AD5382_3] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 32, > - .int_vref = 1250000, > - }, > - [ID_AD5382_5] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 32, > - .int_vref = 2500000, > - }, > - [ID_AD5383_3] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 32, > - .int_vref = 1250000, > - }, > - [ID_AD5383_5] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 32, > - .int_vref = 2500000, > - }, > - [ID_AD5390_3] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 16, > - .int_vref = 1250000, > - }, > - [ID_AD5390_5] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 16, > - .int_vref = 2500000, > - }, > - [ID_AD5391_3] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 16, > - .int_vref = 1250000, > - }, > - [ID_AD5391_5] = { > - .channel_template = AD5380_CHANNEL(12), > - .num_channels = 16, > - .int_vref = 2500000, > - }, > - [ID_AD5392_3] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 8, > - .int_vref = 1250000, > - }, > - [ID_AD5392_5] = { > - .channel_template = AD5380_CHANNEL(14), > - .num_channels = 8, > - .int_vref = 2500000, > - }, > -}; > - > -static ssize_t ad5380_read_dac_powerdown(struct device *dev, > - struct device_attribute *attr, char *buf) > +static ssize_t ad5380_read_dac_powerdown(struct iio_dev *indio_dev, > + uintptr_t private, const struct iio_chan_spec *chan, char *buf) > { > - struct iio_dev *indio_dev = dev_get_drvdata(dev); > struct ad5380_state *st = iio_priv(indio_dev); > > return sprintf(buf, "%d\n", st->pwr_down); > } > > -static ssize_t ad5380_write_dac_powerdown(struct device *dev, > - struct device_attribute *attr, const char *buf, size_t len) > +static ssize_t ad5380_write_dac_powerdown(struct iio_dev *indio_dev, > + uintptr_t private, const struct iio_chan_spec *chan, const char *buf, > + size_t len) > { > - struct iio_dev *indio_dev = dev_get_drvdata(dev); > struct ad5380_state *st = iio_priv(indio_dev); > bool pwr_down; > int ret; > @@ -198,20 +113,14 @@ static ssize_t ad5380_write_dac_powerdown(struct device *dev, > return ret ? ret : len; > } > > -static IIO_DEVICE_ATTR(out_voltage_powerdown, > - S_IRUGO | S_IWUSR, > - ad5380_read_dac_powerdown, > - ad5380_write_dac_powerdown, 0); > - > -static const char ad5380_powerdown_modes[][15] = { > - [0] = "100kohm_to_gnd", > - [1] = "three_state", > +static const char * const ad5380_powerdown_modes[] = { > + "100kohm_to_gnd", > + "three_state", > }; > > -static ssize_t ad5380_read_powerdown_mode(struct device *dev, > - struct device_attribute *attr, char *buf) > +static int ad5380_get_powerdown_mode(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan) > { > - struct iio_dev *indio_dev = dev_get_drvdata(dev); > struct ad5380_state *st = iio_priv(indio_dev); > unsigned int mode; > int ret; > @@ -222,49 +131,27 @@ static ssize_t ad5380_read_powerdown_mode(struct device *dev, > > mode = (mode >> AD5380_CTRL_PWR_DOWN_MODE_OFFSET) & 1; > > - return sprintf(buf, "%s\n", ad5380_powerdown_modes[mode]); > + return mode; > } > > -static ssize_t ad5380_write_powerdown_mode(struct device *dev, > - struct device_attribute *attr, const char *buf, size_t len) > +static int ad5380_set_powerdown_mode(struct iio_dev *indio_dev, > + const struct iio_chan_spec *chan, unsigned int mode) > { > - struct iio_dev *indio_dev = dev_get_drvdata(dev); > struct ad5380_state *st = iio_priv(indio_dev); > - unsigned int i; > int ret; > > - for (i = 0; i < ARRAY_SIZE(ad5380_powerdown_modes); ++i) { > - if (sysfs_streq(buf, ad5380_powerdown_modes[i])) > - break; > - } > - > - if (i == ARRAY_SIZE(ad5380_powerdown_modes)) > - return -EINVAL; > - > ret = regmap_update_bits(st->regmap, AD5380_REG_SF_CTRL, > 1 << AD5380_CTRL_PWR_DOWN_MODE_OFFSET, > - i << AD5380_CTRL_PWR_DOWN_MODE_OFFSET); > + mode << AD5380_CTRL_PWR_DOWN_MODE_OFFSET); > > - return ret ? ret : len; > + return ret; > } > > -static IIO_DEVICE_ATTR(out_voltage_powerdown_mode, > - S_IRUGO | S_IWUSR, > - ad5380_read_powerdown_mode, > - ad5380_write_powerdown_mode, 0); > - > -static IIO_CONST_ATTR(out_voltage_powerdown_mode_available, > - "100kohm_to_gnd three_state"); > - > -static struct attribute *ad5380_attributes[] = { > - &iio_dev_attr_out_voltage_powerdown.dev_attr.attr, > - &iio_dev_attr_out_voltage_powerdown_mode.dev_attr.attr, > - &iio_const_attr_out_voltage_powerdown_mode_available.dev_attr.attr, > - NULL, > -}; > - > -static const struct attribute_group ad5380_attribute_group = { > - .attrs = ad5380_attributes, > +static const struct iio_enum ad5380_powerdown_mode_enum = { > + .items = ad5380_powerdown_modes, > + .num_items = ARRAY_SIZE(ad5380_powerdown_modes), > + .get = ad5380_get_powerdown_mode, > + .set = ad5380_set_powerdown_mode, > }; > > static unsigned int ad5380_info_to_reg(struct iio_chan_spec const *chan, > @@ -352,10 +239,105 @@ static int ad5380_read_raw(struct iio_dev *indio_dev, > static const struct iio_info ad5380_info = { > .read_raw = ad5380_read_raw, > .write_raw = ad5380_write_raw, > - .attrs = &ad5380_attribute_group, > .driver_module = THIS_MODULE, > }; > > +static struct iio_chan_spec_ext_info ad5380_ext_info[] = { > + { > + .name = "powerdown", > + .read = ad5380_read_dac_powerdown, > + .write = ad5380_write_dac_powerdown, > + }, > + IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum), > + IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum), > + { }, > +}; > + > +#define AD5380_CHANNEL(_bits) { \ > + .type = IIO_VOLTAGE, \ > + .indexed = 1, \ > + .output = 1, \ > + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ > + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ > + IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ > + IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ > + .scan_type = IIO_ST('u', (_bits), 16, 14 - (_bits)), \ > + .ext_info = ad5380_ext_info, \ > +} > + > +static const struct ad5380_chip_info ad5380_chip_info_tbl[] = { > + [ID_AD5380_3] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 40, > + .int_vref = 1250000, > + }, > + [ID_AD5380_5] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 40, > + .int_vref = 2500000, > + }, > + [ID_AD5381_3] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 16, > + .int_vref = 1250000, > + }, > + [ID_AD5381_5] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 16, > + .int_vref = 2500000, > + }, > + [ID_AD5382_3] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 32, > + .int_vref = 1250000, > + }, > + [ID_AD5382_5] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 32, > + .int_vref = 2500000, > + }, > + [ID_AD5383_3] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 32, > + .int_vref = 1250000, > + }, > + [ID_AD5383_5] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 32, > + .int_vref = 2500000, > + }, > + [ID_AD5390_3] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 16, > + .int_vref = 1250000, > + }, > + [ID_AD5390_5] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 16, > + .int_vref = 2500000, > + }, > + [ID_AD5391_3] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 16, > + .int_vref = 1250000, > + }, > + [ID_AD5391_5] = { > + .channel_template = AD5380_CHANNEL(12), > + .num_channels = 16, > + .int_vref = 2500000, > + }, > + [ID_AD5392_3] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 8, > + .int_vref = 1250000, > + }, > + [ID_AD5392_5] = { > + .channel_template = AD5380_CHANNEL(14), > + .num_channels = 8, > + .int_vref = 2500000, > + }, > +}; > + > static int __devinit ad5380_alloc_channels(struct iio_dev *indio_dev) > { > struct ad5380_state *st = iio_priv(indio_dev); -- To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html