mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
iio: dac: ad3552r-hs: add support for internal ramp
The ad3552r can be feeded from the HDL controller by an internally generated 16bit ramp, useful for debug pourposes. Add debugfs a file to enable or disable it. Signed-off-by: Angelo Dureghello <adureghello@baylibre.com> Link: https://patch.msgid.link/20250409-wip-bl-ad3552r-fixes-v5-5-fb429c3a6515@baylibre.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
committed by
Jonathan Cameron
parent
ca74d0eb06
commit
b1c5d68ea6
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/iio/backend.h>
|
||||
@@ -54,6 +55,18 @@ struct ad3552r_hs_state {
|
||||
struct ad3552r_hs_platform_data *data;
|
||||
/* INTERFACE_CONFIG_D register cache, in DDR we cannot read values. */
|
||||
u32 config_d;
|
||||
/* Protects backend I/O operations from concurrent accesses. */
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
enum ad3552r_sources {
|
||||
AD3552R_SRC_NORMAL,
|
||||
AD3552R_SRC_RAMP_16BIT,
|
||||
};
|
||||
|
||||
static const char * const dbgfs_attr_source[] = {
|
||||
[AD3552R_SRC_NORMAL] = "normal",
|
||||
[AD3552R_SRC_RAMP_16BIT] = "ramp-16bit",
|
||||
};
|
||||
|
||||
static int ad3552r_hs_reg_read(struct ad3552r_hs_state *st, u32 reg, u32 *val,
|
||||
@@ -65,6 +78,20 @@ static int ad3552r_hs_reg_read(struct ad3552r_hs_state *st, u32 reg, u32 *val,
|
||||
return st->data->bus_reg_read(st->back, reg, val, xfer_size);
|
||||
}
|
||||
|
||||
static int ad3552r_hs_set_data_source(struct ad3552r_hs_state *st,
|
||||
enum iio_backend_data_source type)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < st->model_data->num_hw_channels; ++i) {
|
||||
ret = iio_backend_data_source_set(st->back, i, type);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ad3552r_hs_update_reg_bits(struct ad3552r_hs_state *st, u32 reg,
|
||||
u32 mask, u32 val, size_t xfer_size)
|
||||
{
|
||||
@@ -483,6 +510,103 @@ static int ad3552r_hs_reg_access(struct iio_dev *indio_dev, unsigned int reg,
|
||||
return st->data->bus_reg_write(st->back, reg, writeval, 1);
|
||||
}
|
||||
|
||||
static ssize_t ad3552r_hs_show_data_source(struct file *f, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ad3552r_hs_state *st = file_inode(f)->i_private;
|
||||
enum iio_backend_data_source type;
|
||||
int idx, ret;
|
||||
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
ret = iio_backend_data_source_get(st->back, 0, &type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (type) {
|
||||
case IIO_BACKEND_INTERNAL_RAMP_16BIT:
|
||||
idx = AD3552R_SRC_RAMP_16BIT;
|
||||
break;
|
||||
case IIO_BACKEND_EXTERNAL:
|
||||
idx = AD3552R_SRC_NORMAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos,
|
||||
dbgfs_attr_source[idx],
|
||||
strlen(dbgfs_attr_source[idx]));
|
||||
}
|
||||
|
||||
static ssize_t ad3552r_hs_write_data_source(struct file *f,
|
||||
const char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ad3552r_hs_state *st = file_inode(f)->i_private;
|
||||
char buf[64];
|
||||
int ret, source;
|
||||
|
||||
guard(mutex)(&st->lock);
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
|
||||
count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[count] = '\0';
|
||||
|
||||
ret = match_string(dbgfs_attr_source, ARRAY_SIZE(dbgfs_attr_source),
|
||||
buf);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (ret) {
|
||||
case AD3552R_SRC_RAMP_16BIT:
|
||||
source = IIO_BACKEND_INTERNAL_RAMP_16BIT;
|
||||
break;
|
||||
case AD3552R_SRC_NORMAL:
|
||||
source = IIO_BACKEND_EXTERNAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ad3552r_hs_set_data_source(st, source);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ad3552r_hs_show_data_source_avail(struct file *f,
|
||||
char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
ssize_t len = 0;
|
||||
char buf[128];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dbgfs_attr_source); i++) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%s ",
|
||||
dbgfs_attr_source[i]);
|
||||
}
|
||||
buf[len - 1] = '\n';
|
||||
|
||||
return simple_read_from_buffer(userbuf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static const struct file_operations ad3552r_hs_data_source_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = ad3552r_hs_write_data_source,
|
||||
.read = ad3552r_hs_show_data_source,
|
||||
};
|
||||
|
||||
static const struct file_operations ad3552r_hs_data_source_avail_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = ad3552r_hs_show_data_source_avail,
|
||||
};
|
||||
|
||||
static int ad3552r_hs_setup(struct ad3552r_hs_state *st)
|
||||
{
|
||||
u16 id;
|
||||
@@ -550,11 +674,7 @@ static int ad3552r_hs_setup(struct ad3552r_hs_state *st)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iio_backend_data_source_set(st->back, 1, IIO_BACKEND_EXTERNAL);
|
||||
ret = ad3552r_hs_set_data_source(st, IIO_BACKEND_EXTERNAL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -661,6 +781,26 @@ static const struct iio_info ad3552r_hs_info = {
|
||||
.debugfs_reg_access = &ad3552r_hs_reg_access,
|
||||
};
|
||||
|
||||
static void ad3552r_hs_debugfs_init(struct iio_dev *indio_dev)
|
||||
{
|
||||
struct ad3552r_hs_state *st = iio_priv(indio_dev);
|
||||
struct dentry *d = iio_get_debugfs_dentry(indio_dev);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DEBUG_FS))
|
||||
return;
|
||||
|
||||
d = iio_get_debugfs_dentry(indio_dev);
|
||||
if (!d) {
|
||||
dev_warn(st->dev, "can't set debugfs in driver dir\n");
|
||||
return;
|
||||
}
|
||||
|
||||
debugfs_create_file("data_source", 0600, d, st,
|
||||
&ad3552r_hs_data_source_fops);
|
||||
debugfs_create_file("data_source_available", 0600, d, st,
|
||||
&ad3552r_hs_data_source_avail_fops);
|
||||
}
|
||||
|
||||
static int ad3552r_hs_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ad3552r_hs_state *st;
|
||||
@@ -705,7 +845,17 @@ static int ad3552r_hs_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
ret = devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_mutex_init(&pdev->dev, &st->lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ad3552r_hs_debugfs_init(indio_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ad3552r_hs_of_id[] = {
|
||||
|
||||
Reference in New Issue
Block a user