soundwire: Add Master and Slave port programming
[linux-block.git] / drivers / soundwire / stream.c
CommitLineData
89e59053
SK
1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2// Copyright(c) 2015-18 Intel Corporation.
3
4/*
5 * stream.c - SoundWire Bus stream operations.
6 */
7
8#include <linux/delay.h>
9#include <linux/device.h>
10#include <linux/init.h>
11#include <linux/module.h>
12#include <linux/mod_devicetable.h>
13#include <linux/slab.h>
f8101c74 14#include <linux/soundwire/sdw_registers.h>
89e59053
SK
15#include <linux/soundwire/sdw.h>
16#include "bus.h"
17
f8101c74
SK
18static int _sdw_program_slave_port_params(struct sdw_bus *bus,
19 struct sdw_slave *slave,
20 struct sdw_transport_params *t_params,
21 enum sdw_dpn_type type)
22{
23 u32 addr1, addr2, addr3, addr4;
24 int ret;
25 u16 wbuf;
26
27 if (bus->params.next_bank) {
28 addr1 = SDW_DPN_OFFSETCTRL2_B1(t_params->port_num);
29 addr2 = SDW_DPN_BLOCKCTRL3_B1(t_params->port_num);
30 addr3 = SDW_DPN_SAMPLECTRL2_B1(t_params->port_num);
31 addr4 = SDW_DPN_HCTRL_B1(t_params->port_num);
32 } else {
33 addr1 = SDW_DPN_OFFSETCTRL2_B0(t_params->port_num);
34 addr2 = SDW_DPN_BLOCKCTRL3_B0(t_params->port_num);
35 addr3 = SDW_DPN_SAMPLECTRL2_B0(t_params->port_num);
36 addr4 = SDW_DPN_HCTRL_B0(t_params->port_num);
37 }
38
39 /* Program DPN_OffsetCtrl2 registers */
40 ret = sdw_write(slave, addr1, t_params->offset2);
41 if (ret < 0) {
42 dev_err(bus->dev, "DPN_OffsetCtrl2 register write failed");
43 return ret;
44 }
45
46 /* Program DPN_BlockCtrl3 register */
47 ret = sdw_write(slave, addr2, t_params->blk_pkg_mode);
48 if (ret < 0) {
49 dev_err(bus->dev, "DPN_BlockCtrl3 register write failed");
50 return ret;
51 }
52
53 /*
54 * Data ports are FULL, SIMPLE and REDUCED. This function handles
55 * FULL and REDUCED only and and beyond this point only FULL is
56 * handled, so bail out if we are not FULL data port type
57 */
58 if (type != SDW_DPN_FULL)
59 return ret;
60
61 /* Program DPN_SampleCtrl2 register */
62 wbuf = (t_params->sample_interval - 1);
63 wbuf &= SDW_DPN_SAMPLECTRL_HIGH;
64 wbuf >>= SDW_REG_SHIFT(SDW_DPN_SAMPLECTRL_HIGH);
65
66 ret = sdw_write(slave, addr3, wbuf);
67 if (ret < 0) {
68 dev_err(bus->dev, "DPN_SampleCtrl2 register write failed");
69 return ret;
70 }
71
72 /* Program DPN_HCtrl register */
73 wbuf = t_params->hstart;
74 wbuf <<= SDW_REG_SHIFT(SDW_DPN_HCTRL_HSTART);
75 wbuf |= t_params->hstop;
76
77 ret = sdw_write(slave, addr4, wbuf);
78 if (ret < 0)
79 dev_err(bus->dev, "DPN_HCtrl register write failed");
80
81 return ret;
82}
83
84static int sdw_program_slave_port_params(struct sdw_bus *bus,
85 struct sdw_slave_runtime *s_rt,
86 struct sdw_port_runtime *p_rt)
87{
88 struct sdw_transport_params *t_params = &p_rt->transport_params;
89 struct sdw_port_params *p_params = &p_rt->port_params;
90 struct sdw_slave_prop *slave_prop = &s_rt->slave->prop;
91 u32 addr1, addr2, addr3, addr4, addr5, addr6;
92 struct sdw_dpn_prop *dpn_prop;
93 int ret;
94 u8 wbuf;
95
96 dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
97 s_rt->direction,
98 t_params->port_num);
99 if (!dpn_prop)
100 return -EINVAL;
101
102 addr1 = SDW_DPN_PORTCTRL(t_params->port_num);
103 addr2 = SDW_DPN_BLOCKCTRL1(t_params->port_num);
104
105 if (bus->params.next_bank) {
106 addr3 = SDW_DPN_SAMPLECTRL1_B1(t_params->port_num);
107 addr4 = SDW_DPN_OFFSETCTRL1_B1(t_params->port_num);
108 addr5 = SDW_DPN_BLOCKCTRL2_B1(t_params->port_num);
109 addr6 = SDW_DPN_LANECTRL_B1(t_params->port_num);
110
111 } else {
112 addr3 = SDW_DPN_SAMPLECTRL1_B0(t_params->port_num);
113 addr4 = SDW_DPN_OFFSETCTRL1_B0(t_params->port_num);
114 addr5 = SDW_DPN_BLOCKCTRL2_B0(t_params->port_num);
115 addr6 = SDW_DPN_LANECTRL_B0(t_params->port_num);
116 }
117
118 /* Program DPN_PortCtrl register */
119 wbuf = p_params->data_mode << SDW_REG_SHIFT(SDW_DPN_PORTCTRL_DATAMODE);
120 wbuf |= p_params->flow_mode;
121
122 ret = sdw_update(s_rt->slave, addr1, 0xF, wbuf);
123 if (ret < 0) {
124 dev_err(&s_rt->slave->dev,
125 "DPN_PortCtrl register write failed for port %d",
126 t_params->port_num);
127 return ret;
128 }
129
130 /* Program DPN_BlockCtrl1 register */
131 ret = sdw_write(s_rt->slave, addr2, (p_params->bps - 1));
132 if (ret < 0) {
133 dev_err(&s_rt->slave->dev,
134 "DPN_BlockCtrl1 register write failed for port %d",
135 t_params->port_num);
136 return ret;
137 }
138
139 /* Program DPN_SampleCtrl1 register */
140 wbuf = (t_params->sample_interval - 1) & SDW_DPN_SAMPLECTRL_LOW;
141 ret = sdw_write(s_rt->slave, addr3, wbuf);
142 if (ret < 0) {
143 dev_err(&s_rt->slave->dev,
144 "DPN_SampleCtrl1 register write failed for port %d",
145 t_params->port_num);
146 return ret;
147 }
148
149 /* Program DPN_OffsetCtrl1 registers */
150 ret = sdw_write(s_rt->slave, addr4, t_params->offset1);
151 if (ret < 0) {
152 dev_err(&s_rt->slave->dev,
153 "DPN_OffsetCtrl1 register write failed for port %d",
154 t_params->port_num);
155 return ret;
156 }
157
158 /* Program DPN_BlockCtrl2 register*/
159 if (t_params->blk_grp_ctrl_valid) {
160 ret = sdw_write(s_rt->slave, addr5, t_params->blk_grp_ctrl);
161 if (ret < 0) {
162 dev_err(&s_rt->slave->dev,
163 "DPN_BlockCtrl2 reg write failed for port %d",
164 t_params->port_num);
165 return ret;
166 }
167 }
168
169 /* program DPN_LaneCtrl register */
170 if (slave_prop->lane_control_support) {
171 ret = sdw_write(s_rt->slave, addr6, t_params->lane_ctrl);
172 if (ret < 0) {
173 dev_err(&s_rt->slave->dev,
174 "DPN_LaneCtrl register write failed for port %d",
175 t_params->port_num);
176 return ret;
177 }
178 }
179
180 if (dpn_prop->type != SDW_DPN_SIMPLE) {
181 ret = _sdw_program_slave_port_params(bus, s_rt->slave,
182 t_params, dpn_prop->type);
183 if (ret < 0)
184 dev_err(&s_rt->slave->dev,
185 "Transport reg write failed for port: %d",
186 t_params->port_num);
187 }
188
189 return ret;
190}
191
192static int sdw_program_master_port_params(struct sdw_bus *bus,
193 struct sdw_port_runtime *p_rt)
194{
195 int ret;
196
197 /*
198 * we need to set transport and port parameters for the port.
199 * Transport parameters refers to the smaple interval, offsets and
200 * hstart/stop etc of the data. Port parameters refers to word
201 * length, flow mode etc of the port
202 */
203 ret = bus->port_ops->dpn_set_port_transport_params(bus,
204 &p_rt->transport_params,
205 bus->params.next_bank);
206 if (ret < 0)
207 return ret;
208
209 return bus->port_ops->dpn_set_port_params(bus,
210 &p_rt->port_params,
211 bus->params.next_bank);
212}
213
214/**
215 * sdw_program_port_params() - Programs transport parameters of Master(s)
216 * and Slave(s)
217 *
218 * @m_rt: Master stream runtime
219 */
220static int sdw_program_port_params(struct sdw_master_runtime *m_rt)
221{
222 struct sdw_slave_runtime *s_rt = NULL;
223 struct sdw_bus *bus = m_rt->bus;
224 struct sdw_port_runtime *p_rt;
225 int ret = 0;
226
227 /* Program transport & port parameters for Slave(s) */
228 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
229 list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
230 ret = sdw_program_slave_port_params(bus, s_rt, p_rt);
231 if (ret < 0)
232 return ret;
233 }
234 }
235
236 /* Program transport & port parameters for Master(s) */
237 list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
238 ret = sdw_program_master_port_params(bus, p_rt);
239 if (ret < 0)
240 return ret;
241 }
242
243 return 0;
244}
245
89e59053
SK
246/**
247 * sdw_release_stream() - Free the assigned stream runtime
248 *
249 * @stream: SoundWire stream runtime
250 *
251 * sdw_release_stream should be called only once per stream
252 */
253void sdw_release_stream(struct sdw_stream_runtime *stream)
254{
255 kfree(stream);
256}
257EXPORT_SYMBOL(sdw_release_stream);
258
259/**
260 * sdw_alloc_stream() - Allocate and return stream runtime
261 *
262 * @stream_name: SoundWire stream name
263 *
264 * Allocates a SoundWire stream runtime instance.
265 * sdw_alloc_stream should be called only once per stream. Typically
266 * invoked from ALSA/ASoC machine/platform driver.
267 */
268struct sdw_stream_runtime *sdw_alloc_stream(char *stream_name)
269{
270 struct sdw_stream_runtime *stream;
271
272 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
273 if (!stream)
274 return NULL;
275
276 stream->name = stream_name;
277 stream->state = SDW_STREAM_ALLOCATED;
278
279 return stream;
280}
281EXPORT_SYMBOL(sdw_alloc_stream);
282
283/**
284 * sdw_alloc_master_rt() - Allocates and initialize Master runtime handle
285 *
286 * @bus: SDW bus instance
287 * @stream_config: Stream configuration
288 * @stream: Stream runtime handle.
289 *
290 * This function is to be called with bus_lock held.
291 */
292static struct sdw_master_runtime
293*sdw_alloc_master_rt(struct sdw_bus *bus,
294 struct sdw_stream_config *stream_config,
295 struct sdw_stream_runtime *stream)
296{
297 struct sdw_master_runtime *m_rt;
298
299 m_rt = stream->m_rt;
300
301 /*
302 * check if Master is already allocated (as a result of Slave adding
303 * it first), if so skip allocation and go to configure
304 */
305 if (m_rt)
306 goto stream_config;
307
308 m_rt = kzalloc(sizeof(*m_rt), GFP_KERNEL);
309 if (!m_rt)
310 return NULL;
311
312 /* Initialization of Master runtime handle */
bbe7379d 313 INIT_LIST_HEAD(&m_rt->port_list);
89e59053
SK
314 INIT_LIST_HEAD(&m_rt->slave_rt_list);
315 stream->m_rt = m_rt;
316
317 list_add_tail(&m_rt->bus_node, &bus->m_rt_list);
318
319stream_config:
320 m_rt->ch_count = stream_config->ch_count;
321 m_rt->bus = bus;
322 m_rt->stream = stream;
323 m_rt->direction = stream_config->direction;
324
325 return m_rt;
326}
327
328/**
329 * sdw_alloc_slave_rt() - Allocate and initialize Slave runtime handle.
330 *
331 * @slave: Slave handle
332 * @stream_config: Stream configuration
333 * @stream: Stream runtime handle
334 *
335 * This function is to be called with bus_lock held.
336 */
337static struct sdw_slave_runtime
338*sdw_alloc_slave_rt(struct sdw_slave *slave,
339 struct sdw_stream_config *stream_config,
340 struct sdw_stream_runtime *stream)
341{
342 struct sdw_slave_runtime *s_rt = NULL;
343
344 s_rt = kzalloc(sizeof(*s_rt), GFP_KERNEL);
345 if (!s_rt)
346 return NULL;
347
bbe7379d 348 INIT_LIST_HEAD(&s_rt->port_list);
89e59053
SK
349 s_rt->ch_count = stream_config->ch_count;
350 s_rt->direction = stream_config->direction;
351 s_rt->slave = slave;
352
353 return s_rt;
354}
355
bbe7379d
SK
356static void sdw_master_port_release(struct sdw_bus *bus,
357 struct sdw_master_runtime *m_rt)
358{
359 struct sdw_port_runtime *p_rt, *_p_rt;
360
361 list_for_each_entry_safe(p_rt, _p_rt,
362 &m_rt->port_list, port_node) {
363 list_del(&p_rt->port_node);
364 kfree(p_rt);
365 }
366}
367
368static void sdw_slave_port_release(struct sdw_bus *bus,
369 struct sdw_slave *slave,
370 struct sdw_stream_runtime *stream)
371{
372 struct sdw_port_runtime *p_rt, *_p_rt;
373 struct sdw_master_runtime *m_rt = stream->m_rt;
374 struct sdw_slave_runtime *s_rt;
375
376 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
377 if (s_rt->slave != slave)
378 continue;
379
380 list_for_each_entry_safe(p_rt, _p_rt,
381 &s_rt->port_list, port_node) {
382 list_del(&p_rt->port_node);
383 kfree(p_rt);
384 }
385 }
386}
387
89e59053
SK
388/**
389 * sdw_release_slave_stream() - Free Slave(s) runtime handle
390 *
391 * @slave: Slave handle.
392 * @stream: Stream runtime handle.
393 *
394 * This function is to be called with bus_lock held.
395 */
396static void sdw_release_slave_stream(struct sdw_slave *slave,
397 struct sdw_stream_runtime *stream)
398{
399 struct sdw_slave_runtime *s_rt, *_s_rt;
400 struct sdw_master_runtime *m_rt = stream->m_rt;
401
402 /* Retrieve Slave runtime handle */
403 list_for_each_entry_safe(s_rt, _s_rt,
404 &m_rt->slave_rt_list, m_rt_node) {
405
406 if (s_rt->slave == slave) {
407 list_del(&s_rt->m_rt_node);
408 kfree(s_rt);
409 return;
410 }
411 }
412}
413
414/**
415 * sdw_release_master_stream() - Free Master runtime handle
416 *
417 * @stream: Stream runtime handle.
418 *
419 * This function is to be called with bus_lock held
420 * It frees the Master runtime handle and associated Slave(s) runtime
421 * handle. If this is called first then sdw_release_slave_stream() will have
422 * no effect as Slave(s) runtime handle would already be freed up.
423 */
424static void sdw_release_master_stream(struct sdw_stream_runtime *stream)
425{
426 struct sdw_master_runtime *m_rt = stream->m_rt;
427 struct sdw_slave_runtime *s_rt, *_s_rt;
428
429 list_for_each_entry_safe(s_rt, _s_rt,
430 &m_rt->slave_rt_list, m_rt_node)
431 sdw_stream_remove_slave(s_rt->slave, stream);
432
433 list_del(&m_rt->bus_node);
434}
435
436/**
437 * sdw_stream_remove_master() - Remove master from sdw_stream
438 *
439 * @bus: SDW Bus instance
440 * @stream: SoundWire stream
441 *
bbe7379d 442 * This removes and frees port_rt and master_rt from a stream
89e59053
SK
443 */
444int sdw_stream_remove_master(struct sdw_bus *bus,
445 struct sdw_stream_runtime *stream)
446{
447 mutex_lock(&bus->bus_lock);
448
449 sdw_release_master_stream(stream);
bbe7379d 450 sdw_master_port_release(bus, stream->m_rt);
89e59053
SK
451 stream->state = SDW_STREAM_RELEASED;
452 kfree(stream->m_rt);
453 stream->m_rt = NULL;
454
455 mutex_unlock(&bus->bus_lock);
456
457 return 0;
458}
459EXPORT_SYMBOL(sdw_stream_remove_master);
460
461/**
462 * sdw_stream_remove_slave() - Remove slave from sdw_stream
463 *
464 * @slave: SDW Slave instance
465 * @stream: SoundWire stream
466 *
bbe7379d 467 * This removes and frees port_rt and slave_rt from a stream
89e59053
SK
468 */
469int sdw_stream_remove_slave(struct sdw_slave *slave,
470 struct sdw_stream_runtime *stream)
471{
472 mutex_lock(&slave->bus->bus_lock);
473
bbe7379d 474 sdw_slave_port_release(slave->bus, slave, stream);
89e59053
SK
475 sdw_release_slave_stream(slave, stream);
476
477 mutex_unlock(&slave->bus->bus_lock);
478
479 return 0;
480}
481EXPORT_SYMBOL(sdw_stream_remove_slave);
482
483/**
484 * sdw_config_stream() - Configure the allocated stream
485 *
486 * @dev: SDW device
487 * @stream: SoundWire stream
488 * @stream_config: Stream configuration for audio stream
489 * @is_slave: is API called from Slave or Master
490 *
491 * This function is to be called with bus_lock held.
492 */
493static int sdw_config_stream(struct device *dev,
494 struct sdw_stream_runtime *stream,
495 struct sdw_stream_config *stream_config, bool is_slave)
496{
497 /*
498 * Update the stream rate, channel and bps based on data
499 * source. For more than one data source (multilink),
500 * match the rate, bps, stream type and increment number of channels.
501 *
502 * If rate/bps is zero, it means the values are not set, so skip
503 * comparison and allow the value to be set and stored in stream
504 */
505 if (stream->params.rate &&
506 stream->params.rate != stream_config->frame_rate) {
507 dev_err(dev, "rate not matching, stream:%s", stream->name);
508 return -EINVAL;
509 }
510
511 if (stream->params.bps &&
512 stream->params.bps != stream_config->bps) {
513 dev_err(dev, "bps not matching, stream:%s", stream->name);
514 return -EINVAL;
515 }
516
517 stream->type = stream_config->type;
518 stream->params.rate = stream_config->frame_rate;
519 stream->params.bps = stream_config->bps;
520
521 /* TODO: Update this check during Device-device support */
522 if (is_slave)
523 stream->params.ch_count += stream_config->ch_count;
524
525 return 0;
526}
527
bbe7379d
SK
528static int sdw_is_valid_port_range(struct device *dev,
529 struct sdw_port_runtime *p_rt)
530{
531 if (!SDW_VALID_PORT_RANGE(p_rt->num)) {
532 dev_err(dev,
533 "SoundWire: Invalid port number :%d", p_rt->num);
534 return -EINVAL;
535 }
536
537 return 0;
538}
539
540static struct sdw_port_runtime *sdw_port_alloc(struct device *dev,
541 struct sdw_port_config *port_config,
542 int port_index)
543{
544 struct sdw_port_runtime *p_rt;
545
546 p_rt = kzalloc(sizeof(*p_rt), GFP_KERNEL);
547 if (!p_rt)
548 return NULL;
549
550 p_rt->ch_mask = port_config[port_index].ch_mask;
551 p_rt->num = port_config[port_index].num;
552
553 return p_rt;
554}
555
556static int sdw_master_port_config(struct sdw_bus *bus,
557 struct sdw_master_runtime *m_rt,
558 struct sdw_port_config *port_config,
559 unsigned int num_ports)
560{
561 struct sdw_port_runtime *p_rt;
562 int i;
563
564 /* Iterate for number of ports to perform initialization */
565 for (i = 0; i < num_ports; i++) {
566 p_rt = sdw_port_alloc(bus->dev, port_config, i);
567 if (!p_rt)
568 return -ENOMEM;
569
570 /*
571 * TODO: Check port capabilities for requested
572 * configuration (audio mode support)
573 */
574
575 list_add_tail(&p_rt->port_node, &m_rt->port_list);
576 }
577
578 return 0;
579}
580
581static int sdw_slave_port_config(struct sdw_slave *slave,
582 struct sdw_slave_runtime *s_rt,
583 struct sdw_port_config *port_config,
584 unsigned int num_config)
585{
586 struct sdw_port_runtime *p_rt;
587 int i, ret;
588
589 /* Iterate for number of ports to perform initialization */
590 for (i = 0; i < num_config; i++) {
591 p_rt = sdw_port_alloc(&slave->dev, port_config, i);
592 if (!p_rt)
593 return -ENOMEM;
594
595 /*
596 * TODO: Check valid port range as defined by DisCo/
597 * slave
598 */
599 ret = sdw_is_valid_port_range(&slave->dev, p_rt);
600 if (ret < 0) {
601 kfree(p_rt);
602 return ret;
603 }
604
605 /*
606 * TODO: Check port capabilities for requested
607 * configuration (audio mode support)
608 */
609
610 list_add_tail(&p_rt->port_node, &s_rt->port_list);
611 }
612
613 return 0;
614}
615
89e59053
SK
616/**
617 * sdw_stream_add_master() - Allocate and add master runtime to a stream
618 *
619 * @bus: SDW Bus instance
620 * @stream_config: Stream configuration for audio stream
bbe7379d
SK
621 * @port_config: Port configuration for audio stream
622 * @num_ports: Number of ports
89e59053
SK
623 * @stream: SoundWire stream
624 */
625int sdw_stream_add_master(struct sdw_bus *bus,
626 struct sdw_stream_config *stream_config,
bbe7379d
SK
627 struct sdw_port_config *port_config,
628 unsigned int num_ports,
89e59053
SK
629 struct sdw_stream_runtime *stream)
630{
631 struct sdw_master_runtime *m_rt = NULL;
632 int ret;
633
634 mutex_lock(&bus->bus_lock);
635
636 m_rt = sdw_alloc_master_rt(bus, stream_config, stream);
637 if (!m_rt) {
638 dev_err(bus->dev,
639 "Master runtime config failed for stream:%s",
640 stream->name);
641 ret = -ENOMEM;
642 goto error;
643 }
644
645 ret = sdw_config_stream(bus->dev, stream, stream_config, false);
646 if (ret)
647 goto stream_error;
648
bbe7379d
SK
649 ret = sdw_master_port_config(bus, m_rt, port_config, num_ports);
650 if (ret)
651 goto stream_error;
652
89e59053
SK
653 stream->state = SDW_STREAM_CONFIGURED;
654
655stream_error:
656 sdw_release_master_stream(stream);
657error:
658 mutex_unlock(&bus->bus_lock);
659 return ret;
660}
661EXPORT_SYMBOL(sdw_stream_add_master);
662
663/**
664 * sdw_stream_add_slave() - Allocate and add master/slave runtime to a stream
665 *
666 * @slave: SDW Slave instance
667 * @stream_config: Stream configuration for audio stream
668 * @stream: SoundWire stream
bbe7379d
SK
669 * @port_config: Port configuration for audio stream
670 * @num_ports: Number of ports
89e59053
SK
671 */
672int sdw_stream_add_slave(struct sdw_slave *slave,
673 struct sdw_stream_config *stream_config,
bbe7379d
SK
674 struct sdw_port_config *port_config,
675 unsigned int num_ports,
89e59053
SK
676 struct sdw_stream_runtime *stream)
677{
678 struct sdw_slave_runtime *s_rt;
679 struct sdw_master_runtime *m_rt;
680 int ret;
681
682 mutex_lock(&slave->bus->bus_lock);
683
684 /*
685 * If this API is invoked by Slave first then m_rt is not valid.
686 * So, allocate m_rt and add Slave to it.
687 */
688 m_rt = sdw_alloc_master_rt(slave->bus, stream_config, stream);
689 if (!m_rt) {
690 dev_err(&slave->dev,
691 "alloc master runtime failed for stream:%s",
692 stream->name);
693 ret = -ENOMEM;
694 goto error;
695 }
696
697 s_rt = sdw_alloc_slave_rt(slave, stream_config, stream);
698 if (!s_rt) {
699 dev_err(&slave->dev,
700 "Slave runtime config failed for stream:%s",
701 stream->name);
702 ret = -ENOMEM;
703 goto stream_error;
704 }
705
706 ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
707 if (ret)
708 goto stream_error;
709
710 list_add_tail(&s_rt->m_rt_node, &m_rt->slave_rt_list);
711
bbe7379d
SK
712 ret = sdw_slave_port_config(slave, s_rt, port_config, num_ports);
713 if (ret)
714 goto stream_error;
715
89e59053
SK
716 stream->state = SDW_STREAM_CONFIGURED;
717 goto error;
718
719stream_error:
720 /*
721 * we hit error so cleanup the stream, release all Slave(s) and
722 * Master runtime
723 */
724 sdw_release_master_stream(stream);
725error:
726 mutex_unlock(&slave->bus->bus_lock);
727 return ret;
728}
729EXPORT_SYMBOL(sdw_stream_add_slave);
f8101c74
SK
730
731/**
732 * sdw_get_slave_dpn_prop() - Get Slave port capabilities
733 *
734 * @slave: Slave handle
735 * @direction: Data direction.
736 * @port_num: Port number
737 */
738struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
739 enum sdw_data_direction direction,
740 unsigned int port_num)
741{
742 struct sdw_dpn_prop *dpn_prop;
743 u8 num_ports;
744 int i;
745
746 if (direction == SDW_DATA_DIR_TX) {
747 num_ports = hweight32(slave->prop.source_ports);
748 dpn_prop = slave->prop.src_dpn_prop;
749 } else {
750 num_ports = hweight32(slave->prop.sink_ports);
751 dpn_prop = slave->prop.sink_dpn_prop;
752 }
753
754 for (i = 0; i < num_ports; i++) {
755 dpn_prop = &dpn_prop[i];
756
757 if (dpn_prop->num == port_num)
758 return &dpn_prop[i];
759 }
760
761 return NULL;
762}