#include "common.h" #include #include #include #include #include #include #include "ipc.h" #include "gameCode.h" #include "DSMode.h" void DSMode::SwitchToDSMode(u32 gameCode) const { SwitchToDSTouchAndSoundMode(gameCode); mcu_writeReg(MCU_REG_MODE, 0); *(vu16*)0x04004C04 |= (1 << 8); // ntr wifi REG_SCFG_A9ROM = SCFG_A9ROM_DISABLE_SECURE | SCFG_A9ROM_NITRO; REG_SCFG_A7ROM = SCFG_A7ROM_DISABLE_SECURE | SCFG_A7ROM_NITRO | SCFG_A7ROM_DISABLE_FUSE; REG_SCFG_EXT = 0x12A03000u; sendToArm9(IPC_COMMAND_ARM9_SWITCH_TO_DS_MODE); receiveFromArm9(); LOG_DEBUG("Switched to ds mode\n"); } void DSMode::SwitchToDSTouchAndSoundMode(u32 gameCode) const { REG_I2SCNT = I2SCNT_MIX_RATIO_DSP_0_NITRO_8 | I2SCNT_FREQUENCY_32728_HZ; codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_DAC_NDAC_VAL, 0x87); codec_writeRegister(CODEC_REG_PAGE0_ADC_NADC_VAL, 0x87); codec_writeRegister(CODEC_REG_PAGE0_PLL_J, 21); } REG_I2SCNT |= I2SCNT_ENABLE; SwitchCodecToDSMode(gameCode); REG_SOUNDCNT = SOUNDCNT_MASTER_ENABLE | SOUNDCNT_MASTER_VOLUME(0x7F); LOG_DEBUG("Switched to ds touch and sound mode\n"); } void DSMode::SwitchCodecToDSMode(u32 gameCode) const { // 0xAC: special setting (when found special gamecode) // 0xA7: normal setting (for any other gamecodes) u8 volLevel = ShouldUseVolumeFix(gameCode) ? 0xAC : 0xA7; // Touchscreen codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_GPI3_PIN_CONTROL, 0x00); codec_readRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC); } codec_setPage(CODEC_PAGE_3); { codec_readRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_1); } codec_setPage(CODEC_PAGE_0); { codec_readRegister(CODEC_REG_PAGE0_DAC_DATA_PATH_SETUP); } codec_setPage(CODEC_PAGE_1); { codec_readRegister(CODEC_REG_PAGE1_HPL_DRIVER); codec_readRegister(CODEC_REG_PAGE1_SPL_DRIVER); codec_readRegister(CODEC_REG_PAGE1_MICBIAS); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_VOLUME_CONTROL_FINE_ADJUST, 0x80); codec_writeRegister(CODEC_REG_PAGE0_DAC_VOLUME_CONTROL, 0x0C); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_LEFT_ANALOG_VOL_TO_HPL, 0xFF); codec_writeRegister(CODEC_REG_PAGE1_RIGHT_ANALOG_VOL_TO_HPR, 0xFF); codec_writeRegister(CODEC_REG_PAGE1_LEFT_ANALOG_VOL_TO_SPL, 0x7F); codec_writeRegister(CODEC_REG_PAGE1_RIGHT_ANALOG_VOL_TO_SPR, 0x7F); codec_writeRegister(CODEC_REG_PAGE1_HPL_DRIVER, 0x4A); codec_writeRegister(CODEC_REG_PAGE1_HPR_DRIVER, 0x4A); codec_writeRegister(CODEC_REG_PAGE1_SPL_DRIVER, 0x10); codec_writeRegister(CODEC_REG_PAGE1_SPR_DRIVER, 0x10); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC, 0x00); } codec_setPage(CODEC_PAGE_3); { codec_readRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_1); codec_writeRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_1, 0x98); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_DAC_L_DAC_R_OUTPUT_MIXER_ROUTING, 0x00); codec_writeRegister(CODEC_REG_PAGE1_HEADPHONE_DRIVERS, 0x14); codec_writeRegister(CODEC_REG_PAGE1_CLASS_D_SPEAKER_AMPLIFIER, 0x14); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_DAC_DATA_PATH_SETUP, 0x00); codec_readRegister(CODEC_REG_PAGE0_DAC_NDAC_VAL); codec_writeRegister(CODEC_REG_PAGE0_PLL_P_R, 0x00); codec_writeRegister(CODEC_REG_PAGE0_DAC_NDAC_VAL, 0x01); codec_writeRegister(CODEC_REG_PAGE0_DAC_MDAC_VAL, 0x02); codec_writeRegister(CODEC_REG_PAGE0_ADC_NADC_VAL, 0x01); codec_writeRegister(CODEC_REG_PAGE0_ADC_MADC_VAL, 0x02); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_MICBIAS, 0x00); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_GPI3_PIN_CONTROL, 0x60); codec_writeRegister(CODEC_REG_PAGE0_RESET, 0x01); codec_writeRegister(CODEC_REG_PAGE0_GPI1_GPI2_PIN_CONTROL, 0x66); } codec_setPage(CODEC_PAGE_1); { codec_readRegister(CODEC_REG_PAGE1_CLASS_D_SPEAKER_AMPLIFIER); codec_writeRegister(CODEC_REG_PAGE1_CLASS_D_SPEAKER_AMPLIFIER, 0x10); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_CLOCK_GEN_MUXING, 0x00); codec_writeRegister(CODEC_REG_PAGE0_ADC_NADC_VAL, 0x81); codec_writeRegister(CODEC_REG_PAGE0_ADC_MADC_VAL, 0x82); codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC, 0x82); codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC, 0x00); codec_writeRegister(CODEC_REG_PAGE0_CLOCK_GEN_MUXING, 0x03); codec_writeRegister(CODEC_REG_PAGE0_PLL_P_R, 0xA1); codec_writeRegister(CODEC_REG_PAGE0_PLL_J, 0x15); codec_writeRegister(CODEC_REG_PAGE0_DAC_NDAC_VAL, 0x87); codec_writeRegister(CODEC_REG_PAGE0_DAC_MDAC_VAL, 0x83); codec_writeRegister(CODEC_REG_PAGE0_ADC_NADC_VAL, 0x87); codec_writeRegister(CODEC_REG_PAGE0_ADC_MADC_VAL, 0x83); } codec_setPage(CODEC_PAGE_3); { codec_readRegister(CODEC_REG_PAGE3_SCAN_MODE_TIMER_CLOCK); codec_writeRegister(CODEC_REG_PAGE3_SCAN_MODE_TIMER_CLOCK, 0x08); } codec_setPage(CODEC_PAGE_4); { codec_writeRegister(0x08, 0x7F); codec_writeRegister(0x09, 0xE1); codec_writeRegister(0x0A, 0x80); codec_writeRegister(0x0B, 0x1F); codec_writeRegister(0x0C, 0x7F); codec_writeRegister(0x0D, 0xC1); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_DAC_LEFT_VOLUME_CONTROL, 0x08); codec_writeRegister(CODEC_REG_PAGE0_DAC_RIGHT_VOLUME_CONTROL, 0x08); codec_writeRegister(CODEC_REG_PAGE0_GPI3_PIN_CONTROL, 0x00); } codec_setPage(CODEC_PAGE_4); { codec_writeRegister(0x08, 0x7F); codec_writeRegister(0x09, 0xE1); codec_writeRegister(0x0A, 0x80); codec_writeRegister(0x0B, 0x1F); codec_writeRegister(0x0C, 0x7F); codec_writeRegister(0x0D, 0xC1); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_MIC_PGA, 0x2B); codec_writeRegister(CODEC_REG_PAGE1_DELTA_SIGMA_MONO_ADC_CHANNEL_FINE_GAIN_INPUT_SELECTION_FOR_P_TERMINAL, 0x40); codec_writeRegister(CODEC_REG_PAGE1_ADC_INPUT_SELECTION_FOR_M_TERMINAL, 0x40); codec_writeRegister(CODEC_REG_PAGE1_INPUT_CM_SETTINGS, 0x60); } codec_setPage(CODEC_PAGE_0); { codec_readRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL); codec_writeRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL, 0x02); codec_readRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL); codec_writeRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL, 0x10); codec_readRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL); codec_writeRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL, 0x40); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_HP_OUTPUT_DRIVERS_POP_REMOVAL_SETTINGS, 0x20); codec_writeRegister(CODEC_REG_PAGE1_OUTPUT_DRIVER_PGA_RAMP_DOWN_PERIOD_CONTROL, 0xF0); } codec_setPage(CODEC_PAGE_0); { codec_readRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC); codec_readRegister(CODEC_REG_PAGE0_DAC_DATA_PATH_SETUP); codec_writeRegister(CODEC_REG_PAGE0_DAC_DATA_PATH_SETUP, 0xD4); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_DAC_L_DAC_R_OUTPUT_MIXER_ROUTING, 0x44); codec_writeRegister(CODEC_REG_PAGE1_HEADPHONE_DRIVERS, 0xD4); codec_writeRegister(CODEC_REG_PAGE1_HPL_DRIVER, 0x4E); codec_writeRegister(CODEC_REG_PAGE1_HPR_DRIVER, 0x4E); codec_writeRegister(CODEC_REG_PAGE1_LEFT_ANALOG_VOL_TO_HPL, 0x9E); codec_writeRegister(CODEC_REG_PAGE1_RIGHT_ANALOG_VOL_TO_HPR, 0x9E); codec_writeRegister(CODEC_REG_PAGE1_CLASS_D_SPEAKER_AMPLIFIER, 0xD4); codec_writeRegister(CODEC_REG_PAGE1_SPL_DRIVER, 0x14); codec_writeRegister(CODEC_REG_PAGE1_SPR_DRIVER, 0x14); codec_writeRegister(CODEC_REG_PAGE1_LEFT_ANALOG_VOL_TO_SPL, 0xA7); codec_writeRegister(CODEC_REG_PAGE1_RIGHT_ANALOG_VOL_TO_SPR, 0xA7); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_DAC_VOLUME_CONTROL, 0x00); codec_writeRegister(CODEC_REG_PAGE0_GPI3_PIN_CONTROL, 0x60); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_LEFT_ANALOG_VOL_TO_SPL, volLevel); codec_writeRegister(CODEC_REG_PAGE1_RIGHT_ANALOG_VOL_TO_SPR, volLevel); codec_writeRegister(CODEC_REG_PAGE1_MICBIAS, 0x03); } codec_setPage(CODEC_PAGE_3); { codec_writeRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_2, 0x00); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_HP_OUTPUT_DRIVERS_POP_REMOVAL_SETTINGS, 0x20); codec_writeRegister(CODEC_REG_PAGE1_OUTPUT_DRIVER_PGA_RAMP_DOWN_PERIOD_CONTROL, 0xF0); codec_readRegister(CODEC_REG_PAGE1_OUTPUT_DRIVER_PGA_RAMP_DOWN_PERIOD_CONTROL); codec_writeRegister(CODEC_REG_PAGE1_OUTPUT_DRIVER_PGA_RAMP_DOWN_PERIOD_CONTROL, 0x00); } codec_setPage(CODEC_PAGE_0); { codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_VOLUME_CONTROL_FINE_ADJUST, 0x80); codec_writeRegister(CODEC_REG_PAGE0_ADC_DIGITAL_MIC, 0x00); // Set remaining values codec_writeRegister(0x03, 0x44); codec_writeRegister(CODEC_REG_PAGE0_DAC_DOSR_VAL_MSB, 0x00); codec_writeRegister(CODEC_REG_PAGE0_DAC_DOSR_VAL_LSB, 0x80); codec_writeRegister(CODEC_REG_PAGE0_DAC_IDAC_VAL, 0x80); codec_writeRegister(CODEC_REG_PAGE0_DAC_MINIDSP_INTERPOLATION, 0x08); codec_writeRegister(CODEC_REG_PAGE0_ADC_AOSR_VAL, 0x80); codec_writeRegister(CODEC_REG_PAGE0_ADC_IDAC_VAL, 0x80); codec_writeRegister(CODEC_REG_PAGE0_ADC_MINIDSP_DECIMATION, 0x04); codec_writeRegister(CODEC_REG_PAGE0_CLKOUT_M_VAL, 0x01); codec_writeRegister(CODEC_REG_PAGE0_BCLK_N_VAL, 0x01); codec_writeRegister(CODEC_REG_PAGE0_ADC_FLAG_REGISTER, 0x80); codec_writeRegister(CODEC_REG_PAGE0_GPIO1_IN_OUT_PIN_CONTROL, 0x34); codec_writeRegister(CODEC_REG_PAGE0_GPIO2_IN_OUT_PIN_CONTROL, 0x32); codec_writeRegister(CODEC_REG_PAGE0_SDOUT_OUT_PIN_CONTROL, 0x12); codec_writeRegister(CODEC_REG_PAGE0_SDIN_IN_PIN_CONTROL, 0x03); codec_writeRegister(CODEC_REG_PAGE0_MISO_OUT_PIN_CONTROL, 0x02); codec_writeRegister(CODEC_REG_PAGE0_SCLK_IN_PIN_CONTROL, 0x03); codec_writeRegister(CODEC_REG_PAGE0_DAC_INSTRUCTION_SET, 0x19); codec_writeRegister(CODEC_REG_PAGE0_ADC_INSTRUCTION_SET, 0x05); codec_writeRegister(CODEC_REG_PAGE0_DRC_CONTROL_1, 0x0F); codec_writeRegister(CODEC_REG_PAGE0_DRC_CONTROL_2, 0x38); codec_writeRegister(CODEC_REG_PAGE0_BEEP_LENGTH_MSB, 0x00); codec_writeRegister(CODEC_REG_PAGE0_BEEP_LENGTH_MID, 0x00); codec_writeRegister(CODEC_REG_PAGE0_BEEP_LENGTH_LSB, 0xEE); codec_writeRegister(CODEC_REG_PAGE0_BEEP_SIN_MSB, 0x10); codec_writeRegister(CODEC_REG_PAGE0_BEEP_SIN_LSB, 0xD8); codec_writeRegister(CODEC_REG_PAGE0_BEEP_COS_MSB, 0x7E); codec_writeRegister(CODEC_REG_PAGE0_BEEP_COS_LSB, 0xE3); codec_writeRegister(CODEC_REG_PAGE0_AGC_MAXIMUM_GAIN, 0x7F); codec_writeRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_SAR_ADC_VOLUME_CONTROL, 0xD2); codec_writeRegister(CODEC_REG_PAGE0_VOL_MICDET_PIN_GAIN, 0x2C); } codec_setPage(CODEC_PAGE_1); { codec_writeRegister(CODEC_REG_PAGE1_OUTPUT_DRIVER_PGA_RAMP_DOWN_PERIOD_CONTROL, 0x70); codec_writeRegister(CODEC_REG_PAGE1_HP_DRIVER_CONTROL, 0x20); } // Finish up! codec_setPage(CODEC_PAGE_3); { codec_readRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_1); codec_writeRegister(CODEC_REG_PAGE3_SAR_ADC_CONTROL_1, 0x98); } codec_setPage(CODEC_PAGE_255); { codec_writeRegister(CODEC_REG_PAGE255_BACKWARDS_COMPATIBILITY_MODE, CODEC_PAGE255_BACKWARDS_COMPATIBILITY_MODE_ON); } pmic_setAmplifierEnable(true); } bool DSMode::ShouldUseVolumeFix(u32 gameCode) const { switch (gameCode & 0xFFFFFF) { case GAMECODE_NO_REGION("A3T"): case GAMECODE_NO_REGION("A4U"): case GAMECODE_NO_REGION("A5H"): case GAMECODE_NO_REGION("A5I"): case GAMECODE_NO_REGION("A8N"): case GAMECODE_NO_REGION("ABJ"): case GAMECODE_NO_REGION("ABN"): case GAMECODE_NO_REGION("ABX"): case GAMECODE_NO_REGION("ACC"): case GAMECODE_NO_REGION("ACL"): case GAMECODE_NO_REGION("ACZ"): case GAMECODE_NO_REGION("ADA"): case GAMECODE_NO_REGION("AHD"): case GAMECODE_NO_REGION("AJU"): case GAMECODE_NO_REGION("AKA"): case GAMECODE_NO_REGION("AKE"): case GAMECODE_NO_REGION("ALH"): case GAMECODE_NO_REGION("AMH"): case GAMECODE_NO_REGION("AN9"): case GAMECODE_NO_REGION("ANR"): case GAMECODE_NO_REGION("APA"): case GAMECODE_NO_REGION("APY"): case GAMECODE_NO_REGION("ART"): case GAMECODE_NO_REGION("AV2"): case GAMECODE_NO_REGION("AV3"): case GAMECODE_NO_REGION("AV4"): case GAMECODE_NO_REGION("AV5"): case GAMECODE_NO_REGION("AV6"): case GAMECODE_NO_REGION("AVI"): case GAMECODE_NO_REGION("AVT"): case GAMECODE_NO_REGION("AWH"): case GAMECODE_NO_REGION("AWY"): case GAMECODE_NO_REGION("AXB"): case GAMECODE_NO_REGION("AXJ"): case GAMECODE_NO_REGION("AY7"): case GAMECODE_NO_REGION("AYK"): case GAMECODE_NO_REGION("AZW"): case GAMECODE_NO_REGION("CPU"): case GAMECODE_NO_REGION("YB2"): case GAMECODE_NO_REGION("YB3"): case GAMECODE_NO_REGION("YBO"): case GAMECODE_NO_REGION("YCH"): case GAMECODE_NO_REGION("YCQ"): case GAMECODE_NO_REGION("YFE"): case GAMECODE_NO_REGION("YFS"): case GAMECODE_NO_REGION("YG8"): case GAMECODE_NO_REGION("YGD"): case GAMECODE_NO_REGION("YKR"): case GAMECODE_NO_REGION("YNZ"): case GAMECODE_NO_REGION("YO9"): case GAMECODE_NO_REGION("YON"): case GAMECODE_NO_REGION("YRM"): case GAMECODE_NO_REGION("YT3"): case GAMECODE_NO_REGION("YW2"): case GAMECODE_NO_REGION("YYK"): { return true; } default: { return false; } } }