Skip to content

Commit

Permalink
iio: adc: cf_axi_adc_core: Add SYNC start support via device attrib
Browse files Browse the repository at this point in the history
This adds support for DMA sync start via a new device attribute
called sync_start_enable.

Signed-off-by: Michael Hennerich <[email protected]>
  • Loading branch information
mhennerich committed Oct 19, 2021
1 parent f82e3b4 commit 4055bce
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 3 deletions.
1 change: 1 addition & 0 deletions drivers/iio/adc/cf_axi_adc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#define ADI_MMCM_RSTN (1 << 1)

#define ADI_REG_CNTRL 0x0044
#define ADI_SYNC (1 << 3)
#define ADI_R1_MODE (1 << 2)
#define ADI_DDR_EDGESEL (1 << 1)
#define ADI_PIN_MODE (1 << 0)
Expand Down
99 changes: 96 additions & 3 deletions drivers/iio/adc/cf_axi_adc_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,42 @@ static ssize_t axiadc_sampling_frequency_available(struct device *dev,
return ret;
}

static ssize_t axiadc_sync_start(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct axiadc_state *st = iio_priv(indio_dev);
bool state;
u32 reg;
int ret;

ret = strtobool(buf, &state);
if (ret < 0)
return ret;

if (state) {
mutex_lock(&indio_dev->mlock);
reg = axiadc_read(st, ADI_REG_CNTRL);
axiadc_write(st, ADI_REG_CNTRL, reg | ADI_SYNC);
mutex_unlock(&indio_dev->mlock);
}

return len;
}

static IIO_DEVICE_ATTR(sync_start_enable, 0200,
NULL,
axiadc_sync_start,
0);

static IIO_DEVICE_ATTR(in_voltage_sampling_frequency_available, S_IRUGO,
axiadc_sampling_frequency_available,
NULL,
0);

static struct attribute *axiadc_attributes[] = {
&iio_dev_attr_sync_start_enable.dev_attr.attr,
&iio_dev_attr_in_voltage_sampling_frequency_available.dev_attr.attr,
NULL,
};
Expand Down Expand Up @@ -902,6 +932,60 @@ static const struct of_device_id axiadc_of_match[] = {
};
MODULE_DEVICE_TABLE(of, axiadc_of_match);

int axiadc_append_attrs(struct iio_dev *indio_dev,
const struct attribute_group *add_group, unsigned int skip_cnt)
{
size_t old_cnt = 0, add_cnt = 0, new_cnt;
struct attribute **attrs;
struct attribute_group *group;
struct iio_info *iio_info = (struct iio_info *) indio_dev->info;

if (!add_group)
return -EINVAL;

if (indio_dev->info->attrs) {
attrs = indio_dev->info->attrs->attrs;
while (*attrs++ != NULL)
old_cnt++;
} else if (!skip_cnt) {
iio_info->attrs = add_group;

return 0;
}

if (add_group->attrs) {
attrs = add_group->attrs;
while (*attrs++ != NULL)
add_cnt++;
}

if (skip_cnt > add_cnt)
return -EINVAL;

add_cnt -= skip_cnt;
new_cnt = old_cnt + add_cnt + 1;
attrs = devm_kcalloc(indio_dev->dev.parent, new_cnt,
sizeof(*attrs), GFP_KERNEL);
if (!attrs)
return -ENOMEM;

group = devm_kzalloc(indio_dev->dev.parent,
sizeof(*group), GFP_KERNEL);
if (!group)
return -ENOMEM;

if (old_cnt)
memcpy(attrs, indio_dev->info->attrs->attrs,
old_cnt * sizeof(*attrs));
memcpy(attrs + old_cnt, add_group->attrs, add_cnt * sizeof(*attrs));
attrs[new_cnt - 1] = NULL;
group->attrs = attrs;

iio_info->attrs = group;

return 0;
}

/**
* axiadc_of_probe - probe method for the AIM device.
* @of_dev: pointer to OF device structure
Expand All @@ -921,6 +1005,7 @@ static int axiadc_probe(struct platform_device *pdev)
struct resource *mem;
struct axiadc_spidev axiadc_spidev;
struct axiadc_converter *conv;
unsigned int skip = 1;
int ret;

dev_dbg(&pdev->dev, "Device Tree Probing \'%s\'\n",
Expand Down Expand Up @@ -1051,15 +1136,23 @@ static int axiadc_probe(struct platform_device *pdev)
goto err_put_converter;
}

if (!st->dp_disable && of_property_read_bool(pdev->dev.of_node, "adi,axi-decimation-core-available")) {
if (!st->dp_disable && of_property_read_bool(pdev->dev.of_node,
"adi,axi-decimation-core-available")) {
st->decimation_factor = 1;
WARN_ON(st->iio_info.attrs != NULL);
st->iio_info.attrs = &axiadc_dec_attribute_group;
st->gpio_decimation = devm_gpiod_get_optional(&pdev->dev,
"decimation",
GPIOD_OUT_LOW);
if (IS_ERR(st->gpio_decimation))
dev_err(&pdev->dev, "decimation gpio error\n");
skip = 0;
}

ret = axiadc_append_attrs(indio_dev,
&axiadc_dec_attribute_group, skip);
if (ret) {
dev_err(&pdev->dev,
"Failed to add sysfs attributes (%d)\n", ret);
goto err_unconfigure_ring;
}

ret = iio_device_register(indio_dev);
Expand Down

0 comments on commit 4055bce

Please sign in to comment.