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

ASoC: cs35l56: Wake transactions need to be issued twice

As the dummy wake is a toggling signal (either I2C or SPI activity) it
is not guaranteed to meet the minimum asserted hold time for a wake
signal. In this case the wake must guarantee rising edges separated by
at least the minimum hold time.

Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20231006111039.101914-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Simon Trimmer and committed by
Mark Brown
3df761bd a47cf4da

+36 -16
+1
include/sound/cs35l56.h
··· 243 243 #define CS35L56_HALO_STATE_POLL_US 1000 244 244 #define CS35L56_HALO_STATE_TIMEOUT_US 50000 245 245 #define CS35L56_RESET_PULSE_MIN_US 1100 246 + #define CS35L56_WAKE_HOLD_TIME_US 1000 246 247 247 248 #define CS35L56_SDW1_PLAYBACK_PORT 1 248 249 #define CS35L56_SDW1_CAPTURE_PORT 3
+35 -16
sound/soc/codecs/cs35l56-shared.c
··· 446 446 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_WAKEUP), 447 447 }; 448 448 449 + static void cs35l56_issue_wake_event(struct cs35l56_base *cs35l56_base) 450 + { 451 + /* 452 + * Dummy transactions to trigger I2C/SPI auto-wake. Issue two 453 + * transactions to meet the minimum required time from the rising edge 454 + * to the last falling edge of wake. 455 + * 456 + * It uses bypassed write because we must wake the chip before 457 + * disabling regmap cache-only. 458 + * 459 + * This can NAK on I2C which will terminate the write sequence so the 460 + * single-write sequence is issued twice. 461 + */ 462 + regmap_multi_reg_write_bypassed(cs35l56_base->regmap, 463 + cs35l56_hibernate_wake_seq, 464 + ARRAY_SIZE(cs35l56_hibernate_wake_seq)); 465 + 466 + usleep_range(CS35L56_WAKE_HOLD_TIME_US, 2 * CS35L56_WAKE_HOLD_TIME_US); 467 + 468 + regmap_multi_reg_write_bypassed(cs35l56_base->regmap, 469 + cs35l56_hibernate_wake_seq, 470 + ARRAY_SIZE(cs35l56_hibernate_wake_seq)); 471 + 472 + cs35l56_wait_control_port_ready(); 473 + } 474 + 449 475 int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base) 450 476 { 451 477 unsigned int val; ··· 526 500 if (!cs35l56_base->can_hibernate) 527 501 goto out_sync; 528 502 529 - if (!is_soundwire) { 530 - /* 531 - * Dummy transaction to trigger I2C/SPI auto-wake. This will NAK on I2C. 532 - * Must be done before releasing cache-only. 533 - */ 534 - regmap_multi_reg_write_bypassed(cs35l56_base->regmap, 535 - cs35l56_hibernate_wake_seq, 536 - ARRAY_SIZE(cs35l56_hibernate_wake_seq)); 537 - 538 - cs35l56_wait_control_port_ready(); 539 - } 503 + /* Must be done before releasing cache-only */ 504 + if (!is_soundwire) 505 + cs35l56_issue_wake_event(cs35l56_base); 540 506 541 507 out_sync: 542 508 regcache_cache_only(cs35l56_base->regmap, false); ··· 596 578 unsigned int devid, revid, otpid, secured; 597 579 598 580 /* 599 - * If the system is not using a reset_gpio then issue a 600 - * dummy read to force a wakeup. 581 + * When the system is not using a reset_gpio ensure the device is 582 + * awake, otherwise the device has just been released from reset and 583 + * the driver must wait for the control port to become usable. 601 584 */ 602 585 if (!cs35l56_base->reset_gpio) 603 - regmap_read(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, &devid); 604 - 605 - cs35l56_wait_control_port_ready(); 586 + cs35l56_issue_wake_event(cs35l56_base); 587 + else 588 + cs35l56_wait_control_port_ready(); 606 589 607 590 /* 608 591 * The HALO_STATE register is in different locations on Ax and B0