From 093a6c67005148ae32a5c9e4553491b9f5c2457b Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:40:51 +0000
Subject: [PATCH] disable kernel build waring
---
kernel/include/linux/soundwire/sdw.h | 294 +++++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 247 insertions(+), 47 deletions(-)
diff --git a/kernel/include/linux/soundwire/sdw.h b/kernel/include/linux/soundwire/sdw.h
index 962971e..57cda3a 100644
--- a/kernel/include/linux/soundwire/sdw.h
+++ b/kernel/include/linux/soundwire/sdw.h
@@ -1,8 +1,11 @@
-// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
-// Copyright(c) 2015-17 Intel Corporation.
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/* Copyright(c) 2015-17 Intel Corporation. */
#ifndef __SOUNDWIRE_H
#define __SOUNDWIRE_H
+
+#include <linux/mod_devicetable.h>
+#include <linux/bitfield.h>
struct sdw_bus;
struct sdw_slave;
@@ -36,10 +39,33 @@
#define SDW_FRAME_CTRL_BITS 48
#define SDW_MAX_DEVICES 11
-#define SDW_VALID_PORT_RANGE(n) (n <= 14 && n >= 1)
+#define SDW_MAX_PORTS 15
+#define SDW_VALID_PORT_RANGE(n) ((n) < SDW_MAX_PORTS && (n) >= 1)
-#define SDW_DAI_ID_RANGE_START 100
-#define SDW_DAI_ID_RANGE_END 200
+enum {
+ SDW_PORT_DIRN_SINK = 0,
+ SDW_PORT_DIRN_SOURCE,
+ SDW_PORT_DIRN_MAX,
+};
+
+/*
+ * constants for flow control, ports and transport
+ *
+ * these are bit masks as devices can have multiple capabilities
+ */
+
+/*
+ * flow modes for SDW port. These can be isochronous, tx controlled,
+ * rx controlled or async
+ */
+#define SDW_PORT_FLOW_MODE_ISOCH 0
+#define SDW_PORT_FLOW_MODE_TX_CNTRL BIT(0)
+#define SDW_PORT_FLOW_MODE_RX_CNTRL BIT(1)
+#define SDW_PORT_FLOW_MODE_ASYNC GENMASK(1, 0)
+
+/* sample packaging for block. It can be per port or per channel */
+#define SDW_BLOCK_PACKG_PER_PORT BIT(0)
+#define SDW_BLOCK_PACKG_PER_CH BIT(1)
/**
* enum sdw_slave_status - Slave status
@@ -53,6 +79,21 @@
SDW_SLAVE_ATTACHED = 1,
SDW_SLAVE_ALERT = 2,
SDW_SLAVE_RESERVED = 3,
+};
+
+/**
+ * enum sdw_clk_stop_type: clock stop operations
+ *
+ * @SDW_CLK_PRE_PREPARE: pre clock stop prepare
+ * @SDW_CLK_POST_PREPARE: post clock stop prepare
+ * @SDW_CLK_PRE_DEPREPARE: pre clock stop de-prepare
+ * @SDW_CLK_POST_DEPREPARE: post clock stop de-prepare
+ */
+enum sdw_clk_stop_type {
+ SDW_CLK_PRE_PREPARE = 0,
+ SDW_CLK_POST_PREPARE,
+ SDW_CLK_PRE_DEPREPARE,
+ SDW_CLK_POST_DEPREPARE,
};
/**
@@ -74,6 +115,14 @@
SDW_CMD_FAIL = 2,
SDW_CMD_TIMEOUT = 3,
SDW_CMD_FAIL_OTHER = 4,
+};
+
+/* block group count enum */
+enum sdw_dpn_grouping {
+ SDW_BLK_GRP_CNT_1 = 0,
+ SDW_BLK_GRP_CNT_2 = 1,
+ SDW_BLK_GRP_CNT_3 = 2,
+ SDW_BLK_GRP_CNT_4 = 3,
};
/**
@@ -98,6 +147,26 @@
enum sdw_data_direction {
SDW_DATA_DIR_RX = 0,
SDW_DATA_DIR_TX = 1,
+};
+
+/**
+ * enum sdw_port_data_mode: Data Port mode
+ *
+ * @SDW_PORT_DATA_MODE_NORMAL: Normal data mode where audio data is received
+ * and transmitted.
+ * @SDW_PORT_DATA_MODE_PRBS: Test mode which uses a PRBS generator to produce
+ * a pseudo random data pattern that is transferred
+ * @SDW_PORT_DATA_MODE_STATIC_0: Simple test mode which uses static value of
+ * logic 0. The encoding will result in no signal transitions
+ * @SDW_PORT_DATA_MODE_STATIC_1: Simple test mode which uses static value of
+ * logic 1. The encoding will result in signal transitions at every bitslot
+ * owned by this Port
+ */
+enum sdw_port_data_mode {
+ SDW_PORT_DATA_MODE_NORMAL = 0,
+ SDW_PORT_DATA_MODE_PRBS = 1,
+ SDW_PORT_DATA_MODE_STATIC_0 = 2,
+ SDW_PORT_DATA_MODE_STATIC_1 = 3,
};
/*
@@ -153,10 +222,11 @@
* (inclusive)
* @num_words: number of wordlengths supported
* @words: wordlengths supported
- * @flow_controlled: Slave implementation results in an OK_NotReady
+ * @BRA_flow_controlled: Slave implementation results in an OK_NotReady
* response
* @simple_ch_prep_sm: If channel prepare sequence is required
- * @device_interrupts: If implementation-defined interrupts are supported
+ * @imp_def_interrupts: If set, each bit corresponds to support for
+ * implementation-defined interrupts
*
* The wordlengths are specified by Spec as max, min AND number of
* discrete values, implementation can define based on the wordlengths they
@@ -167,9 +237,9 @@
u32 min_word;
u32 num_words;
u32 *words;
- bool flow_controlled;
+ bool BRA_flow_controlled;
bool simple_ch_prep_sm;
- bool device_interrupts;
+ bool imp_def_interrupts;
};
/**
@@ -219,18 +289,19 @@
* @simple_ch_prep_sm: If the port supports simplified channel prepare state
* machine
* @ch_prep_timeout: Port-specific timeout value, in milliseconds
- * @device_interrupts: If set, each bit corresponds to support for
+ * @imp_def_interrupts: If set, each bit corresponds to support for
* implementation-defined interrupts
* @max_ch: Maximum channels supported
* @min_ch: Minimum channels supported
- * @num_ch: Number of discrete channels supported
- * @ch: Discrete channels supported
+ * @num_channels: Number of discrete channels supported
+ * @channels: Discrete channels supported
* @num_ch_combinations: Number of channel combinations supported
* @ch_combinations: Channel combinations supported
* @modes: SDW mode supported
* @max_async_buffer: Number of samples that this port can buffer in
* asynchronous modes
* @block_pack_mode: Type of block port mode supported
+ * @read_only_wordlength: Read Only wordlength field in DPN_BlockCtrl1 register
* @port_encoding: Payload Channel Sample encoding schemes supported
* @audio_modes: Audio modes supported
*/
@@ -244,16 +315,17 @@
u32 max_grouping;
bool simple_ch_prep_sm;
u32 ch_prep_timeout;
- u32 device_interrupts;
+ u32 imp_def_interrupts;
u32 max_ch;
u32 min_ch;
- u32 num_ch;
- u32 *ch;
+ u32 num_channels;
+ u32 *channels;
u32 num_ch_combinations;
u32 *ch_combinations;
u32 modes;
u32 max_async_buffer;
bool block_pack_mode;
+ bool read_only_wordlength;
u32 port_encoding;
struct sdw_dpn_audio_mode *audio_modes;
};
@@ -285,6 +357,8 @@
* @dp0_prop: Data Port 0 properties
* @src_dpn_prop: Source Data Port N properties
* @sink_dpn_prop: Sink Data Port N properties
+ * @scp_int1_mask: SCP_INT1_MASK desired settings
+ * @quirks: bitmask identifying deltas from the MIPI specification
*/
struct sdw_slave_prop {
u32 mipi_revision;
@@ -306,41 +380,45 @@
struct sdw_dp0_prop *dp0_prop;
struct sdw_dpn_prop *src_dpn_prop;
struct sdw_dpn_prop *sink_dpn_prop;
+ u8 scp_int1_mask;
+ u32 quirks;
};
+
+#define SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY BIT(0)
/**
* struct sdw_master_prop - Master properties
* @revision: MIPI spec version of the implementation
- * @master_count: Number of masters
- * @clk_stop_mode: Bitmap for Clock Stop modes supported
- * @max_freq: Maximum Bus clock frequency, in Hz
+ * @clk_stop_modes: Bitmap, bit N set when clock-stop-modeN supported
+ * @max_clk_freq: Maximum Bus clock frequency, in Hz
* @num_clk_gears: Number of clock gears supported
* @clk_gears: Clock gears supported
- * @num_freq: Number of clock frequencies supported, in Hz
- * @freq: Clock frequencies supported, in Hz
+ * @num_clk_freq: Number of clock frequencies supported, in Hz
+ * @clk_freq: Clock frequencies supported, in Hz
* @default_frame_rate: Controller default Frame rate, in Hz
* @default_row: Number of rows
* @default_col: Number of columns
- * @dynamic_frame: Dynamic frame supported
+ * @dynamic_frame: Dynamic frame shape supported
* @err_threshold: Number of times that software may retry sending a single
* command
- * @dpn_prop: Data Port N properties
+ * @mclk_freq: clock reference passed to SoundWire Master, in Hz.
+ * @hw_disabled: if true, the Master is not functional, typically due to pin-mux
*/
struct sdw_master_prop {
u32 revision;
- u32 master_count;
- enum sdw_clk_stop_mode clk_stop_mode;
- u32 max_freq;
+ u32 clk_stop_modes;
+ u32 max_clk_freq;
u32 num_clk_gears;
u32 *clk_gears;
- u32 num_freq;
- u32 *freq;
+ u32 num_clk_freq;
+ u32 *clk_freq;
u32 default_frame_rate;
u32 default_row;
u32 default_col;
bool dynamic_frame;
u32 err_threshold;
- struct sdw_dpn_prop *dpn_prop;
+ u32 mclk_freq;
+ bool hw_disabled;
};
int sdw_master_read_prop(struct sdw_bus *bus);
@@ -350,12 +428,13 @@
* SDW Slave Structures and APIs
*/
+#define SDW_IGNORED_UNIQUE_ID 0xFF
+
/**
* struct sdw_slave_id - Slave ID
* @mfg_id: MIPI Manufacturer ID
* @part_id: Device Part ID
- * @class_id: MIPI Class ID, unused now.
- * Currently a placeholder in MIPI SoundWire Spec
+ * @class_id: MIPI Class ID (defined starting with SoundWire 1.2 spec)
* @unique_id: Device unique ID
* @sdw_version: SDW version implemented
*
@@ -365,9 +444,38 @@
__u16 mfg_id;
__u16 part_id;
__u8 class_id;
- __u8 unique_id:4;
+ __u8 unique_id;
__u8 sdw_version:4;
};
+
+/*
+ * Helper macros to extract the MIPI-defined IDs
+ *
+ * Spec definition
+ * Register Bit Contents
+ * DevId_0 [7:4] 47:44 sdw_version
+ * DevId_0 [3:0] 43:40 unique_id
+ * DevId_1 39:32 mfg_id [15:8]
+ * DevId_2 31:24 mfg_id [7:0]
+ * DevId_3 23:16 part_id [15:8]
+ * DevId_4 15:08 part_id [7:0]
+ * DevId_5 07:00 class_id
+ *
+ * The MIPI DisCo for SoundWire defines in addition the link_id as bits 51:48
+ */
+#define SDW_DISCO_LINK_ID_MASK GENMASK_ULL(51, 48)
+#define SDW_VERSION_MASK GENMASK_ULL(47, 44)
+#define SDW_UNIQUE_ID_MASK GENMASK_ULL(43, 40)
+#define SDW_MFG_ID_MASK GENMASK_ULL(39, 24)
+#define SDW_PART_ID_MASK GENMASK_ULL(23, 8)
+#define SDW_CLASS_ID_MASK GENMASK_ULL(7, 0)
+
+#define SDW_DISCO_LINK_ID(addr) FIELD_GET(SDW_DISCO_LINK_ID_MASK, addr)
+#define SDW_VERSION(addr) FIELD_GET(SDW_VERSION_MASK, addr)
+#define SDW_UNIQUE_ID(addr) FIELD_GET(SDW_UNIQUE_ID_MASK, addr)
+#define SDW_MFG_ID(addr) FIELD_GET(SDW_MFG_ID_MASK, addr)
+#define SDW_PART_ID(addr) FIELD_GET(SDW_PART_ID_MASK, addr)
+#define SDW_CLASS_ID(addr) FIELD_GET(SDW_CLASS_ID_MASK, addr)
/**
* struct sdw_slave_intr_status - Slave interrupt status
@@ -446,6 +554,10 @@
* @bandwidth: Current bandwidth
* @col: Active columns
* @row: Active rows
+ * @s_data_mode: NORMAL, STATIC or PRBS mode for all Slave ports
+ * @m_data_mode: NORMAL, STATIC or PRBS mode for all Master ports. The value
+ * should be the same to detect transmission issues, but can be different to
+ * test the interrupt reports
*/
struct sdw_bus_params {
enum sdw_reg_bank curr_bank;
@@ -455,6 +567,8 @@
unsigned int bandwidth;
unsigned int col;
unsigned int row;
+ int s_data_mode;
+ int m_data_mode;
};
/**
@@ -470,14 +584,19 @@
struct sdw_slave_ops {
int (*read_prop)(struct sdw_slave *sdw);
int (*interrupt_callback)(struct sdw_slave *slave,
- struct sdw_slave_intr_status *status);
+ struct sdw_slave_intr_status *status);
int (*update_status)(struct sdw_slave *slave,
- enum sdw_slave_status status);
+ enum sdw_slave_status status);
int (*bus_config)(struct sdw_slave *slave,
- struct sdw_bus_params *params);
+ struct sdw_bus_params *params);
int (*port_prep)(struct sdw_slave *slave,
- struct sdw_prepare_ch *prepare_ch,
- enum sdw_port_prep_ops pre_ops);
+ struct sdw_prepare_ch *prepare_ch,
+ enum sdw_port_prep_ops pre_ops);
+ int (*get_clk_stop_mode)(struct sdw_slave *slave);
+ int (*clk_stop)(struct sdw_slave *slave,
+ enum sdw_clk_stop_mode mode,
+ enum sdw_clk_stop_type type);
+
};
/**
@@ -488,9 +607,27 @@
* @bus: Bus handle
* @ops: Slave callback ops
* @prop: Slave properties
+ * @debugfs: Slave debugfs
* @node: node for bus list
* @port_ready: Port ready completion flag for each Slave port
- * @dev_num: Device Number assigned by Bus
+ * @dev_num: Current Device Number, values can be 0 or dev_num_sticky
+ * @dev_num_sticky: one-time static Device Number assigned by Bus
+ * @probed: boolean tracking driver state
+ * @probe_complete: completion utility to control potential races
+ * on startup between driver probe/initialization and SoundWire
+ * Slave state changes/implementation-defined interrupts
+ * @enumeration_complete: completion utility to control potential races
+ * on startup between device enumeration and read/write access to the
+ * Slave device
+ * @initialization_complete: completion utility to control potential races
+ * on startup between device enumeration and settings being restored
+ * @unattach_request: mask field to keep track why the Slave re-attached and
+ * was re-initialized. This is useful to deal with potential race conditions
+ * between the Master suspending and the codec resuming, and make sure that
+ * when the Master triggered a reset the Slave is properly enumerated and
+ * initialized
+ * @first_interrupt_done: status flag tracking if the interrupt handling
+ * for a Slave happens for the first time after enumeration
*/
struct sdw_slave {
struct sdw_slave_id id;
@@ -499,12 +636,36 @@
struct sdw_bus *bus;
const struct sdw_slave_ops *ops;
struct sdw_slave_prop prop;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs;
+#endif
struct list_head node;
- struct completion *port_ready;
+ struct completion port_ready[SDW_MAX_PORTS];
+ enum sdw_clk_stop_mode curr_clk_stop_mode;
u16 dev_num;
+ u16 dev_num_sticky;
+ bool probed;
+ struct completion probe_complete;
+ struct completion enumeration_complete;
+ struct completion initialization_complete;
+ u32 unattach_request;
+ bool first_interrupt_done;
};
#define dev_to_sdw_dev(_dev) container_of(_dev, struct sdw_slave, dev)
+
+/**
+ * struct sdw_master_device - SoundWire 'Master Device' representation
+ * @dev: Linux device for this Master
+ * @bus: Bus handle shortcut
+ */
+struct sdw_master_device {
+ struct device dev;
+ struct sdw_bus *bus;
+};
+
+#define dev_to_sdw_master_device(d) \
+ container_of(d, struct sdw_master_device, dev)
struct sdw_driver {
const char *name;
@@ -520,9 +681,13 @@
struct device_driver driver;
};
-#define SDW_SLAVE_ENTRY(_mfg_id, _part_id, _drv_data) \
- { .mfg_id = (_mfg_id), .part_id = (_part_id), \
+#define SDW_SLAVE_ENTRY_EXT(_mfg_id, _part_id, _version, _c_id, _drv_data) \
+ { .mfg_id = (_mfg_id), .part_id = (_part_id), \
+ .sdw_version = (_version), .class_id = (_c_id), \
.driver_data = (unsigned long)(_drv_data) }
+
+#define SDW_SLAVE_ENTRY(_mfg_id, _part_id, _drv_data) \
+ SDW_SLAVE_ENTRY_EXT((_mfg_id), (_part_id), 0, 0, (_drv_data))
int sdw_handle_slave_status(struct sdw_bus *bus,
enum sdw_slave_status status[]);
@@ -661,13 +826,16 @@
/**
* struct sdw_bus - SoundWire bus
- * @dev: Master linux device
+ * @dev: Shortcut to &bus->md->dev to avoid changing the entire code.
+ * @md: Master device
* @link_id: Link id number, can be 0 to N, unique for each Master
+ * @id: bus system-wide unique id
* @slaves: list of Slaves on this bus
* @assigned: Bitmap for Slave device numbers.
* Bit set implies used number, bit clear implies unused number.
* @bus_lock: bus lock
* @msg_lock: message lock
+ * @compute_params: points to Bus resource management implementation
* @ops: Master callback ops
* @port_ops: Master port callback ops
* @params: Current bus parameters
@@ -675,29 +843,47 @@
* @m_rt_list: List of Master instance of all stream(s) running on Bus. This
* is used to compute and program bus bandwidth, clock, frame shape,
* transport and port parameters
+ * @debugfs: Bus debugfs
* @defer_msg: Defer message
* @clk_stop_timeout: Clock stop timeout computed
* @bank_switch_timeout: Bank switch timeout computed
+ * @multi_link: Store bus property that indicates if multi links
+ * are supported. This flag is populated by drivers after reading
+ * appropriate firmware (ACPI/DT).
+ * @hw_sync_min_links: Number of links used by a stream above which
+ * hardware-based synchronization is required. This value is only
+ * meaningful if multi_link is set. If set to 1, hardware-based
+ * synchronization will be used even if a stream only uses a single
+ * SoundWire segment.
*/
struct sdw_bus {
struct device *dev;
+ struct sdw_master_device *md;
unsigned int link_id;
+ int id;
struct list_head slaves;
DECLARE_BITMAP(assigned, SDW_MAX_DEVICES);
struct mutex bus_lock;
struct mutex msg_lock;
+ int (*compute_params)(struct sdw_bus *bus);
const struct sdw_master_ops *ops;
const struct sdw_master_port_ops *port_ops;
struct sdw_bus_params params;
struct sdw_master_prop prop;
struct list_head m_rt_list;
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *debugfs;
+#endif
struct sdw_defer defer_msg;
unsigned int clk_stop_timeout;
u32 bank_switch_timeout;
+ bool multi_link;
+ int hw_sync_min_links;
};
-int sdw_add_bus_master(struct sdw_bus *bus);
-void sdw_delete_bus_master(struct sdw_bus *bus);
+int sdw_bus_master_add(struct sdw_bus *bus, struct device *parent,
+ struct fwnode_handle *fwnode);
+void sdw_bus_master_delete(struct sdw_bus *bus);
/**
* sdw_port_config: Master or Slave Port configuration
@@ -768,18 +954,25 @@
* @params: Stream parameters
* @state: Current state of the stream
* @type: Stream type PCM or PDM
- * @m_rt: Master runtime
+ * @master_list: List of Master runtime(s) in this stream.
+ * master_list can contain only one m_rt per Master instance
+ * for a stream
+ * @m_rt_count: Count of Master runtime(s) in this stream
*/
struct sdw_stream_runtime {
- char *name;
+ const char *name;
struct sdw_stream_params params;
enum sdw_stream_state state;
enum sdw_stream_type type;
- struct sdw_master_runtime *m_rt;
+ struct list_head master_list;
+ int m_rt_count;
};
-struct sdw_stream_runtime *sdw_alloc_stream(char *stream_name);
+struct sdw_stream_runtime *sdw_alloc_stream(const char *stream_name);
void sdw_release_stream(struct sdw_stream_runtime *stream);
+
+int sdw_compute_params(struct sdw_bus *bus);
+
int sdw_stream_add_master(struct sdw_bus *bus,
struct sdw_stream_config *stream_config,
struct sdw_port_config *port_config,
@@ -794,15 +987,22 @@
struct sdw_stream_runtime *stream);
int sdw_stream_remove_slave(struct sdw_slave *slave,
struct sdw_stream_runtime *stream);
+int sdw_startup_stream(void *sdw_substream);
int sdw_prepare_stream(struct sdw_stream_runtime *stream);
int sdw_enable_stream(struct sdw_stream_runtime *stream);
int sdw_disable_stream(struct sdw_stream_runtime *stream);
int sdw_deprepare_stream(struct sdw_stream_runtime *stream);
+void sdw_shutdown_stream(void *sdw_substream);
+int sdw_bus_prep_clk_stop(struct sdw_bus *bus);
+int sdw_bus_clk_stop(struct sdw_bus *bus);
+int sdw_bus_exit_clk_stop(struct sdw_bus *bus);
/* messaging and data APIs */
int sdw_read(struct sdw_slave *slave, u32 addr);
int sdw_write(struct sdw_slave *slave, u32 addr, u8 value);
+int sdw_write_no_pm(struct sdw_slave *slave, u32 addr, u8 value);
+int sdw_read_no_pm(struct sdw_slave *slave, u32 addr);
int sdw_nread(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
int sdw_nwrite(struct sdw_slave *slave, u32 addr, size_t count, u8 *val);
--
Gitblit v1.6.2