]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/soundwire/stream.c
soundwire: Add helpers for ports operations
[mirror_ubuntu-hirsute-kernel.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
79df15b7
SK
246/**
247 * sdw_enable_disable_slave_ports: Enable/disable slave data port
248 *
249 * @bus: bus instance
250 * @s_rt: slave runtime
251 * @p_rt: port runtime
252 * @en: enable or disable operation
253 *
254 * This function only sets the enable/disable bits in the relevant bank, the
255 * actual enable/disable is done with a bank switch
256 */
257static int sdw_enable_disable_slave_ports(struct sdw_bus *bus,
258 struct sdw_slave_runtime *s_rt,
259 struct sdw_port_runtime *p_rt, bool en)
260{
261 struct sdw_transport_params *t_params = &p_rt->transport_params;
262 u32 addr;
263 int ret;
264
265 if (bus->params.next_bank)
266 addr = SDW_DPN_CHANNELEN_B1(p_rt->num);
267 else
268 addr = SDW_DPN_CHANNELEN_B0(p_rt->num);
269
270 /*
271 * Since bus doesn't support sharing a port across two streams,
272 * it is safe to reset this register
273 */
274 if (en)
275 ret = sdw_update(s_rt->slave, addr, 0xFF, p_rt->ch_mask);
276 else
277 ret = sdw_update(s_rt->slave, addr, 0xFF, 0x0);
278
279 if (ret < 0)
280 dev_err(&s_rt->slave->dev,
281 "Slave chn_en reg write failed:%d port:%d",
282 ret, t_params->port_num);
283
284 return ret;
285}
286
287static int sdw_enable_disable_master_ports(struct sdw_master_runtime *m_rt,
288 struct sdw_port_runtime *p_rt, bool en)
289{
290 struct sdw_transport_params *t_params = &p_rt->transport_params;
291 struct sdw_bus *bus = m_rt->bus;
292 struct sdw_enable_ch enable_ch;
293 int ret = 0;
294
295 enable_ch.port_num = p_rt->num;
296 enable_ch.ch_mask = p_rt->ch_mask;
297 enable_ch.enable = en;
298
299 /* Perform Master port channel(s) enable/disable */
300 if (bus->port_ops->dpn_port_enable_ch) {
301 ret = bus->port_ops->dpn_port_enable_ch(bus,
302 &enable_ch, bus->params.next_bank);
303 if (ret < 0) {
304 dev_err(bus->dev,
305 "Master chn_en write failed:%d port:%d",
306 ret, t_params->port_num);
307 return ret;
308 }
309 } else {
310 dev_err(bus->dev,
311 "dpn_port_enable_ch not supported, %s failed\n",
312 en ? "enable" : "disable");
313 return -EINVAL;
314 }
315
316 return 0;
317}
318
319/**
320 * sdw_enable_disable_ports() - Enable/disable port(s) for Master and
321 * Slave(s)
322 *
323 * @m_rt: Master stream runtime
324 * @en: mode (enable/disable)
325 */
326static int sdw_enable_disable_ports(struct sdw_master_runtime *m_rt, bool en)
327{
328 struct sdw_port_runtime *s_port, *m_port;
329 struct sdw_slave_runtime *s_rt = NULL;
330 int ret = 0;
331
332 /* Enable/Disable Slave port(s) */
333 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
334 list_for_each_entry(s_port, &s_rt->port_list, port_node) {
335 ret = sdw_enable_disable_slave_ports(m_rt->bus, s_rt,
336 s_port, en);
337 if (ret < 0)
338 return ret;
339 }
340 }
341
342 /* Enable/Disable Master port(s) */
343 list_for_each_entry(m_port, &m_rt->port_list, port_node) {
344 ret = sdw_enable_disable_master_ports(m_rt, m_port, en);
345 if (ret < 0)
346 return ret;
347 }
348
349 return 0;
350}
351
352static int sdw_do_port_prep(struct sdw_slave_runtime *s_rt,
353 struct sdw_prepare_ch prep_ch, enum sdw_port_prep_ops cmd)
354{
355 const struct sdw_slave_ops *ops = s_rt->slave->ops;
356 int ret;
357
358 if (ops->port_prep) {
359 ret = ops->port_prep(s_rt->slave, &prep_ch, cmd);
360 if (ret < 0) {
361 dev_err(&s_rt->slave->dev,
362 "Slave Port Prep cmd %d failed: %d", cmd, ret);
363 return ret;
364 }
365 }
366
367 return 0;
368}
369
370static int sdw_prep_deprep_slave_ports(struct sdw_bus *bus,
371 struct sdw_slave_runtime *s_rt,
372 struct sdw_port_runtime *p_rt, bool prep)
373{
374 struct completion *port_ready = NULL;
375 struct sdw_dpn_prop *dpn_prop;
376 struct sdw_prepare_ch prep_ch;
377 unsigned int time_left;
378 bool intr = false;
379 int ret = 0, val;
380 u32 addr;
381
382 prep_ch.num = p_rt->num;
383 prep_ch.ch_mask = p_rt->ch_mask;
384
385 dpn_prop = sdw_get_slave_dpn_prop(s_rt->slave,
386 s_rt->direction,
387 prep_ch.num);
388 if (!dpn_prop) {
389 dev_err(bus->dev,
390 "Slave Port:%d properties not found", prep_ch.num);
391 return -EINVAL;
392 }
393
394 prep_ch.prepare = prep;
395
396 prep_ch.bank = bus->params.next_bank;
397
398 if (dpn_prop->device_interrupts || !dpn_prop->simple_ch_prep_sm)
399 intr = true;
400
401 /*
402 * Enable interrupt before Port prepare.
403 * For Port de-prepare, it is assumed that port
404 * was prepared earlier
405 */
406 if (prep && intr) {
407 ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
408 dpn_prop->device_interrupts);
409 if (ret < 0)
410 return ret;
411 }
412
413 /* Inform slave about the impending port prepare */
414 sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_PRE_PREP);
415
416 /* Prepare Slave port implementing CP_SM */
417 if (!dpn_prop->simple_ch_prep_sm) {
418 addr = SDW_DPN_PREPARECTRL(p_rt->num);
419
420 if (prep)
421 ret = sdw_update(s_rt->slave, addr,
422 0xFF, p_rt->ch_mask);
423 else
424 ret = sdw_update(s_rt->slave, addr, 0xFF, 0x0);
425
426 if (ret < 0) {
427 dev_err(&s_rt->slave->dev,
428 "Slave prep_ctrl reg write failed");
429 return ret;
430 }
431
432 /* Wait for completion on port ready */
433 port_ready = &s_rt->slave->port_ready[prep_ch.num];
434 time_left = wait_for_completion_timeout(port_ready,
435 msecs_to_jiffies(dpn_prop->ch_prep_timeout));
436
437 val = sdw_read(s_rt->slave, SDW_DPN_PREPARESTATUS(p_rt->num));
438 val &= p_rt->ch_mask;
439 if (!time_left || val) {
440 dev_err(&s_rt->slave->dev,
441 "Chn prep failed for port:%d", prep_ch.num);
442 return -ETIMEDOUT;
443 }
444 }
445
446 /* Inform slaves about ports prepared */
447 sdw_do_port_prep(s_rt, prep_ch, SDW_OPS_PORT_POST_PREP);
448
449 /* Disable interrupt after Port de-prepare */
450 if (!prep && intr)
451 ret = sdw_configure_dpn_intr(s_rt->slave, p_rt->num, prep,
452 dpn_prop->device_interrupts);
453
454 return ret;
455}
456
457static int sdw_prep_deprep_master_ports(struct sdw_master_runtime *m_rt,
458 struct sdw_port_runtime *p_rt, bool prep)
459{
460 struct sdw_transport_params *t_params = &p_rt->transport_params;
461 struct sdw_bus *bus = m_rt->bus;
462 const struct sdw_master_port_ops *ops = bus->port_ops;
463 struct sdw_prepare_ch prep_ch;
464 int ret = 0;
465
466 prep_ch.num = p_rt->num;
467 prep_ch.ch_mask = p_rt->ch_mask;
468 prep_ch.prepare = prep; /* Prepare/De-prepare */
469 prep_ch.bank = bus->params.next_bank;
470
471 /* Pre-prepare/Pre-deprepare port(s) */
472 if (ops->dpn_port_prep) {
473 ret = ops->dpn_port_prep(bus, &prep_ch);
474 if (ret < 0) {
475 dev_err(bus->dev, "Port prepare failed for port:%d",
476 t_params->port_num);
477 return ret;
478 }
479 }
480
481 return ret;
482}
483
484/**
485 * sdw_prep_deprep_ports() - Prepare/De-prepare port(s) for Master(s) and
486 * Slave(s)
487 *
488 * @m_rt: Master runtime handle
489 * @prep: Prepare or De-prepare
490 */
491static int sdw_prep_deprep_ports(struct sdw_master_runtime *m_rt, bool prep)
492{
493 struct sdw_slave_runtime *s_rt = NULL;
494 struct sdw_port_runtime *p_rt;
495 int ret = 0;
496
497 /* Prepare/De-prepare Slave port(s) */
498 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
499 list_for_each_entry(p_rt, &s_rt->port_list, port_node) {
500 ret = sdw_prep_deprep_slave_ports(m_rt->bus, s_rt,
501 p_rt, prep);
502 if (ret < 0)
503 return ret;
504 }
505 }
506
507 /* Prepare/De-prepare Master port(s) */
508 list_for_each_entry(p_rt, &m_rt->port_list, port_node) {
509 ret = sdw_prep_deprep_master_ports(m_rt, p_rt, prep);
510 if (ret < 0)
511 return ret;
512 }
513
514 return ret;
515}
516
89e59053
SK
517/**
518 * sdw_release_stream() - Free the assigned stream runtime
519 *
520 * @stream: SoundWire stream runtime
521 *
522 * sdw_release_stream should be called only once per stream
523 */
524void sdw_release_stream(struct sdw_stream_runtime *stream)
525{
526 kfree(stream);
527}
528EXPORT_SYMBOL(sdw_release_stream);
529
530/**
531 * sdw_alloc_stream() - Allocate and return stream runtime
532 *
533 * @stream_name: SoundWire stream name
534 *
535 * Allocates a SoundWire stream runtime instance.
536 * sdw_alloc_stream should be called only once per stream. Typically
537 * invoked from ALSA/ASoC machine/platform driver.
538 */
539struct sdw_stream_runtime *sdw_alloc_stream(char *stream_name)
540{
541 struct sdw_stream_runtime *stream;
542
543 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
544 if (!stream)
545 return NULL;
546
547 stream->name = stream_name;
548 stream->state = SDW_STREAM_ALLOCATED;
549
550 return stream;
551}
552EXPORT_SYMBOL(sdw_alloc_stream);
553
554/**
555 * sdw_alloc_master_rt() - Allocates and initialize Master runtime handle
556 *
557 * @bus: SDW bus instance
558 * @stream_config: Stream configuration
559 * @stream: Stream runtime handle.
560 *
561 * This function is to be called with bus_lock held.
562 */
563static struct sdw_master_runtime
564*sdw_alloc_master_rt(struct sdw_bus *bus,
565 struct sdw_stream_config *stream_config,
566 struct sdw_stream_runtime *stream)
567{
568 struct sdw_master_runtime *m_rt;
569
570 m_rt = stream->m_rt;
571
572 /*
573 * check if Master is already allocated (as a result of Slave adding
574 * it first), if so skip allocation and go to configure
575 */
576 if (m_rt)
577 goto stream_config;
578
579 m_rt = kzalloc(sizeof(*m_rt), GFP_KERNEL);
580 if (!m_rt)
581 return NULL;
582
583 /* Initialization of Master runtime handle */
bbe7379d 584 INIT_LIST_HEAD(&m_rt->port_list);
89e59053
SK
585 INIT_LIST_HEAD(&m_rt->slave_rt_list);
586 stream->m_rt = m_rt;
587
588 list_add_tail(&m_rt->bus_node, &bus->m_rt_list);
589
590stream_config:
591 m_rt->ch_count = stream_config->ch_count;
592 m_rt->bus = bus;
593 m_rt->stream = stream;
594 m_rt->direction = stream_config->direction;
595
596 return m_rt;
597}
598
599/**
600 * sdw_alloc_slave_rt() - Allocate and initialize Slave runtime handle.
601 *
602 * @slave: Slave handle
603 * @stream_config: Stream configuration
604 * @stream: Stream runtime handle
605 *
606 * This function is to be called with bus_lock held.
607 */
608static struct sdw_slave_runtime
609*sdw_alloc_slave_rt(struct sdw_slave *slave,
610 struct sdw_stream_config *stream_config,
611 struct sdw_stream_runtime *stream)
612{
613 struct sdw_slave_runtime *s_rt = NULL;
614
615 s_rt = kzalloc(sizeof(*s_rt), GFP_KERNEL);
616 if (!s_rt)
617 return NULL;
618
bbe7379d 619 INIT_LIST_HEAD(&s_rt->port_list);
89e59053
SK
620 s_rt->ch_count = stream_config->ch_count;
621 s_rt->direction = stream_config->direction;
622 s_rt->slave = slave;
623
624 return s_rt;
625}
626
bbe7379d
SK
627static void sdw_master_port_release(struct sdw_bus *bus,
628 struct sdw_master_runtime *m_rt)
629{
630 struct sdw_port_runtime *p_rt, *_p_rt;
631
632 list_for_each_entry_safe(p_rt, _p_rt,
633 &m_rt->port_list, port_node) {
634 list_del(&p_rt->port_node);
635 kfree(p_rt);
636 }
637}
638
639static void sdw_slave_port_release(struct sdw_bus *bus,
640 struct sdw_slave *slave,
641 struct sdw_stream_runtime *stream)
642{
643 struct sdw_port_runtime *p_rt, *_p_rt;
644 struct sdw_master_runtime *m_rt = stream->m_rt;
645 struct sdw_slave_runtime *s_rt;
646
647 list_for_each_entry(s_rt, &m_rt->slave_rt_list, m_rt_node) {
648 if (s_rt->slave != slave)
649 continue;
650
651 list_for_each_entry_safe(p_rt, _p_rt,
652 &s_rt->port_list, port_node) {
653 list_del(&p_rt->port_node);
654 kfree(p_rt);
655 }
656 }
657}
658
89e59053
SK
659/**
660 * sdw_release_slave_stream() - Free Slave(s) runtime handle
661 *
662 * @slave: Slave handle.
663 * @stream: Stream runtime handle.
664 *
665 * This function is to be called with bus_lock held.
666 */
667static void sdw_release_slave_stream(struct sdw_slave *slave,
668 struct sdw_stream_runtime *stream)
669{
670 struct sdw_slave_runtime *s_rt, *_s_rt;
671 struct sdw_master_runtime *m_rt = stream->m_rt;
672
673 /* Retrieve Slave runtime handle */
674 list_for_each_entry_safe(s_rt, _s_rt,
675 &m_rt->slave_rt_list, m_rt_node) {
676
677 if (s_rt->slave == slave) {
678 list_del(&s_rt->m_rt_node);
679 kfree(s_rt);
680 return;
681 }
682 }
683}
684
685/**
686 * sdw_release_master_stream() - Free Master runtime handle
687 *
688 * @stream: Stream runtime handle.
689 *
690 * This function is to be called with bus_lock held
691 * It frees the Master runtime handle and associated Slave(s) runtime
692 * handle. If this is called first then sdw_release_slave_stream() will have
693 * no effect as Slave(s) runtime handle would already be freed up.
694 */
695static void sdw_release_master_stream(struct sdw_stream_runtime *stream)
696{
697 struct sdw_master_runtime *m_rt = stream->m_rt;
698 struct sdw_slave_runtime *s_rt, *_s_rt;
699
700 list_for_each_entry_safe(s_rt, _s_rt,
701 &m_rt->slave_rt_list, m_rt_node)
702 sdw_stream_remove_slave(s_rt->slave, stream);
703
704 list_del(&m_rt->bus_node);
705}
706
707/**
708 * sdw_stream_remove_master() - Remove master from sdw_stream
709 *
710 * @bus: SDW Bus instance
711 * @stream: SoundWire stream
712 *
bbe7379d 713 * This removes and frees port_rt and master_rt from a stream
89e59053
SK
714 */
715int sdw_stream_remove_master(struct sdw_bus *bus,
716 struct sdw_stream_runtime *stream)
717{
718 mutex_lock(&bus->bus_lock);
719
720 sdw_release_master_stream(stream);
bbe7379d 721 sdw_master_port_release(bus, stream->m_rt);
89e59053
SK
722 stream->state = SDW_STREAM_RELEASED;
723 kfree(stream->m_rt);
724 stream->m_rt = NULL;
725
726 mutex_unlock(&bus->bus_lock);
727
728 return 0;
729}
730EXPORT_SYMBOL(sdw_stream_remove_master);
731
732/**
733 * sdw_stream_remove_slave() - Remove slave from sdw_stream
734 *
735 * @slave: SDW Slave instance
736 * @stream: SoundWire stream
737 *
bbe7379d 738 * This removes and frees port_rt and slave_rt from a stream
89e59053
SK
739 */
740int sdw_stream_remove_slave(struct sdw_slave *slave,
741 struct sdw_stream_runtime *stream)
742{
743 mutex_lock(&slave->bus->bus_lock);
744
bbe7379d 745 sdw_slave_port_release(slave->bus, slave, stream);
89e59053
SK
746 sdw_release_slave_stream(slave, stream);
747
748 mutex_unlock(&slave->bus->bus_lock);
749
750 return 0;
751}
752EXPORT_SYMBOL(sdw_stream_remove_slave);
753
754/**
755 * sdw_config_stream() - Configure the allocated stream
756 *
757 * @dev: SDW device
758 * @stream: SoundWire stream
759 * @stream_config: Stream configuration for audio stream
760 * @is_slave: is API called from Slave or Master
761 *
762 * This function is to be called with bus_lock held.
763 */
764static int sdw_config_stream(struct device *dev,
765 struct sdw_stream_runtime *stream,
766 struct sdw_stream_config *stream_config, bool is_slave)
767{
768 /*
769 * Update the stream rate, channel and bps based on data
770 * source. For more than one data source (multilink),
771 * match the rate, bps, stream type and increment number of channels.
772 *
773 * If rate/bps is zero, it means the values are not set, so skip
774 * comparison and allow the value to be set and stored in stream
775 */
776 if (stream->params.rate &&
777 stream->params.rate != stream_config->frame_rate) {
778 dev_err(dev, "rate not matching, stream:%s", stream->name);
779 return -EINVAL;
780 }
781
782 if (stream->params.bps &&
783 stream->params.bps != stream_config->bps) {
784 dev_err(dev, "bps not matching, stream:%s", stream->name);
785 return -EINVAL;
786 }
787
788 stream->type = stream_config->type;
789 stream->params.rate = stream_config->frame_rate;
790 stream->params.bps = stream_config->bps;
791
792 /* TODO: Update this check during Device-device support */
793 if (is_slave)
794 stream->params.ch_count += stream_config->ch_count;
795
796 return 0;
797}
798
bbe7379d
SK
799static int sdw_is_valid_port_range(struct device *dev,
800 struct sdw_port_runtime *p_rt)
801{
802 if (!SDW_VALID_PORT_RANGE(p_rt->num)) {
803 dev_err(dev,
804 "SoundWire: Invalid port number :%d", p_rt->num);
805 return -EINVAL;
806 }
807
808 return 0;
809}
810
811static struct sdw_port_runtime *sdw_port_alloc(struct device *dev,
812 struct sdw_port_config *port_config,
813 int port_index)
814{
815 struct sdw_port_runtime *p_rt;
816
817 p_rt = kzalloc(sizeof(*p_rt), GFP_KERNEL);
818 if (!p_rt)
819 return NULL;
820
821 p_rt->ch_mask = port_config[port_index].ch_mask;
822 p_rt->num = port_config[port_index].num;
823
824 return p_rt;
825}
826
827static int sdw_master_port_config(struct sdw_bus *bus,
828 struct sdw_master_runtime *m_rt,
829 struct sdw_port_config *port_config,
830 unsigned int num_ports)
831{
832 struct sdw_port_runtime *p_rt;
833 int i;
834
835 /* Iterate for number of ports to perform initialization */
836 for (i = 0; i < num_ports; i++) {
837 p_rt = sdw_port_alloc(bus->dev, port_config, i);
838 if (!p_rt)
839 return -ENOMEM;
840
841 /*
842 * TODO: Check port capabilities for requested
843 * configuration (audio mode support)
844 */
845
846 list_add_tail(&p_rt->port_node, &m_rt->port_list);
847 }
848
849 return 0;
850}
851
852static int sdw_slave_port_config(struct sdw_slave *slave,
853 struct sdw_slave_runtime *s_rt,
854 struct sdw_port_config *port_config,
855 unsigned int num_config)
856{
857 struct sdw_port_runtime *p_rt;
858 int i, ret;
859
860 /* Iterate for number of ports to perform initialization */
861 for (i = 0; i < num_config; i++) {
862 p_rt = sdw_port_alloc(&slave->dev, port_config, i);
863 if (!p_rt)
864 return -ENOMEM;
865
866 /*
867 * TODO: Check valid port range as defined by DisCo/
868 * slave
869 */
870 ret = sdw_is_valid_port_range(&slave->dev, p_rt);
871 if (ret < 0) {
872 kfree(p_rt);
873 return ret;
874 }
875
876 /*
877 * TODO: Check port capabilities for requested
878 * configuration (audio mode support)
879 */
880
881 list_add_tail(&p_rt->port_node, &s_rt->port_list);
882 }
883
884 return 0;
885}
886
89e59053
SK
887/**
888 * sdw_stream_add_master() - Allocate and add master runtime to a stream
889 *
890 * @bus: SDW Bus instance
891 * @stream_config: Stream configuration for audio stream
bbe7379d
SK
892 * @port_config: Port configuration for audio stream
893 * @num_ports: Number of ports
89e59053
SK
894 * @stream: SoundWire stream
895 */
896int sdw_stream_add_master(struct sdw_bus *bus,
897 struct sdw_stream_config *stream_config,
bbe7379d
SK
898 struct sdw_port_config *port_config,
899 unsigned int num_ports,
89e59053
SK
900 struct sdw_stream_runtime *stream)
901{
902 struct sdw_master_runtime *m_rt = NULL;
903 int ret;
904
905 mutex_lock(&bus->bus_lock);
906
907 m_rt = sdw_alloc_master_rt(bus, stream_config, stream);
908 if (!m_rt) {
909 dev_err(bus->dev,
910 "Master runtime config failed for stream:%s",
911 stream->name);
912 ret = -ENOMEM;
913 goto error;
914 }
915
916 ret = sdw_config_stream(bus->dev, stream, stream_config, false);
917 if (ret)
918 goto stream_error;
919
bbe7379d
SK
920 ret = sdw_master_port_config(bus, m_rt, port_config, num_ports);
921 if (ret)
922 goto stream_error;
923
89e59053
SK
924 stream->state = SDW_STREAM_CONFIGURED;
925
926stream_error:
927 sdw_release_master_stream(stream);
928error:
929 mutex_unlock(&bus->bus_lock);
930 return ret;
931}
932EXPORT_SYMBOL(sdw_stream_add_master);
933
934/**
935 * sdw_stream_add_slave() - Allocate and add master/slave runtime to a stream
936 *
937 * @slave: SDW Slave instance
938 * @stream_config: Stream configuration for audio stream
939 * @stream: SoundWire stream
bbe7379d
SK
940 * @port_config: Port configuration for audio stream
941 * @num_ports: Number of ports
89e59053
SK
942 */
943int sdw_stream_add_slave(struct sdw_slave *slave,
944 struct sdw_stream_config *stream_config,
bbe7379d
SK
945 struct sdw_port_config *port_config,
946 unsigned int num_ports,
89e59053
SK
947 struct sdw_stream_runtime *stream)
948{
949 struct sdw_slave_runtime *s_rt;
950 struct sdw_master_runtime *m_rt;
951 int ret;
952
953 mutex_lock(&slave->bus->bus_lock);
954
955 /*
956 * If this API is invoked by Slave first then m_rt is not valid.
957 * So, allocate m_rt and add Slave to it.
958 */
959 m_rt = sdw_alloc_master_rt(slave->bus, stream_config, stream);
960 if (!m_rt) {
961 dev_err(&slave->dev,
962 "alloc master runtime failed for stream:%s",
963 stream->name);
964 ret = -ENOMEM;
965 goto error;
966 }
967
968 s_rt = sdw_alloc_slave_rt(slave, stream_config, stream);
969 if (!s_rt) {
970 dev_err(&slave->dev,
971 "Slave runtime config failed for stream:%s",
972 stream->name);
973 ret = -ENOMEM;
974 goto stream_error;
975 }
976
977 ret = sdw_config_stream(&slave->dev, stream, stream_config, true);
978 if (ret)
979 goto stream_error;
980
981 list_add_tail(&s_rt->m_rt_node, &m_rt->slave_rt_list);
982
bbe7379d
SK
983 ret = sdw_slave_port_config(slave, s_rt, port_config, num_ports);
984 if (ret)
985 goto stream_error;
986
89e59053
SK
987 stream->state = SDW_STREAM_CONFIGURED;
988 goto error;
989
990stream_error:
991 /*
992 * we hit error so cleanup the stream, release all Slave(s) and
993 * Master runtime
994 */
995 sdw_release_master_stream(stream);
996error:
997 mutex_unlock(&slave->bus->bus_lock);
998 return ret;
999}
1000EXPORT_SYMBOL(sdw_stream_add_slave);
f8101c74
SK
1001
1002/**
1003 * sdw_get_slave_dpn_prop() - Get Slave port capabilities
1004 *
1005 * @slave: Slave handle
1006 * @direction: Data direction.
1007 * @port_num: Port number
1008 */
1009struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
1010 enum sdw_data_direction direction,
1011 unsigned int port_num)
1012{
1013 struct sdw_dpn_prop *dpn_prop;
1014 u8 num_ports;
1015 int i;
1016
1017 if (direction == SDW_DATA_DIR_TX) {
1018 num_ports = hweight32(slave->prop.source_ports);
1019 dpn_prop = slave->prop.src_dpn_prop;
1020 } else {
1021 num_ports = hweight32(slave->prop.sink_ports);
1022 dpn_prop = slave->prop.sink_dpn_prop;
1023 }
1024
1025 for (i = 0; i < num_ports; i++) {
1026 dpn_prop = &dpn_prop[i];
1027
1028 if (dpn_prop->num == port_num)
1029 return &dpn_prop[i];
1030 }
1031
1032 return NULL;
1033}