On Fri, May 03, 2019 at 08:00:25PM -0500, Pierre-Louis Bossart wrote:
Add DisCo Slave properties as device attributes. Add a device for Data Port 0 which adds Dp0 properties as attributes. Add devices for Source and Sink Data Ports, and add Dp-N properties as attributes.
The Slave, DP0 and DPn cases are intentionally handled in separate files to avoid conflicts with attributes having the same names at different levels.
Audio modes are not supported for now. Depending on the discussions the SoundWire Device Class, we may add it later as is or follow the new specification.
Credits: this patch is based on an earlier internal contribution by Vinod Koul, Sanyog Kale, Shreyas Nc and Hardik Shah
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com
drivers/soundwire/Makefile | 2 +- drivers/soundwire/bus.c | 2 + drivers/soundwire/bus.h | 2 + drivers/soundwire/bus_type.c | 5 + drivers/soundwire/slave.c | 1 + drivers/soundwire/sysfs.c | 213 ++++++++++++++++++++++++++++ drivers/soundwire/sysfs_local.h | 42 ++++++ drivers/soundwire/sysfs_slave_dp0.c | 112 +++++++++++++++ drivers/soundwire/sysfs_slave_dpn.c | 168 ++++++++++++++++++++++ include/linux/soundwire/sdw.h | 5 + 10 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 drivers/soundwire/sysfs_local.h create mode 100644 drivers/soundwire/sysfs_slave_dp0.c create mode 100644 drivers/soundwire/sysfs_slave_dpn.c
diff --git a/drivers/soundwire/Makefile b/drivers/soundwire/Makefile index 787f1cbf342c..a72a29731a28 100644 --- a/drivers/soundwire/Makefile +++ b/drivers/soundwire/Makefile @@ -4,7 +4,7 @@
#Bus Objs soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o stream.o \
sysfs.o
sysfs.o sysfs_slave_dp0.o sysfs_slave_dpn.o
obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
#Cadence Objs diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index 38de7071e135..dd9181693554 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -113,6 +113,8 @@ static int sdw_delete_slave(struct device *dev, void *data) struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_bus *bus = slave->bus;
sdw_sysfs_slave_exit(slave);
mutex_lock(&bus->bus_lock);
if (slave->dev_num) /* clear dev_num if assigned */
diff --git a/drivers/soundwire/bus.h b/drivers/soundwire/bus.h index 3048ca153f22..0707e68a8d21 100644 --- a/drivers/soundwire/bus.h +++ b/drivers/soundwire/bus.h @@ -18,6 +18,8 @@ static inline int sdw_acpi_find_slaves(struct sdw_bus *bus) void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id);
+extern const struct attribute_group *sdw_slave_dev_attr_groups[];
enum { SDW_MSG_FLAG_READ = 0, SDW_MSG_FLAG_WRITE, diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 2655602f0cfb..f68fe45c1037 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -97,6 +97,11 @@ static int sdw_drv_probe(struct device *dev) if (slave->ops && slave->ops->read_prop) slave->ops->read_prop(slave);
- /* init the sysfs as we have properties now */
- ret = sdw_sysfs_slave_init(slave);
- if (ret < 0)
dev_warn(dev, "Slave sysfs init failed:%d\n", ret);
- /*
- Check for valid clk_stop_timeout, use DisCo worst case value of
- 300ms
diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index f39a5815e25d..bad73a267fdd 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -34,6 +34,7 @@ static int sdw_slave_add(struct sdw_bus *bus, id->class_id, id->unique_id);
slave->dev.release = sdw_slave_release;
- slave->dev.groups = sdw_slave_dev_attr_groups; slave->dev.bus = &sdw_bus_type; slave->bus = bus; slave->status = SDW_SLAVE_UNATTACHED;
diff --git a/drivers/soundwire/sysfs.c b/drivers/soundwire/sysfs.c index 7b6c3826a73a..734e2c8bc5cd 100644 --- a/drivers/soundwire/sysfs.c +++ b/drivers/soundwire/sysfs.c @@ -8,6 +8,7 @@ #include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw_type.h> #include "bus.h" +#include "sysfs_local.h"
struct sdw_master_sysfs { struct device dev; @@ -160,3 +161,215 @@ void sdw_sysfs_bus_exit(struct sdw_bus *bus) put_device(&master->dev); bus->sysfs = NULL; }
+/*
- Slave sysfs
- */
+/*
- The sysfs for Slave reflects the MIPI description as given
- in the MIPI DisCo spec
- Base file is device
- |---- mipi_revision
- |---- wake_capable
- |---- test_mode_capable
- |---- simple_clk_stop_capable
- |---- clk_stop_timeout
- |---- ch_prep_timeout
- |---- reset_behave
- |---- high_PHY_capable
- |---- paging_support
- |---- bank_delay_support
- |---- p15_behave
- |---- master_count
- |---- source_ports
- |---- sink_ports
- |---- dp0
|---- max_word
|---- min_word
|---- words
|---- flow_controlled
|---- simple_ch_prep_sm
|---- device_interrupts
- |---- dpN
|---- max_word
|---- min_word
|---- words
|---- type
|---- max_grouping
|---- simple_ch_prep_sm
|---- ch_prep_timeout
|---- device_interrupts
|---- max_ch
|---- min_ch
|---- ch
|---- ch_combinations
|---- modes
|---- max_async_buffer
|---- block_pack_mode
|---- port_encoding
|---- audio_modeM
|---- bus_min_freq
|---- bus_max_freq
|---- bus_freq
|---- max_freq
|---- min_freq
|---- freq
|---- prep_ch_behave
|---- glitchless
- */
+#define sdw_slave_attr(field, format_string) \ +static ssize_t field##_show(struct device *dev, \
struct device_attribute *attr, \
char *buf) \
+{ \
- struct sdw_slave *slave = dev_to_sdw_dev(dev); \
- return sprintf(buf, format_string, slave->prop.field); \
+} \ +static DEVICE_ATTR_RO(field)
+sdw_slave_attr(mipi_revision, "0x%x\n"); +sdw_slave_attr(wake_capable, "%d\n"); +sdw_slave_attr(test_mode_capable, "%d\n"); +sdw_slave_attr(clk_stop_mode1, "%d\n"); +sdw_slave_attr(simple_clk_stop_capable, "%d\n"); +sdw_slave_attr(clk_stop_timeout, "%d\n"); +sdw_slave_attr(ch_prep_timeout, "%d\n"); +sdw_slave_attr(reset_behave, "%d\n"); +sdw_slave_attr(high_PHY_capable, "%d\n"); +sdw_slave_attr(paging_support, "%d\n"); +sdw_slave_attr(bank_delay_support, "%d\n"); +sdw_slave_attr(p15_behave, "%d\n"); +sdw_slave_attr(master_count, "%d\n"); +sdw_slave_attr(source_ports, "%d\n"); +sdw_slave_attr(sink_ports, "%d\n");
+static ssize_t modalias_show(struct device *dev,
struct device_attribute *attr, char *buf)
+{
- struct sdw_slave *slave = dev_to_sdw_dev(dev);
- return sdw_slave_modalias(slave, buf, 256);
+} +static DEVICE_ATTR_RO(modalias);
+static struct attribute *slave_dev_attrs[] = {
- &dev_attr_mipi_revision.attr,
- &dev_attr_wake_capable.attr,
- &dev_attr_test_mode_capable.attr,
- &dev_attr_clk_stop_mode1.attr,
- &dev_attr_simple_clk_stop_capable.attr,
- &dev_attr_clk_stop_timeout.attr,
- &dev_attr_ch_prep_timeout.attr,
- &dev_attr_reset_behave.attr,
- &dev_attr_high_PHY_capable.attr,
- &dev_attr_paging_support.attr,
- &dev_attr_bank_delay_support.attr,
- &dev_attr_p15_behave.attr,
- &dev_attr_master_count.attr,
- &dev_attr_source_ports.attr,
- &dev_attr_sink_ports.attr,
- &dev_attr_modalias.attr,
- NULL,
+};
+static struct attribute_group sdw_slave_dev_attr_group = {
- .attrs = slave_dev_attrs,
+};
+const struct attribute_group *sdw_slave_dev_attr_groups[] = {
- &sdw_slave_dev_attr_group,
- NULL
+};
ATTRIBUTE_GROUP()?
+int sdw_sysfs_slave_init(struct sdw_slave *slave) +{
- struct sdw_slave_sysfs *sysfs;
- unsigned int src_dpns, sink_dpns, i, j;
- int err;
- if (slave->sysfs) {
dev_err(&slave->dev, "SDW Slave sysfs is already initialized\n");
err = -EIO;
goto err_ret;
- }
- sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL);
Same question as patch 1, why a new device?
thanks,
greg k-h