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#include <linux/delay.h>
27#include <linux/slab.h>
28
29#include "dm_services.h"
30#include "core_types.h"
31#include "dce_aux.h"
32#include "dce/dce_11_0_sh_mask.h"
33#include "dm_event_log.h"
34
35#define CTX \
36 aux110->base.ctx
37#define REG(reg_name)\
38 (aux110->regs->reg_name)
39
40#define DC_LOGGER \
41 engine->ctx->logger
42
43#include "reg_helper.h"
44
45#undef FN
46#define FN(reg_name, field_name) \
47 aux110->shift->field_name, aux110->mask->field_name
48
49#define FROM_AUX_ENGINE(ptr) \
50 container_of((ptr), struct aux_engine_dce110, base)
51
52#define FROM_ENGINE(ptr) \
53 FROM_AUX_ENGINE(container_of((ptr), struct dce_aux, base))
54
55#define FROM_AUX_ENGINE_ENGINE(ptr) \
56 container_of((ptr), struct dce_aux, base)
57enum {
58 AUX_INVALID_REPLY_RETRY_COUNTER = 1,
59 AUX_TIMED_OUT_RETRY_COUNTER = 2,
60 AUX_DEFER_RETRY_COUNTER = 6
61};
62
63#define TIME_OUT_INCREMENT 1016
64#define TIME_OUT_MULTIPLIER_8 8
65#define TIME_OUT_MULTIPLIER_16 16
66#define TIME_OUT_MULTIPLIER_32 32
67#define TIME_OUT_MULTIPLIER_64 64
68#define MAX_TIMEOUT_LENGTH 127
69#define DEFAULT_AUX_ENGINE_MULT 0
70#define DEFAULT_AUX_ENGINE_LENGTH 69
71
72static void release_engine(
73 struct dce_aux *engine)
74{
75 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
76
77 dal_ddc_close(engine->ddc);
78
79 engine->ddc = NULL;
80
81 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_DONE_USING_AUX_REG, 1);
82}
83
84#define SW_CAN_ACCESS_AUX 1
85#define DMCU_CAN_ACCESS_AUX 2
86
87static bool is_engine_available(
88 struct dce_aux *engine)
89{
90 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
91
92 uint32_t value = REG_READ(AUX_ARB_CONTROL);
93 uint32_t field = get_reg_field_value(
94 value,
95 AUX_ARB_CONTROL,
96 AUX_REG_RW_CNTL_STATUS);
97
98 return (field != DMCU_CAN_ACCESS_AUX);
99}
100static bool acquire_engine(
101 struct dce_aux *engine)
102{
103 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
104
105 uint32_t value = REG_READ(AUX_ARB_CONTROL);
106 uint32_t field = get_reg_field_value(
107 value,
108 AUX_ARB_CONTROL,
109 AUX_REG_RW_CNTL_STATUS);
110 if (field == DMCU_CAN_ACCESS_AUX)
111 return false;
112
113 value = REG_READ(AUX_CONTROL);
114 field = get_reg_field_value(value,
115 AUX_CONTROL,
116 AUX_EN);
117
118 if (field == 0) {
119 set_reg_field_value(
120 value,
121 1,
122 AUX_CONTROL,
123 AUX_EN);
124
125 if (REG(AUX_RESET_MASK)) {
126
127 set_reg_field_value(
128 value,
129 1,
130 AUX_CONTROL,
131 AUX_RESET);
132 }
133
134 REG_WRITE(AUX_CONTROL, value);
135
136 if (REG(AUX_RESET_MASK)) {
137
138
139 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 1,
140 1, 11);
141
142 set_reg_field_value(
143 value,
144 0,
145 AUX_CONTROL,
146 AUX_RESET);
147
148 REG_WRITE(AUX_CONTROL, value);
149
150 REG_WAIT(AUX_CONTROL, AUX_RESET_DONE, 0,
151 1, 11);
152 }
153 }
154
155
156 REG_UPDATE(AUX_ARB_CONTROL, AUX_SW_USE_AUX_REG_REQ, 1);
157
158 value = REG_READ(AUX_ARB_CONTROL);
159 field = get_reg_field_value(
160 value,
161 AUX_ARB_CONTROL,
162 AUX_REG_RW_CNTL_STATUS);
163
164 return (field == SW_CAN_ACCESS_AUX);
165}
166
167#define COMPOSE_AUX_SW_DATA_16_20(command, address) \
168 ((command) | ((0xF0000 & (address)) >> 16))
169
170#define COMPOSE_AUX_SW_DATA_8_15(address) \
171 ((0xFF00 & (address)) >> 8)
172
173#define COMPOSE_AUX_SW_DATA_0_7(address) \
174 (0xFF & (address))
175
176static void submit_channel_request(
177 struct dce_aux *engine,
178 struct aux_request_transaction_data *request)
179{
180 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
181 uint32_t value;
182 uint32_t length;
183
184 bool is_write =
185 ((request->type == AUX_TRANSACTION_TYPE_DP) &&
186 (request->action == I2CAUX_TRANSACTION_ACTION_DP_WRITE)) ||
187 ((request->type == AUX_TRANSACTION_TYPE_I2C) &&
188 ((request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE) ||
189 (request->action == I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT)));
190 if (REG(AUXN_IMPCAL)) {
191
192 REG_UPDATE_SEQ_2(AUXN_IMPCAL,
193 AUXN_CALOUT_ERROR_AK, 1,
194 AUXN_CALOUT_ERROR_AK, 0);
195
196 REG_UPDATE_SEQ_2(AUXP_IMPCAL,
197 AUXP_CALOUT_ERROR_AK, 1,
198 AUXP_CALOUT_ERROR_AK, 0);
199
200
201 REG_UPDATE_SEQ_2(AUXN_IMPCAL,
202 AUXN_IMPCAL_ENABLE, 1,
203 AUXN_IMPCAL_OVERRIDE_ENABLE, 0);
204
205
206
207 REG_UPDATE_SEQ_2(AUXP_IMPCAL,
208 AUXP_IMPCAL_OVERRIDE_ENABLE, 1,
209 AUXP_IMPCAL_OVERRIDE_ENABLE, 0);
210 }
211
212 REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
213
214 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
215 10, aux110->polling_timeout_period/10);
216
217
218
219
220
221
222
223
224
225
226 length = request->length ? 4 : 3;
227 if (is_write)
228 length += request->length;
229
230 REG_UPDATE_2(AUX_SW_CONTROL,
231 AUX_SW_START_DELAY, request->delay,
232 AUX_SW_WR_BYTES, length);
233
234
235 value = REG_UPDATE_4(AUX_SW_DATA,
236 AUX_SW_INDEX, 0,
237 AUX_SW_DATA_RW, 0,
238 AUX_SW_AUTOINCREMENT_DISABLE, 1,
239 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_16_20(request->action, request->address));
240
241 value = REG_SET_2(AUX_SW_DATA, value,
242 AUX_SW_AUTOINCREMENT_DISABLE, 0,
243 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_8_15(request->address));
244
245 value = REG_SET(AUX_SW_DATA, value,
246 AUX_SW_DATA, COMPOSE_AUX_SW_DATA_0_7(request->address));
247
248 if (request->length) {
249 value = REG_SET(AUX_SW_DATA, value,
250 AUX_SW_DATA, request->length - 1);
251 }
252
253 if (is_write) {
254
255
256
257
258
259 uint32_t i = 0;
260
261 while (i < request->length) {
262 value = REG_SET(AUX_SW_DATA, value,
263 AUX_SW_DATA, request->data[i]);
264
265 ++i;
266 }
267 }
268
269 REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
270 EVENT_LOG_AUX_REQ(engine->ddc->pin_data->en, EVENT_LOG_AUX_ORIGIN_NATIVE,
271 request->action, request->address, request->length, request->data);
272}
273
274static int read_channel_reply(struct dce_aux *engine, uint32_t size,
275 uint8_t *buffer, uint8_t *reply_result,
276 uint32_t *sw_status)
277{
278 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
279 uint32_t bytes_replied;
280 uint32_t reply_result_32;
281
282 *sw_status = REG_GET(AUX_SW_STATUS, AUX_SW_REPLY_BYTE_COUNT,
283 &bytes_replied);
284
285
286 if ((*sw_status & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
287 return -1;
288
289
290 if (!bytes_replied)
291 return -1;
292
293 REG_UPDATE_SEQ_3(AUX_SW_DATA,
294 AUX_SW_INDEX, 0,
295 AUX_SW_AUTOINCREMENT_DISABLE, 1,
296 AUX_SW_DATA_RW, 1);
297
298 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &reply_result_32);
299 reply_result_32 = reply_result_32 >> 4;
300 if (reply_result != NULL)
301 *reply_result = (uint8_t)reply_result_32;
302
303 if (reply_result_32 == 0) {
304 uint32_t i = 0;
305
306
307 --bytes_replied;
308
309
310 if (bytes_replied > size)
311 return -1;
312
313 while (i < bytes_replied) {
314 uint32_t aux_sw_data_val;
315
316 REG_GET(AUX_SW_DATA, AUX_SW_DATA, &aux_sw_data_val);
317 buffer[i] = aux_sw_data_val;
318 ++i;
319 }
320
321 return i;
322 }
323
324 return 0;
325}
326
327static enum aux_channel_operation_result get_channel_status(
328 struct dce_aux *engine,
329 uint8_t *returned_bytes)
330{
331 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(engine);
332
333 uint32_t value;
334
335 if (returned_bytes == NULL) {
336
337 ASSERT_CRITICAL(false);
338 return AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN;
339 }
340 *returned_bytes = 0;
341
342
343 REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 1,
344 10, aux110->polling_timeout_period/10);
345
346 value = REG_READ(AUX_SW_STATUS);
347
348 if ((value & AUX_SW_STATUS__AUX_SW_HPD_DISCON_MASK))
349 return AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON;
350
351
352
353
354
355
356
357
358
359 if (value & AUX_SW_STATUS__AUX_SW_DONE_MASK) {
360 if ((value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_STATE_MASK) ||
361 (value & AUX_SW_STATUS__AUX_SW_RX_TIMEOUT_MASK))
362 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
363
364 else if ((value & AUX_SW_STATUS__AUX_SW_RX_INVALID_STOP_MASK) ||
365 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_NO_DET_MASK) ||
366 (value &
367 AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_H_MASK) ||
368 (value & AUX_SW_STATUS__AUX_SW_RX_RECV_INVALID_L_MASK))
369 return AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
370
371 *returned_bytes = get_reg_field_value(value,
372 AUX_SW_STATUS,
373 AUX_SW_REPLY_BYTE_COUNT);
374
375 if (*returned_bytes == 0)
376 return
377 AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY;
378 else {
379 *returned_bytes -= 1;
380 return AUX_CHANNEL_OPERATION_SUCCEEDED;
381 }
382 } else {
383
384
385
386 ASSERT_CRITICAL(false);
387 return AUX_CHANNEL_OPERATION_FAILED_TIMEOUT;
388 }
389}
390
391enum i2caux_engine_type get_engine_type(
392 const struct dce_aux *engine)
393{
394 return I2CAUX_ENGINE_TYPE_AUX;
395}
396
397static bool acquire(
398 struct dce_aux *engine,
399 struct ddc *ddc)
400{
401 enum gpio_result result;
402
403 if ((engine == NULL) || !is_engine_available(engine))
404 return false;
405
406 result = dal_ddc_open(ddc, GPIO_MODE_HARDWARE,
407 GPIO_DDC_CONFIG_TYPE_MODE_AUX);
408
409 if (result != GPIO_RESULT_OK)
410 return false;
411
412 if (!acquire_engine(engine)) {
413 dal_ddc_close(ddc);
414 return false;
415 }
416
417 engine->ddc = ddc;
418
419 return true;
420}
421
422void dce110_engine_destroy(struct dce_aux **engine)
423{
424
425 struct aux_engine_dce110 *engine110 = FROM_AUX_ENGINE(*engine);
426
427 kfree(engine110);
428 *engine = NULL;
429
430}
431
432static uint32_t dce_aux_configure_timeout(struct ddc_service *ddc,
433 uint32_t timeout_in_us)
434{
435 uint32_t multiplier = 0;
436 uint32_t length = 0;
437 uint32_t prev_length = 0;
438 uint32_t prev_mult = 0;
439 uint32_t prev_timeout_val = 0;
440 struct ddc *ddc_pin = ddc->ddc_pin;
441 struct dce_aux *aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
442 struct aux_engine_dce110 *aux110 = FROM_AUX_ENGINE(aux_engine);
443
444
445 aux110->polling_timeout_period = timeout_in_us * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER;
446
447
448 if (timeout_in_us == 0) {
449 multiplier = DEFAULT_AUX_ENGINE_MULT;
450 length = DEFAULT_AUX_ENGINE_LENGTH;
451 } else if (timeout_in_us <= TIME_OUT_INCREMENT) {
452 multiplier = 0;
453 length = timeout_in_us/TIME_OUT_MULTIPLIER_8;
454 if (timeout_in_us % TIME_OUT_MULTIPLIER_8 != 0)
455 length++;
456 } else if (timeout_in_us <= 2 * TIME_OUT_INCREMENT) {
457 multiplier = 1;
458 length = timeout_in_us/TIME_OUT_MULTIPLIER_16;
459 if (timeout_in_us % TIME_OUT_MULTIPLIER_16 != 0)
460 length++;
461 } else if (timeout_in_us <= 4 * TIME_OUT_INCREMENT) {
462 multiplier = 2;
463 length = timeout_in_us/TIME_OUT_MULTIPLIER_32;
464 if (timeout_in_us % TIME_OUT_MULTIPLIER_32 != 0)
465 length++;
466 } else if (timeout_in_us > 4 * TIME_OUT_INCREMENT) {
467 multiplier = 3;
468 length = timeout_in_us/TIME_OUT_MULTIPLIER_64;
469 if (timeout_in_us % TIME_OUT_MULTIPLIER_64 != 0)
470 length++;
471 }
472
473 length = (length < MAX_TIMEOUT_LENGTH) ? length : MAX_TIMEOUT_LENGTH;
474
475 REG_GET_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, &prev_length, AUX_RX_TIMEOUT_LEN_MUL, &prev_mult);
476
477 switch (prev_mult) {
478 case 0:
479 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_8;
480 break;
481 case 1:
482 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_16;
483 break;
484 case 2:
485 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_32;
486 break;
487 case 3:
488 prev_timeout_val = prev_length * TIME_OUT_MULTIPLIER_64;
489 break;
490 default:
491 prev_timeout_val = DEFAULT_AUX_ENGINE_LENGTH * TIME_OUT_MULTIPLIER_8;
492 break;
493 }
494
495 REG_UPDATE_SEQ_2(AUX_DPHY_RX_CONTROL1, AUX_RX_TIMEOUT_LEN, length, AUX_RX_TIMEOUT_LEN_MUL, multiplier);
496
497 return prev_timeout_val;
498}
499
500static struct dce_aux_funcs aux_functions = {
501 .configure_timeout = NULL,
502 .destroy = NULL,
503};
504
505struct dce_aux *dce110_aux_engine_construct(struct aux_engine_dce110 *aux_engine110,
506 struct dc_context *ctx,
507 uint32_t inst,
508 uint32_t timeout_period,
509 const struct dce110_aux_registers *regs,
510 const struct dce110_aux_registers_mask *mask,
511 const struct dce110_aux_registers_shift *shift,
512 bool is_ext_aux_timeout_configurable)
513{
514 aux_engine110->base.ddc = NULL;
515 aux_engine110->base.ctx = ctx;
516 aux_engine110->base.delay = 0;
517 aux_engine110->base.max_defer_write_retry = 0;
518 aux_engine110->base.inst = inst;
519 aux_engine110->polling_timeout_period = timeout_period;
520 aux_engine110->regs = regs;
521
522 aux_engine110->mask = mask;
523 aux_engine110->shift = shift;
524 aux_engine110->base.funcs = &aux_functions;
525 if (is_ext_aux_timeout_configurable)
526 aux_engine110->base.funcs->configure_timeout = &dce_aux_configure_timeout;
527
528 return &aux_engine110->base;
529}
530
531static enum i2caux_transaction_action i2caux_action_from_payload(struct aux_payload *payload)
532{
533 if (payload->i2c_over_aux) {
534 if (payload->write) {
535 if (payload->mot)
536 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE_MOT;
537 return I2CAUX_TRANSACTION_ACTION_I2C_WRITE;
538 }
539 if (payload->mot)
540 return I2CAUX_TRANSACTION_ACTION_I2C_READ_MOT;
541 return I2CAUX_TRANSACTION_ACTION_I2C_READ;
542 }
543 if (payload->write)
544 return I2CAUX_TRANSACTION_ACTION_DP_WRITE;
545 return I2CAUX_TRANSACTION_ACTION_DP_READ;
546}
547
548int dce_aux_transfer_raw(struct ddc_service *ddc,
549 struct aux_payload *payload,
550 enum aux_channel_operation_result *operation_result)
551{
552 struct ddc *ddc_pin = ddc->ddc_pin;
553 struct dce_aux *aux_engine;
554 struct aux_request_transaction_data aux_req;
555 struct aux_reply_transaction_data aux_rep;
556 uint8_t returned_bytes = 0;
557 int res = -1;
558 uint32_t status;
559
560 memset(&aux_req, 0, sizeof(aux_req));
561 memset(&aux_rep, 0, sizeof(aux_rep));
562
563 aux_engine = ddc->ctx->dc->res_pool->engines[ddc_pin->pin_data->en];
564 if (!acquire(aux_engine, ddc_pin)) {
565 *operation_result = AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE;
566 return -1;
567 }
568
569 if (payload->i2c_over_aux)
570 aux_req.type = AUX_TRANSACTION_TYPE_I2C;
571 else
572 aux_req.type = AUX_TRANSACTION_TYPE_DP;
573
574 aux_req.action = i2caux_action_from_payload(payload);
575
576 aux_req.address = payload->address;
577 aux_req.delay = 0;
578 aux_req.length = payload->length;
579 aux_req.data = payload->data;
580
581 submit_channel_request(aux_engine, &aux_req);
582 *operation_result = get_channel_status(aux_engine, &returned_bytes);
583
584 if (*operation_result == AUX_CHANNEL_OPERATION_SUCCEEDED) {
585 int bytes_replied = 0;
586 bytes_replied = read_channel_reply(aux_engine, payload->length,
587 payload->data, payload->reply,
588 &status);
589 EVENT_LOG_AUX_REP(aux_engine->ddc->pin_data->en,
590 EVENT_LOG_AUX_ORIGIN_NATIVE, *payload->reply,
591 bytes_replied, payload->data);
592 res = returned_bytes;
593 } else {
594 res = -1;
595 }
596
597 release_engine(aux_engine);
598 return res;
599}
600
601#define AUX_MAX_RETRIES 7
602#define AUX_MAX_DEFER_RETRIES 7
603#define AUX_MAX_I2C_DEFER_RETRIES 7
604#define AUX_MAX_INVALID_REPLY_RETRIES 2
605#define AUX_MAX_TIMEOUT_RETRIES 3
606
607bool dce_aux_transfer_with_retries(struct ddc_service *ddc,
608 struct aux_payload *payload)
609{
610 int i, ret = 0;
611 uint8_t reply;
612 bool payload_reply = true;
613 enum aux_channel_operation_result operation_result;
614 bool retry_on_defer = false;
615
616 int aux_ack_retries = 0,
617 aux_defer_retries = 0,
618 aux_i2c_defer_retries = 0,
619 aux_timeout_retries = 0,
620 aux_invalid_reply_retries = 0;
621
622 if (!payload->reply) {
623 payload_reply = false;
624 payload->reply = &reply;
625 }
626
627 for (i = 0; i < AUX_MAX_RETRIES; i++) {
628 ret = dce_aux_transfer_raw(ddc, payload, &operation_result);
629 switch (operation_result) {
630 case AUX_CHANNEL_OPERATION_SUCCEEDED:
631 aux_timeout_retries = 0;
632 aux_invalid_reply_retries = 0;
633
634 switch (*payload->reply) {
635 case AUX_TRANSACTION_REPLY_AUX_ACK:
636 if (!payload->write && payload->length != ret) {
637 if (++aux_ack_retries >= AUX_MAX_RETRIES)
638 goto fail;
639 else
640 udelay(300);
641 } else
642 return true;
643 break;
644
645 case AUX_TRANSACTION_REPLY_AUX_DEFER:
646 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER:
647 retry_on_defer = true;
648 fallthrough;
649 case AUX_TRANSACTION_REPLY_I2C_OVER_AUX_NACK:
650 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES) {
651 goto fail;
652 } else {
653 if ((*payload->reply == AUX_TRANSACTION_REPLY_AUX_DEFER) ||
654 (*payload->reply == AUX_TRANSACTION_REPLY_I2C_OVER_AUX_DEFER)) {
655 if (payload->defer_delay > 0)
656 msleep(payload->defer_delay);
657 }
658 }
659 break;
660
661 case AUX_TRANSACTION_REPLY_I2C_DEFER:
662 aux_defer_retries = 0;
663 if (++aux_i2c_defer_retries >= AUX_MAX_I2C_DEFER_RETRIES)
664 goto fail;
665 break;
666
667 case AUX_TRANSACTION_REPLY_AUX_NACK:
668 case AUX_TRANSACTION_REPLY_HPD_DISCON:
669 default:
670 goto fail;
671 }
672 break;
673
674 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY:
675 if (++aux_invalid_reply_retries >= AUX_MAX_INVALID_REPLY_RETRIES)
676 goto fail;
677 else
678 udelay(400);
679 break;
680
681 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT:
682
683
684 if (retry_on_defer) {
685 if (++aux_defer_retries >= AUX_MAX_DEFER_RETRIES)
686 goto fail;
687 else if (payload->defer_delay > 0)
688 msleep(payload->defer_delay);
689 } else {
690 if (++aux_timeout_retries >= AUX_MAX_TIMEOUT_RETRIES)
691 goto fail;
692 else {
693
694
695
696
697
698
699 }
700 }
701 break;
702
703 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON:
704 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE:
705 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN:
706 default:
707 goto fail;
708 }
709 }
710
711fail:
712 if (!payload_reply)
713 payload->reply = NULL;
714 return false;
715}
716