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

soundwire: Add MIPI DisCo property helpers

MIPI Discovery And Configuration (DisCo) Specification for SoundWire
specifies properties to be implemented for SoundWire Masters and
Slaves. The DisCo spec doesn't mandate these properties. However,
SDW bus cannot work without knowing these values.

The helper functions read the Master and Slave properties.
Implementers of Master or Slave drivers can use any of the below
three mechanisms:
a) Use these APIs here as .read_prop() callback for Master
and Slave
b) Implement own methods and set those as .read_prop(), but invoke
APIs in this file for generic read and override the values with
platform specific data
c) Implement ones own methods which do not use anything provided
here

Signed-off-by: Sanyog Kale <sanyog.r.kale@intel.com>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Acked-By: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Vinod Koul and committed by
Greg Kroah-Hartman
56d4fe31 7c3cd189

+706 -2
+1 -1
drivers/soundwire/Makefile
··· 3 3 # 4 4 5 5 #Bus Objs 6 - soundwire-bus-objs := bus_type.o bus.o slave.o 6 + soundwire-bus-objs := bus_type.o bus.o slave.o mipi_disco.o 7 7 obj-$(CONFIG_SOUNDWIRE_BUS) += soundwire-bus.o
+8
drivers/soundwire/bus.c
··· 25 25 mutex_init(&bus->bus_lock); 26 26 INIT_LIST_HEAD(&bus->slaves); 27 27 28 + if (bus->ops->read_prop) { 29 + ret = bus->ops->read_prop(bus); 30 + if (ret < 0) { 31 + dev_err(bus->dev, "Bus read properties failed:%d", ret); 32 + return ret; 33 + } 34 + } 35 + 28 36 /* 29 37 * Device numbers in SoundWire are 0 thru 15. Enumeration device 30 38 * number (0), Broadcast device number (15), Group numbers (12 and
+22 -1
drivers/soundwire/bus_type.c
··· 77 77 if (!id) 78 78 return -ENODEV; 79 79 80 + slave->ops = drv->ops; 81 + 80 82 /* 81 83 * attach to power domain but don't turn on (last arg) 82 84 */ ··· 91 89 } 92 90 } 93 91 94 - return ret; 92 + if (ret) 93 + return ret; 94 + 95 + /* device is probed so let's read the properties now */ 96 + if (slave->ops && slave->ops->read_prop) 97 + slave->ops->read_prop(slave); 98 + 99 + /* 100 + * Check for valid clk_stop_timeout, use DisCo worst case value of 101 + * 300ms 102 + * 103 + * TODO: check the timeouts and driver removal case 104 + */ 105 + if (slave->prop.clk_stop_timeout == 0) 106 + slave->prop.clk_stop_timeout = 300; 107 + 108 + slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout, 109 + slave->prop.clk_stop_timeout); 110 + 111 + return 0; 95 112 } 96 113 97 114 static int sdw_drv_remove(struct device *dev)
+401
drivers/soundwire/mipi_disco.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 + // Copyright(c) 2015-17 Intel Corporation. 3 + 4 + /* 5 + * MIPI Discovery And Configuration (DisCo) Specification for SoundWire 6 + * specifies properties to be implemented for SoundWire Masters and Slaves. 7 + * The DisCo spec doesn't mandate these properties. However, SDW bus cannot 8 + * work without knowing these values. 9 + * 10 + * The helper functions read the Master and Slave properties. Implementers 11 + * of Master or Slave drivers can use any of the below three mechanisms: 12 + * a) Use these APIs here as .read_prop() callback for Master and Slave 13 + * b) Implement own methods and set those as .read_prop(), but invoke 14 + * APIs in this file for generic read and override the values with 15 + * platform specific data 16 + * c) Implement ones own methods which do not use anything provided 17 + * here 18 + */ 19 + 20 + #include <linux/device.h> 21 + #include <linux/property.h> 22 + #include <linux/mod_devicetable.h> 23 + #include <linux/soundwire/sdw.h> 24 + #include "bus.h" 25 + 26 + /** 27 + * sdw_master_read_prop() - Read Master properties 28 + * @bus: SDW bus instance 29 + */ 30 + int sdw_master_read_prop(struct sdw_bus *bus) 31 + { 32 + struct sdw_master_prop *prop = &bus->prop; 33 + struct fwnode_handle *link; 34 + char name[32]; 35 + int nval, i; 36 + 37 + device_property_read_u32(bus->dev, 38 + "mipi-sdw-sw-interface-revision", &prop->revision); 39 + 40 + /* Find master handle */ 41 + snprintf(name, sizeof(name), 42 + "mipi-sdw-master-%d-subproperties", bus->link_id); 43 + 44 + link = device_get_named_child_node(bus->dev, name); 45 + if (!link) { 46 + dev_err(bus->dev, "Master node %s not found\n", name); 47 + return -EIO; 48 + } 49 + 50 + if (fwnode_property_read_bool(link, 51 + "mipi-sdw-clock-stop-mode0-supported") == true) 52 + prop->clk_stop_mode = SDW_CLK_STOP_MODE0; 53 + 54 + if (fwnode_property_read_bool(link, 55 + "mipi-sdw-clock-stop-mode1-supported") == true) 56 + prop->clk_stop_mode |= SDW_CLK_STOP_MODE1; 57 + 58 + fwnode_property_read_u32(link, 59 + "mipi-sdw-max-clock-frequency", &prop->max_freq); 60 + 61 + nval = fwnode_property_read_u32_array(link, 62 + "mipi-sdw-clock-frequencies-supported", NULL, 0); 63 + if (nval > 0) { 64 + 65 + prop->num_freq = nval; 66 + prop->freq = devm_kcalloc(bus->dev, prop->num_freq, 67 + sizeof(*prop->freq), GFP_KERNEL); 68 + if (!prop->freq) 69 + return -ENOMEM; 70 + 71 + fwnode_property_read_u32_array(link, 72 + "mipi-sdw-clock-frequencies-supported", 73 + prop->freq, prop->num_freq); 74 + } 75 + 76 + /* 77 + * Check the frequencies supported. If FW doesn't provide max 78 + * freq, then populate here by checking values. 79 + */ 80 + if (!prop->max_freq && prop->freq) { 81 + prop->max_freq = prop->freq[0]; 82 + for (i = 1; i < prop->num_freq; i++) { 83 + if (prop->freq[i] > prop->max_freq) 84 + prop->max_freq = prop->freq[i]; 85 + } 86 + } 87 + 88 + nval = fwnode_property_read_u32_array(link, 89 + "mipi-sdw-supported-clock-gears", NULL, 0); 90 + if (nval > 0) { 91 + 92 + prop->num_clk_gears = nval; 93 + prop->clk_gears = devm_kcalloc(bus->dev, prop->num_clk_gears, 94 + sizeof(*prop->clk_gears), GFP_KERNEL); 95 + if (!prop->clk_gears) 96 + return -ENOMEM; 97 + 98 + fwnode_property_read_u32_array(link, 99 + "mipi-sdw-supported-clock-gears", 100 + prop->clk_gears, prop->num_clk_gears); 101 + } 102 + 103 + fwnode_property_read_u32(link, "mipi-sdw-default-frame-rate", 104 + &prop->default_frame_rate); 105 + 106 + fwnode_property_read_u32(link, "mipi-sdw-default-frame-row-size", 107 + &prop->default_row); 108 + 109 + fwnode_property_read_u32(link, "mipi-sdw-default-frame-col-size", 110 + &prop->default_col); 111 + 112 + prop->dynamic_frame = fwnode_property_read_bool(link, 113 + "mipi-sdw-dynamic-frame-shape"); 114 + 115 + fwnode_property_read_u32(link, "mipi-sdw-command-error-threshold", 116 + &prop->err_threshold); 117 + 118 + return 0; 119 + } 120 + EXPORT_SYMBOL(sdw_master_read_prop); 121 + 122 + static int sdw_slave_read_dp0(struct sdw_slave *slave, 123 + struct fwnode_handle *port, struct sdw_dp0_prop *dp0) 124 + { 125 + int nval; 126 + 127 + fwnode_property_read_u32(port, "mipi-sdw-port-max-wordlength", 128 + &dp0->max_word); 129 + 130 + fwnode_property_read_u32(port, "mipi-sdw-port-min-wordlength", 131 + &dp0->min_word); 132 + 133 + nval = fwnode_property_read_u32_array(port, 134 + "mipi-sdw-port-wordlength-configs", NULL, 0); 135 + if (nval > 0) { 136 + 137 + dp0->num_words = nval; 138 + dp0->words = devm_kcalloc(&slave->dev, 139 + dp0->num_words, sizeof(*dp0->words), 140 + GFP_KERNEL); 141 + if (!dp0->words) 142 + return -ENOMEM; 143 + 144 + fwnode_property_read_u32_array(port, 145 + "mipi-sdw-port-wordlength-configs", 146 + dp0->words, dp0->num_words); 147 + } 148 + 149 + dp0->flow_controlled = fwnode_property_read_bool( 150 + port, "mipi-sdw-bra-flow-controlled"); 151 + 152 + dp0->simple_ch_prep_sm = fwnode_property_read_bool( 153 + port, "mipi-sdw-simplified-channel-prepare-sm"); 154 + 155 + dp0->device_interrupts = fwnode_property_read_bool( 156 + port, "mipi-sdw-imp-def-dp0-interrupts-supported"); 157 + 158 + return 0; 159 + } 160 + 161 + static int sdw_slave_read_dpn(struct sdw_slave *slave, 162 + struct sdw_dpn_prop *dpn, int count, int ports, char *type) 163 + { 164 + struct fwnode_handle *node; 165 + u32 bit, i = 0; 166 + int nval; 167 + unsigned long addr; 168 + char name[40]; 169 + 170 + addr = ports; 171 + /* valid ports are 1 to 14 so apply mask */ 172 + addr &= GENMASK(14, 1); 173 + 174 + for_each_set_bit(bit, &addr, 32) { 175 + snprintf(name, sizeof(name), 176 + "mipi-sdw-dp-%d-%s-subproperties", bit, type); 177 + 178 + dpn[i].num = bit; 179 + 180 + node = device_get_named_child_node(&slave->dev, name); 181 + if (!node) { 182 + dev_err(&slave->dev, "%s dpN not found\n", name); 183 + return -EIO; 184 + } 185 + 186 + fwnode_property_read_u32(node, "mipi-sdw-port-max-wordlength", 187 + &dpn[i].max_word); 188 + fwnode_property_read_u32(node, "mipi-sdw-port-min-wordlength", 189 + &dpn[i].min_word); 190 + 191 + nval = fwnode_property_read_u32_array(node, 192 + "mipi-sdw-port-wordlength-configs", NULL, 0); 193 + if (nval > 0) { 194 + 195 + dpn[i].num_words = nval; 196 + dpn[i].words = devm_kcalloc(&slave->dev, 197 + dpn[i].num_words, 198 + sizeof(*dpn[i].words), GFP_KERNEL); 199 + if (!dpn[i].words) 200 + return -ENOMEM; 201 + 202 + fwnode_property_read_u32_array(node, 203 + "mipi-sdw-port-wordlength-configs", 204 + dpn[i].words, dpn[i].num_words); 205 + } 206 + 207 + fwnode_property_read_u32(node, "mipi-sdw-data-port-type", 208 + &dpn[i].type); 209 + 210 + fwnode_property_read_u32(node, 211 + "mipi-sdw-max-grouping-supported", 212 + &dpn[i].max_grouping); 213 + 214 + dpn[i].simple_ch_prep_sm = fwnode_property_read_bool(node, 215 + "mipi-sdw-simplified-channelprepare-sm"); 216 + 217 + fwnode_property_read_u32(node, 218 + "mipi-sdw-port-channelprepare-timeout", 219 + &dpn[i].ch_prep_timeout); 220 + 221 + fwnode_property_read_u32(node, 222 + "mipi-sdw-imp-def-dpn-interrupts-supported", 223 + &dpn[i].device_interrupts); 224 + 225 + fwnode_property_read_u32(node, "mipi-sdw-min-channel-number", 226 + &dpn[i].min_ch); 227 + 228 + fwnode_property_read_u32(node, "mipi-sdw-max-channel-number", 229 + &dpn[i].max_ch); 230 + 231 + nval = fwnode_property_read_u32_array(node, 232 + "mipi-sdw-channel-number-list", NULL, 0); 233 + if (nval > 0) { 234 + 235 + dpn[i].num_ch = nval; 236 + dpn[i].ch = devm_kcalloc(&slave->dev, dpn[i].num_ch, 237 + sizeof(*dpn[i].ch), GFP_KERNEL); 238 + if (!dpn[i].ch) 239 + return -ENOMEM; 240 + 241 + fwnode_property_read_u32_array(node, 242 + "mipi-sdw-channel-number-list", 243 + dpn[i].ch, dpn[i].num_ch); 244 + } 245 + 246 + nval = fwnode_property_read_u32_array(node, 247 + "mipi-sdw-channel-combination-list", NULL, 0); 248 + if (nval > 0) { 249 + 250 + dpn[i].num_ch_combinations = nval; 251 + dpn[i].ch_combinations = devm_kcalloc(&slave->dev, 252 + dpn[i].num_ch_combinations, 253 + sizeof(*dpn[i].ch_combinations), 254 + GFP_KERNEL); 255 + if (!dpn[i].ch_combinations) 256 + return -ENOMEM; 257 + 258 + fwnode_property_read_u32_array(node, 259 + "mipi-sdw-channel-combination-list", 260 + dpn[i].ch_combinations, 261 + dpn[i].num_ch_combinations); 262 + } 263 + 264 + fwnode_property_read_u32(node, 265 + "mipi-sdw-modes-supported", &dpn[i].modes); 266 + 267 + fwnode_property_read_u32(node, "mipi-sdw-max-async-buffer", 268 + &dpn[i].max_async_buffer); 269 + 270 + dpn[i].block_pack_mode = fwnode_property_read_bool(node, 271 + "mipi-sdw-block-packing-mode"); 272 + 273 + fwnode_property_read_u32(node, "mipi-sdw-port-encoding-type", 274 + &dpn[i].port_encoding); 275 + 276 + /* TODO: Read audio mode */ 277 + 278 + i++; 279 + } 280 + 281 + return 0; 282 + } 283 + 284 + /** 285 + * sdw_slave_read_prop() - Read Slave properties 286 + * @slave: SDW Slave 287 + */ 288 + int sdw_slave_read_prop(struct sdw_slave *slave) 289 + { 290 + struct sdw_slave_prop *prop = &slave->prop; 291 + struct device *dev = &slave->dev; 292 + struct fwnode_handle *port; 293 + int num_of_ports, nval, i, dp0 = 0; 294 + 295 + device_property_read_u32(dev, "mipi-sdw-sw-interface-revision", 296 + &prop->mipi_revision); 297 + 298 + prop->wake_capable = device_property_read_bool(dev, 299 + "mipi-sdw-wake-up-unavailable"); 300 + prop->wake_capable = !prop->wake_capable; 301 + 302 + prop->test_mode_capable = device_property_read_bool(dev, 303 + "mipi-sdw-test-mode-supported"); 304 + 305 + prop->clk_stop_mode1 = false; 306 + if (device_property_read_bool(dev, 307 + "mipi-sdw-clock-stop-mode1-supported")) 308 + prop->clk_stop_mode1 = true; 309 + 310 + prop->simple_clk_stop_capable = device_property_read_bool(dev, 311 + "mipi-sdw-simplified-clockstopprepare-sm-supported"); 312 + 313 + device_property_read_u32(dev, "mipi-sdw-clockstopprepare-timeout", 314 + &prop->clk_stop_timeout); 315 + 316 + device_property_read_u32(dev, "mipi-sdw-slave-channelprepare-timeout", 317 + &prop->ch_prep_timeout); 318 + 319 + device_property_read_u32(dev, 320 + "mipi-sdw-clockstopprepare-hard-reset-behavior", 321 + &prop->reset_behave); 322 + 323 + prop->high_PHY_capable = device_property_read_bool(dev, 324 + "mipi-sdw-highPHY-capable"); 325 + 326 + prop->paging_support = device_property_read_bool(dev, 327 + "mipi-sdw-paging-support"); 328 + 329 + prop->bank_delay_support = device_property_read_bool(dev, 330 + "mipi-sdw-bank-delay-support"); 331 + 332 + device_property_read_u32(dev, 333 + "mipi-sdw-port15-read-behavior", &prop->p15_behave); 334 + 335 + device_property_read_u32(dev, "mipi-sdw-master-count", 336 + &prop->master_count); 337 + 338 + device_property_read_u32(dev, "mipi-sdw-source-port-list", 339 + &prop->source_ports); 340 + 341 + device_property_read_u32(dev, "mipi-sdw-sink-port-list", 342 + &prop->sink_ports); 343 + 344 + /* Read dp0 properties */ 345 + port = device_get_named_child_node(dev, "mipi-sdw-dp-0-subproperties"); 346 + if (!port) { 347 + dev_dbg(dev, "DP0 node not found!!\n"); 348 + } else { 349 + 350 + prop->dp0_prop = devm_kzalloc(&slave->dev, 351 + sizeof(*prop->dp0_prop), GFP_KERNEL); 352 + if (!prop->dp0_prop) 353 + return -ENOMEM; 354 + 355 + sdw_slave_read_dp0(slave, port, prop->dp0_prop); 356 + dp0 = 1; 357 + } 358 + 359 + /* 360 + * Based on each DPn port, get source and sink dpn properties. 361 + * Also, some ports can operate as both source or sink. 362 + */ 363 + 364 + /* Allocate memory for set bits in port lists */ 365 + nval = hweight32(prop->source_ports); 366 + prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 367 + sizeof(*prop->src_dpn_prop), GFP_KERNEL); 368 + if (!prop->src_dpn_prop) 369 + return -ENOMEM; 370 + 371 + /* Read dpn properties for source port(s) */ 372 + sdw_slave_read_dpn(slave, prop->src_dpn_prop, nval, 373 + prop->source_ports, "source"); 374 + 375 + nval = hweight32(prop->sink_ports); 376 + prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, 377 + sizeof(*prop->sink_dpn_prop), GFP_KERNEL); 378 + if (!prop->sink_dpn_prop) 379 + return -ENOMEM; 380 + 381 + /* Read dpn properties for sink port(s) */ 382 + sdw_slave_read_dpn(slave, prop->sink_dpn_prop, nval, 383 + prop->sink_ports, "sink"); 384 + 385 + /* some ports are bidirectional so check total ports by ORing */ 386 + nval = prop->source_ports | prop->sink_ports; 387 + num_of_ports = hweight32(nval) + dp0; /* add DP0 */ 388 + 389 + /* Allocate port_ready based on num_of_ports */ 390 + slave->port_ready = devm_kcalloc(&slave->dev, num_of_ports, 391 + sizeof(*slave->port_ready), GFP_KERNEL); 392 + if (!slave->port_ready) 393 + return -ENOMEM; 394 + 395 + /* Initialize completion */ 396 + for (i = 0; i < num_of_ports; i++) 397 + init_completion(&slave->port_ready[i]); 398 + 399 + return 0; 400 + } 401 + EXPORT_SYMBOL(sdw_slave_read_prop);
+274
include/linux/soundwire/sdw.h
··· 39 39 }; 40 40 41 41 /* 42 + * SDW properties, defined in MIPI DisCo spec v1.0 43 + */ 44 + enum sdw_clk_stop_reset_behave { 45 + SDW_CLK_STOP_KEEP_STATUS = 1, 46 + }; 47 + 48 + /** 49 + * enum sdw_p15_behave - Slave Port 15 behaviour when the Master attempts a 50 + * read 51 + * @SDW_P15_READ_IGNORED: Read is ignored 52 + * @SDW_P15_CMD_OK: Command is ok 53 + */ 54 + enum sdw_p15_behave { 55 + SDW_P15_READ_IGNORED = 0, 56 + SDW_P15_CMD_OK = 1, 57 + }; 58 + 59 + /** 60 + * enum sdw_dpn_type - Data port types 61 + * @SDW_DPN_FULL: Full Data Port is supported 62 + * @SDW_DPN_SIMPLE: Simplified Data Port as defined in spec. 63 + * DPN_SampleCtrl2, DPN_OffsetCtrl2, DPN_HCtrl and DPN_BlockCtrl3 64 + * are not implemented. 65 + * @SDW_DPN_REDUCED: Reduced Data Port as defined in spec. 66 + * DPN_SampleCtrl2, DPN_HCtrl are not implemented. 67 + */ 68 + enum sdw_dpn_type { 69 + SDW_DPN_FULL = 0, 70 + SDW_DPN_SIMPLE = 1, 71 + SDW_DPN_REDUCED = 2, 72 + }; 73 + 74 + /** 75 + * enum sdw_clk_stop_mode - Clock Stop modes 76 + * @SDW_CLK_STOP_MODE0: Slave can continue operation seamlessly on clock 77 + * restart 78 + * @SDW_CLK_STOP_MODE1: Slave may have entered a deeper power-saving mode, 79 + * not capable of continuing operation seamlessly when the clock restarts 80 + */ 81 + enum sdw_clk_stop_mode { 82 + SDW_CLK_STOP_MODE0 = 0, 83 + SDW_CLK_STOP_MODE1 = 1, 84 + }; 85 + 86 + /** 87 + * struct sdw_dp0_prop - DP0 properties 88 + * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64 89 + * (inclusive) 90 + * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64 91 + * (inclusive) 92 + * @num_words: number of wordlengths supported 93 + * @words: wordlengths supported 94 + * @flow_controlled: Slave implementation results in an OK_NotReady 95 + * response 96 + * @simple_ch_prep_sm: If channel prepare sequence is required 97 + * @device_interrupts: If implementation-defined interrupts are supported 98 + * 99 + * The wordlengths are specified by Spec as max, min AND number of 100 + * discrete values, implementation can define based on the wordlengths they 101 + * support 102 + */ 103 + struct sdw_dp0_prop { 104 + u32 max_word; 105 + u32 min_word; 106 + u32 num_words; 107 + u32 *words; 108 + bool flow_controlled; 109 + bool simple_ch_prep_sm; 110 + bool device_interrupts; 111 + }; 112 + 113 + /** 114 + * struct sdw_dpn_audio_mode - Audio mode properties for DPn 115 + * @bus_min_freq: Minimum bus frequency, in Hz 116 + * @bus_max_freq: Maximum bus frequency, in Hz 117 + * @bus_num_freq: Number of discrete frequencies supported 118 + * @bus_freq: Discrete bus frequencies, in Hz 119 + * @min_freq: Minimum sampling frequency, in Hz 120 + * @max_freq: Maximum sampling bus frequency, in Hz 121 + * @num_freq: Number of discrete sampling frequency supported 122 + * @freq: Discrete sampling frequencies, in Hz 123 + * @prep_ch_behave: Specifies the dependencies between Channel Prepare 124 + * sequence and bus clock configuration 125 + * If 0, Channel Prepare can happen at any Bus clock rate 126 + * If 1, Channel Prepare sequence shall happen only after Bus clock is 127 + * changed to a frequency supported by this mode or compatible modes 128 + * described by the next field 129 + * @glitchless: Bitmap describing possible glitchless transitions from this 130 + * Audio Mode to other Audio Modes 131 + */ 132 + struct sdw_dpn_audio_mode { 133 + u32 bus_min_freq; 134 + u32 bus_max_freq; 135 + u32 bus_num_freq; 136 + u32 *bus_freq; 137 + u32 max_freq; 138 + u32 min_freq; 139 + u32 num_freq; 140 + u32 *freq; 141 + u32 prep_ch_behave; 142 + u32 glitchless; 143 + }; 144 + 145 + /** 146 + * struct sdw_dpn_prop - Data Port DPn properties 147 + * @num: port number 148 + * @max_word: Maximum number of bits in a Payload Channel Sample, 1 to 64 149 + * (inclusive) 150 + * @min_word: Minimum number of bits in a Payload Channel Sample, 1 to 64 151 + * (inclusive) 152 + * @num_words: Number of discrete supported wordlengths 153 + * @words: Discrete supported wordlength 154 + * @type: Data port type. Full, Simplified or Reduced 155 + * @max_grouping: Maximum number of samples that can be grouped together for 156 + * a full data port 157 + * @simple_ch_prep_sm: If the port supports simplified channel prepare state 158 + * machine 159 + * @ch_prep_timeout: Port-specific timeout value, in milliseconds 160 + * @device_interrupts: If set, each bit corresponds to support for 161 + * implementation-defined interrupts 162 + * @max_ch: Maximum channels supported 163 + * @min_ch: Minimum channels supported 164 + * @num_ch: Number of discrete channels supported 165 + * @ch: Discrete channels supported 166 + * @num_ch_combinations: Number of channel combinations supported 167 + * @ch_combinations: Channel combinations supported 168 + * @modes: SDW mode supported 169 + * @max_async_buffer: Number of samples that this port can buffer in 170 + * asynchronous modes 171 + * @block_pack_mode: Type of block port mode supported 172 + * @port_encoding: Payload Channel Sample encoding schemes supported 173 + * @audio_modes: Audio modes supported 174 + */ 175 + struct sdw_dpn_prop { 176 + u32 num; 177 + u32 max_word; 178 + u32 min_word; 179 + u32 num_words; 180 + u32 *words; 181 + enum sdw_dpn_type type; 182 + u32 max_grouping; 183 + bool simple_ch_prep_sm; 184 + u32 ch_prep_timeout; 185 + u32 device_interrupts; 186 + u32 max_ch; 187 + u32 min_ch; 188 + u32 num_ch; 189 + u32 *ch; 190 + u32 num_ch_combinations; 191 + u32 *ch_combinations; 192 + u32 modes; 193 + u32 max_async_buffer; 194 + bool block_pack_mode; 195 + u32 port_encoding; 196 + struct sdw_dpn_audio_mode *audio_modes; 197 + }; 198 + 199 + /** 200 + * struct sdw_slave_prop - SoundWire Slave properties 201 + * @mipi_revision: Spec version of the implementation 202 + * @wake_capable: Wake-up events are supported 203 + * @test_mode_capable: If test mode is supported 204 + * @clk_stop_mode1: Clock-Stop Mode 1 is supported 205 + * @simple_clk_stop_capable: Simple clock mode is supported 206 + * @clk_stop_timeout: Worst-case latency of the Clock Stop Prepare State 207 + * Machine transitions, in milliseconds 208 + * @ch_prep_timeout: Worst-case latency of the Channel Prepare State Machine 209 + * transitions, in milliseconds 210 + * @reset_behave: Slave keeps the status of the SlaveStopClockPrepare 211 + * state machine (P=1 SCSP_SM) after exit from clock-stop mode1 212 + * @high_PHY_capable: Slave is HighPHY capable 213 + * @paging_support: Slave implements paging registers SCP_AddrPage1 and 214 + * SCP_AddrPage2 215 + * @bank_delay_support: Slave implements bank delay/bridge support registers 216 + * SCP_BankDelay and SCP_NextFrame 217 + * @p15_behave: Slave behavior when the Master attempts a read to the Port15 218 + * alias 219 + * @lane_control_support: Slave supports lane control 220 + * @master_count: Number of Masters present on this Slave 221 + * @source_ports: Bitmap identifying source ports 222 + * @sink_ports: Bitmap identifying sink ports 223 + * @dp0_prop: Data Port 0 properties 224 + * @src_dpn_prop: Source Data Port N properties 225 + * @sink_dpn_prop: Sink Data Port N properties 226 + */ 227 + struct sdw_slave_prop { 228 + u32 mipi_revision; 229 + bool wake_capable; 230 + bool test_mode_capable; 231 + bool clk_stop_mode1; 232 + bool simple_clk_stop_capable; 233 + u32 clk_stop_timeout; 234 + u32 ch_prep_timeout; 235 + enum sdw_clk_stop_reset_behave reset_behave; 236 + bool high_PHY_capable; 237 + bool paging_support; 238 + bool bank_delay_support; 239 + enum sdw_p15_behave p15_behave; 240 + bool lane_control_support; 241 + u32 master_count; 242 + u32 source_ports; 243 + u32 sink_ports; 244 + struct sdw_dp0_prop *dp0_prop; 245 + struct sdw_dpn_prop *src_dpn_prop; 246 + struct sdw_dpn_prop *sink_dpn_prop; 247 + }; 248 + 249 + /** 250 + * struct sdw_master_prop - Master properties 251 + * @revision: MIPI spec version of the implementation 252 + * @master_count: Number of masters 253 + * @clk_stop_mode: Bitmap for Clock Stop modes supported 254 + * @max_freq: Maximum Bus clock frequency, in Hz 255 + * @num_clk_gears: Number of clock gears supported 256 + * @clk_gears: Clock gears supported 257 + * @num_freq: Number of clock frequencies supported, in Hz 258 + * @freq: Clock frequencies supported, in Hz 259 + * @default_frame_rate: Controller default Frame rate, in Hz 260 + * @default_row: Number of rows 261 + * @default_col: Number of columns 262 + * @dynamic_frame: Dynamic frame supported 263 + * @err_threshold: Number of times that software may retry sending a single 264 + * command 265 + * @dpn_prop: Data Port N properties 266 + */ 267 + struct sdw_master_prop { 268 + u32 revision; 269 + u32 master_count; 270 + enum sdw_clk_stop_mode clk_stop_mode; 271 + u32 max_freq; 272 + u32 num_clk_gears; 273 + u32 *clk_gears; 274 + u32 num_freq; 275 + u32 *freq; 276 + u32 default_frame_rate; 277 + u32 default_row; 278 + u32 default_col; 279 + bool dynamic_frame; 280 + u32 err_threshold; 281 + struct sdw_dpn_prop *dpn_prop; 282 + }; 283 + 284 + int sdw_master_read_prop(struct sdw_bus *bus); 285 + int sdw_slave_read_prop(struct sdw_slave *slave); 286 + 287 + /* 42 288 * SDW Slave Structures and APIs 43 289 */ 44 290 ··· 308 62 }; 309 63 310 64 /** 65 + * struct sdw_slave_ops - Slave driver callback ops 66 + * @read_prop: Read Slave properties 67 + */ 68 + struct sdw_slave_ops { 69 + int (*read_prop)(struct sdw_slave *sdw); 70 + }; 71 + 72 + /** 311 73 * struct sdw_slave - SoundWire Slave 312 74 * @id: MIPI device ID 313 75 * @dev: Linux device 314 76 * @status: Status reported by the Slave 315 77 * @bus: Bus handle 78 + * @ops: Slave callback ops 79 + * @prop: Slave properties 316 80 * @node: node for bus list 81 + * @port_ready: Port ready completion flag for each Slave port 317 82 * @dev_num: Device Number assigned by Bus 318 83 */ 319 84 struct sdw_slave { ··· 332 75 struct device dev; 333 76 enum sdw_slave_status status; 334 77 struct sdw_bus *bus; 78 + const struct sdw_slave_ops *ops; 79 + struct sdw_slave_prop prop; 335 80 struct list_head node; 81 + struct completion *port_ready; 336 82 u16 dev_num; 337 83 }; 338 84 ··· 364 104 */ 365 105 366 106 /** 107 + * struct sdw_master_ops - Master driver ops 108 + * @read_prop: Read Master properties 109 + */ 110 + struct sdw_master_ops { 111 + int (*read_prop)(struct sdw_bus *bus); 112 + }; 113 + 114 + /** 367 115 * struct sdw_bus - SoundWire bus 368 116 * @dev: Master linux device 369 117 * @link_id: Link id number, can be 0 to N, unique for each Master ··· 379 111 * @assigned: Bitmap for Slave device numbers. 380 112 * Bit set implies used number, bit clear implies unused number. 381 113 * @bus_lock: bus lock 114 + * @ops: Master callback ops 115 + * @prop: Master properties 116 + * @clk_stop_timeout: Clock stop timeout computed 382 117 */ 383 118 struct sdw_bus { 384 119 struct device *dev; ··· 389 118 struct list_head slaves; 390 119 DECLARE_BITMAP(assigned, SDW_MAX_DEVICES); 391 120 struct mutex bus_lock; 121 + const struct sdw_master_ops *ops; 122 + struct sdw_master_prop prop; 123 + unsigned int clk_stop_timeout; 392 124 }; 393 125 394 126 int sdw_add_bus_master(struct sdw_bus *bus);