Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ /* Copyright(c) 2015-17 Intel Corporation. */ #ifndef __SDW_BUS_H #define __SDW_BUS_H #define DEFAULT_BANK_SWITCH_TIMEOUT 3000 #define DEFAULT_PROBE_TIMEOUT 2000 u64 sdw_dmi_override_adr(struct sdw_bus *bus, u64 addr); #if IS_ENABLED(CONFIG_ACPI) int sdw_acpi_find_slaves(struct sdw_bus *bus); #else static inline int sdw_acpi_find_slaves(struct sdw_bus *bus) { return -ENOTSUPP; } #endif int sdw_of_find_slaves(struct sdw_bus *bus); void sdw_extract_slave_id(struct sdw_bus *bus, u64 addr, struct sdw_slave_id *id); int sdw_slave_add(struct sdw_bus *bus, struct sdw_slave_id *id, struct fwnode_handle *fwnode); int sdw_master_device_add(struct sdw_bus *bus, struct device *parent, struct fwnode_handle *fwnode); int sdw_master_device_del(struct sdw_bus *bus); #ifdef CONFIG_DEBUG_FS void sdw_bus_debugfs_init(struct sdw_bus *bus); void sdw_bus_debugfs_exit(struct sdw_bus *bus); void sdw_slave_debugfs_init(struct sdw_slave *slave); void sdw_slave_debugfs_exit(struct sdw_slave *slave); void sdw_debugfs_init(void); void sdw_debugfs_exit(void); #else static inline void sdw_bus_debugfs_init(struct sdw_bus *bus) {} static inline void sdw_bus_debugfs_exit(struct sdw_bus *bus) {} static inline void sdw_slave_debugfs_init(struct sdw_slave *slave) {} static inline void sdw_slave_debugfs_exit(struct sdw_slave *slave) {} static inline void sdw_debugfs_init(void) {} static inline void sdw_debugfs_exit(void) {} #endif enum { SDW_MSG_FLAG_READ = 0, SDW_MSG_FLAG_WRITE, }; /** * struct sdw_msg - Message structure * @addr: Register address accessed in the Slave * @len: number of messages * @dev_num: Slave device number * @addr_page1: SCP address page 1 Slave register * @addr_page2: SCP address page 2 Slave register * @flags: transfer flags, indicate if xfer is read or write * @buf: message data buffer * @ssp_sync: Send message at SSP (Stream Synchronization Point) * @page: address requires paging */ struct sdw_msg { u16 addr; u16 len; u8 dev_num; u8 addr_page1; u8 addr_page2; u8 flags; u8 *buf; bool ssp_sync; bool page; }; #define SDW_DOUBLE_RATE_FACTOR 2 #define SDW_STRM_RATE_GROUPING 1 extern int sdw_rows[SDW_FRAME_ROWS]; extern int sdw_cols[SDW_FRAME_COLS]; int sdw_find_row_index(int row); int sdw_find_col_index(int col); /** * sdw_port_runtime: Runtime port parameters for Master or Slave * * @num: Port number. For audio streams, valid port number ranges from * [1,14] * @ch_mask: Channel mask * @transport_params: Transport parameters * @port_params: Port parameters * @port_node: List node for Master or Slave port_list * * SoundWire spec has no mention of ports for Master interface but the * concept is logically extended. */ struct sdw_port_runtime { int num; int ch_mask; struct sdw_transport_params transport_params; struct sdw_port_params port_params; struct list_head port_node; }; /** * sdw_slave_runtime: Runtime Stream parameters for Slave * * @slave: Slave handle * @direction: Data direction for Slave * @ch_count: Number of channels handled by the Slave for * this stream * @m_rt_node: sdw_master_runtime list node * @port_list: List of Slave Ports configured for this stream */ struct sdw_slave_runtime { struct sdw_slave *slave; enum sdw_data_direction direction; unsigned int ch_count; struct list_head m_rt_node; struct list_head port_list; }; /** * sdw_master_runtime: Runtime stream parameters for Master * * @bus: Bus handle * @stream: Stream runtime handle * @direction: Data direction for Master * @ch_count: Number of channels handled by the Master for * this stream, can be zero. * @slave_rt_list: Slave runtime list * @port_list: List of Master Ports configured for this stream, can be zero. * @stream_node: sdw_stream_runtime master_list node * @bus_node: sdw_bus m_rt_list node */ struct sdw_master_runtime { struct sdw_bus *bus; struct sdw_stream_runtime *stream; enum sdw_data_direction direction; unsigned int ch_count; struct list_head slave_rt_list; struct list_head port_list; struct list_head stream_node; struct list_head bus_node; }; struct sdw_transport_data { int hstart; int hstop; int block_offset; int sub_block_offset; }; struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave, enum sdw_data_direction direction, unsigned int port_num); int sdw_configure_dpn_intr(struct sdw_slave *slave, int port, bool enable, int mask); int sdw_transfer(struct sdw_bus *bus, struct sdw_msg *msg); int sdw_transfer_defer(struct sdw_bus *bus, struct sdw_msg *msg); #define SDW_READ_INTR_CLEAR_RETRY 10 int sdw_fill_msg(struct sdw_msg *msg, struct sdw_slave *slave, u32 addr, size_t count, u16 dev_num, u8 flags, u8 *buf); /* Fill transport parameter data structure */ static inline void sdw_fill_xport_params(struct sdw_transport_params *params, int port_num, bool grp_ctrl_valid, int grp_ctrl, int sample_int, int off1, int off2, int hstart, int hstop, int pack_mode, int lane_ctrl) { params->port_num = port_num; params->blk_grp_ctrl_valid = grp_ctrl_valid; params->blk_grp_ctrl = grp_ctrl; params->sample_interval = sample_int; params->offset1 = off1; params->offset2 = off2; params->hstart = hstart; params->hstop = hstop; params->blk_pkg_mode = pack_mode; params->lane_ctrl = lane_ctrl; } /* Fill port parameter data structure */ static inline void sdw_fill_port_params(struct sdw_port_params *params, int port_num, int bps, int flow_mode, int data_mode) { params->num = port_num; params->bps = bps; params->flow_mode = flow_mode; params->data_mode = data_mode; } /* broadcast read/write for tests */ int sdw_bread_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr); int sdw_bwrite_no_pm_unlocked(struct sdw_bus *bus, u16 dev_num, u32 addr, u8 value); /* * At the moment we only track Master-initiated hw_reset. * Additional fields can be added as needed */ #define SDW_UNATTACH_REQUEST_MASTER_RESET BIT(0) void sdw_clear_slave_status(struct sdw_bus *bus, u32 request); int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size); void sdw_compute_slave_ports(struct sdw_master_runtime *m_rt, struct sdw_transport_data *t_data); #endif /* __SDW_BUS_H */ |