16c39710dSShuming Fan // SPDX-License-Identifier: GPL-2.0-only
26c39710dSShuming Fan //
36c39710dSShuming Fan // rt712-sdca-sdw.c -- rt712 SDCA ALSA SoC audio driver
46c39710dSShuming Fan //
56c39710dSShuming Fan // Copyright(c) 2023 Realtek Semiconductor Corp.
66c39710dSShuming Fan //
76c39710dSShuming Fan //
86c39710dSShuming Fan 
96c39710dSShuming Fan #include <linux/delay.h>
106c39710dSShuming Fan #include <linux/device.h>
116c39710dSShuming Fan #include <linux/mod_devicetable.h>
126c39710dSShuming Fan #include <linux/module.h>
136c39710dSShuming Fan #include <linux/pm_runtime.h>
146c39710dSShuming Fan #include <linux/soundwire/sdw_registers.h>
156c39710dSShuming Fan #include "rt712-sdca.h"
166c39710dSShuming Fan #include "rt712-sdca-sdw.h"
176c39710dSShuming Fan 
rt712_sdca_readable_register(struct device * dev,unsigned int reg)186c39710dSShuming Fan static bool rt712_sdca_readable_register(struct device *dev, unsigned int reg)
196c39710dSShuming Fan {
206c39710dSShuming Fan 	switch (reg) {
216c39710dSShuming Fan 	case 0x201a ... 0x201f:
226c39710dSShuming Fan 	case 0x2029 ... 0x202a:
236c39710dSShuming Fan 	case 0x202d ... 0x2034:
246c39710dSShuming Fan 	case 0x2230 ... 0x2232:
256c39710dSShuming Fan 	case 0x2f01 ... 0x2f0a:
266c39710dSShuming Fan 	case 0x2f35 ... 0x2f36:
276c39710dSShuming Fan 	case 0x2f50:
286c39710dSShuming Fan 	case 0x2f54:
296c39710dSShuming Fan 	case 0x2f58 ... 0x2f5d:
306c39710dSShuming Fan 	case 0x3201:
316c39710dSShuming Fan 	case 0x320c:
326c39710dSShuming Fan 	case 0x3301 ... 0x3303:
336c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_SELECTED_MODE, 0):
346c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0):
356c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
366c39710dSShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0):
376c39710dSShuming Fan 	case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2:
386c39710dSShuming Fan 		return true;
396c39710dSShuming Fan 	default:
406c39710dSShuming Fan 		return false;
416c39710dSShuming Fan 	}
426c39710dSShuming Fan }
436c39710dSShuming Fan 
rt712_sdca_volatile_register(struct device * dev,unsigned int reg)446c39710dSShuming Fan static bool rt712_sdca_volatile_register(struct device *dev, unsigned int reg)
456c39710dSShuming Fan {
466c39710dSShuming Fan 	switch (reg) {
476c39710dSShuming Fan 	case 0x201b:
486c39710dSShuming Fan 	case 0x201c:
496c39710dSShuming Fan 	case 0x201d:
506c39710dSShuming Fan 	case 0x201f:
516c39710dSShuming Fan 	case 0x202d ... 0x202f:
526c39710dSShuming Fan 	case 0x2230:
536c39710dSShuming Fan 	case 0x2f01:
546c39710dSShuming Fan 	case 0x2f35:
556c39710dSShuming Fan 	case 0x320c:
566c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0):
576c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
586c39710dSShuming Fan 		SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0):
596c39710dSShuming Fan 	case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2:
606c39710dSShuming Fan 		return true;
616c39710dSShuming Fan 	default:
626c39710dSShuming Fan 		return false;
636c39710dSShuming Fan 	}
646c39710dSShuming Fan }
656c39710dSShuming Fan 
rt712_sdca_mbq_readable_register(struct device * dev,unsigned int reg)666c39710dSShuming Fan static bool rt712_sdca_mbq_readable_register(struct device *dev, unsigned int reg)
676c39710dSShuming Fan {
686c39710dSShuming Fan 	switch (reg) {
696c39710dSShuming Fan 	case 0x2000000 ... 0x200008e:
706c39710dSShuming Fan 	case 0x5300000 ... 0x530000e:
716c39710dSShuming Fan 	case 0x5400000 ... 0x540000e:
726c39710dSShuming Fan 	case 0x5600000 ... 0x5600008:
736c39710dSShuming Fan 	case 0x5700000 ... 0x570000d:
746c39710dSShuming Fan 	case 0x5800000 ... 0x5800021:
756c39710dSShuming Fan 	case 0x5900000 ... 0x5900028:
766c39710dSShuming Fan 	case 0x5a00000 ... 0x5a00009:
776c39710dSShuming Fan 	case 0x5b00000 ... 0x5b00051:
786c39710dSShuming Fan 	case 0x5c00000 ... 0x5c0009a:
796c39710dSShuming Fan 	case 0x5d00000 ... 0x5d00009:
806c39710dSShuming Fan 	case 0x5f00000 ... 0x5f00030:
816c39710dSShuming Fan 	case 0x6100000 ... 0x6100068:
826c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_L):
836c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_R):
846c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_L):
856c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_R):
866c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_L):
876c39710dSShuming Fan 	case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_R):
886c39710dSShuming Fan 		return true;
896c39710dSShuming Fan 	default:
906c39710dSShuming Fan 		return false;
916c39710dSShuming Fan 	}
926c39710dSShuming Fan }
936c39710dSShuming Fan 
rt712_sdca_mbq_volatile_register(struct device * dev,unsigned int reg)946c39710dSShuming Fan static bool rt712_sdca_mbq_volatile_register(struct device *dev, unsigned int reg)
956c39710dSShuming Fan {
966c39710dSShuming Fan 	switch (reg) {
976c39710dSShuming Fan 	case 0x2000000:
986c39710dSShuming Fan 	case 0x200001a:
996c39710dSShuming Fan 	case 0x2000024:
1006c39710dSShuming Fan 	case 0x2000046:
1016c39710dSShuming Fan 	case 0x200008a:
1026c39710dSShuming Fan 	case 0x5800000:
1036c39710dSShuming Fan 	case 0x5800001:
1046c39710dSShuming Fan 	case 0x6100008:
1056c39710dSShuming Fan 		return true;
1066c39710dSShuming Fan 	default:
1076c39710dSShuming Fan 		return false;
1086c39710dSShuming Fan 	}
1096c39710dSShuming Fan }
1106c39710dSShuming Fan 
1116c39710dSShuming Fan static const struct regmap_config rt712_sdca_regmap = {
1126c39710dSShuming Fan 	.reg_bits = 32,
1136c39710dSShuming Fan 	.val_bits = 8,
1146c39710dSShuming Fan 	.readable_reg = rt712_sdca_readable_register,
1156c39710dSShuming Fan 	.volatile_reg = rt712_sdca_volatile_register,
1166c39710dSShuming Fan 	.max_register = 0x44ffffff,
1176c39710dSShuming Fan 	.reg_defaults = rt712_sdca_reg_defaults,
1186c39710dSShuming Fan 	.num_reg_defaults = ARRAY_SIZE(rt712_sdca_reg_defaults),
119f438c799SMark Brown 	.cache_type = REGCACHE_MAPLE,
1206c39710dSShuming Fan 	.use_single_read = true,
1216c39710dSShuming Fan 	.use_single_write = true,
1226c39710dSShuming Fan };
1236c39710dSShuming Fan 
1246c39710dSShuming Fan static const struct regmap_config rt712_sdca_mbq_regmap = {
1256c39710dSShuming Fan 	.name = "sdw-mbq",
1266c39710dSShuming Fan 	.reg_bits = 32,
1276c39710dSShuming Fan 	.val_bits = 16,
1286c39710dSShuming Fan 	.readable_reg = rt712_sdca_mbq_readable_register,
1296c39710dSShuming Fan 	.volatile_reg = rt712_sdca_mbq_volatile_register,
1306c39710dSShuming Fan 	.max_register = 0x41000312,
1316c39710dSShuming Fan 	.reg_defaults = rt712_sdca_mbq_defaults,
1326c39710dSShuming Fan 	.num_reg_defaults = ARRAY_SIZE(rt712_sdca_mbq_defaults),
133f438c799SMark Brown 	.cache_type = REGCACHE_MAPLE,
1346c39710dSShuming Fan 	.use_single_read = true,
1356c39710dSShuming Fan 	.use_single_write = true,
1366c39710dSShuming Fan };
1376c39710dSShuming Fan 
rt712_sdca_update_status(struct sdw_slave * slave,enum sdw_slave_status status)1386c39710dSShuming Fan static int rt712_sdca_update_status(struct sdw_slave *slave,
1396c39710dSShuming Fan 				enum sdw_slave_status status)
1406c39710dSShuming Fan {
1416c39710dSShuming Fan 	struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev);
1426c39710dSShuming Fan 
1436c39710dSShuming Fan 	if (status == SDW_SLAVE_UNATTACHED)
1446c39710dSShuming Fan 		rt712->hw_init = false;
1456c39710dSShuming Fan 
1466c39710dSShuming Fan 	if (status == SDW_SLAVE_ATTACHED) {
1476c39710dSShuming Fan 		if (rt712->hs_jack) {
1486c39710dSShuming Fan 			/*
1496c39710dSShuming Fan 			 * Due to the SCP_SDCA_INTMASK will be cleared by any reset, and then
1506c39710dSShuming Fan 			 * if the device attached again, we will need to set the setting back.
1516c39710dSShuming Fan 			 * It could avoid losing the jack detection interrupt.
1526c39710dSShuming Fan 			 * This also could sync with the cache value as the rt712_sdca_jack_init set.
1536c39710dSShuming Fan 			 */
1546c39710dSShuming Fan 			sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK1,
1556c39710dSShuming Fan 				SDW_SCP_SDCA_INTMASK_SDCA_0);
1566c39710dSShuming Fan 			sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK2,
1576c39710dSShuming Fan 				SDW_SCP_SDCA_INTMASK_SDCA_8);
1586c39710dSShuming Fan 		}
1596c39710dSShuming Fan 	}
1606c39710dSShuming Fan 
1616c39710dSShuming Fan 	/*
1626c39710dSShuming Fan 	 * Perform initialization only if slave status is present and
1636c39710dSShuming Fan 	 * hw_init flag is false
1646c39710dSShuming Fan 	 */
1655cd02f96SKrzysztof Kozlowski 	if (rt712->hw_init || status != SDW_SLAVE_ATTACHED)
1666c39710dSShuming Fan 		return 0;
1676c39710dSShuming Fan 
1686c39710dSShuming Fan 	/* perform I/O transfers required for Slave initialization */
1696c39710dSShuming Fan 	return rt712_sdca_io_init(&slave->dev, slave);
1706c39710dSShuming Fan }
1716c39710dSShuming Fan 
rt712_sdca_read_prop(struct sdw_slave * slave)1726c39710dSShuming Fan static int rt712_sdca_read_prop(struct sdw_slave *slave)
1736c39710dSShuming Fan {
1746c39710dSShuming Fan 	struct sdw_slave_prop *prop = &slave->prop;
1756c39710dSShuming Fan 	int nval;
1766c39710dSShuming Fan 	int i, j;
1776c39710dSShuming Fan 	u32 bit;
1786c39710dSShuming Fan 	unsigned long addr;
1796c39710dSShuming Fan 	struct sdw_dpn_prop *dpn;
1806c39710dSShuming Fan 
1816c39710dSShuming Fan 	prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
1826c39710dSShuming Fan 	prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
1836c39710dSShuming Fan 
1846c39710dSShuming Fan 	prop->paging_support = true;
1856c39710dSShuming Fan 
1866c39710dSShuming Fan 	/* first we need to allocate memory for set bits in port lists */
1876c39710dSShuming Fan 	prop->source_ports = BIT(4); /* BITMAP: 00010000 */
1886c39710dSShuming Fan 	prop->sink_ports = BIT(3) | BIT(1); /* BITMAP:  00001010 */
1896c39710dSShuming Fan 
1906c39710dSShuming Fan 	nval = hweight32(prop->source_ports);
1916c39710dSShuming Fan 	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
1926c39710dSShuming Fan 		sizeof(*prop->src_dpn_prop), GFP_KERNEL);
1936c39710dSShuming Fan 	if (!prop->src_dpn_prop)
1946c39710dSShuming Fan 		return -ENOMEM;
1956c39710dSShuming Fan 
1966c39710dSShuming Fan 	i = 0;
1976c39710dSShuming Fan 	dpn = prop->src_dpn_prop;
1986c39710dSShuming Fan 	addr = prop->source_ports;
1996c39710dSShuming Fan 	for_each_set_bit(bit, &addr, 32) {
2006c39710dSShuming Fan 		dpn[i].num = bit;
2016c39710dSShuming Fan 		dpn[i].type = SDW_DPN_FULL;
2026c39710dSShuming Fan 		dpn[i].simple_ch_prep_sm = true;
2036c39710dSShuming Fan 		dpn[i].ch_prep_timeout = 10;
2046c39710dSShuming Fan 		i++;
2056c39710dSShuming Fan 	}
2066c39710dSShuming Fan 
2076c39710dSShuming Fan 	/* do this again for sink now */
2086c39710dSShuming Fan 	nval = hweight32(prop->sink_ports);
2096c39710dSShuming Fan 	prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,
2106c39710dSShuming Fan 		sizeof(*prop->sink_dpn_prop), GFP_KERNEL);
2116c39710dSShuming Fan 	if (!prop->sink_dpn_prop)
2126c39710dSShuming Fan 		return -ENOMEM;
2136c39710dSShuming Fan 
2146c39710dSShuming Fan 	j = 0;
2156c39710dSShuming Fan 	dpn = prop->sink_dpn_prop;
2166c39710dSShuming Fan 	addr = prop->sink_ports;
2176c39710dSShuming Fan 	for_each_set_bit(bit, &addr, 32) {
2186c39710dSShuming Fan 		dpn[j].num = bit;
2196c39710dSShuming Fan 		dpn[j].type = SDW_DPN_FULL;
2206c39710dSShuming Fan 		dpn[j].simple_ch_prep_sm = true;
2216c39710dSShuming Fan 		dpn[j].ch_prep_timeout = 10;
2226c39710dSShuming Fan 		j++;
2236c39710dSShuming Fan 	}
2246c39710dSShuming Fan 
2256c39710dSShuming Fan 	/* set the timeout values */
2266c39710dSShuming Fan 	prop->clk_stop_timeout = 1380;
2276c39710dSShuming Fan 
2286c39710dSShuming Fan 	/* wake-up event */
2296c39710dSShuming Fan 	prop->wake_capable = 1;
2306c39710dSShuming Fan 
2316c39710dSShuming Fan 	return 0;
2326c39710dSShuming Fan }
2336c39710dSShuming Fan 
rt712_sdca_interrupt_callback(struct sdw_slave * slave,struct sdw_slave_intr_status * status)2346c39710dSShuming Fan static int rt712_sdca_interrupt_callback(struct sdw_slave *slave,
2356c39710dSShuming Fan 					struct sdw_slave_intr_status *status)
2366c39710dSShuming Fan {
2376c39710dSShuming Fan 	struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev);
2386c39710dSShuming Fan 	int ret, stat;
2396c39710dSShuming Fan 	int count = 0, retry = 3;
2406c39710dSShuming Fan 	unsigned int sdca_cascade, scp_sdca_stat1, scp_sdca_stat2 = 0;
2416c39710dSShuming Fan 
2426c39710dSShuming Fan 	dev_dbg(&slave->dev,
2436c39710dSShuming Fan 		"%s control_port_stat=%x, sdca_cascade=%x", __func__,
2446c39710dSShuming Fan 		status->control_port, status->sdca_cascade);
2456c39710dSShuming Fan 
2466c39710dSShuming Fan 	if (cancel_delayed_work_sync(&rt712->jack_detect_work)) {
2476c39710dSShuming Fan 		dev_warn(&slave->dev, "%s the pending delayed_work was cancelled", __func__);
2486c39710dSShuming Fan 		/* avoid the HID owner doesn't change to device */
2496c39710dSShuming Fan 		if (rt712->scp_sdca_stat2)
2506c39710dSShuming Fan 			scp_sdca_stat2 = rt712->scp_sdca_stat2;
2516c39710dSShuming Fan 	}
2526c39710dSShuming Fan 
2536c39710dSShuming Fan 	/*
2546c39710dSShuming Fan 	 * The critical section below intentionally protects a rather large piece of code.
2556c39710dSShuming Fan 	 * We don't want to allow the system suspend to disable an interrupt while we are
2566c39710dSShuming Fan 	 * processing it, which could be problematic given the quirky SoundWire interrupt
2576c39710dSShuming Fan 	 * scheme. We do want however to prevent new workqueues from being scheduled if
2586c39710dSShuming Fan 	 * the disable_irq flag was set during system suspend.
2596c39710dSShuming Fan 	 */
2606c39710dSShuming Fan 	mutex_lock(&rt712->disable_irq_lock);
2616c39710dSShuming Fan 
2626c39710dSShuming Fan 	ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1);
2636c39710dSShuming Fan 	if (ret < 0)
2646c39710dSShuming Fan 		goto io_error;
2656c39710dSShuming Fan 	rt712->scp_sdca_stat1 = ret;
2666c39710dSShuming Fan 	ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2);
2676c39710dSShuming Fan 	if (ret < 0)
2686c39710dSShuming Fan 		goto io_error;
2696c39710dSShuming Fan 	rt712->scp_sdca_stat2 = ret;
2706c39710dSShuming Fan 	if (scp_sdca_stat2)
2716c39710dSShuming Fan 		rt712->scp_sdca_stat2 |= scp_sdca_stat2;
2726c39710dSShuming Fan 
2736c39710dSShuming Fan 	do {
2746c39710dSShuming Fan 		/* clear flag */
2756c39710dSShuming Fan 		ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1);
2766c39710dSShuming Fan 		if (ret < 0)
2776c39710dSShuming Fan 			goto io_error;
2786c39710dSShuming Fan 		if (ret & SDW_SCP_SDCA_INTMASK_SDCA_0) {
2796c39710dSShuming Fan 			ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT1,
2806c39710dSShuming Fan 						SDW_SCP_SDCA_INTMASK_SDCA_0);
2816c39710dSShuming Fan 			if (ret < 0)
2826c39710dSShuming Fan 				goto io_error;
2836c39710dSShuming Fan 		}
2846c39710dSShuming Fan 		ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2);
2856c39710dSShuming Fan 		if (ret < 0)
2866c39710dSShuming Fan 			goto io_error;
2876c39710dSShuming Fan 		if (ret & SDW_SCP_SDCA_INTMASK_SDCA_8) {
2886c39710dSShuming Fan 			ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT2,
2896c39710dSShuming Fan 						SDW_SCP_SDCA_INTMASK_SDCA_8);
2906c39710dSShuming Fan 			if (ret < 0)
2916c39710dSShuming Fan 				goto io_error;
2926c39710dSShuming Fan 		}
2936c39710dSShuming Fan 
2946c39710dSShuming Fan 		/* check if flag clear or not */
2956c39710dSShuming Fan 		ret = sdw_read_no_pm(rt712->slave, SDW_DP0_INT);
2966c39710dSShuming Fan 		if (ret < 0)
2976c39710dSShuming Fan 			goto io_error;
2986c39710dSShuming Fan 		sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
2996c39710dSShuming Fan 
3006c39710dSShuming Fan 		ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1);
3016c39710dSShuming Fan 		if (ret < 0)
3026c39710dSShuming Fan 			goto io_error;
3036c39710dSShuming Fan 		scp_sdca_stat1 = ret & SDW_SCP_SDCA_INTMASK_SDCA_0;
3046c39710dSShuming Fan 
3056c39710dSShuming Fan 		ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2);
3066c39710dSShuming Fan 		if (ret < 0)
3076c39710dSShuming Fan 			goto io_error;
3086c39710dSShuming Fan 		scp_sdca_stat2 = ret & SDW_SCP_SDCA_INTMASK_SDCA_8;
3096c39710dSShuming Fan 
3106c39710dSShuming Fan 		stat = scp_sdca_stat1 || scp_sdca_stat2 || sdca_cascade;
3116c39710dSShuming Fan 
3126c39710dSShuming Fan 		count++;
3136c39710dSShuming Fan 	} while (stat != 0 && count < retry);
3146c39710dSShuming Fan 
3156c39710dSShuming Fan 	if (stat)
3166c39710dSShuming Fan 		dev_warn(&slave->dev,
3176c39710dSShuming Fan 			"%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,
3186c39710dSShuming Fan 			rt712->scp_sdca_stat1, rt712->scp_sdca_stat2);
3196c39710dSShuming Fan 
3206c39710dSShuming Fan 	if (status->sdca_cascade && !rt712->disable_irq)
3216c39710dSShuming Fan 		mod_delayed_work(system_power_efficient_wq,
3226c39710dSShuming Fan 			&rt712->jack_detect_work, msecs_to_jiffies(30));
3236c39710dSShuming Fan 
3246c39710dSShuming Fan 	mutex_unlock(&rt712->disable_irq_lock);
3256c39710dSShuming Fan 
3266c39710dSShuming Fan 	return 0;
3276c39710dSShuming Fan 
3286c39710dSShuming Fan io_error:
3296c39710dSShuming Fan 	mutex_unlock(&rt712->disable_irq_lock);
3306c39710dSShuming Fan 	pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret);
3316c39710dSShuming Fan 	return ret;
3326c39710dSShuming Fan }
3336c39710dSShuming Fan 
3346c39710dSShuming Fan static struct sdw_slave_ops rt712_sdca_slave_ops = {
3356c39710dSShuming Fan 	.read_prop = rt712_sdca_read_prop,
3366c39710dSShuming Fan 	.interrupt_callback = rt712_sdca_interrupt_callback,
3376c39710dSShuming Fan 	.update_status = rt712_sdca_update_status,
3386c39710dSShuming Fan };
3396c39710dSShuming Fan 
rt712_sdca_sdw_probe(struct sdw_slave * slave,const struct sdw_device_id * id)3406c39710dSShuming Fan static int rt712_sdca_sdw_probe(struct sdw_slave *slave,
3416c39710dSShuming Fan 				const struct sdw_device_id *id)
3426c39710dSShuming Fan {
3436c39710dSShuming Fan 	struct regmap *regmap, *mbq_regmap;
3446c39710dSShuming Fan 
3456c39710dSShuming Fan 	/* Regmap Initialization */
3466c39710dSShuming Fan 	mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt712_sdca_mbq_regmap);
3476c39710dSShuming Fan 	if (IS_ERR(mbq_regmap))
3486c39710dSShuming Fan 		return PTR_ERR(mbq_regmap);
3496c39710dSShuming Fan 
3506c39710dSShuming Fan 	regmap = devm_regmap_init_sdw(slave, &rt712_sdca_regmap);
3516c39710dSShuming Fan 	if (IS_ERR(regmap))
3526c39710dSShuming Fan 		return PTR_ERR(regmap);
3536c39710dSShuming Fan 
3546c39710dSShuming Fan 	return rt712_sdca_init(&slave->dev, regmap, mbq_regmap, slave);
3556c39710dSShuming Fan }
3566c39710dSShuming Fan 
rt712_sdca_sdw_remove(struct sdw_slave * slave)3576c39710dSShuming Fan static int rt712_sdca_sdw_remove(struct sdw_slave *slave)
3586c39710dSShuming Fan {
3596c39710dSShuming Fan 	struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev);
3606c39710dSShuming Fan 
3616c39710dSShuming Fan 	if (rt712->hw_init) {
3626c39710dSShuming Fan 		cancel_delayed_work_sync(&rt712->jack_detect_work);
3636c39710dSShuming Fan 		cancel_delayed_work_sync(&rt712->jack_btn_check_work);
3646c39710dSShuming Fan 	}
3656c39710dSShuming Fan 
3666c39710dSShuming Fan 	pm_runtime_disable(&slave->dev);
3676c39710dSShuming Fan 
3686c39710dSShuming Fan 	mutex_destroy(&rt712->calibrate_mutex);
3696c39710dSShuming Fan 	mutex_destroy(&rt712->disable_irq_lock);
3706c39710dSShuming Fan 
3716c39710dSShuming Fan 	return 0;
3726c39710dSShuming Fan }
3736c39710dSShuming Fan 
3746c39710dSShuming Fan static const struct sdw_device_id rt712_sdca_id[] = {
3756c39710dSShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x712, 0x3, 0x1, 0),
3766c39710dSShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x713, 0x3, 0x1, 0),
3776c39710dSShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x716, 0x3, 0x1, 0),
3786c39710dSShuming Fan 	SDW_SLAVE_ENTRY_EXT(0x025d, 0x717, 0x3, 0x1, 0),
3796c39710dSShuming Fan 	{},
3806c39710dSShuming Fan };
3816c39710dSShuming Fan MODULE_DEVICE_TABLE(sdw, rt712_sdca_id);
3826c39710dSShuming Fan 
rt712_sdca_dev_suspend(struct device * dev)3836c39710dSShuming Fan static int __maybe_unused rt712_sdca_dev_suspend(struct device *dev)
3846c39710dSShuming Fan {
3856c39710dSShuming Fan 	struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);
3866c39710dSShuming Fan 
3876c39710dSShuming Fan 	if (!rt712->hw_init)
3886c39710dSShuming Fan 		return 0;
3896c39710dSShuming Fan 
3906c39710dSShuming Fan 	cancel_delayed_work_sync(&rt712->jack_detect_work);
3916c39710dSShuming Fan 	cancel_delayed_work_sync(&rt712->jack_btn_check_work);
3926c39710dSShuming Fan 
3936c39710dSShuming Fan 	regcache_cache_only(rt712->regmap, true);
3946c39710dSShuming Fan 	regcache_cache_only(rt712->mbq_regmap, true);
3956c39710dSShuming Fan 
3966c39710dSShuming Fan 	return 0;
3976c39710dSShuming Fan }
3986c39710dSShuming Fan 
rt712_sdca_dev_system_suspend(struct device * dev)3996c39710dSShuming Fan static int __maybe_unused rt712_sdca_dev_system_suspend(struct device *dev)
4006c39710dSShuming Fan {
4016c39710dSShuming Fan 	struct rt712_sdca_priv *rt712_sdca = dev_get_drvdata(dev);
4026c39710dSShuming Fan 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
4036c39710dSShuming Fan 	int ret1, ret2;
4046c39710dSShuming Fan 
4056c39710dSShuming Fan 	if (!rt712_sdca->hw_init)
4066c39710dSShuming Fan 		return 0;
4076c39710dSShuming Fan 
4086c39710dSShuming Fan 	/*
4096c39710dSShuming Fan 	 * prevent new interrupts from being handled after the
4106c39710dSShuming Fan 	 * deferred work completes and before the parent disables
4116c39710dSShuming Fan 	 * interrupts on the link
4126c39710dSShuming Fan 	 */
4136c39710dSShuming Fan 	mutex_lock(&rt712_sdca->disable_irq_lock);
4146c39710dSShuming Fan 	rt712_sdca->disable_irq = true;
4156c39710dSShuming Fan 	ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1,
4166c39710dSShuming Fan 				SDW_SCP_SDCA_INTMASK_SDCA_0, 0);
4176c39710dSShuming Fan 	ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2,
4186c39710dSShuming Fan 				SDW_SCP_SDCA_INTMASK_SDCA_8, 0);
4196c39710dSShuming Fan 	mutex_unlock(&rt712_sdca->disable_irq_lock);
4206c39710dSShuming Fan 
4216c39710dSShuming Fan 	if (ret1 < 0 || ret2 < 0) {
4226c39710dSShuming Fan 		/* log but don't prevent suspend from happening */
4236c39710dSShuming Fan 		dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__);
4246c39710dSShuming Fan 	}
4256c39710dSShuming Fan 
4266c39710dSShuming Fan 	return rt712_sdca_dev_suspend(dev);
4276c39710dSShuming Fan }
4286c39710dSShuming Fan 
4296c39710dSShuming Fan #define RT712_PROBE_TIMEOUT 5000
4306c39710dSShuming Fan 
rt712_sdca_dev_resume(struct device * dev)4316c39710dSShuming Fan static int __maybe_unused rt712_sdca_dev_resume(struct device *dev)
4326c39710dSShuming Fan {
4336c39710dSShuming Fan 	struct sdw_slave *slave = dev_to_sdw_dev(dev);
4346c39710dSShuming Fan 	struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);
4356c39710dSShuming Fan 	unsigned long time;
4366c39710dSShuming Fan 
4376c39710dSShuming Fan 	if (!rt712->first_hw_init)
4386c39710dSShuming Fan 		return 0;
4396c39710dSShuming Fan 
4407a8735c1SShuming Fan 	if (!slave->unattach_request) {
4417a8735c1SShuming Fan 		mutex_lock(&rt712->disable_irq_lock);
442*10641083SPierre-Louis Bossart 		if (rt712->disable_irq == true) {
443*10641083SPierre-Louis Bossart 
4447a8735c1SShuming Fan 			sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0);
4457a8735c1SShuming Fan 			sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8);
4467a8735c1SShuming Fan 			rt712->disable_irq = false;
4477a8735c1SShuming Fan 		}
448*10641083SPierre-Louis Bossart 		mutex_unlock(&rt712->disable_irq_lock);
4496c39710dSShuming Fan 		goto regmap_sync;
4507a8735c1SShuming Fan 	}
4516c39710dSShuming Fan 
4526c39710dSShuming Fan 	time = wait_for_completion_timeout(&slave->initialization_complete,
4536c39710dSShuming Fan 				msecs_to_jiffies(RT712_PROBE_TIMEOUT));
4546c39710dSShuming Fan 	if (!time) {
4556c39710dSShuming Fan 		dev_err(&slave->dev, "Initialization not complete, timed out\n");
4566c39710dSShuming Fan 		sdw_show_ping_status(slave->bus, true);
4576c39710dSShuming Fan 
4586c39710dSShuming Fan 		return -ETIMEDOUT;
4596c39710dSShuming Fan 	}
4606c39710dSShuming Fan 
4616c39710dSShuming Fan regmap_sync:
4626c39710dSShuming Fan 	slave->unattach_request = 0;
4636c39710dSShuming Fan 	regcache_cache_only(rt712->regmap, false);
4646c39710dSShuming Fan 	regcache_sync(rt712->regmap);
4656c39710dSShuming Fan 	regcache_cache_only(rt712->mbq_regmap, false);
4666c39710dSShuming Fan 	regcache_sync(rt712->mbq_regmap);
4676c39710dSShuming Fan 	return 0;
4686c39710dSShuming Fan }
4696c39710dSShuming Fan 
4706c39710dSShuming Fan static const struct dev_pm_ops rt712_sdca_pm = {
4716c39710dSShuming Fan 	SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dev_system_suspend, rt712_sdca_dev_resume)
4726c39710dSShuming Fan 	SET_RUNTIME_PM_OPS(rt712_sdca_dev_suspend, rt712_sdca_dev_resume, NULL)
4736c39710dSShuming Fan };
4746c39710dSShuming Fan 
4756c39710dSShuming Fan static struct sdw_driver rt712_sdca_sdw_driver = {
4766c39710dSShuming Fan 	.driver = {
4776c39710dSShuming Fan 		.name = "rt712-sdca",
4786c39710dSShuming Fan 		.owner = THIS_MODULE,
4796c39710dSShuming Fan 		.pm = &rt712_sdca_pm,
4806c39710dSShuming Fan 	},
4816c39710dSShuming Fan 	.probe = rt712_sdca_sdw_probe,
4826c39710dSShuming Fan 	.remove = rt712_sdca_sdw_remove,
4836c39710dSShuming Fan 	.ops = &rt712_sdca_slave_ops,
4846c39710dSShuming Fan 	.id_table = rt712_sdca_id,
4856c39710dSShuming Fan };
4866c39710dSShuming Fan module_sdw_driver(rt712_sdca_sdw_driver);
4876c39710dSShuming Fan 
4886c39710dSShuming Fan MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver");
4896c39710dSShuming Fan MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
4906c39710dSShuming Fan MODULE_LICENSE("GPL");
491