1898 lines
83 KiB
C
1898 lines
83 KiB
C
|
|
// this contains functions converted to use proper i2c calls
|
|
|
|
// re-define this here so can turn this off for this file specifically
|
|
#define mycodec_i2c_local_info mycodec_i2c_info
|
|
|
|
static void cs42l83_headset_button_detect_interrupts_off(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_button_detect_interrupts_off\n");
|
|
|
|
// this could be AppleHDAMikeyInternalCS8409::disableButtonDetection
|
|
// - this calls 0x1b7c and 0x1b7a
|
|
|
|
//snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_POWER_STATE, 0x00000000); // 0x00170500
|
|
hda_set_node_power_state(codec, codec->core.afg, AC_PWRST_D0);
|
|
|
|
// register 0x1b7c - this is undocumented for 42l42 (reserved) - maybe more interrupt mask registers
|
|
// sort of assuming it shows which interrupts have occurred
|
|
// value 0x00
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// changed from 0xff (default) to 0xff (all masked)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7aff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_set_hpout_clamp_disable(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_set_hpout_clamp_disable\n");
|
|
|
|
// AppleHDATDM_CS42L83::setHPOutClamp
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x2 (default) to 0x06
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0602
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0606 i2c data 0x0006
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0006, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_complete_jack_detect(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_complete_jack_detect\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::completeJackDetectUR
|
|
|
|
// similar calls also appear in AppleHDATDM_CS42L83::enterStandby - but these are explicit calls in completeJackDetectUR
|
|
|
|
// so this appears to change 0x1b75 from 0x9f to 0xb5
|
|
// according to docs this is 0x80 LATCH_TO_VP set
|
|
// and HS_DETECT_LEVEL from 0x1f (default) to 0x35
|
|
|
|
// register 0x1b75 - Mic Detect Control 1
|
|
// changed from 0x9f ((0x80 LATCH_TO_VP set, HS_DETECT_LEVEL 1f) to 0xb5 (0x80 LATCH_TO_VP set, HS_DETECT_LEVEL 0x35)
|
|
|
|
// maybe readMikey with 0x6 1st arg doesnt do anything??
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x3 (default) to 0x1 (Output HiZ, powered Down)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7500 i2c data 0x759f
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x75b5 i2c data 0x00b5
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7403
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7401 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b75, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b75, 0x00b5, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0001, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_power_hs_bias_on(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_hs_bias_on\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::powerHSBIAS
|
|
|
|
// readMikey analysis for AppleHDATDM_CS42L83::readMikey
|
|
// if 1st arg is equal or above 0x70 we send eg 0x1b70 (0x1b for our case)
|
|
// if 1st arg is below 0x70 we do special things
|
|
// subtract 8 from it compare in range 0 to 5
|
|
// (so 8 becomes 0, 9 becomes 1, 10 becomes 2, 11 becomes 3)
|
|
// 0x111f is loaded by default
|
|
// 8 0 is 0x111f
|
|
// 9 1 is 0x1120
|
|
// 10 2 is 0x1121
|
|
// 11 3 is 0x1124
|
|
|
|
// writeMikey analysis for AppleHDATDM_CS42L83::writeMikey
|
|
// if 1st arg is equal or above 0x70 we send eg 0x1b70 (0x1b for our case)
|
|
// if 1st arg is below 0x70 we do special things
|
|
// subtract 6 from it compare in range 0 to 7
|
|
// (so 8 becomes 2, 9 becomes 3, 10 becomes 4)
|
|
// 0x111f is loaded by default
|
|
// 8 2 is 0x111f
|
|
// 9 3 is 0x1120
|
|
// 10 4 is 0x1121
|
|
// 11 5 is 0x1124
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// value 0x1 (Output HiZ, powered Down)
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x0 (default) to 0x8 (manual disabled, hs bias closed, auto time 10 microsecs)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// set to 0x7 (Output 2.7V, powered Down) - headset interface functional
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x8 to 0x0 (default)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7401
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2008 i2c data 0x0008
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7407 i2c data 0x0007
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2008
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0008, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0007, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hs_auto_int_on(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hs_auto_int_on\n");
|
|
|
|
// AppleHDATDM_CS42L83::enableHSDetAutoInt(bool)
|
|
// this involves a read then write
|
|
|
|
// register 0x131b - Codec Interrupt Mask
|
|
// changed from 0x3 (default) to 0x1
|
|
// this is enabling auto headset detection (well HSDET_AUTO_DONE)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x13 lo 0x1b00 i2c data 0x1b03
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x13 lo 0x1b01 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x131b, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x131b, 0x0001, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_unplug_interrupt_setup(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_unplug_interrupt_setup\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::completeJackDetectUR
|
|
|
|
// interrupt clearing seems to be triggered by reading registers in this routine (hence the name)
|
|
|
|
// register 0x1b7b - this is undocumented for 42l42 but labelled in fig 4-45 as Interrupt
|
|
// Detect Interrupt 1 Status
|
|
// value 0x00
|
|
// register 0x1b79 - Detect Interrupt Mask 1
|
|
// changed from 0xa0 to 0xc0
|
|
// this masks TIP_SENSE_PLUG and unmasks TIP_SENSE_UNPLUG
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7b00 i2c data 0x7b00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7900 i2c data 0x79a0
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x79c0 i2c data 0x00c0
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7b, 1); // snd_hda
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b79, 1); // snd_hda
|
|
|
|
newval = (retval & 0x9f) | 0x40;
|
|
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b79, newval, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b79, 0x00c0, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_set_hpout_pulldown_off(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_set_hpout_pulldown_off\n");
|
|
|
|
// AppleHDATDM_CS42L83::setHPOutPulldown
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x6 to 0x86 (no HPOUT_PULL_DOWN)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0606
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0686 i2c data 0x0086
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0086, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1f06, 0xf0, 0x80, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_detect_on(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_detect_on\n");
|
|
|
|
// this is AppleHDAMikeyInternalCS8409::enableHSDetection
|
|
// this calls readMikey/writeMikey with either 0x8 arg or 0x9 arg
|
|
// I think 0x8 arg is one used in the log
|
|
|
|
// readMikey analysis for AppleHDATDM_CS42L83::readMikey
|
|
// if 1st arg is equal or above 0x70 we send eg 0x1b70 (0x1b for our case)
|
|
// if 1st arg is below 0x70 we do special things
|
|
// subtract 7 from it compare in range 0 to 5
|
|
// (so 8 becomes 1, 9 becomes 2)
|
|
// 0x111f is loaded by default
|
|
// 1 is 0x1120
|
|
|
|
// writeMikey analysis for AppleHDATDM_CS42L83::writeMikey
|
|
// if 1st arg is equal or above 0x70 we send eg 0x1b70 (0x1b for our case)
|
|
// if 1st arg is below 0x70 we do special things
|
|
// subtract 5 from it compare in range 0 to 7
|
|
// (so 8 becomes 3, 9 becomes 4)
|
|
// 0x111f is loaded by default
|
|
// 3 is 0x1120
|
|
|
|
// register 0x111f - Headset Detect Control 1
|
|
// changed from 0x77 (default) to 0x72
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x00 (default) to 0xc2
|
|
// 0xc0 headset detection automatic, 0x2 HSDET_AUTO_TIME 50 microsecs
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x1f00 i2c data 0x1f77
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x1f72 i2c data 0x0072
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x20c2 i2c data 0x00c2
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x111f, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x111f, 0x0072, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x00c2, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_detect_off(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_detect_off\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSDetection
|
|
|
|
// register 0x111f - Headset Detect Control 1
|
|
// changed from 0x72 to 0x72
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0xc2 (default) to 0x82
|
|
// 0x80 headset detection disabled, 0x2 HSDET_AUTO_TIME 50 microsecs
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x1f00 i2c data 0x1f72
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x1f72 i2c data 0x0072
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x20c2
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2082 i2c data 0x0082
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x111f, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x111f, 0x0072, 1); // snd_hda
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_detect_onoff(struct hda_codec *codec, int onstate)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_detect_onoff\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSDetection
|
|
|
|
// register 0x111f - Headset Detect Control 1
|
|
// changed from 0x72 to 0x72
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0xc2 (default) to 0x82
|
|
// 0x80 headset detection disabled, 0x2 HSDET_AUTO_TIME 50 microsecs
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x1f00 i2c data 0x1f72
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x1f72 i2c data 0x0072
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x20c2
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2082 i2c data 0x0082
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x111f, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x111f, 0x0072, 1); // snd_hda
|
|
|
|
if (onstate)
|
|
{
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
|
|
if (0xc0 >= retval)
|
|
{
|
|
newval = (retval & 0x3f) | 0x80;
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
}
|
|
}
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
|
|
if (onstate)
|
|
newval = (retval & 0x3c) | 0x80;
|
|
else
|
|
newval = retval | 0xc0;
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
}
|
|
|
|
static void cs42l83_enable_hs_auto_int_off(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hs_auto_int_off\n");
|
|
|
|
// from AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
|
|
// AppleHDATDM_CS42L83::enableHSDetAutoInt
|
|
|
|
// register 0x131b - Codec Interrupt Mask
|
|
// changed from 0x3 (default) to 0x3
|
|
// this is disabling auto headset detection (well HSDET_AUTO_DONE)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x13 lo 0x1b00 i2c data 0x1b03
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x13 lo 0x1b03 i2c data 0x0003
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x131b, 1); // snd_hda
|
|
|
|
newval = (retval & 0xfd) | 0x02;
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x131b, 0x0003, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static int cs42l83_headset_type(struct hda_codec *codec)
|
|
{
|
|
int retval_type;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_type\n");
|
|
|
|
// this is readMikey function 0xb
|
|
|
|
// register 0x1124 - Headset Detect Status
|
|
// value 0x06 - 0x4 undocumented, headset type 0x02 (3)
|
|
|
|
// types are 0x00 (1), 0x01 (2), 0x02 (3) and 0x3 (4)
|
|
// type 1 Pin 1 Left, Pin 2 Right, Pin 3 Gnd, Pin 4 Mic
|
|
// type 2 Pin 1 Left, Pin 2 Right, Pin 3 Mic, Pin 4 Gnd
|
|
// type 3 Pin 1 Left, Pin 2 Right, Pin 3 Gnd, Pin 4 Gnd
|
|
// type 4 Optical!!
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2400 i2c data 0x2406
|
|
|
|
retval_type = cs_8409_vendor_i2cRead(codec, 0x90, 0x1124, 1); // snd_hda
|
|
|
|
return retval_type;
|
|
}
|
|
|
|
static void cs42l83_set_hpout_pulldown_on(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_set_hpout_pulldown_on\n");
|
|
|
|
// AppleHDATDM_CS42L83::setHPOutPulldown(bool)
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x86 to 0x06 (HPOUT_PULL_DOWN on)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0686
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0606 i2c data 0x0006
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0006, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_set_hpout_pulldown_onoff(struct hda_codec *codec, int onstate)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_set_hpout_pulldown_onoff\n");
|
|
|
|
// AppleHDATDM_CS42L83::setHPOutPulldown(bool)
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x86 to 0x06 (HPOUT_PULL_DOWN on)
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x6 to 0x86 (no HPOUT_PULL_DOWN)
|
|
|
|
if (onstate)
|
|
{
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0686
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0606 i2c data 0x0006
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0006, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1f06, 0xf0, 0x00, 1); // snd_hda
|
|
}
|
|
else
|
|
{
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0606
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0686 i2c data 0x0086
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0086, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1f06, 0xf0, 0x80, 1); // snd_hda
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_set_hpout_clamp_enable(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_set_hpout_clamp_enable\n");
|
|
|
|
// AppleHDATDM_CS42L83::setHPOutClamp
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// changed from 0x06 to 0x02 (default)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1f lo 0x0600 i2c data 0x0606
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0602 i2c data 0x0002
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1f06, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0002, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1f06, 0x04, 0x00, 1); // snd_hda
|
|
}
|
|
|
|
static void cs42l83_headset_mike_detect_off(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_mike_detect_off\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::handleTypeDetectUR
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x7 to 0x7 (Output 2.7V, mic detect powered Down) - headset interface functional
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7407
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7407 i2c data 0x0007
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
|
|
// this sets the detect mode to 0b00 (default, inactive)
|
|
newval = (retval & 0xe7);
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0007, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_power_hs_bias_off(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_hs_bias_off\n");
|
|
|
|
// multiple calls to this
|
|
// AppleHDAMikeyInternalCS8409::handleTypeDetectUR
|
|
// AppleHDAMikeyInternalCS8409::completeJackDetectUR
|
|
// AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
// AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::powerHSBIAS(unsigned int)
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// value 0x7 (Output 2.7V, mic level detect powered Down) - headset interface functional
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x82 (automatic disabled, auto time 50 microsecs) to 0x8a (automatic disabled, hs bias closed, auto time 50 microsecs)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// set 0x3 (default) (Output weak ground, mic level detect powered Down)
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x8a to 0x82 ((automatic disabled, auto time 50 microsecs)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7407
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2082
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x208a i2c data 0x008a
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7403 i2c data 0x0003
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x208a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2082 i2c data 0x0082
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x008a, 1); // snd_hda
|
|
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0003, 1); // snd_hda
|
|
|
|
//IOSleep(0x28);
|
|
msleep(0x28);
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
|
|
//IOSleep(0x14);
|
|
msleep(0x14);
|
|
}
|
|
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_on(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_on\n");
|
|
|
|
// in AppleHDAMikeyInternalCS4208::handleTypeDetectUR
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0x03 to 0x03 (HS Sense Bias trip 52 microamps
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7003 i2c data 0x0003
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0003, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_off(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off\n");
|
|
|
|
// in AppleHDAMikeyInternalCS4208::handleTypeDetectUR
|
|
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0x03 to 0x03 (HS Sense Bias trip 52 microamps
|
|
// set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7003 i2c data 0x0003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7046 i2c data 0x0046
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0003, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0046, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_setup_button_detect(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_setup_button_detect\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// register 0x1b7c - Detect Interrupt Status 1
|
|
// value 0x00
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// value 0xff all masked
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// set to 0xe7 (this appears to be a difference from the 42l42 doc
|
|
// - for the 42l42 0xe7 0x10 and 0x08 are reserved bits - maybe mike button bits)
|
|
// register 0x1b76 - Mic Detect Control 2
|
|
// changed from 0x2f (default) to 0x3f (again undocumented bit)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x3 (default) to 0x3 (0x02 hsbias ctl weak ground, 0x01 mic lvl detect powered down)
|
|
// register 0x1b78 - Detect Status 2
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x3 (default) to 0x1b (0x18 normal mode, 0x2 weak ground, 0x01 mic lvl detect powered down)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x1b to 0x9b (0x80 undocumented)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7aff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7ae7 i2c data 0x00e7
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7600 i2c data 0x762f
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x763f i2c data 0x003f
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7403
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7403 i2c data 0x0003
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7800 i2c data 0x78d0
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7403
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x741b i2c data 0x001b
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x741b
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x749b i2c data 0x009b
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00e7, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b76, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b76, 0x003f, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0003, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b78, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x001b, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x009b, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_power_hs_bias_button_on(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_hs_bias_button_on\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::powerHSBIAS
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
// value 0x9b (0x80 undocumented, 0x18 normal mode, 0x2 weak ground, 0x1 mic DC level detect powered down)
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x82 (automatic disabled, auto time 50 microsecs) to 0x8a (automatic disabled, hs bias closed, auto time 50 microsecs)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// set 0x9f (0x80 undocumented, 0x18 normal mode, 0x6 2.7V headset interface functional, 0x1 mic DC level detect powered down)
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x8a to 0x82 ((automatic disabled, auto time 50 microsecs)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x749b
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2082
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x208a i2c data 0x008a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x749f i2c data 0x009f
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x208a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2082 i2c data 0x0082
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x008a, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x009f, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_off1(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off1\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0x46 to 0x06
|
|
// set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7046
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7006 i2c data 0x0006
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7046 i2c data 0x0046
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0006, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0046, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static int cs42l83_handle_button_detect(struct hda_codec *codec)
|
|
{
|
|
int ret_ignore;
|
|
int ret_mask;
|
|
int ret_sense;
|
|
int ret_state1 = 0;
|
|
int ret_state2 = 0;
|
|
int ret_detect1 = 0;
|
|
int ret_detect2 = 0;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_handle_button_detect\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::handleButtonDetectUR
|
|
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// value 0xe7 (0x18 unmasked - undocumented - maybe mike buttons - rest masked)
|
|
// register 0x1b7c - this is undocumented for 42l42 (reserved)
|
|
// Detect Interrupt 2 Status
|
|
// value 0x00 (none ie inverse of 0xe7 state of 0x1b7a)
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// changed from 0xe7 to 0xff
|
|
// register 0x1b77 - Detect Status 1
|
|
// value 0x92 0x80 HP plugged bias 0x12
|
|
// register 0x1b78 - Detect Status 2
|
|
// value 0x40 (undocumented - maybe this indicates we have buttons)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x9f to 0x1f
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7ae7
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7ae7
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7700 i2c data 0x7792
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7800 i2c data 0x7840
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7800 i2c data 0x7840
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x749f
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x741f i2c data 0x001f
|
|
|
|
ret_mask = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
|
|
//if ((ret_mask & 0xe7) != 0xe7)
|
|
if ((~ret_mask & 0x18) != 0x18)
|
|
{
|
|
printk("snd_hda_intel: cs42l83_handle_button_detect invalid mask 0x%08x\n",ret_mask);
|
|
return 0;
|
|
}
|
|
|
|
// dont get this - return is 0 - we have no interrupts signalled in the unmasked section??
|
|
// the cs42l42 documentation mentions shadow registers which says reading this register
|
|
// loads the shadow register contents to register 0x1b7c - but dont see such a 2nd read here??
|
|
// maybe we are just clearing any bad initial state??
|
|
ret_ignore = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
|
|
// this is headphone sense - not clear what we do if dont sense headphones
|
|
ret_sense = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b77, 1); // snd_hda
|
|
|
|
ret_state1 = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b78, 1); // snd_hda
|
|
ret_state2 = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b78, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x001f, 1); // snd_hda
|
|
|
|
// possible coding from assembler - do not rely on!!
|
|
//ret_detect1 = (ret_state >> 2) & 0x7;
|
|
//ret_detect2 = (ret_state + ret_state) & 0x6;
|
|
//ret_state1 = (((ret_state1 >> 0x7) | ret_detect2) >> 4) & 0x7;
|
|
|
|
// this seems to be returning 0x40 - which is undocumented
|
|
// for the moment going to assume 0x40 means we have buttons
|
|
return ((ret_sense & 0xff) << 16) | ((ret_state2 & 0xff) << 8) | (ret_state1 & 0xff);
|
|
}
|
|
|
|
static int cs42l83_mike_connected(struct hda_codec *codec)
|
|
{
|
|
int ret_connect = 0;
|
|
int retval = 0;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_mike_connected\n");
|
|
|
|
// from AppleHDAMikeyInternalCS8409::handleButtonDetectUR
|
|
|
|
// from AppleHDAMikeyInternal::configureHeadset(unsigned char, unsigned char, unsigned char)
|
|
|
|
// AppleHDAMikeyInternalCS8409::microphoneConnected(bool*)
|
|
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x1f to 0x1e
|
|
// register 0x1b75 - Mic Detect Control 1
|
|
// changed from 0xb5 to 0xb5 (0x80 LATCH_TO_VP set, HS_DETECT_LEVEL 0x35)
|
|
// register 0x1b78 - Detect Status 2
|
|
// value 0x42 (0x40 unknown 0x2 hsbias_in true)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// set to 0x1f
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x741f
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x741e i2c data 0x001e
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7500 i2c data 0x75b5
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x75b5 i2c data 0x00b5
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7800 i2c data 0x7842
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x741f i2c data 0x001f
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x001e, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b75, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b75, 0x00b5, 1); // snd_hda
|
|
|
|
// this is returning a different value - now get 0x42
|
|
// assuming 0x40 indicates we have buttons
|
|
// and 0x02 seems to be indication we have a mike (from code analysis)
|
|
ret_connect = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b78, 1); // snd_hda
|
|
|
|
// this converts 0x2 to a bool response ie 0x0 or 0x1
|
|
retval = ((ret_connect > 1) & 0x01);
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x001f, 1); // snd_hda
|
|
|
|
return ret_connect;
|
|
}
|
|
|
|
|
|
static void cs42l83_configure_int_mclk(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_configure_int_mclk\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_configureIntMClk
|
|
|
|
// configuring clocks in the CS42L83 is extremely complex
|
|
// multiple divisors/multipliers
|
|
// only some registers decoded here
|
|
|
|
// register 0x1007 - Serial Port SRC Control
|
|
// changed from 0x10 to 0x10 - bypass equalizer
|
|
|
|
// register 0x1009 - MCLK Control
|
|
// ....
|
|
|
|
// register 0x1208 - ASP Frame Configuration
|
|
// set to 0x00
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x10 lo 0x0700 i2c data 0x0710
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x0710 i2c data 0x0010
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x0902 i2c data 0x0002
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0c02 i2c data 0x0002
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x02ff i2c data 0x00ff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x039c i2c data 0x009c
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0470 i2c data 0x0070
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x052e i2c data 0x002e
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x1b03 i2c data 0x0003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0a5d i2c data 0x005d
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0810 i2c data 0x0010
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0101 i2c data 0x0001
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x05ff i2c data 0x00ff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0600 i2c data 0x0000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0100 i2c data 0x0100
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0100 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0800 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1007, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1007, 0x0010, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1009, 0x0002, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x120c, 0x0002, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1502, 0x00ff, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1503, 0x009c, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1504, 0x0070, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1505, 0x002e, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x151b, 0x0003, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x150a, 0x005d, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1508, 0x0010, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1501, 0x0001, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1205, 0x00ff, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1206, 0x0000, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1201, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1201, 0x0000, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1208, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_power_on_on_nouse(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_power_on_on_nouse\n");
|
|
|
|
// AppleHDATDM_CS42L83::powerOn
|
|
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0700 i2c data 0x0720
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0720 i2c data 0x0020
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0101 i2c data 0x0001
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0701 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1207, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1207, 0x0020, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1501, 0x0001, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1107, 0x0001, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_power_onoff(struct hda_codec *codec, bool onflag)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_onoff\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::powerOn
|
|
|
|
// bool arg switches order of 0x1107/0x1501 - on (0x1207) 0x1501/0x1107 - off 0x1107/0x1501
|
|
|
|
if (onflag)
|
|
{
|
|
// register 0x1207 - ASP Clock Configuration 1
|
|
// changed from 0x00 to 0x20 - ASP_LCPOL_OUT inverted
|
|
// register 0x1501 - PLL Control 1
|
|
// set to 0x01 - powered on
|
|
// register 0x1107 - Oscillator Switch Control
|
|
// set to 0x01 - SCLK is present and the internal MCLK is sourced from the SCLK pin
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0700 i2c data 0x0700
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0720 i2c data 0x0020
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0101 i2c data 0x0001
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0701 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1207, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1207, 0x0020, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1501, 0x0001, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1107, 0x0001, 1); // snd_hda
|
|
}
|
|
else
|
|
{
|
|
// register 0x1107 - Oscillator Switch Control
|
|
// set to 0x00 (power down, in transition)
|
|
// register 0x1501 - PLL Control 1
|
|
// set to 0x00 (powered off)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0700 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0100 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1107, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1501, 0x0000, 1); // snd_hda
|
|
}
|
|
}
|
|
|
|
static void cs42l83_configure_serial_port(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_configure_serial_port\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_configureSerialPort
|
|
|
|
// register 0x2505 - Serial Port Transmit Isochronous Control
|
|
// changed from 0x04 to 0x05 (NFS mode, 48k isochronous stream)
|
|
// register 0x2502 - Serial Port Receive Isochronous Control
|
|
// changed from 0x04 to 0x05 (NFS mode, 48k isochronous stream)
|
|
// register 0x2503 - Serial Port Receive Sample Rate
|
|
// changed from 0x8c to 0x8a (48 kHz to 44.1 kHz)
|
|
// register 0x2506 - Serial Port Transmit Sample Rate
|
|
// changed from 0xcc to 0xca (48 kHz to 44.1 kHz)
|
|
// register 0x1208 - ASP Frame Configuration
|
|
// changed from 0x00 to 0x02 (ASP_STP from high to low, ASP frame start 1.0 delay)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0500 i2c data 0x0504
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x0505 i2c data 0x0005
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0200 i2c data 0x0204
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x0205 i2c data 0x0005
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0300 i2c data 0x038c
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x038a i2c data 0x008a
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0600 i2c data 0x06cc
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x06ca i2c data 0x00ca
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0800 i2c data 0x0800
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0802 i2c data 0x0002
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2505, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2505, 0x0005, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2502, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2502, 0x0005, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2503, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2503, 0x008a, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2506, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2506, 0x00ca, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1208, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1208, 0x0002, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_output_set_input_sample_rate(struct hda_codec *codec)
|
|
{
|
|
// changed name from cs42l83_set_sample_rate
|
|
// NOTA BENE - it says output sample rate because its the sample rate for digital data
|
|
// coming into the cs42l83 and being converted to analog output
|
|
// - so the register is labelled the Input sample rate!!
|
|
int ret_fs_rate;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_output_set_input_sample_rate\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setSampleRate
|
|
|
|
// register 0x2601 - SRC Input Sample Rate
|
|
// changed from 0x40 to 0x4a (0x0a is 44.1 kHz)
|
|
// register 0x2503 - Serial Port Receive Sample Rate
|
|
// changed from 0x8a to 0x8a (0x0a is 44.1 kHz)
|
|
// register 0x120a - Input ASRC Clock Select
|
|
// changed from 0x00 to 0x00 (0x00 6 MHz)
|
|
// register 0x1209 - FS Rate Enable
|
|
// changed from 0x00 to 0x01 (0x01 Enable IASRC 96K and lower rates)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x26 lo 0x0100 i2c data 0x0140
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x26 lo 0x014a i2c data 0x004a
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0300 i2c data 0x038a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x038a i2c data 0x008a
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0a00 i2c data 0x0a00
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0a00 i2c data 0x0000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0900 i2c data 0x0900
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0901 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2601, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2601, 0x004a, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2503, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2503, 0x008a, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x120a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x120a, 0x0000, 1); // snd_hda
|
|
|
|
// correctly implement this to mask in the right bit as per docs
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1209, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1209, 0x0001, 1); // snd_hda
|
|
ret_fs_rate = cs_8409_vendor_i2cRead(codec, 0x90, 0x1209, 1); // snd_hda
|
|
ret_fs_rate |= 0x1;
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1209, ret_fs_rate, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_setup_audio_output(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_setup_audio_output\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setupAudioOutput
|
|
|
|
// register 0x1f06 - DAC Control 2
|
|
// set to 0x2 (default) DAC HPF enable
|
|
// register 0x2001 - HP Control
|
|
// changed from 0x0d (default) to 0x0d
|
|
// register 0x2a04 - ASP Receive DAI0 Channel 1 Bit Start LSB
|
|
// set to 0x00
|
|
// register 0x2a07 - ASP Receive DAI0 Channel 2 Bit Start LSB
|
|
// set to 0x20 (is this 32 bits?? - maybe)
|
|
// register 0x2301 - Mixer Channel A Input Volume
|
|
// set to 0x00 (0 dB - positive values negative dB as usual 0x3f mute (default))
|
|
// register 0x2303 - Mixer Channel B Input Volume
|
|
// set to 0x00 (0 dB - positive values negative dB as usual 0x3f mute (default))
|
|
// register 0x2a02 - ASP Receive DAI0 Channel 1 Phase and Resolution
|
|
// set to 0x02 (24 bits per sample)
|
|
// (0x00 8 bits, 0x01 16 bits, 0x03 32 bits (default))
|
|
// register 0x2a05 - ASP Receive DAI0 Channel 2 Phase and Resolution
|
|
// set to 0x02 (24 bits per sample)
|
|
// (0x00 8 bits, 0x01 16 bits, 0x03 32 bits (default))
|
|
// register 0x100b - Slow Start Enable
|
|
// changed from 0x70 (default) to 0x00 (disabled)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1f lo 0x0602 i2c data 0x0002
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x20 lo 0x0100 i2c data 0x010d
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x20 lo 0x010d i2c data 0x000d
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0400 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0720 i2c data 0x0020
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x23 lo 0x0100 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x23 lo 0x0300 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0202 i2c data 0x0002
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0502 i2c data 0x0002
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x10 lo 0x0b00 i2c data 0x0b70
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x0b00 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1f06, 0x0002, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2001, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2001, 0x000d, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a04, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a07, 0x0020, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2301, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2303, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a02, 0x0002, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a05, 0x0002, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x100b, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x100b, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_headset_rcv_enable_on(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_rcv_enable_on\n");
|
|
|
|
// AppleHDATDM_CS42L83::enable
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x010c i2c data 0x000c
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a01, 0x000c, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_buffers_onoff(struct hda_codec *codec, bool onflag)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_buffers_onoff\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// yet again this has a bool arg which is enable/disable
|
|
|
|
if (onflag)
|
|
{
|
|
// register 0x2a01 - ASP Receive Enable
|
|
// set to 0x0c (populate channel buffers for 1 and 2)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x010c i2c data 0x000c
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a01, 0x000c, 1); // snd_hda
|
|
}
|
|
else
|
|
{
|
|
// register 0x2a01 - ASP Receive Enable
|
|
// set to 0x00 (channel buffers not populated)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0100 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a01, 0x0000, 1); // snd_hda
|
|
}
|
|
}
|
|
|
|
static void cs42l83_set_power_state_on_nouse(struct hda_codec *codec, int dummy)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_set_power_state_on_nouse\n");
|
|
|
|
// AppleHDATDM_CS42L83::setPowerState
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x01fe
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x019e i2c data 0x009e
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x13 lo 0x0b00 i2c data 0x0b60
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x13 lo 0x0b00 i2c data 0x0b60
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x13 lo 0x0b00 i2c data 0x0b24
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x019e
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0196 i2c data 0x0096
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x009e, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x130b, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x130b, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x130b, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x0096, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_headset_enable_on(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_enable_on\n");
|
|
|
|
// looks as tho this is only enabling the headphone component
|
|
// - doesnt seem to be needed for the headset mike to work
|
|
// (unless it just happens the headphone component is always enabled so
|
|
// dont see it for the headset mike)
|
|
|
|
// AppleHDATDM_CS42L83::setPowerState
|
|
// AppleHDATDM_CS42L83::enableHeadphones
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x7e99 i2c data 0x0099
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x0830 i2c data 0x0030
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x21 lo 0x0200 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x7e00 i2c data 0x0000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x20 lo 0x0100 i2c data 0x010d
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x20 lo 0x0101 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x107e, 0x0099, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b08, 0x0030, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2102, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x107e, 0x0000, 1); // snd_hda
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x2001, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x2001, 0x0001, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x2001, 0x0c, 0x00, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_plugin_interrupt_setup(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_plugin_interrupt_setup\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
|
|
// this enables the headphone plugin sense interrupt
|
|
|
|
// register 0x1b7b - this is undocumented for 42l42 but labelled in fig 4-45 as Interrupt
|
|
// now think this shows which interrupt of 0x1b79 was triggered
|
|
// reading this clears any interrupt which will send a UR
|
|
// value 0x00
|
|
// register 0x1b79 - Detect Interrupt Mask 1
|
|
// changed from 0xe0 (default) to 0xa0 - unmasks TIP_SENSE_PLUG
|
|
// changed from 0xc0 (TIP_SENSE_UNPLUG unmasked) to 0xa0 (TIP_SENSE_UNPLUG masked TIP_SENSE_PLUG unmasked)
|
|
|
|
// so reading 0x1b7b seems to lead to 2 UNSOL events
|
|
// one with interrupt set followed by one with interrupt cleared
|
|
|
|
mycodec_info(codec, "command cs42l83_plugin_interrupt_setup start\n");
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7b00 i2c data 0x7b00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7900 i2c data 0x79c0
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x79a0 i2c data 0x00a0
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7b, 1); // snd_hda
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b79, 1); // snd_hda
|
|
|
|
newval = (retval & 0x9f) | 0x20;
|
|
|
|
myprintk_dbg("snd_hda_intel: cs42l83_plugin_interrupt_setup 0x%04x 0x%04x: 0x%04x (0x%04x 0x%04x 0x%04x)",0x90,0x1b79,newval,0x00a0,retval,0x00c0);
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b79, 0x00a0, 1); // snd_hda
|
|
|
|
mycodec_info(codec, "command cs42l83_plugin_interrupt_setup end\n");
|
|
}
|
|
|
|
static void cs42l83_headset_detect2_off(struct hda_codec *codec)
|
|
{
|
|
int retval;
|
|
int newval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_detect2_off\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
|
|
// register 0x1b7c - Detect Interrupt 2 Status
|
|
// value 0x00 (none ie inverse of 0xff state of 0x1b7a)
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// changed from 0xff to 0xff (all masked)
|
|
// register 0x1b74 - Miscellaneous Detect Control
|
|
// changed from 0x3 (default) to 0x3
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c00
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7aff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7400 i2c data 0x7403
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7403 i2c data 0x0003
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
|
|
newval = (retval | 0x38);
|
|
|
|
myprintk_dbg("snd_hda_intel: cs42l83_headset_detect2_off 0x%04x 0x%04x: 0x%04x (0x%04x 0x%04x 0x%04x)",0x90,0x1b7a,newval,0x00ff,retval,0x00ff);
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
|
|
|
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b74, 1); // snd_hda
|
|
|
|
newval = (retval & 0xe7);
|
|
|
|
myprintk_dbg("snd_hda_intel: cs42l83_headset_detect2_off 0x%04x 0x%04x: 0x%04x (0x%04x 0x%04x 0x%04x)",0x90,0x1b7c,newval,0x00a0,retval,0x00c0);
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b74, 0x0003, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_off3(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off3\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0xc6 to 0x06
|
|
// set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x70c6
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7006 i2c data 0x0006
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7046 i2c data 0x0046
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0006, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0046, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_disable_button_interrupts(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_disable_button_interrupts\n");
|
|
|
|
// AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// register 0x1b7c - Detect Interrupt Status 1
|
|
// value 0x04
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// value 0xfc
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// set to 0xff
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// set to 0xff
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c04
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7afc
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7aff i2c data 0x00ff
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00ff, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_unplug_headset_detect_off(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_unplug_headset_detect_off\n");
|
|
|
|
// this is AppleHDAMikeyInternalCS8409::enableHSDetection
|
|
// this calls readMikey/writeMikey with 0x8 arg and 0x9 arg
|
|
|
|
// register 0x111f - Headset Detect Control 1
|
|
// changed from 0x72 to 0x72
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x82 to 0x82
|
|
// 0x80 headset detection automatic, disabled, 0x2 HSDET_AUTO_TIME 50 microsecs
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x1f00 i2c data 0x1f72
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x1f72 i2c data 0x0072
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2082
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2082 i2c data 0x0082
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x111f, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x111f, 0x0072, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0082, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_switch_control(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_switch_control\n");
|
|
|
|
// from AppleHDAMikeyInternalCS8409::handleJackDisconnectUR
|
|
|
|
// this is likely writeMikey 0x9, 0xa making it plausibly AppleHDAMikeyInternalCS8409::configureForUSHeadset
|
|
|
|
// register 0x1120 - Headset Detect Control 2
|
|
// changed from 0x82 to 0x42
|
|
// 0x40 headset detection manual, 0x2 HSDET_AUTO_TIME 50 microsecs
|
|
|
|
// I think this is writeMikey with 0xa arg
|
|
|
|
// register 0x1121 - Headset Switch Control
|
|
// set to 0xa6
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x2000 i2c data 0x2082
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x2042 i2c data 0x0042
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x21a6 i2c data 0x00a6
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1120, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1120, 0x0042, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1121, 0x00a6, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_headset_enable_off(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_enable_off\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable - 0x22cb
|
|
// from AppleHDATDM_CS42L83::_powerOffCodecOutput
|
|
// AppleHDATDM_CS42L83::enableHeadphones(bool)
|
|
|
|
// register 0x2001 - HP Control
|
|
// changed from 0x01 to 0x0d
|
|
// 0x107e - undocumented Global
|
|
// set to 0x99
|
|
// 0x1b08 - undocumented Headset Interface
|
|
// set to 0x10
|
|
// 0x2102 - Class H?? DPn Port Control??
|
|
// set to 0x20
|
|
// 0x107e - undocumented Global
|
|
// set to 0x00
|
|
|
|
myprintk("snd_hda_intel: cs42l83_headset_enable_off start\n");
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x20 lo 0x0100 i2c data 0x0101
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x20 lo 0x010d i2c data 0x000d
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x7e99 i2c data 0x0099
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x0810 i2c data 0x0010
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x21 lo 0x0220 i2c data 0x0020
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x10 lo 0x7e00 i2c data 0x0000
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x2001, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x2001, 0x000d, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x2001, 0x0c, 0x0c, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x107e, 0x0099, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b08, 0x0010, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2102, 0x0020, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x107e, 0x0000, 1); // snd_hda
|
|
|
|
myprintk("snd_hda_intel: cs42l83_headset_enable_off end\n");
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_power_off_codec_output(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_off_codec_output\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable or AppleHDATDM_CS42L83::setPowerState
|
|
// AppleHDATDM_CS42L83::_powerOffCodecOutput
|
|
|
|
// register 0x1101 - Power Down Control 1
|
|
// 0xff powered down 0x00 powered up
|
|
// changed from 0x96 to 0x9e (0x40 ASP Input, 0x20 Mixer, 0x08 HPOut, 0x1 codec powered to
|
|
// 0x40 ASP Input, 0x20 Mixer, 0x1 codec powered)
|
|
// register 0x1101 - Power Down Control 1
|
|
// changed from 0x9e (0x40 ASP Input, 0x20 Mixer, 0x1 codec powered) to 0xfe (default - 0x1 codec powered))
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x0196
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x019e i2c data 0x009e
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x019e
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x01fe i2c data 0x00fe
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x009e, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1101, 0x08, 0x08, 1); // snd_hda
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x00fe, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1101, 0x60, 0x60, 1); // snd_hda
|
|
}
|
|
|
|
static void cs42l83_power_off_codec_input(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_power_off_codec_input\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable or AppleHDATDM_CS42L83::setPowerState
|
|
// AppleHDATDM_CS42L83::_powerOffCodecInput
|
|
|
|
// note there is a call to AppleHDATDM_CS42L83::enableExtMicrophone(0) in this routine
|
|
// ah - thats the 0x1d03 mute/unmute volume register
|
|
|
|
// register 0x1101 - Power Down Control 1
|
|
// 0xff powered down 0x00 powered up
|
|
// changed from 0x12 to 0x16 (0x80 ASP Output, 0x40 ASP Input, 0x20 Mixer, 0x08 HPOut, 0x4 ADC, 0x1 codec powered to
|
|
// 0x80 ASP Output, 0x40 ASP Input, 0x20 Mixer, 0x08 HPout, 0x1 codec powered)
|
|
// register 0x1101 - Power Down Control 1
|
|
// changed from 0x16 (0x80 ASP Output, 0x40 ASP Input, 0x20 Mixer, 0x08 HPOut, 0x1 codec powered) to
|
|
// 0x96 (0x40 ASP Input, 0x20 Mixer, 0x08 HPOut, 0x1 codec powered)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x0112
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0116 i2c data 0x0016
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x11 lo 0x0100 i2c data 0x0116
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0196 i2c data 0x0096
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x0016, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1101, 0x04, 0x04, 1); // snd_hda
|
|
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1101, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1101, 0x0096, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWriteMask(codec, 0x90, 0x1101, 0x80, 0x80, 1); // snd_hda
|
|
}
|
|
|
|
static void cs42l83_headset_rcv_enable_off(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_rcv_enable_off\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
// this is only place we have a 0x2a01
|
|
|
|
// yet again this has a bool arg which is enable/disable
|
|
|
|
// register 0x2a01 - ASP Receive Enable
|
|
// set to 0x00 (channel buffers not populated)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x2a lo 0x0100 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2a01, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_power_off(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_power_off\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::powerOn
|
|
// likely power off - bool arg switches order of 0x1107/0x1501 - on (0x2a10) 0x1501/0x1107 - off 0x1107/0x1501
|
|
|
|
// register 0x1107 - Oscillator Switch Control
|
|
// set to 0x00 (power down, in transition)
|
|
// register 0x1501 - PLL Control 1
|
|
// set to 0x00 (powered off)
|
|
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x11 lo 0x0700 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x15 lo 0x0100 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1107, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1501, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
//static void cs42l83_line_or_mike_set_sample_rate(struct hda_codec *codec)
|
|
static void cs42l83_input_set_output_sample_rate(struct hda_codec *codec)
|
|
{
|
|
// changed name from cs42l83_line_or_mike_set_sample_rate
|
|
// NOTA BENE - it says input sample rate because its the sample rate for data
|
|
// from analog inputs converted to digital and going out of the cs42l83
|
|
// - so the register is labelled the Output sample rate!!
|
|
|
|
int ret_fs_rate;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_input_set_output_sample_rate\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setSampleRate
|
|
|
|
// is this for line or mike??
|
|
|
|
// register 0x2609 - SRC Output Sample Rate
|
|
// changed from 0x40 to 0x4a (0x0a is 44.1 kHz)
|
|
// register 0x2506 - Serial Port Transmit Sample Rate
|
|
// changed from 0xca to 0xca (0x0a is 44.1 kHz)
|
|
// register 0x120b - Output ASRC Clock Select
|
|
// changed from 0x00 to 0x00 (0x00 6 MHz)
|
|
// register 0x1209 - FS Rate Enable
|
|
// changed from 0x00 to 0x03 (0x01 Enable IASRC 96K and lower rates, 0x02 Enable OASRC96K and lower rates)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x26 lo 0x0900 i2c data 0x0940
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x26 lo 0x094a i2c data 0x004a
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0600 i2c data 0x06ca
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x06ca i2c data 0x00ca
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0b00 i2c data 0x0b00
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0b00 i2c data 0x0000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0900 i2c data 0x0901
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0903 i2c data 0x0003
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2609, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2609, 0x004a, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2506, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2506, 0x00ca, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x120b, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x120b, 0x0000, 1); // snd_hda
|
|
|
|
// correctly implement this to mask in the right bit as per docs
|
|
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1209, 1); // snd_hda
|
|
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1209, 0x0003, 1); // snd_hda
|
|
ret_fs_rate = cs_8409_vendor_i2cRead(codec, 0x90, 0x1209, 1); // snd_hda
|
|
ret_fs_rate |= 0x2;
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1209, ret_fs_rate, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_mike_setup_audio_input(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_mike_setup_audio_input\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setupAudioInput
|
|
|
|
// register 0x2903 - ASP Transmit Channel Phase and Resolution
|
|
// register 0x2905 - ASP Transmit Channel 1 Bit Start LSB
|
|
// register 0x290b - ASP Transmit Channel 2 Bit Start LSB
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x29 lo 0x0300 i2c data 0x030f
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x030a i2c data 0x000a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0500 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0b20 i2c data 0x0020
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2903, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2903, 0x000a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2905, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x290b, 0x0020, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_mike_enable(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_mike_enable\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// register 0x2902 - ASP Transmit Channel Enable
|
|
// set to 0x03 (ASP Transmit Channel 1 enable (0x01), ASP Transmit Channel 2 enable (0x02))
|
|
// register 0x2901 - ASP Transmit Size and Enable
|
|
// set to 0x01 (Enabled)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0203 i2c data 0x0003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0101 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2902, 0x0003, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2901, 0x0001, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_mike_disable(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_mike_disable\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// register 0x2901 - ASP Transmit Size and Enable
|
|
// set to 0x00 (Disabled)
|
|
// register 0x2902 - ASP Transmit Channel Enable
|
|
// set to 0x00 (disabled)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0100 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0200 i2c data 0x0000
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2901, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2902, 0x0000, 1); // snd_hda
|
|
|
|
}
|
|
|
|
//static void cs42l83_line_or_mike_set_sample_rate1(struct hda_codec *codec)
|
|
static void cs42l83_input_set_output_sample_rate1(struct hda_codec *codec)
|
|
{
|
|
// changed name from cs42l83_line_or_mike_set_sample_rate1
|
|
// NOTA BENE - it says input sample rate because its the sample rate for data
|
|
// from analog inputs converted to digital and going out of the cs42l83
|
|
// - so the register is labelled the Output sample rate!!
|
|
// NOTA BENE - NOT fixed to do bit op for 0x1209 register!!!
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_input_set_output_sample_rate1\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setSampleRate
|
|
|
|
// is this for line or mike??
|
|
|
|
// register 0x2609 - SRC Output Sample Rate
|
|
// changed from 0x4a to 0x4a (0x0a is 44.1 kHz)
|
|
// register 0x2506 - Serial Port Transmit Sample Rate
|
|
// changed from 0xca to 0xca (0x0a is 44.1 kHz)
|
|
// register 0x120b - Output ASRC Clock Select
|
|
// changed from 0x00 to 0x00 (0x00 6 MHz)
|
|
// register 0x1209 - FS Rate Enable
|
|
// changed from 0x00 to 0x01 (0x01 Enable IASRC 96K and lower rates)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x26 lo 0x0900 i2c data 0x094a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x26 lo 0x094a i2c data 0x004a
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x25 lo 0x0600 i2c data 0x06ca
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x25 lo 0x06ca i2c data 0x00ca
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0b00 i2c data 0x0b00
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0b00 i2c data 0x0000
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x12 lo 0x0900 i2c data 0x0903
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x12 lo 0x0903 i2c data 0x0003
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2609, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2609, 0x004a, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2506, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2506, 0x00ca, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x120b, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x120b, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1209, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1209, 0x0003, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_line_or_mike_setup_audio_input(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_line_or_mike_setup_audio_input\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// AppleHDATDM_CS42L83::_setupAudioInput
|
|
|
|
// register 0x2903 - ASP Transmit Channel Phase and Resolution
|
|
// register 0x2905 - ASP Transmit Channel 1 Bit Start LSB
|
|
// register 0x290b - ASP Transmit Channel 2 Bit Start LSB
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x29 lo 0x0300 i2c data 0x030a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x030a i2c data 0x000a
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0500 i2c data 0x0000
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0b20 i2c data 0x0020
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x2903, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2903, 0x000a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2905, 0x0000, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x290b, 0x0020, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_line_or_mike_enable_nouse(struct hda_codec *codec)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_line_or_mike_enable_nouse\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enable
|
|
|
|
// register 0x2902 - ASP Transmit Channel Enable
|
|
// set to 0x03 (ASP Transmit Channel 1 enable (0x01), ASP Transmit Channel 2 enable (0x02))
|
|
// register 0x2901 - ASP Transmit Size and Enable
|
|
// set to 0x01 (Enabled)
|
|
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0203 i2c data 0x0003
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x29 lo 0x0101 i2c data 0x0001
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2902, 0x0003, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x2901, 0x0001, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_headset_mike_pin_enable(struct hda_codec *codec)
|
|
{
|
|
int retval = 0;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_mike_pin_enable\n");
|
|
|
|
// why twice??
|
|
|
|
retval = snd_hda_codec_read_check(codec, 0x3c, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00000000, 0x00000020, 14146); // 0x03cf0700
|
|
|
|
retval = snd_hda_codec_read_check(codec, 0x3c, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00000000, 0x00000020, 14147); // 0x03cf0700
|
|
|
|
snd_hda_codec_write(codec, 0x3c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00000020); // 0x03c70720
|
|
// snd_hda: 60 ['AC_PINCTL_IN_EN']
|
|
|
|
snd_hda_codec_write(codec, 0x3c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00000020); // 0x03c70720
|
|
// snd_hda: 60 ['AC_PINCTL_IN_EN']
|
|
|
|
}
|
|
|
|
static void cs42l83_configure_headset_button_interrupts(struct hda_codec *codec)
|
|
{
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_configure_headset_button_interrupts\n");
|
|
|
|
// from AppleHDAMikeyInternalCS8409::handleButtonDetectUR(unsigned int)
|
|
|
|
// AppleHDAMikeyInternalCS8409::configureHeadset
|
|
// - this calls 0x1b7c and 0x1b7a
|
|
|
|
// register 0x1b7c - Detect Interrupt Status 1
|
|
// value 0x00
|
|
// register 0x1b7a - Detect Interrupt Mask 2
|
|
// changed from 0xff to 0xdc (0x23 unmasked, 0x18 masked - undocumented - maybe mike buttons - rest unmasked)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7c00 i2c data 0x7c40
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7a00 i2c data 0x7aff
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7adc i2c data 0x00dc
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7c, 1); // snd_hda
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b7a, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b7a, 0x00dc, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_off2(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off2\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0x46 to 0x06
|
|
// set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps)
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7046
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7006 i2c data 0x0006
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x7046 i2c data 0x0046
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0006, 1); // snd_hda
|
|
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0046, 1); // snd_hda
|
|
|
|
}
|
|
|
|
static void cs42l83_enable_hsbias_auto_clamp_on3(struct hda_codec *codec)
|
|
{
|
|
|
|
//int retval;
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_on3\n");
|
|
|
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
|
|
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
|
|
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
|
// changed from 0x46 to 0xc6
|
|
|
|
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7046
|
|
// snd_hda i2cPagedWrite i2c address 0x90 i2c reg hi 0x1b lo 0x70c6 i2c data 0x00c6
|
|
|
|
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x00c6, 1); // snd_hda
|
|
|
|
}
|
|
|
|
|
|
static void cs42l83_headset_mike_adc_unmutevol(struct hda_codec *codec, int unmute)
|
|
{
|
|
|
|
mycodec_i2c_local_info(codec, "cs42l83_headset_mike_adc_unmutevol\n");
|
|
|
|
// in AppleHDATDM_CS42L83::enableExtMicrophone
|
|
|
|
if (unmute)
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1d03, 0x0000, 1); // snd_hda
|
|
else
|
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1d03, 0x0080, 1); // snd_hda
|
|
}
|
|
|