#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw_type.h>
+#include <linux/string_choices.h>
#include <linux/swab.h>
#include <linux/types.h>
#include <linux/workqueue.h>
struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
struct sdw_slave_prop *prop = &peripheral->prop;
struct sdw_dpn_prop *ports;
+ u8 clock_stop_1 = false;
+ int ret;
+
+ ret = fwnode_property_read_u8(dev_fwnode(cs35l56->base.dev),
+ "mipi-sdw-clock-stop-mode1-supported",
+ &clock_stop_1);
+ if (ret == 0)
+ prop->clk_stop_mode1 = !!clock_stop_1;
ports = devm_kcalloc(cs35l56->base.dev, 2, sizeof(*ports), GFP_KERNEL);
if (!ports)
ports[1].ch_prep_timeout = 10;
prop->src_dpn_prop = &ports[1];
+ dev_dbg(&peripheral->dev, "clock stop mode 1 supported: %s\n",
+ str_yes_no(prop->clk_stop_mode1));
+
return 0;
}
switch (status) {
case SDW_SLAVE_ATTACHED:
dev_dbg(cs35l56->base.dev, "%s: ATTACHED\n", __func__);
+ cs35l56->sdw_in_clock_stop_1 = false;
if (cs35l56->sdw_attached)
break;
{
struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev);
- dev_dbg(cs35l56->base.dev, "%s: mode:%d type:%d\n", __func__, mode, type);
+ dev_dbg(cs35l56->base.dev, "%s: clock_stop_mode%d stage:%d\n", __func__, mode, type);
- return 0;
+ switch (type) {
+ case SDW_CLK_POST_PREPARE:
+ if (mode == SDW_CLK_STOP_MODE1)
+ cs35l56->sdw_in_clock_stop_1 = true;
+ else
+ cs35l56->sdw_in_clock_stop_1 = false;
+ return 0;
+ default:
+ return 0;
+ }
}
static const struct sdw_slave_ops cs35l56_sdw_ops = {
.read_prop = cs35l56_sdw_read_prop,
.interrupt_callback = cs35l56_sdw_interrupt,
.update_status = cs35l56_sdw_update_status,
-#ifdef DEBUG
.clk_stop = cs35l56_sdw_clk_stop,
-#endif
};
static int __maybe_unused cs35l56_sdw_handle_unattach(struct cs35l56_private *cs35l56)
{
struct sdw_slave *peripheral = cs35l56->sdw_peripheral;
- if (peripheral->unattach_request) {
+ dev_dbg(cs35l56->base.dev, "attached:%u unattach_request:%u in_clock_stop_1:%u\n",
+ cs35l56->sdw_attached, peripheral->unattach_request, cs35l56->sdw_in_clock_stop_1);
+
+ if (cs35l56->sdw_in_clock_stop_1 || peripheral->unattach_request) {
/* Cannot access registers until bus is re-initialized. */
dev_dbg(cs35l56->base.dev, "Wait for initialization_complete\n");
if (!wait_for_completion_timeout(&peripheral->initialization_complete,
}
peripheral->unattach_request = 0;
+ cs35l56->sdw_in_clock_stop_1 = false;
/*
* Don't call regcache_mark_dirty(), we can't be sure that the