Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/drivers/soundwire/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 7 kB image not shown  

Quelle  sysfs_slave_dpn.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
// Copyright(c) 2015-2020 Intel Corporation.

#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include "bus.h"
#include "sysfs_local.h"

struct dpn_attribute {
 struct device_attribute dev_attr;
 int N;
 int dir;
 const char *format_string;
};

/*
 * Since we can't use ARRAY_SIZE, hard-code number of dpN attributes.
 * This needs to be updated when adding new attributes - an error will be
 * flagged on a mismatch.
 */

#define SDW_DPN_ATTRIBUTES 15

#define sdw_dpn_attribute_alloc(field)     \
static int field##_attribute_alloc(struct device *dev,   \
    struct attribute **res,   \
    int N, int dir,    \
    const char *format_string)  \
{         \
 struct dpn_attribute *dpn_attr;     \
         \
 dpn_attr = devm_kzalloc(dev, sizeof(*dpn_attr), GFP_KERNEL); \
 if (!dpn_attr)       \
  return -ENOMEM;      \
 dpn_attr->N = N;      \
 dpn_attr->dir = dir;      \
 sysfs_attr_init(&dpn_attr->dev_attr.attr);   \
 dpn_attr->format_string = format_string;   \
 dpn_attr->dev_attr.attr.name = __stringify(field);  \
 dpn_attr->dev_attr.attr.mode = 0444;    \
 dpn_attr->dev_attr.show = field##_show;    \
         \
 *res = &dpn_attr->dev_attr.attr;    \
         \
 return 0;       \
}

#define sdw_dpn_attr(field)      \
         \
static ssize_t field##_dpn_show(struct sdw_slave *slave,  \
    int N,     \
    int dir,    \
    const char *format_string,  \
    char *buf)    \
{         \
 struct sdw_dpn_prop *dpn;     \
 unsigned long mask;      \
 int bit;       \
 int i;        \
         \
 if (dir) {       \
  dpn = slave->prop.src_dpn_prop;    \
  mask = slave->prop.source_ports;   \
 } else {       \
  dpn = slave->prop.sink_dpn_prop;   \
  mask = slave->prop.sink_ports;    \
 }        \
         \
 i = 0;        \
 for_each_set_bit(bit, &mask, 32) {    \
  if (bit == N) {      \
   return sprintf(buf, format_string,  \
           dpn[i].field);   \
  }       \
  i++;       \
 }        \
 return -EINVAL;       \
}         \
         \
static ssize_t field##_show(struct device *dev,    \
       struct device_attribute *attr,  \
       char *buf)     \
{         \
 struct sdw_slave *slave = dev_to_sdw_dev(dev);   \
 struct dpn_attribute *dpn_attr =    \
  container_of(attr, struct dpn_attribute, dev_attr); \
         \
 return field##_dpn_show(slave,     \
    dpn_attr->N, dpn_attr->dir,  \
    dpn_attr->format_string,  \
    buf);     \
}         \
sdw_dpn_attribute_alloc(field)

sdw_dpn_attr(imp_def_interrupts);
sdw_dpn_attr(max_word);
sdw_dpn_attr(min_word);
sdw_dpn_attr(type);
sdw_dpn_attr(max_grouping);
sdw_dpn_attr(simple_ch_prep_sm);
sdw_dpn_attr(ch_prep_timeout);
sdw_dpn_attr(max_ch);
sdw_dpn_attr(min_ch);
sdw_dpn_attr(max_async_buffer);
sdw_dpn_attr(block_pack_mode);
sdw_dpn_attr(port_encoding);

#define sdw_dpn_array_attr(field)     \
         \
static ssize_t field##_dpn_show(struct sdw_slave *slave,  \
    int N,     \
    int dir,    \
    const char *format_string,  \
    char *buf)    \
{         \
 struct sdw_dpn_prop *dpn;     \
 unsigned long mask;      \
 ssize_t size = 0;      \
 int bit;       \
 int i;        \
 int j;        \
         \
 if (dir) {       \
  dpn = slave->prop.src_dpn_prop;    \
  mask = slave->prop.source_ports;   \
 } else {       \
  dpn = slave->prop.sink_dpn_prop;   \
  mask = slave->prop.sink_ports;    \
 }        \
         \
 i = 0;        \
 for_each_set_bit(bit, &mask, 32) {    \
  if (bit == N) {      \
   for (j = 0; j < dpn[i].num_##field; j++) \
    size += sprintf(buf + size,  \
      format_string,  \
      dpn[i].field[j]); \
   size += sprintf(buf + size, "\n");  \
   return size;     \
  }       \
  i++;       \
 }        \
 return -EINVAL;       \
}         \
static ssize_t field##_show(struct device *dev,    \
       struct device_attribute *attr,  \
       char *buf)     \
{         \
 struct sdw_slave *slave = dev_to_sdw_dev(dev);   \
 struct dpn_attribute *dpn_attr =    \
  container_of(attr, struct dpn_attribute, dev_attr); \
         \
 return field##_dpn_show(slave,     \
    dpn_attr->N, dpn_attr->dir,  \
    dpn_attr->format_string,  \
    buf);     \
}         \
sdw_dpn_attribute_alloc(field)

sdw_dpn_array_attr(words);
sdw_dpn_array_attr(ch_combinations);
sdw_dpn_array_attr(channels);

static int add_all_attributes(struct device *dev, int N, int dir)
{
 struct attribute **dpn_attrs;
 struct attribute_group *dpn_group;
 int i = 0;
 int ret;

 /* allocate attributes, last one is NULL */
 dpn_attrs = devm_kcalloc(dev, SDW_DPN_ATTRIBUTES + 1,
     sizeof(struct attribute *),
     GFP_KERNEL);
 if (!dpn_attrs)
  return -ENOMEM;

 ret = max_word_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = min_word_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = words_attribute_alloc(dev, &dpn_attrs[i++],
        N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = type_attribute_alloc(dev, &dpn_attrs[i++],
       N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = max_grouping_attribute_alloc(dev, &dpn_attrs[i++],
        N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = simple_ch_prep_sm_attribute_alloc(dev, &dpn_attrs[i++],
      N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = ch_prep_timeout_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = imp_def_interrupts_attribute_alloc(dev, &dpn_attrs[i++],
       N, dir, "0x%x\n");
 if (ret < 0)
  return ret;

 ret = min_ch_attribute_alloc(dev, &dpn_attrs[i++],
         N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = max_ch_attribute_alloc(dev, &dpn_attrs[i++],
         N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = channels_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = ch_combinations_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = max_async_buffer_attribute_alloc(dev, &dpn_attrs[i++],
            N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = block_pack_mode_attribute_alloc(dev, &dpn_attrs[i++],
           N, dir, "%d\n");
 if (ret < 0)
  return ret;

 ret = port_encoding_attribute_alloc(dev, &dpn_attrs[i++],
         N, dir, "%d\n");
 if (ret < 0)
  return ret;

 /* paranoia check for editing mistakes */
 if (i != SDW_DPN_ATTRIBUTES) {
  dev_err(dev, "mismatch in attributes, allocated %d got %d\n",
   SDW_DPN_ATTRIBUTES, i);
  return -EINVAL;
 }

 dpn_group = devm_kzalloc(dev, sizeof(*dpn_group), GFP_KERNEL);
 if (!dpn_group)
  return -ENOMEM;

 dpn_group->attrs = dpn_attrs;
 dpn_group->name = devm_kasprintf(dev, GFP_KERNEL, "dp%d_%s",
      N, dir ? "src" : "sink");
 if (!dpn_group->name)
  return -ENOMEM;

 ret = devm_device_add_group(dev, dpn_group);
 if (ret < 0)
  return ret;

 return 0;
}

int sdw_slave_sysfs_dpn_init(struct sdw_slave *slave)
{
 unsigned long mask;
 int ret;
 int i;

 if (!slave->prop.source_ports && !slave->prop.sink_ports)
  return 0;

 mask = slave->prop.source_ports;
 for_each_set_bit(i, &mask, 32) {
  ret = add_all_attributes(&slave->dev, i, 1);
  if (ret < 0)
   return ret;
 }

 mask = slave->prop.sink_ports;
 for_each_set_bit(i, &mask, 32) {
  ret = add_all_attributes(&slave->dev, i, 0);
  if (ret < 0)
   return ret;
 }

 return 0;
}

Messung V0.5
C=99 H=99 G=98

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.