Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

soundwire: introduce BPT section

Currently we send a BRA message with a start address with continuous
registers in a BPT stream. However, a codec may need to write different
register sections shortly. Introduce a register section in struct
sdw_btp_msg which contain register start address, length, and buffer.
This commit uses only 1 section for each BPT message. And we need to add
up all BPT section length and check if it reach maximum BPT bytes.
No function changes.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Tested-by: Shuming Fan <shumingf@realtek.com>
Link: https://patch.msgid.link/20251021094355.132943-2-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Bard Liao and committed by
Vinod Koul
fdfa1960 8931f5bc

+48 -20
+8 -2
drivers/soundwire/bus.c
··· 2052 2052 2053 2053 int sdw_bpt_send_async(struct sdw_bus *bus, struct sdw_slave *slave, struct sdw_bpt_msg *msg) 2054 2054 { 2055 - if (msg->len > SDW_BPT_MSG_MAX_BYTES) { 2056 - dev_err(bus->dev, "Invalid BPT message length %d\n", msg->len); 2055 + int len = 0; 2056 + int i; 2057 + 2058 + for (i = 0; i < msg->sections; i++) 2059 + len += msg->sec[i].len; 2060 + 2061 + if (len > SDW_BPT_MSG_MAX_BYTES) { 2062 + dev_err(bus->dev, "Invalid BPT message length %d\n", len); 2057 2063 return -EINVAL; 2058 2064 } 2059 2065
+16 -6
drivers/soundwire/bus.h
··· 73 73 }; 74 74 75 75 /** 76 - * struct sdw_btp_msg - Message structure 76 + * struct sdw_btp_section - Message section structure 77 77 * @addr: Start Register address accessed in the Slave 78 78 * @len: number of bytes to transfer. More than 64Kb can be transferred 79 79 * but a practical limit of SDW_BPT_MSG_MAX_BYTES is enforced. 80 - * @dev_num: Slave device number 81 - * @flags: transfer flags, indicate if xfer is read or write 82 - * @buf: message data buffer (filled by host for write, filled 80 + * @buf: section data buffer (filled by host for write, filled 83 81 * by Peripheral hardware for reads) 84 82 */ 85 - struct sdw_bpt_msg { 83 + struct sdw_bpt_section { 86 84 u32 addr; 87 85 u32 len; 86 + u8 *buf; 87 + }; 88 + 89 + /** 90 + * struct sdw_btp_msg - Message structure 91 + * @sec: Pointer to array of sections 92 + * @sections: Number of sections in the array 93 + * @dev_num: Slave device number 94 + * @flags: transfer flags, indicate if xfer is read or write 95 + */ 96 + struct sdw_bpt_msg { 97 + struct sdw_bpt_section *sec; 98 + int sections; 88 99 u8 dev_num; 89 100 u8 flags; 90 - u8 *buf; 91 101 }; 92 102 93 103 #define SDW_DOUBLE_RATE_FACTOR 2
+11 -3
drivers/soundwire/debugfs.c
··· 222 222 static int do_bpt_sequence(struct sdw_slave *slave, bool write, u8 *buffer) 223 223 { 224 224 struct sdw_bpt_msg msg = {0}; 225 + struct sdw_bpt_section *sec; 225 226 226 - msg.addr = start_addr; 227 - msg.len = num_bytes; 227 + sec = kcalloc(1, sizeof(*sec), GFP_KERNEL); 228 + if (!sec) 229 + return -ENOMEM; 230 + msg.sections = 1; 231 + 232 + sec[0].addr = start_addr; 233 + sec[0].len = num_bytes; 234 + 235 + msg.sec = sec; 228 236 msg.dev_num = slave->dev_num; 229 237 if (write) 230 238 msg.flags = SDW_MSG_FLAG_WRITE; 231 239 else 232 240 msg.flags = SDW_MSG_FLAG_READ; 233 - msg.buf = buffer; 241 + sec[0].buf = buffer; 234 242 235 243 return sdw_bpt_send_sync(slave->bus, slave, &msg); 236 244 }
+13 -9
drivers/soundwire/intel_ace2x.c
··· 156 156 goto deprepare_stream; 157 157 158 158 ret = sdw_cdns_bpt_find_buffer_sizes(command, cdns->bus.params.row, cdns->bus.params.col, 159 - msg->len, SDW_BPT_MSG_MAX_BYTES, &data_per_frame, 160 - &pdi0_buffer_size, &pdi1_buffer_size, &num_frames); 159 + msg->sec[0].len, SDW_BPT_MSG_MAX_BYTES, 160 + &data_per_frame, &pdi0_buffer_size, &pdi1_buffer_size, 161 + &num_frames); 161 162 if (ret < 0) 162 163 goto deprepare_stream; 163 164 ··· 205 204 } 206 205 207 206 dev_dbg(cdns->dev, "Message len %d transferred in %d frames (%d per frame)\n", 208 - msg->len, num_frames, data_per_frame); 207 + msg->sec[0].len, num_frames, data_per_frame); 209 208 dev_dbg(cdns->dev, "sizes pdi0 %d pdi1 %d tx_bandwidth %d rx_bandwidth %d\n", 210 209 pdi0_buffer_size, pdi1_buffer_size, tx_dma_bandwidth, rx_dma_bandwidth); 211 210 ··· 220 219 } 221 220 222 221 if (!command) { 223 - ret = sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->addr, msg->buf, 224 - msg->len, data_per_frame, 222 + ret = sdw_cdns_prepare_write_dma_buffer(msg->dev_num, msg->sec[0].addr, 223 + msg->sec[0].buf, 224 + msg->sec[0].len, data_per_frame, 225 225 sdw->bpt_ctx.dmab_tx_bdl.area, 226 226 pdi0_buffer_size, &tx_total_bytes); 227 227 } else { 228 - ret = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->addr, msg->len, 228 + ret = sdw_cdns_prepare_read_dma_buffer(msg->dev_num, msg->sec[0].addr, 229 + msg->sec[0].len, 229 230 data_per_frame, 230 231 sdw->bpt_ctx.dmab_tx_bdl.area, 231 232 pdi0_buffer_size, &tx_total_bytes, ··· 308 305 struct sdw_cdns *cdns = &sdw->cdns; 309 306 int ret; 310 307 311 - if (msg->len < INTEL_BPT_MSG_BYTE_MIN) { 308 + if (msg->sec[0].len < INTEL_BPT_MSG_BYTE_MIN) { 312 309 dev_err(cdns->dev, "BPT message length %d is less than the minimum bytes %d\n", 313 - msg->len, INTEL_BPT_MSG_BYTE_MIN); 310 + msg->sec[0].len, INTEL_BPT_MSG_BYTE_MIN); 314 311 return -EINVAL; 315 312 } 316 313 ··· 370 367 } else { 371 368 ret = sdw_cdns_check_read_response(cdns->dev, sdw->bpt_ctx.dmab_rx_bdl.area, 372 369 sdw->bpt_ctx.pdi1_buffer_size, 373 - msg->buf, msg->len, sdw->bpt_ctx.num_frames, 370 + msg->sec[0].buf, msg->sec[0].len, 371 + sdw->bpt_ctx.num_frames, 374 372 sdw->bpt_ctx.data_per_frame); 375 373 if (ret < 0) 376 374 dev_err(cdns->dev, "%s: BPT Read failed %d\n", __func__, ret);