soundwire: master: add sysfs support
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Mon, 18 May 2020 20:35:50 +0000 (04:35 +0800)
committerVinod Koul <vkoul@kernel.org>
Wed, 20 May 2020 11:52:36 +0000 (17:22 +0530)
Add the master properties as attributes. The description is directly
derived from the MIPI DisCo 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>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20200518203551.2053-3-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Documentation/ABI/testing/sysfs-bus-soundwire-master [new file with mode: 0644]
drivers/soundwire/master.c

diff --git a/Documentation/ABI/testing/sysfs-bus-soundwire-master b/Documentation/ABI/testing/sysfs-bus-soundwire-master
new file mode 100644 (file)
index 0000000..46ef038
--- /dev/null
@@ -0,0 +1,23 @@
+What:          /sys/bus/soundwire/devices/sdw-master-N/revision
+               /sys/bus/soundwire/devices/sdw-master-N/clk_stop_modes
+               /sys/bus/soundwire/devices/sdw-master-N/clk_freq
+               /sys/bus/soundwire/devices/sdw-master-N/clk_gears
+               /sys/bus/soundwire/devices/sdw-master-N/default_col
+               /sys/bus/soundwire/devices/sdw-master-N/default_frame_rate
+               /sys/bus/soundwire/devices/sdw-master-N/default_row
+               /sys/bus/soundwire/devices/sdw-master-N/dynamic_shape
+               /sys/bus/soundwire/devices/sdw-master-N/err_threshold
+               /sys/bus/soundwire/devices/sdw-master-N/max_clk_freq
+
+Date:          April 2020
+
+Contact:       Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+               Bard Liao <yung-chuan.liao@linux.intel.com>
+               Vinod Koul <vkoul@kernel.org>
+
+Description:   SoundWire Master-N DisCo properties.
+               These properties are defined by MIPI DisCo Specification
+               for SoundWire. They define various properties of the Master
+               and are used by the bus to configure the Master. clk_stop_modes
+               is a bitmask for simplifications and combines the
+               clock-stop-mode0 and clock-stop-mode1 properties.
index 5411791..5f0b218 100644 (file)
@@ -8,6 +8,89 @@
 #include <linux/soundwire/sdw_type.h>
 #include "bus.h"
 
+/*
+ * The sysfs for properties reflects the MIPI description as given
+ * in the MIPI DisCo spec
+ *
+ * Base file is:
+ *     sdw-master-N
+ *      |---- revision
+ *      |---- clk_stop_modes
+ *      |---- max_clk_freq
+ *      |---- clk_freq
+ *      |---- clk_gears
+ *      |---- default_row
+ *      |---- default_col
+ *      |---- dynamic_shape
+ *      |---- err_threshold
+ */
+
+#define sdw_master_attr(field, format_string)                          \
+static ssize_t field##_show(struct device *dev,                                \
+                           struct device_attribute *attr,              \
+                           char *buf)                                  \
+{                                                                      \
+       struct sdw_master_device *md = dev_to_sdw_master_device(dev);   \
+       return sprintf(buf, format_string, md->bus->prop.field);        \
+}                                                                      \
+static DEVICE_ATTR_RO(field)
+
+sdw_master_attr(revision, "0x%x\n");
+sdw_master_attr(clk_stop_modes, "0x%x\n");
+sdw_master_attr(max_clk_freq, "%d\n");
+sdw_master_attr(default_row, "%d\n");
+sdw_master_attr(default_col, "%d\n");
+sdw_master_attr(default_frame_rate, "%d\n");
+sdw_master_attr(dynamic_frame, "%d\n");
+sdw_master_attr(err_threshold, "%d\n");
+
+static ssize_t clock_frequencies_show(struct device *dev,
+                                     struct device_attribute *attr, char *buf)
+{
+       struct sdw_master_device *md = dev_to_sdw_master_device(dev);
+       ssize_t size = 0;
+       int i;
+
+       for (i = 0; i < md->bus->prop.num_clk_freq; i++)
+               size += sprintf(buf + size, "%8d ",
+                               md->bus->prop.clk_freq[i]);
+       size += sprintf(buf + size, "\n");
+
+       return size;
+}
+static DEVICE_ATTR_RO(clock_frequencies);
+
+static ssize_t clock_gears_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct sdw_master_device *md = dev_to_sdw_master_device(dev);
+       ssize_t size = 0;
+       int i;
+
+       for (i = 0; i < md->bus->prop.num_clk_gears; i++)
+               size += sprintf(buf + size, "%8d ",
+                               md->bus->prop.clk_gears[i]);
+       size += sprintf(buf + size, "\n");
+
+       return size;
+}
+static DEVICE_ATTR_RO(clock_gears);
+
+static struct attribute *master_node_attrs[] = {
+       &dev_attr_revision.attr,
+       &dev_attr_clk_stop_modes.attr,
+       &dev_attr_max_clk_freq.attr,
+       &dev_attr_default_row.attr,
+       &dev_attr_default_col.attr,
+       &dev_attr_default_frame_rate.attr,
+       &dev_attr_dynamic_frame.attr,
+       &dev_attr_err_threshold.attr,
+       &dev_attr_clock_frequencies.attr,
+       &dev_attr_clock_gears.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(master_node);
+
 static void sdw_master_device_release(struct device *dev)
 {
        struct sdw_master_device *md = dev_to_sdw_master_device(dev);
@@ -48,6 +131,7 @@ int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
        md->dev.bus = &sdw_bus_type;
        md->dev.type = &sdw_master_type;
        md->dev.parent = parent;
+       md->dev.groups = master_node_groups;
        md->dev.of_node = parent->of_node;
        md->dev.fwnode = fwnode;
        md->dev.dma_mask = parent->dma_mask;