staticbool rt712_sdca_readable_register(struct device *dev, unsignedint reg)
{ switch (reg) { case 0x201a ... 0x201f: case 0x2029 ... 0x202a: case 0x202d ... 0x2034: case 0x2230 ... 0x2232: case 0x2f01 ... 0x2f0a: case 0x2f35 ... 0x2f36: case 0x2f50: case 0x2f54: case 0x2f58 ... 0x2f5d: case 0x3201: case 0x320c: case 0x3301 ... 0x3303: case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_SELECTED_MODE, 0): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0): case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2: returntrue; default: returnfalse;
}
}
staticbool rt712_sdca_volatile_register(struct device *dev, unsignedint reg)
{ switch (reg) { case 0x201b: case 0x201c: case 0x201d: case 0x201f: case 0x202d ... 0x202f: case 0x2230: case 0x2f01: case 0x2f35: case 0x320c: case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_GE49, RT712_SDCA_CTL_DETECTED_MODE, 0): case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_CURRENT_OWNER, 0) ...
SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT_HID01, RT712_SDCA_CTL_HIDTX_MESSAGE_LENGTH, 0): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_HID, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT0, RT712_SDCA_CTL_FUNC_STATUS, 0): case RT712_BUF_ADDR_HID1 ... RT712_BUF_ADDR_HID2: returntrue; default: returnfalse;
}
}
staticbool rt712_sdca_mbq_readable_register(struct device *dev, unsignedint reg)
{ switch (reg) { case 0x2000000 ... 0x200008e: case 0x5300000 ... 0x530000e: case 0x5400000 ... 0x540000e: case 0x5600000 ... 0x5600008: case 0x5700000 ... 0x570000d: case 0x5800000 ... 0x5800021: case 0x5900000 ... 0x5900028: case 0x5a00000 ... 0x5a00009: case 0x5b00000 ... 0x5b00051: case 0x5c00000 ... 0x5c0009a: case 0x5d00000 ... 0x5d00009: case 0x5f00000 ... 0x5f00030: case 0x6100000 ... 0x61000f1: case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_01): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU05, RT712_SDCA_CTL_FU_VOLUME, CH_02): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_01): case SDW_SDCA_CTL(FUNC_NUM_JACK_CODEC, RT712_SDCA_ENT_USER_FU0F, RT712_SDCA_CTL_FU_VOLUME, CH_02): case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_01): case SDW_SDCA_CTL(FUNC_NUM_AMP, RT712_SDCA_ENT_USER_FU06, RT712_SDCA_CTL_FU_VOLUME, CH_02): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_01): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_02): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_03): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_USER_FU1E, RT712_SDCA_CTL_FU_VOLUME, CH_04): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_01): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_02): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_03): case SDW_SDCA_CTL(FUNC_NUM_MIC_ARRAY, RT712_SDCA_ENT_PLATFORM_FU15, RT712_SDCA_CTL_FU_CH_GAIN, CH_04): returntrue; default: returnfalse;
}
}
staticbool rt712_sdca_mbq_volatile_register(struct device *dev, unsignedint reg)
{ switch (reg) { case 0x2000000: case 0x200001a: case 0x2000020: case 0x2000024: case 0x2000030: case 0x2000046: case 0x200008a: case 0x5800000: case 0x5800001: case 0x6100008: returntrue; default: returnfalse;
}
}
if (status == SDW_SLAVE_UNATTACHED)
rt712->hw_init = false;
if (status == SDW_SLAVE_ATTACHED) { if (rt712->hs_jack) { /* * Due to the SCP_SDCA_INTMASK will be cleared by any reset, and then * if the device attached again, we will need to set the setting back. * It could avoid losing the jack detection interrupt. * This also could sync with the cache value as the rt712_sdca_jack_init set.
*/
sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK1,
SDW_SCP_SDCA_INTMASK_SDCA_0);
sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INTMASK2,
SDW_SCP_SDCA_INTMASK_SDCA_8);
}
}
/* * Perform initialization only if slave status is present and * hw_init flag is false
*/ if (rt712->hw_init || status != SDW_SLAVE_ATTACHED) return 0;
/* first we need to allocate memory for set bits in port lists */
prop->source_ports = BIT(8) | BIT(4); /* BITMAP: 100010000 */
prop->sink_ports = BIT(3) | BIT(1); /* BITMAP: 00001010 */
/* do this again for sink now */
nval = hweight32(prop->sink_ports);
prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, sizeof(*prop->sink_dpn_prop), GFP_KERNEL); if (!prop->sink_dpn_prop) return -ENOMEM;
if (cancel_delayed_work_sync(&rt712->jack_detect_work)) {
dev_warn(&slave->dev, "%s the pending delayed_work was cancelled", __func__); /* avoid the HID owner doesn't change to device */ if (rt712->scp_sdca_stat2)
scp_sdca_stat2 = rt712->scp_sdca_stat2;
}
/* * The critical section below intentionally protects a rather large piece of code. * We don't want to allow the system suspend to disable an interrupt while we are * processing it, which could be problematic given the quirky SoundWire interrupt * scheme. We do want however to prevent new workqueues from being scheduled if * the disable_irq flag was set during system suspend.
*/
mutex_lock(&rt712->disable_irq_lock);
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); if (ret < 0) goto io_error;
rt712->scp_sdca_stat1 = ret;
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); if (ret < 0) goto io_error;
rt712->scp_sdca_stat2 = ret; if (scp_sdca_stat2)
rt712->scp_sdca_stat2 |= scp_sdca_stat2;
do { /* clear flag */
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); if (ret < 0) goto io_error; if (ret & SDW_SCP_SDCA_INTMASK_SDCA_0) {
ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT1,
SDW_SCP_SDCA_INTMASK_SDCA_0); if (ret < 0) goto io_error;
}
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); if (ret < 0) goto io_error; if (ret & SDW_SCP_SDCA_INTMASK_SDCA_8) {
ret = sdw_write_no_pm(rt712->slave, SDW_SCP_SDCA_INT2,
SDW_SCP_SDCA_INTMASK_SDCA_8); if (ret < 0) goto io_error;
}
/* check if flag clear or not */
ret = sdw_read_no_pm(rt712->slave, SDW_DP0_INT); if (ret < 0) goto io_error;
sdca_cascade = ret & SDW_DP0_SDCA_CASCADE;
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT1); if (ret < 0) goto io_error;
scp_sdca_stat1 = ret & SDW_SCP_SDCA_INTMASK_SDCA_0;
ret = sdw_read_no_pm(rt712->slave, SDW_SCP_SDCA_INT2); if (ret < 0) goto io_error;
scp_sdca_stat2 = ret & SDW_SCP_SDCA_INTMASK_SDCA_8;
stat = scp_sdca_stat1 || scp_sdca_stat2 || sdca_cascade;
count++;
} while (stat != 0 && count < retry);
if (stat)
dev_warn(&slave->dev, "%s scp_sdca_stat1=0x%x, scp_sdca_stat2=0x%x\n", __func__,
rt712->scp_sdca_stat1, rt712->scp_sdca_stat2);
if (status->sdca_cascade && !rt712->disable_irq)
mod_delayed_work(system_power_efficient_wq,
&rt712->jack_detect_work, msecs_to_jiffies(30));
mutex_unlock(&rt712->disable_irq_lock);
return 0;
io_error:
mutex_unlock(&rt712->disable_irq_lock);
pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); return ret;
}
/* * prevent new interrupts from being handled after the * deferred work completes and before the parent disables * interrupts on the link
*/
mutex_lock(&rt712_sdca->disable_irq_lock);
rt712_sdca->disable_irq = true;
ret1 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK1,
SDW_SCP_SDCA_INTMASK_SDCA_0, 0);
ret2 = sdw_update_no_pm(slave, SDW_SCP_SDCA_INTMASK2,
SDW_SCP_SDCA_INTMASK_SDCA_8, 0);
mutex_unlock(&rt712_sdca->disable_irq_lock);
if (ret1 < 0 || ret2 < 0) { /* log but don't prevent suspend from happening */
dev_dbg(&slave->dev, "%s: could not disable SDCA interrupts\n:", __func__);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.