snd-hda-codec-cs8409/patch_cirrus_real84_i2c.h
Alexander Egorenkov d0d785dc18 CS8409 TAS5764L support
Signed-off-by: Alexander Egorenkov <egorenar-dev@posteo.net>
2022-10-21 08:44:06 +02:00

1955 lines
86 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 updval;
//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
// explicit coding
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x0003, 1); // snd_hda
// bit coding
//updval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
//updval &= 0x3f;
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, updval, 1); // snd_hda
}
static void cs42l83_enable_hsbias_auto_clamp_off(struct hda_codec *codec)
{
int updval;
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 (0x03 -> 0x06) )
// 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
// explicit coding
//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
// bit coding
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
updval = retval & 0x3f;
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, updval, 1); // snd_hda
updval = (retval & 0xb8) | 0x46;
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, updval, 1); // snd_hda
}
static void cs42l83_enable_hsbias_auto_clamp_off0(struct hda_codec *codec)
{
//int retval;
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off0\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 (0x03 -> 0x06) )
// 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
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 -> 0x06) )
// 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)
{
// this function replaced by cs42l83_power_onoff
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;
// this function has been replaced by cs42l83_buffers_onoff
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
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 ->0x06) )
// 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)
{
// this function has been replaced by cs42l83_buffers_onoff
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)
{
// this function replaced by cs42l83_power_onoff
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
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 ->0x06) )
// 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_hsbias_sense_on(struct hda_codec *codec)
{
int updval;
//int retval;
mycodec_i2c_local_info(codec, "cs42l83_hsbias_sense_on\n");
// in AppleHDAMikeyInternalCS8409::handleButtonDetectUR
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
// changed from 0x46 to 0xc6
// set to 0xc6 (HS Bias Sense Enable (0x80) Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 ->0x06) )
// 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
// explicit coding
//cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
//cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x00c6, 1); // snd_hda
// bit coding
updval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
updval |= 0x80;
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, updval, 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
}