iio: refactor info mask and ext_info attribute creation.
Introduce an enum to specify whether the attribute is separate or shared. Factor out the bitmap handling for loop into a separate function. Tidy up error handling and add a NULL assignment to squish a false positive warning from GCC. Change ext_info shared type from boolean to enum and update in all drivers. Signed-off-by: Jonathan Cameron <jic23@kernel.org> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Родитель
9761696f2b
Коммит
3704432fb1
|
@ -285,8 +285,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5064_read_dac_powerdown,
|
||||
.write = ad5064_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -247,8 +247,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5380_read_dac_powerdown,
|
||||
.write = ad5380_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||
&ad5380_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5446_read_dac_powerdown,
|
||||
.write = ad5446_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -248,8 +248,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5504_read_dac_powerdown,
|
||||
.write = ad5504_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||
&ad5504_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -163,8 +163,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5624r_read_dac_powerdown,
|
||||
.write = ad5624r_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||
&ad5624r_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -264,8 +264,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5686_read_dac_powerdown,
|
||||
.write = ad5686_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -386,6 +386,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad5755_read_powerdown,
|
||||
.write = ad5755_write_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
|
|||
static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
|
||||
{
|
||||
.name = "powerdown",
|
||||
.shared = true,
|
||||
.shared = IIO_SHARED_BY_TYPE,
|
||||
.read = ad5791_read_dac_powerdown,
|
||||
.write = ad5791_write_dac_powerdown,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||
&ad5791_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = ad7303_read_dac_powerdown,
|
||||
.write = ad7303_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
|
|||
.name = "powerdown",
|
||||
.read = mcp4725_read_powerdown,
|
||||
.write = mcp4725_write_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
|
||||
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
|
||||
IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
|
|||
.read = adf4350_read, \
|
||||
.write = adf4350_write, \
|
||||
.private = _ident, \
|
||||
.shared = IIO_SEPARATE, \
|
||||
}
|
||||
|
||||
static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
|
||||
|
|
|
@ -30,7 +30,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
|||
const char *buf,
|
||||
size_t len),
|
||||
u64 mask,
|
||||
bool generic,
|
||||
enum iio_shared_by shared_by,
|
||||
struct device *dev,
|
||||
struct list_head *attr_list);
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
|
|||
&iio_show_scan_index,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
IIO_SEPARATE,
|
||||
&indio_dev->dev,
|
||||
&buffer->scan_el_dev_attr_list);
|
||||
if (ret)
|
||||
|
|
|
@ -517,14 +517,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
|||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t len),
|
||||
bool generic)
|
||||
enum iio_shared_by shared_by)
|
||||
{
|
||||
int ret;
|
||||
char *name_format, *full_postfix;
|
||||
int ret = 0;
|
||||
char *name_format = NULL;
|
||||
char *full_postfix;
|
||||
sysfs_attr_init(&dev_attr->attr);
|
||||
|
||||
/* Build up postfix of <extend_name>_<modifier>_postfix */
|
||||
if (chan->modified && !generic) {
|
||||
if (chan->modified && (shared_by == IIO_SEPARATE)) {
|
||||
if (chan->extend_name)
|
||||
full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
|
||||
iio_modifier_names[chan
|
||||
|
@ -545,41 +546,48 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
|||
chan->extend_name,
|
||||
postfix);
|
||||
}
|
||||
if (full_postfix == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto error_ret;
|
||||
}
|
||||
if (full_postfix == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (chan->differential) { /* Differential can not have modifier */
|
||||
if (generic)
|
||||
switch (shared_by) {
|
||||
case IIO_SHARED_BY_TYPE:
|
||||
name_format
|
||||
= kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
|
||||
iio_direction[chan->output],
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
full_postfix);
|
||||
else if (chan->indexed)
|
||||
break;
|
||||
case IIO_SEPARATE:
|
||||
if (!chan->indexed) {
|
||||
WARN_ON("Differential channels must be indexed\n");
|
||||
ret = -EINVAL;
|
||||
goto error_free_full_postfix;
|
||||
}
|
||||
name_format
|
||||
= kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
|
||||
= kasprintf(GFP_KERNEL,
|
||||
"%s_%s%d-%s%d_%s",
|
||||
iio_direction[chan->output],
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
chan->channel,
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
chan->channel2,
|
||||
full_postfix);
|
||||
else {
|
||||
WARN_ON("Differential channels must be indexed\n");
|
||||
ret = -EINVAL;
|
||||
goto error_free_full_postfix;
|
||||
break;
|
||||
}
|
||||
} else { /* Single ended */
|
||||
if (generic)
|
||||
switch (shared_by) {
|
||||
case IIO_SHARED_BY_TYPE:
|
||||
name_format
|
||||
= kasprintf(GFP_KERNEL, "%s_%s_%s",
|
||||
iio_direction[chan->output],
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
full_postfix);
|
||||
else if (chan->indexed)
|
||||
break;
|
||||
|
||||
case IIO_SEPARATE:
|
||||
if (chan->indexed)
|
||||
name_format
|
||||
= kasprintf(GFP_KERNEL, "%s_%s%d_%s",
|
||||
iio_direction[chan->output],
|
||||
|
@ -592,6 +600,8 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
|||
iio_direction[chan->output],
|
||||
iio_chan_type_name_spec[chan->type],
|
||||
full_postfix);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (name_format == NULL) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -615,16 +625,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
|||
dev_attr->attr.mode |= S_IWUSR;
|
||||
dev_attr->store = writefunc;
|
||||
}
|
||||
kfree(name_format);
|
||||
kfree(full_postfix);
|
||||
|
||||
return 0;
|
||||
|
||||
error_free_name_format:
|
||||
kfree(name_format);
|
||||
error_free_full_postfix:
|
||||
kfree(full_postfix);
|
||||
error_ret:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -643,7 +648,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
|||
const char *buf,
|
||||
size_t len),
|
||||
u64 mask,
|
||||
bool generic,
|
||||
enum iio_shared_by shared_by,
|
||||
struct device *dev,
|
||||
struct list_head *attr_list)
|
||||
{
|
||||
|
@ -657,7 +662,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
|||
}
|
||||
ret = __iio_device_attr_init(&iio_attr->dev_attr,
|
||||
postfix, chan,
|
||||
readfunc, writefunc, generic);
|
||||
readfunc, writefunc, shared_by);
|
||||
if (ret)
|
||||
goto error_iio_dev_attr_free;
|
||||
iio_attr->c = chan;
|
||||
|
@ -665,7 +670,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
|||
list_for_each_entry(t, attr_list, l)
|
||||
if (strcmp(t->dev_attr.attr.name,
|
||||
iio_attr->dev_attr.attr.name) == 0) {
|
||||
if (!generic)
|
||||
if (shared_by == IIO_SEPARATE)
|
||||
dev_err(dev, "tried to double register : %s\n",
|
||||
t->dev_attr.attr.name);
|
||||
ret = -EBUSY;
|
||||
|
@ -683,45 +688,53 @@ error_ret:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
enum iio_shared_by shared_by,
|
||||
const long *infomask)
|
||||
{
|
||||
int i, ret, attrcount = 0;
|
||||
|
||||
for_each_set_bit(i, infomask, sizeof(infomask)*8) {
|
||||
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
||||
chan,
|
||||
&iio_read_channel_info,
|
||||
&iio_write_channel_info,
|
||||
i,
|
||||
shared_by,
|
||||
&indio_dev->dev,
|
||||
&indio_dev->channel_attr_list);
|
||||
if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
|
||||
continue;
|
||||
else if (ret < 0)
|
||||
return ret;
|
||||
attrcount++;
|
||||
}
|
||||
|
||||
return attrcount;
|
||||
}
|
||||
|
||||
static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan)
|
||||
{
|
||||
int ret, attrcount = 0;
|
||||
int i;
|
||||
const struct iio_chan_spec_ext_info *ext_info;
|
||||
|
||||
if (chan->channel < 0)
|
||||
return 0;
|
||||
for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
|
||||
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
||||
chan,
|
||||
&iio_read_channel_info,
|
||||
&iio_write_channel_info,
|
||||
i,
|
||||
0,
|
||||
&indio_dev->dev,
|
||||
&indio_dev->channel_attr_list);
|
||||
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||
IIO_SEPARATE,
|
||||
&chan->info_mask_separate);
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
attrcount++;
|
||||
}
|
||||
for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
|
||||
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
||||
chan,
|
||||
&iio_read_channel_info,
|
||||
&iio_write_channel_info,
|
||||
i,
|
||||
1,
|
||||
&indio_dev->dev,
|
||||
&indio_dev->channel_attr_list);
|
||||
if (ret == -EBUSY) {
|
||||
ret = 0;
|
||||
continue;
|
||||
} else if (ret < 0) {
|
||||
goto error_ret;
|
||||
}
|
||||
attrcount++;
|
||||
}
|
||||
return ret;
|
||||
attrcount += ret;
|
||||
|
||||
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||
IIO_SHARED_BY_TYPE,
|
||||
&chan->info_mask_shared_by_type);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
attrcount += ret;
|
||||
|
||||
if (chan->ext_info) {
|
||||
unsigned int i = 0;
|
||||
|
@ -741,15 +754,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
|||
continue;
|
||||
|
||||
if (ret)
|
||||
goto error_ret;
|
||||
return ret;
|
||||
|
||||
attrcount++;
|
||||
}
|
||||
}
|
||||
|
||||
ret = attrcount;
|
||||
error_ret:
|
||||
return ret;
|
||||
return attrcount;
|
||||
}
|
||||
|
||||
static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
|
||||
|
|
|
@ -39,6 +39,11 @@ enum iio_chan_info_enum {
|
|||
IIO_CHAN_INFO_INT_TIME,
|
||||
};
|
||||
|
||||
enum iio_shared_by {
|
||||
IIO_SEPARATE,
|
||||
IIO_SHARED_BY_TYPE
|
||||
};
|
||||
|
||||
enum iio_endian {
|
||||
IIO_CPU,
|
||||
IIO_BE,
|
||||
|
@ -58,7 +63,7 @@ struct iio_dev;
|
|||
*/
|
||||
struct iio_chan_spec_ext_info {
|
||||
const char *name;
|
||||
bool shared;
|
||||
enum iio_shared_by shared;
|
||||
ssize_t (*read)(struct iio_dev *, uintptr_t private,
|
||||
struct iio_chan_spec const *, char *buf);
|
||||
ssize_t (*write)(struct iio_dev *, uintptr_t private,
|
||||
|
@ -126,7 +131,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev,
|
|||
#define IIO_ENUM_AVAILABLE(_name, _e) \
|
||||
{ \
|
||||
.name = (_name "_available"), \
|
||||
.shared = true, \
|
||||
.shared = IIO_SHARED_BY_TYPE, \
|
||||
.read = iio_enum_available_read, \
|
||||
.private = (uintptr_t)(_e), \
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче