Compare commits
No commits in common. "master" and "linux5.14" have entirely different histories.
15 changed files with 4543 additions and 7660 deletions
11
Makefile
11
Makefile
|
@ -1,10 +1,11 @@
|
||||||
snd-hda-codec-cs8409-objs := patch_cs8409.o patch_cs8409-tables.o
|
snd-hda-codec-cirrus-objs := patch_cirrus.o
|
||||||
obj-$(CONFIG_SND_HDA_CODEC_CS8409) += snd-hda-codec-cs8409.o
|
obj-$(CONFIG_SND_HDA_CODEC_CIRRUS) += snd-hda-codec-cirrus.o
|
||||||
|
|
||||||
# debug build flags
|
# debug build flags
|
||||||
#KBUILD_EXTRA_CFLAGS = "-DCONFIG_SND_DEBUG=1 -DMYSOUNDDEBUGFULL -DAPPLE_PINSENSE_FIXUP -DAPPLE_CODECS -DCONFIG_SND_HDA_RECONFIG=1 -Wno-unused-variable -Wno-unused-function"
|
#KBUILD_EXTRA_CFLAGS = "-DCONFIG_SND_DEBUG=1 -DMYSOUNDDEBUGFULL -DCONFIG_SND_HDA_RECONFIG=1 -Wno-unused-variable -Wno-unused-function"
|
||||||
# normal build flags
|
# normal build flags
|
||||||
KBUILD_EXTRA_CFLAGS = "-DAPPLE_PINSENSE_FIXUP -DAPPLE_CODECS -DCONFIG_SND_HDA_RECONFIG=1 -Wno-unused-variable -Wno-unused-function"
|
KBUILD_EXTRA_CFLAGS = "-DCONFIG_SND_HDA_RECONFIG=1 -Wno-unused-variable -Wno-unused-function"
|
||||||
|
|
||||||
|
|
||||||
ifdef KVER
|
ifdef KVER
|
||||||
KDIR := /lib/modules/$(KVER)
|
KDIR := /lib/modules/$(KVER)
|
||||||
|
@ -19,5 +20,5 @@ clean:
|
||||||
|
|
||||||
install:
|
install:
|
||||||
mkdir -p $(KDIR)/updates/
|
mkdir -p $(KDIR)/updates/
|
||||||
cp snd-hda-codec-cs8409.ko $(KDIR)/updates/
|
cp snd-hda-codec-cirrus.ko $(KDIR)/updates/
|
||||||
depmod -a
|
depmod -a
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
#ifndef __SOUND_HDA_AUTO_PARSER_H
|
#ifndef __SOUND_HDA_AUTO_PARSER_H
|
||||||
#define __SOUND_HDA_AUTO_PARSER_H
|
#define __SOUND_HDA_AUTO_PARSER_H
|
||||||
|
|
||||||
#include "hda_local.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper for automatic pin configuration
|
* Helper for automatic pin configuration
|
||||||
*/
|
*/
|
||||||
|
@ -37,7 +35,6 @@ struct auto_pin_cfg_item {
|
||||||
unsigned int is_headset_mic:1;
|
unsigned int is_headset_mic:1;
|
||||||
unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */
|
unsigned int is_headphone_mic:1; /* Mic-only in headphone jack */
|
||||||
unsigned int has_boost_on_pin:1;
|
unsigned int has_boost_on_pin:1;
|
||||||
int order;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct auto_pin_cfg;
|
struct auto_pin_cfg;
|
||||||
|
|
|
@ -9,9 +9,6 @@
|
||||||
#define __SOUND_HDA_GENERIC_H
|
#define __SOUND_HDA_GENERIC_H
|
||||||
|
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include "hda_auto_parser.h"
|
|
||||||
|
|
||||||
struct hda_jack_callback;
|
|
||||||
|
|
||||||
/* table entry for multi-io paths */
|
/* table entry for multi-io paths */
|
||||||
struct hda_multi_io {
|
struct hda_multi_io {
|
||||||
|
@ -186,7 +183,7 @@ struct hda_gen_spec {
|
||||||
struct automic_entry am_entry[MAX_AUTO_MIC_PINS];
|
struct automic_entry am_entry[MAX_AUTO_MIC_PINS];
|
||||||
|
|
||||||
/* for pin sensing */
|
/* for pin sensing */
|
||||||
/* current status; set in hda_generic.c */
|
/* current status; set in hda_geneic.c */
|
||||||
unsigned int hp_jack_present:1;
|
unsigned int hp_jack_present:1;
|
||||||
unsigned int line_jack_present:1;
|
unsigned int line_jack_present:1;
|
||||||
unsigned int speaker_muted:1; /* current status of speaker mute */
|
unsigned int speaker_muted:1; /* current status of speaker mute */
|
||||||
|
@ -232,6 +229,7 @@ struct hda_gen_spec {
|
||||||
unsigned int power_down_unused:1; /* power down unused widgets */
|
unsigned int power_down_unused:1; /* power down unused widgets */
|
||||||
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
unsigned int dac_min_mute:1; /* minimal = mute for DACs */
|
||||||
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
unsigned int suppress_vmaster:1; /* don't create vmaster kctls */
|
||||||
|
unsigned int obey_preferred_dacs:1; /* obey preferred_dacs assignment */
|
||||||
|
|
||||||
/* other internal flags */
|
/* other internal flags */
|
||||||
unsigned int no_analog:1; /* digital I/O only */
|
unsigned int no_analog:1; /* digital I/O only */
|
||||||
|
@ -296,9 +294,6 @@ struct hda_gen_spec {
|
||||||
struct hda_jack_callback *cb);
|
struct hda_jack_callback *cb);
|
||||||
void (*mic_autoswitch_hook)(struct hda_codec *codec,
|
void (*mic_autoswitch_hook)(struct hda_codec *codec,
|
||||||
struct hda_jack_callback *cb);
|
struct hda_jack_callback *cb);
|
||||||
|
|
||||||
/* leds */
|
|
||||||
struct led_classdev *led_cdevs[NUM_AUDIO_LEDS];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* values for add_stereo_mix_input flag */
|
/* values for add_stereo_mix_input flag */
|
||||||
|
@ -329,6 +324,7 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
|
||||||
struct auto_pin_cfg *cfg);
|
struct auto_pin_cfg *cfg);
|
||||||
int snd_hda_gen_build_controls(struct hda_codec *codec);
|
int snd_hda_gen_build_controls(struct hda_codec *codec);
|
||||||
int snd_hda_gen_build_pcms(struct hda_codec *codec);
|
int snd_hda_gen_build_pcms(struct hda_codec *codec);
|
||||||
|
void snd_hda_gen_reboot_notify(struct hda_codec *codec);
|
||||||
|
|
||||||
/* standard jack event callbacks */
|
/* standard jack event callbacks */
|
||||||
void snd_hda_gen_hp_automute(struct hda_codec *codec,
|
void snd_hda_gen_hp_automute(struct hda_codec *codec,
|
||||||
|
@ -339,7 +335,9 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
|
||||||
struct hda_jack_callback *jack);
|
struct hda_jack_callback *jack);
|
||||||
void snd_hda_gen_update_outputs(struct hda_codec *codec);
|
void snd_hda_gen_update_outputs(struct hda_codec *codec);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid);
|
||||||
|
#endif
|
||||||
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||||
hda_nid_t nid,
|
hda_nid_t nid,
|
||||||
unsigned int power_state);
|
unsigned int power_state);
|
||||||
|
@ -352,6 +350,5 @@ int snd_hda_gen_add_mute_led_cdev(struct hda_codec *codec,
|
||||||
int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
|
int snd_hda_gen_add_micmute_led_cdev(struct hda_codec *codec,
|
||||||
int (*callback)(struct led_classdev *,
|
int (*callback)(struct led_classdev *,
|
||||||
enum led_brightness));
|
enum led_brightness));
|
||||||
bool snd_hda_gen_shutup_speakers(struct hda_codec *codec);
|
|
||||||
|
|
||||||
#endif /* __SOUND_HDA_GENERIC_H */
|
#endif /* __SOUND_HDA_GENERIC_H */
|
||||||
|
|
|
@ -69,7 +69,6 @@ struct hda_jack_tbl *
|
||||||
snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec,
|
snd_hda_jack_tbl_get_from_tag(struct hda_codec *codec,
|
||||||
unsigned char tag, int dev_id);
|
unsigned char tag, int dev_id);
|
||||||
|
|
||||||
void snd_hda_jack_tbl_disconnect(struct hda_codec *codec);
|
|
||||||
void snd_hda_jack_tbl_clear(struct hda_codec *codec);
|
void snd_hda_jack_tbl_clear(struct hda_codec *codec);
|
||||||
|
|
||||||
void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
|
void snd_hda_jack_set_dirty_all(struct hda_codec *codec);
|
||||||
|
|
48
hda_local.h
48
hda_local.h
|
@ -135,7 +135,8 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
|
||||||
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \
|
#define snd_hda_add_vmaster(codec, name, tlv, followers, suffix, access) \
|
||||||
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL)
|
__snd_hda_add_vmaster(codec, name, tlv, followers, suffix, true, access, NULL)
|
||||||
int snd_hda_codec_reset(struct hda_codec *codec);
|
int snd_hda_codec_reset(struct hda_codec *codec);
|
||||||
void snd_hda_codec_disconnect_pcms(struct hda_codec *codec);
|
void snd_hda_codec_register(struct hda_codec *codec);
|
||||||
|
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
|
||||||
|
|
||||||
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
#define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
|
||||||
|
|
||||||
|
@ -292,32 +293,6 @@ struct hda_fixup {
|
||||||
} v;
|
} v;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* extended form of snd_pci_quirk:
|
|
||||||
* for PCI SSID matching, use SND_PCI_QUIRK() like before;
|
|
||||||
* for codec SSID matching, use the new HDA_CODEC_QUIRK() instead
|
|
||||||
*/
|
|
||||||
struct hda_quirk {
|
|
||||||
unsigned short subvendor; /* PCI subvendor ID */
|
|
||||||
unsigned short subdevice; /* PCI subdevice ID */
|
|
||||||
unsigned short subdevice_mask; /* bitmask to match */
|
|
||||||
bool match_codec_ssid; /* match only with codec SSID */
|
|
||||||
int value; /* value */
|
|
||||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
||||||
const char *name; /* name of the device (optional) */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
||||||
#define HDA_CODEC_QUIRK(vend, dev, xname, val) \
|
|
||||||
{ _SND_PCI_QUIRK_ID(vend, dev), .value = (val), .name = (xname),\
|
|
||||||
.match_codec_ssid = true }
|
|
||||||
#else
|
|
||||||
#define HDA_CODEC_QUIRK(vend, dev, xname, val) \
|
|
||||||
{ _SND_PCI_QUIRK_ID(vend, dev), .value = (val), \
|
|
||||||
.match_codec_ssid = true }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct snd_hda_pin_quirk {
|
struct snd_hda_pin_quirk {
|
||||||
unsigned int codec; /* Codec vendor/device ID */
|
unsigned int codec; /* Codec vendor/device ID */
|
||||||
unsigned short subvendor; /* PCI subvendor ID */
|
unsigned short subvendor; /* PCI subvendor ID */
|
||||||
|
@ -374,10 +349,9 @@ void snd_hda_apply_verbs(struct hda_codec *codec);
|
||||||
void snd_hda_apply_pincfgs(struct hda_codec *codec,
|
void snd_hda_apply_pincfgs(struct hda_codec *codec,
|
||||||
const struct hda_pintbl *cfg);
|
const struct hda_pintbl *cfg);
|
||||||
void snd_hda_apply_fixup(struct hda_codec *codec, int action);
|
void snd_hda_apply_fixup(struct hda_codec *codec, int action);
|
||||||
void __snd_hda_apply_fixup(struct hda_codec *codec, int id, int action, int depth);
|
|
||||||
void snd_hda_pick_fixup(struct hda_codec *codec,
|
void snd_hda_pick_fixup(struct hda_codec *codec,
|
||||||
const struct hda_model_fixup *models,
|
const struct hda_model_fixup *models,
|
||||||
const struct hda_quirk *quirk,
|
const struct snd_pci_quirk *quirk,
|
||||||
const struct hda_fixup *fixlist);
|
const struct hda_fixup *fixlist);
|
||||||
void snd_hda_pick_pin_fixup(struct hda_codec *codec,
|
void snd_hda_pick_pin_fixup(struct hda_codec *codec,
|
||||||
const struct snd_hda_pin_quirk *pin_quirk,
|
const struct snd_hda_pin_quirk *pin_quirk,
|
||||||
|
@ -464,15 +438,6 @@ int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid,
|
||||||
#define for_each_hda_codec_node(nid, codec) \
|
#define for_each_hda_codec_node(nid, codec) \
|
||||||
for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++)
|
for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++)
|
||||||
|
|
||||||
/* Set the codec power_state flag to indicate to allow unsol event handling;
|
|
||||||
* see hda_codec_unsol_event() in hda_bind.c. Calling this might confuse the
|
|
||||||
* state tracking, so use with care.
|
|
||||||
*/
|
|
||||||
static inline void snd_hda_codec_allow_unsol_events(struct hda_codec *codec)
|
|
||||||
{
|
|
||||||
codec->core.dev.power.power_state = PMSG_ON;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get widget capabilities
|
* get widget capabilities
|
||||||
*/
|
*/
|
||||||
|
@ -650,8 +615,6 @@ unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
|
||||||
hda_nid_t nid,
|
hda_nid_t nid,
|
||||||
unsigned int power_state);
|
unsigned int power_state);
|
||||||
|
|
||||||
void snd_hda_codec_shutdown(struct hda_codec *codec);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AMP control callbacks
|
* AMP control callbacks
|
||||||
*/
|
*/
|
||||||
|
@ -738,8 +701,7 @@ int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid,
|
||||||
|
|
||||||
#ifdef CONFIG_SND_PROC_FS
|
#ifdef CONFIG_SND_PROC_FS
|
||||||
void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
|
void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
|
||||||
struct snd_info_buffer *buffer,
|
struct snd_info_buffer *buffer);
|
||||||
hda_nid_t pin_nid, int dev_id, hda_nid_t cvt_nid);
|
|
||||||
void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
|
void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
|
||||||
struct snd_info_buffer *buffer);
|
struct snd_info_buffer *buffer);
|
||||||
#endif
|
#endif
|
||||||
|
@ -747,8 +709,6 @@ void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
|
||||||
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
|
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
|
||||||
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
|
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
|
||||||
|
|
||||||
void snd_hda_codec_display_power(struct hda_codec *codec, bool enable);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
#define codec_err(codec, fmt, args...) \
|
#define codec_err(codec, fmt, args...) \
|
||||||
|
|
3790
patch_cirrus.c
Normal file
3790
patch_cirrus.c
Normal file
File diff suppressed because it is too large
Load diff
3083
patch_cirrus_apple.h
3083
patch_cirrus_apple.h
File diff suppressed because it is too large
Load diff
|
@ -1634,7 +1634,7 @@ static void setup_jack_pin_config(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
|
|
||||||
//int retval;
|
//int retval;
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
// this is likely some call of setPinConfigDefault
|
// this is likely some call of setPinConfigDefault
|
||||||
// 0x45 -> 0x23 (macbook pro) is the line in path - so why does it say its a mike??
|
// 0x45 -> 0x23 (macbook pro) is the line in path - so why does it say its a mike??
|
||||||
|
@ -1753,7 +1753,7 @@ static void determine_speaker_id(struct hda_codec *codec)
|
||||||
|
|
||||||
// this is call AppleHDAFunctionGroup::setGPIOEnable in determineSpeakerID
|
// this is call AppleHDAFunctionGroup::setGPIOEnable in determineSpeakerID
|
||||||
|
|
||||||
if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00)
|
if (codec->core.subsystem_id == 0x106b3900)
|
||||||
{
|
{
|
||||||
//snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_MASK, 0x00000008); // 0x00171608
|
//snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_MASK, 0x00000008); // 0x00171608
|
||||||
// snd_hda: gpio enable 1 0x08
|
// snd_hda: gpio enable 1 0x08
|
||||||
|
@ -1771,13 +1771,13 @@ static void determine_speaker_id(struct hda_codec *codec)
|
||||||
|
|
||||||
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
||||||
|
|
||||||
mycodec_info(codec, "command determine_speaker_id gpio mask 0x8 data 0x%08x\n", retval);
|
mycodec_info(codec, "command determine_speaker_id gpio data 0x%08x\n", retval);
|
||||||
|
|
||||||
snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_MASK, 0x0000000c); // 0x0017160c
|
snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_MASK, 0x0000000c); // 0x0017160c
|
||||||
|
|
||||||
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
||||||
|
|
||||||
mycodec_info(codec, "command determine_speaker_id gpio mask 0xc data 0x%08x\n", retval);
|
mycodec_info(codec, "command determine_speaker_id gpio data 0x%08x\n", retval);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1792,7 +1792,7 @@ static void determine_speaker_id(struct hda_codec *codec)
|
||||||
|
|
||||||
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
retval = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_GPIO_DATA, 0x00000000); // 0x001f1500
|
||||||
|
|
||||||
mycodec_info(codec, "command determine_speaker_id gpio mask 0x4 data 0x%08x\n", retval);
|
mycodec_info(codec, "command determine_speaker_id gpio data 0x%08x\n", retval);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2412,13 +2412,13 @@ static void cs42l83_mic_detect(struct hda_codec *codec)
|
||||||
mycodec_info(codec, "command cs42l83_mic_detect end\n");
|
mycodec_info(codec, "command cs42l83_mic_detect end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cs42l83_tip_sense(struct hda_codec *codec, int invert)
|
static void cs42l83_tip_sense(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
int newval1;
|
int newval1;
|
||||||
int newval2;
|
int newval2;
|
||||||
int newval;
|
int newval;
|
||||||
//int invert = 0;
|
int flag = 0;
|
||||||
|
|
||||||
// likely in AppleHDAMikeyInternalCS8409::setupJackDetection
|
// likely in AppleHDAMikeyInternalCS8409::setupJackDetection
|
||||||
// - only 0x73 readMikey/writeMikey calls seen
|
// - only 0x73 readMikey/writeMikey calls seen
|
||||||
|
@ -2431,19 +2431,14 @@ static void cs42l83_tip_sense(struct hda_codec *codec, int invert)
|
||||||
|
|
||||||
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b73, 1); // snd_hda
|
retval = cs_8409_vendor_i2cRead(codec, 0x90, 0x1b73, 1); // snd_hda
|
||||||
|
|
||||||
// invert indicates inverted signal path for physical jack presence detect circuit
|
|
||||||
|
|
||||||
// following code translated from assembler
|
|
||||||
newval1 = (retval & 0x1c);
|
newval1 = (retval & 0x1c);
|
||||||
if (invert)
|
|
||||||
|
if (flag)
|
||||||
newval = (newval1 | 0xe0);
|
newval = (newval1 | 0xe0);
|
||||||
else
|
else
|
||||||
newval = (newval1 | 0xc0);
|
newval = (newval1 | 0xc0);
|
||||||
|
|
||||||
|
|
||||||
if (invert)
|
|
||||||
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b73, 0x00e0, 1); // snd_hda
|
|
||||||
else
|
|
||||||
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b73, 0x00c0, 1); // snd_hda
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b73, 0x00c0, 1); // snd_hda
|
||||||
|
|
||||||
mycodec_info(codec, "command cs42l83_tip_sense end\n");
|
mycodec_info(codec, "command cs42l83_tip_sense end\n");
|
||||||
|
|
|
@ -340,8 +340,6 @@ add_control(struct hda_gen_spec *spec, int type, const char *name,
|
||||||
knew->index = cidx;
|
knew->index = cidx;
|
||||||
if (get_amp_nid_(val))
|
if (get_amp_nid_(val))
|
||||||
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
knew->subdevice = HDA_SUBDEV_AMP_FLAG;
|
||||||
if (knew->access == 0)
|
|
||||||
knew->access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
|
|
||||||
knew->private_value = val;
|
knew->private_value = val;
|
||||||
return knew;
|
return knew;
|
||||||
}
|
}
|
||||||
|
@ -352,11 +350,7 @@ static int add_control_with_pfx(struct hda_gen_spec *spec, int type,
|
||||||
const char *sfx, int cidx, unsigned long val)
|
const char *sfx, int cidx, unsigned long val)
|
||||||
{
|
{
|
||||||
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||||
int len;
|
snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
|
||||||
|
|
||||||
len = snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
|
|
||||||
if (snd_BUG_ON(len >= sizeof(name)))
|
|
||||||
return -EINVAL;
|
|
||||||
if (!add_control(spec, type, name, cidx, val))
|
if (!add_control(spec, type, name, cidx, val))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -75,7 +75,7 @@ static unsigned int hda_set_node_power_state_dbg(struct hda_codec *codec, hda_ni
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dev_info(hda_codec_dev(codec), "hda_set_node_power_state ERROR!! nid 0x%02x 0x%04x\n",nid, state);
|
dev_info(hda_codec_dev(codec), "hda_set_node_power_state ERROR!! 0x%04x\n",state);
|
||||||
}
|
}
|
||||||
if (dbgflg) mycodec_info(codec, "hda_set_node_power_state end power %d\n",state);
|
if (dbgflg) mycodec_info(codec, "hda_set_node_power_state end power %d\n",state);
|
||||||
|
|
||||||
|
@ -118,15 +118,15 @@ static void hda_check_power_state(struct hda_codec *codec, hda_nid_t nid, int fl
|
||||||
|
|
||||||
static inline unsigned int cs_8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
|
static inline unsigned int cs_8409_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
unsigned int retval;
|
unsigned int retval;
|
||||||
snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_read(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_GET_COEF_INDEX, 0);
|
AC_VERB_GET_COEF_INDEX, 0);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, idx);
|
AC_VERB_SET_COEF_INDEX, idx);
|
||||||
retval = snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0,
|
retval = snd_hda_codec_read(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_GET_PROC_COEF, 0);
|
AC_VERB_GET_PROC_COEF, 0);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, 0);
|
AC_VERB_SET_COEF_INDEX, 0);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -134,14 +134,14 @@ static inline unsigned int cs_8409_vendor_coef_get(struct hda_codec *codec, unsi
|
||||||
static inline void cs_8409_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
|
static inline void cs_8409_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
|
||||||
unsigned int coef)
|
unsigned int coef)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_read(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_GET_COEF_INDEX, 0);
|
AC_VERB_GET_COEF_INDEX, 0);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, idx);
|
AC_VERB_SET_COEF_INDEX, idx);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_PROC_COEF, coef);
|
AC_VERB_SET_PROC_COEF, coef);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, 0);
|
AC_VERB_SET_COEF_INDEX, 0);
|
||||||
// appears to return 0
|
// appears to return 0
|
||||||
}
|
}
|
||||||
|
@ -150,16 +150,16 @@ static inline unsigned int cs_8409_vendor_coef_set_mask(struct hda_codec *codec,
|
||||||
unsigned int coef, unsigned int mask, unsigned int srcval, int srcidx)
|
unsigned int coef, unsigned int mask, unsigned int srcval, int srcidx)
|
||||||
{
|
{
|
||||||
// for the moment hackily add srcidx argument while debugging
|
// for the moment hackily add srcidx argument while debugging
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
unsigned int retval;
|
unsigned int retval;
|
||||||
unsigned int mask_coef;
|
unsigned int mask_coef;
|
||||||
snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_read(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_GET_COEF_INDEX, 0);
|
AC_VERB_GET_COEF_INDEX, 0);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, idx);
|
AC_VERB_SET_COEF_INDEX, idx);
|
||||||
retval = snd_hda_codec_read(codec, CS8409_VENDOR_NID, 0,
|
retval = snd_hda_codec_read(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_GET_PROC_COEF, 0);
|
AC_VERB_GET_PROC_COEF, 0);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, idx);
|
AC_VERB_SET_COEF_INDEX, idx);
|
||||||
mask_coef = (retval & ~mask) | coef;
|
mask_coef = (retval & ~mask) | coef;
|
||||||
if (srcval != 0)
|
if (srcval != 0)
|
||||||
|
@ -172,9 +172,9 @@ static inline unsigned int cs_8409_vendor_coef_set_mask(struct hda_codec *codec,
|
||||||
else
|
else
|
||||||
//if (mask != 0xffff)
|
//if (mask != 0xffff)
|
||||||
myprintk_dbg("snd_hda_intel: cs_8409_vendor_coef_set_mask 0x%04x 0x%04x: 0x%04x (0x%04x 0x%04x 0x%04x) %d",idx,coef,mask_coef,retval,coef,mask,srcidx);
|
myprintk_dbg("snd_hda_intel: cs_8409_vendor_coef_set_mask 0x%04x 0x%04x: 0x%04x (0x%04x 0x%04x 0x%04x) %d",idx,coef,mask_coef,retval,coef,mask,srcidx);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_PROC_COEF, mask_coef);
|
AC_VERB_SET_PROC_COEF, mask_coef);
|
||||||
snd_hda_codec_write(codec, CS8409_VENDOR_NID, 0,
|
snd_hda_codec_write(codec, spec->vendor_nid, 0,
|
||||||
AC_VERB_SET_COEF_INDEX, 0);
|
AC_VERB_SET_COEF_INDEX, 0);
|
||||||
// appears to return 0
|
// appears to return 0
|
||||||
// lets return the read value for checking
|
// lets return the read value for checking
|
||||||
|
@ -569,7 +569,7 @@ void snd_hda_double_reset(struct hda_codec *codec)
|
||||||
|
|
||||||
static void clear_pins(struct hda_codec *codec)
|
static void clear_pins(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
//struct cs8409_apple_spec *spec = codec->spec;
|
//struct cs_spec *spec = codec->spec;
|
||||||
hda_nid_t nid;
|
hda_nid_t nid;
|
||||||
|
|
||||||
mycodec_info(codec, "start clear_pins\n");
|
mycodec_info(codec, "start clear_pins\n");
|
||||||
|
@ -585,7 +585,7 @@ static void clear_pins(struct hda_codec *codec)
|
||||||
|
|
||||||
static void read_coefs_all_loop(struct hda_codec *codec)
|
static void read_coefs_all_loop(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
//struct cs8409_apple_spec *spec = codec->spec;
|
//struct cs_spec *spec = codec->spec;
|
||||||
int idx;
|
int idx;
|
||||||
mycodec_info(codec, "start read_coefs_all\n");
|
mycodec_info(codec, "start read_coefs_all\n");
|
||||||
for (idx = 0; idx < 130; idx++)
|
for (idx = 0; idx < 130; idx++)
|
||||||
|
@ -612,9 +612,6 @@ struct hda_cvt_setup {
|
||||||
unsigned char dirty; /* setups should be cleared */
|
unsigned char dirty; /* setups should be cleared */
|
||||||
};
|
};
|
||||||
|
|
||||||
// we now setup our local cache data in the spec structure
|
|
||||||
// - cvt_setups is an opaque pointer type so we can see it here
|
|
||||||
// but we dont know how to access the data - except by re-defining hda_cvt_setup as above
|
|
||||||
|
|
||||||
/* get or create a cache entry for the given audio converter NID */
|
/* get or create a cache entry for the given audio converter NID */
|
||||||
static struct hda_cvt_setup *
|
static struct hda_cvt_setup *
|
||||||
|
@ -623,7 +620,8 @@ get_hda_cvt_setup_8409(struct hda_codec *codec, hda_nid_t nid)
|
||||||
struct hda_cvt_setup *p;
|
struct hda_cvt_setup *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
snd_array_for_each(&codec->cvt_setups, i, p) {
|
for (i = 0; i < codec->cvt_setups.used; i++) {
|
||||||
|
p = snd_array_elem(&codec->cvt_setups, i);
|
||||||
if (p->nid == nid)
|
if (p->nid == nid)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -633,41 +631,9 @@ get_hda_cvt_setup_8409(struct hda_codec *codec, hda_nid_t nid)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// so we actually need both versions - one using the hda_cvt_setup struct
|
|
||||||
// and one using our local hda_cvt_setup_apple struct
|
|
||||||
|
|
||||||
static struct hda_cvt_setup_apple *
|
|
||||||
get_hda_cvt_setup_apple_8409(struct hda_codec *codec, hda_nid_t nid)
|
|
||||||
{
|
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
|
||||||
|
|
||||||
switch (nid)
|
|
||||||
{
|
|
||||||
case 0x02:
|
|
||||||
return &spec->nid_0x02;
|
|
||||||
case 0x03:
|
|
||||||
return &spec->nid_0x03;
|
|
||||||
case 0x0a:
|
|
||||||
return &spec->nid_0x0a;
|
|
||||||
case 0x22:
|
|
||||||
return &spec->nid_0x22;
|
|
||||||
case 0x23:
|
|
||||||
return &spec->nid_0x23;
|
|
||||||
case 0x1a:
|
|
||||||
return &spec->nid_0x1a;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
codec_err(codec, "get_hda_cvt_setup_apple_8409: UNKNOWN NID!! 0x%02x\n", nid);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cs_8409_dump_stream_format(struct hda_codec *codec, hda_nid_t nid)
|
static void cs_8409_dump_stream_format(struct hda_codec *codec, hda_nid_t nid)
|
||||||
{
|
{
|
||||||
struct hda_cvt_setup_apple *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// use explicit search so we dont create one if doesnt exist
|
// use explicit search so we dont create one if doesnt exist
|
||||||
|
@ -679,45 +645,34 @@ static void cs_8409_dump_stream_format(struct hda_codec *codec, hda_nid_t nid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
mycodec_dbg(codec, "cs_8409_dump_stream_format: NID=0x%x, codec cached values: stream=0x%x, channel=%d, format=0x%x\n", nid, p->stream_tag, p->channel_id, p->format_id);
|
codec_dbg(codec, "cs_8409_dump_stream_format: NID=0x%x, cached values: stream=0x%x, channel=%d, format=0x%x\n", nid, p->stream_tag, p->channel_id, p->format_id);
|
||||||
else
|
else
|
||||||
mycodec_dbg(codec, "cs_8409_dump_stream_format: NID=0x%x, codec cached values: NULL\n", nid);
|
codec_dbg(codec, "cs_8409_dump_stream_format: NID=0x%x, cached values: NULL\n", nid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cs_8409_reset_stream_format(struct hda_codec *codec, hda_nid_t nid, int format, int doreset)
|
static void cs_8409_reset_stream_format(struct hda_codec *codec, hda_nid_t nid, int format, int doreset)
|
||||||
{
|
{
|
||||||
// note that this routine is currently not used
|
|
||||||
|
|
||||||
// this resets the cached stream format so that next
|
// this resets the cached stream format so that next
|
||||||
// stream setup will actually rewrite the stream format and stream id
|
// stream setup will actually rewrite the stream format and stream id
|
||||||
// or if doreset set it will perform the stream update now
|
// or if doreset set it will perform the stream update now
|
||||||
// also allow for only updating the stream format and not stream id
|
// also allow for only updating the stream format and not stream id
|
||||||
|
|
||||||
// NOTE we now save the stream format in our local cache as the hda_codec cache
|
// problem - the get_hda_cvt_setup function is local to hda_codec - so need our own copy above
|
||||||
// is cleared at end of the prepare stage and we want to store it more permanently
|
|
||||||
// really only the stream id is variable
|
|
||||||
|
|
||||||
struct hda_cvt_setup *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
struct hda_cvt_setup_apple *papl = NULL;
|
|
||||||
u32 stream_tag_sv;
|
u32 stream_tag_sv;
|
||||||
int channel_id_sv;
|
int channel_id_sv;
|
||||||
int format_id_sv;
|
int format_id_sv;
|
||||||
|
|
||||||
// problem - the get_hda_cvt_setup function is local to hda_codec - so need our own copy above
|
p = get_hda_cvt_setup_8409(codec, nid);
|
||||||
|
|
||||||
papl = get_hda_cvt_setup_apple_8409(codec, nid);
|
stream_tag_sv = p->stream_tag;
|
||||||
|
channel_id_sv = p->channel_id;
|
||||||
stream_tag_sv = papl->stream_tag;
|
format_id_sv = p->format_id;
|
||||||
channel_id_sv = papl->channel_id;
|
|
||||||
format_id_sv = papl->format_id;
|
|
||||||
|
|
||||||
mycodec_info(codec, "cs_8409_reset_stream_format RESET for nid 0x%02x: 0x%08x id 0x%08x chan 0x%08x\n", nid, format_id_sv, stream_tag_sv, channel_id_sv);
|
mycodec_info(codec, "cs_8409_reset_stream_format RESET for nid 0x%02x: 0x%08x id 0x%08x chan 0x%08x\n", nid, format_id_sv, stream_tag_sv, channel_id_sv);
|
||||||
|
|
||||||
// snd_hda_codec_setup_stream uses a caching system so only sends verbs when a change occurs
|
|
||||||
// we want to force a send here so need to clear the cached data
|
|
||||||
|
|
||||||
p = get_hda_cvt_setup_8409(codec, nid);
|
|
||||||
|
|
||||||
p->stream_tag = 0;
|
p->stream_tag = 0;
|
||||||
p->channel_id = 0;
|
p->channel_id = 0;
|
||||||
if (format)
|
if (format)
|
||||||
|
@ -733,21 +688,6 @@ static void cs_8409_reset_stream_format(struct hda_codec *codec, hda_nid_t nid,
|
||||||
// - we want to remove the Apple specific stream format/channel setup
|
// - we want to remove the Apple specific stream format/channel setup
|
||||||
// and just call snd_hda_setup_stream - but we need the actual stream format for this
|
// and just call snd_hda_setup_stream - but we need the actual stream format for this
|
||||||
// - hopefully getting from the hda_cvt_setup struct
|
// - hopefully getting from the hda_cvt_setup struct
|
||||||
// unfortunately this idea of storing in the hda_cvt_setup table turns out to be not useful
|
|
||||||
// as at end of snd_hda_codec_prepare it clears out (ie zeros) all unused/inactive cache entries
|
|
||||||
// so we have to store in a separate cache using our own copied definition for hda_cvt_setup
|
|
||||||
// hda_cvt_setup_apple
|
|
||||||
|
|
||||||
|
|
||||||
// the following 2 functions are used in the sync converter functions
|
|
||||||
// where apple essentially disables streaming (set stream id to 0) updates some vendor nid parameters
|
|
||||||
// then restores streaming
|
|
||||||
// so we store the stream info in a local variable copy and set it to the unused stream id ie stream id of 0
|
|
||||||
// then cs_8409_update_from_save_stream_format sets it back to what it was
|
|
||||||
// note that the format is unchanged for these operations
|
|
||||||
// the main reason for doing it this way is because of the caching used in snd_hda_codec_setup_stream
|
|
||||||
// - if we just sent the hda verbs then the cached data in snd_hda_codec_setup_stream
|
|
||||||
// would be inconsistent with the actual state of streaming on the nid
|
|
||||||
|
|
||||||
static void cs_8409_save_and_clear_stream_format(struct hda_codec *codec, hda_nid_t nid, struct hda_cvt_setup *savep)
|
static void cs_8409_save_and_clear_stream_format(struct hda_codec *codec, hda_nid_t nid, struct hda_cvt_setup *savep)
|
||||||
{
|
{
|
||||||
|
@ -756,7 +696,7 @@ static void cs_8409_save_and_clear_stream_format(struct hda_codec *codec, hda_ni
|
||||||
int channel_id_sv;
|
int channel_id_sv;
|
||||||
int format_id_sv;
|
int format_id_sv;
|
||||||
|
|
||||||
mycodec_dbg(codec, "cs_8409_save_and_clear_stream_format nid 0x%02x\n", nid);
|
codec_dbg(codec, "cs_8409_save_and_clear_stream_format\n");
|
||||||
|
|
||||||
// use this to save the stream format and clear the stream id and channel
|
// use this to save the stream format and clear the stream id and channel
|
||||||
|
|
||||||
|
@ -773,7 +713,7 @@ static void cs_8409_update_from_save_stream_format(struct hda_codec *codec, hda_
|
||||||
{
|
{
|
||||||
struct hda_cvt_setup *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
|
|
||||||
mycodec_dbg(codec, "cs_8409_update_from_save_stream_format nid 0x%02x\n", nid);
|
codec_dbg(codec, "cs_8409_update_from_save_stream_format\n");
|
||||||
|
|
||||||
// so this will ensure the format is re-updated
|
// so this will ensure the format is re-updated
|
||||||
|
|
||||||
|
@ -787,52 +727,29 @@ static void cs_8409_update_from_save_stream_format(struct hda_codec *codec, hda_
|
||||||
if (update_format_id)
|
if (update_format_id)
|
||||||
p->format_id = 0;
|
p->format_id = 0;
|
||||||
|
|
||||||
mycodec_info(codec, "cs_8409_update_from_save_stream_format tag 0x%08x chnl 0x%08x fmt 0x%08x\n", savep->stream_tag, savep->channel_id, savep->format_id);
|
|
||||||
|
|
||||||
snd_hda_codec_setup_stream(codec, nid, savep->stream_tag, savep->channel_id, savep->format_id);
|
snd_hda_codec_setup_stream(codec, nid, savep->stream_tag, savep->channel_id, savep->format_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// so these are the crucial routines for setting our local cached copy of the stream info (in the spec structure)
|
|
||||||
// we use a different struct definition (hda_cvt_setup_apple) to keep the re-definition of hda_cvt_setup more local
|
|
||||||
// note that this stream info is only stored once per stream prepare function call
|
|
||||||
// and this routine always updates from that initial data
|
|
||||||
|
|
||||||
static void cs_8409_really_update_stream_format(struct hda_codec *codec, hda_nid_t nid, int update_format_id, int update_stream_id, unsigned int new_channel_id)
|
static void cs_8409_really_update_stream_format(struct hda_codec *codec, hda_nid_t nid, int update_format_id, int update_stream_id, unsigned int new_channel_id)
|
||||||
{
|
{
|
||||||
struct hda_cvt_setup *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
struct hda_cvt_setup_apple *papl = NULL;
|
u32 stream_tag_sv;
|
||||||
u32 stream_tag_sv = 0;
|
int channel_id_sv;
|
||||||
int channel_id_sv = 0;
|
int format_id_sv;
|
||||||
int format_id_sv = 0;
|
|
||||||
|
|
||||||
mycodec_dbg(codec, "cs_8409_really_update_stream_format nid 0x%02x updfmt %d updstrmid %d nchnlid %d\n", nid, update_format_id, update_stream_id, new_channel_id);
|
codec_dbg(codec, "cs_8409_really_update_stream_format\n");
|
||||||
//dump_stack();
|
|
||||||
|
|
||||||
// so here we take our local cached format and save locally, clear out the cached values
|
cs_8409_dump_stream_format(codec, nid);
|
||||||
|
|
||||||
|
// so here we take the cached format and save locally, clear out the cached values
|
||||||
// then call snd_hda_codec_setup_stream with the cached values
|
// then call snd_hda_codec_setup_stream with the cached values
|
||||||
// this will ensure we update the HDA with the stream format
|
// this will ensure we update the HDA with the stream format
|
||||||
|
|
||||||
// maybe now we should just update from our local stored version??
|
|
||||||
|
|
||||||
papl = get_hda_cvt_setup_apple_8409(codec, nid);
|
|
||||||
|
|
||||||
if (papl != NULL)
|
|
||||||
{
|
|
||||||
stream_tag_sv = papl->stream_tag;
|
|
||||||
channel_id_sv = papl->channel_id;
|
|
||||||
format_id_sv = papl->format_id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
codec_err(codec, "cs_8409_really_update_stream_format bad nid 0x%02x FAIL!!\n", nid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
p = get_hda_cvt_setup_8409(codec, nid);
|
p = get_hda_cvt_setup_8409(codec, nid);
|
||||||
|
|
||||||
mycodec_info(codec, "cs_8409_really_update_stream_format cached tag 0x%08x chnl 0x%08x fmt 0x%08x\n", papl->stream_tag, papl->channel_id, papl->format_id);
|
stream_tag_sv = p->stream_tag;
|
||||||
|
channel_id_sv = p->channel_id;
|
||||||
|
format_id_sv = p->format_id;
|
||||||
|
|
||||||
if (update_stream_id)
|
if (update_stream_id)
|
||||||
{
|
{
|
||||||
|
@ -842,30 +759,17 @@ static void cs_8409_really_update_stream_format(struct hda_codec *codec, hda_nid
|
||||||
if (update_format_id)
|
if (update_format_id)
|
||||||
p->format_id = 0;
|
p->format_id = 0;
|
||||||
|
|
||||||
mycodec_info(codec, "cs_8409_really_update_stream_format to update tag 0x%08x chnl 0x%08x fmt 0x%08x\n", p->stream_tag, p->channel_id, p->format_id);
|
|
||||||
|
|
||||||
if (update_stream_id == 2)
|
|
||||||
mycodec_info(codec, "cs_8409_really_update_stream_format new tag 0x%08x chnl 0x%08x fmt 0x%08x\n", stream_tag_sv, new_channel_id, format_id_sv);
|
|
||||||
else
|
|
||||||
mycodec_info(codec, "cs_8409_really_update_stream_format new tag 0x%08x chnl 0x%08x fmt 0x%08x\n", stream_tag_sv, channel_id_sv, format_id_sv);
|
|
||||||
|
|
||||||
cs_8409_dump_stream_format(codec, nid);
|
|
||||||
|
|
||||||
if (update_stream_id == 2)
|
if (update_stream_id == 2)
|
||||||
snd_hda_codec_setup_stream(codec, nid, stream_tag_sv, new_channel_id, format_id_sv);
|
snd_hda_codec_setup_stream(codec, nid, stream_tag_sv, new_channel_id, format_id_sv);
|
||||||
else
|
else
|
||||||
snd_hda_codec_setup_stream(codec, nid, stream_tag_sv, channel_id_sv, format_id_sv);
|
snd_hda_codec_setup_stream(codec, nid, stream_tag_sv, channel_id_sv, format_id_sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove function from compile so get error when building if use it
|
|
||||||
#if 0
|
|
||||||
static void cs_8409_setup_stream_format(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format)
|
static void cs_8409_setup_stream_format(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format)
|
||||||
{
|
{
|
||||||
struct hda_cvt_setup *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
|
|
||||||
// NOTE - this function should no longer be used
|
codec_dbg(codec, "cs_8409_setup_stream_format nid 0x%02x\n",nid);
|
||||||
|
|
||||||
mycodec_dbg(codec, "cs_8409_setup_stream_format nid 0x%02x\n",nid);
|
|
||||||
|
|
||||||
cs_8409_dump_stream_format(codec, nid);
|
cs_8409_dump_stream_format(codec, nid);
|
||||||
|
|
||||||
|
@ -881,40 +785,6 @@ static void cs_8409_setup_stream_format(struct hda_codec *codec, hda_nid_t nid,
|
||||||
p->channel_id = 0;
|
p->channel_id = 0;
|
||||||
p->format_id = format;
|
p->format_id = format;
|
||||||
|
|
||||||
cs_8409_dump_stream_format(codec, nid);
|
|
||||||
|
|
||||||
mycodec_dbg(codec, "end cs_8409_setup_stream_format\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void cs_8409_store_stream_format(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format)
|
|
||||||
{
|
|
||||||
struct hda_cvt_setup_apple *papl = NULL;
|
|
||||||
|
|
||||||
mycodec_dbg(codec, "cs_8409_store_stream_format nid 0x%02x\n",nid);
|
|
||||||
|
|
||||||
cs_8409_dump_stream_format(codec, nid);
|
|
||||||
|
|
||||||
// this functions sets up our local cached stream save store
|
|
||||||
// NOTA BENE we do not do the update here - we are relying that this will be done by a call to
|
|
||||||
// cs_8409_really_update_stream_format now we have set the format correctly
|
|
||||||
|
|
||||||
papl = get_hda_cvt_setup_apple_8409(codec, nid);
|
|
||||||
|
|
||||||
if (papl != NULL)
|
|
||||||
{
|
|
||||||
// NOTA BENE - we do not set the channel id here - this will be done by cs_8409_really_update_stream_format
|
|
||||||
|
|
||||||
papl->stream_tag = stream_tag;
|
|
||||||
papl->channel_id = 0;
|
|
||||||
papl->format_id = format;
|
|
||||||
|
|
||||||
mycodec_info(codec, "cs_8409_store_stream_format cached tag 0x%08x chnl 0x%08x fmt 0x%08x\n", papl->stream_tag, papl->channel_id, papl->format_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
codec_err(codec, "cs_8409_store_stream_format bad nid 0x%02x FAIL!!\n", nid);
|
|
||||||
|
|
||||||
mycodec_dbg(codec, "end cs_8409_store_stream_format\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -930,40 +800,40 @@ static void switch_input_src(struct hda_codec *codec)
|
||||||
struct hda_input_mux *imux = &spec->input_mux;
|
struct hda_input_mux *imux = &spec->input_mux;
|
||||||
struct nid_path *path;
|
struct nid_path *path;
|
||||||
int i, c, nums;
|
int i, c, nums;
|
||||||
mycodec_dbg(codec, "switch_input_src enter\n");
|
codec_dbg(codec, "switch_input_src enter\n");
|
||||||
|
|
||||||
nums = spec->num_adc_nids;
|
nums = spec->num_adc_nids;
|
||||||
|
|
||||||
mycodec_dbg(codec, "switch_input_src num adc nids %d %d\n",nums,spec->dyn_adc_switch);
|
codec_dbg(codec, "switch_input_src num adc nids %d %d\n",nums,spec->dyn_adc_switch);
|
||||||
|
|
||||||
for (c = 0; c < nums; c++) {
|
for (c = 0; c < nums; c++) {
|
||||||
mycodec_dbg(codec, "switch_input_src num_items %d\n",imux->num_items);
|
codec_dbg(codec, "switch_input_src num_items %d\n",imux->num_items);
|
||||||
for (i = 0; i < imux->num_items; i++) {
|
for (i = 0; i < imux->num_items; i++) {
|
||||||
//path = get_input_path(codec, c, i);
|
//path = get_input_path(codec, c, i);
|
||||||
path = snd_hda_get_path_from_idx(codec, spec->input_paths[i][c]);
|
path = snd_hda_get_path_from_idx(codec, spec->input_paths[i][c]);
|
||||||
if (path) {
|
if (path) {
|
||||||
int in;
|
int in;
|
||||||
bool active = path->active;
|
bool active = path->active;
|
||||||
mycodec_dbg(codec, "switch_input_src path active %d\n",active);
|
codec_dbg(codec, "switch_input_src path active %d\n",active);
|
||||||
for (in = path->depth - 1; in >= 0; in--) {
|
for (in = path->depth - 1; in >= 0; in--) {
|
||||||
hda_nid_t tnid = path->path[in];
|
hda_nid_t tnid = path->path[in];
|
||||||
mycodec_dbg(codec, "switch_input_src path nid %d: 0x%02x\n",in,tnid);
|
codec_dbg(codec, "switch_input_src path nid %d: 0x%02x\n",in,tnid);
|
||||||
}
|
}
|
||||||
if (path->active) {
|
if (path->active) {
|
||||||
mycodec_dbg(codec, "switch_input_src path nid 0x%02x deactivate\n",path->path[1]);
|
codec_dbg(codec, "switch_input_src path nid 0x%02x deactivate\n",path->path[1]);
|
||||||
snd_hda_activate_path(codec, path, false, false);
|
snd_hda_activate_path(codec, path, false, false);
|
||||||
} else {
|
} else {
|
||||||
mycodec_dbg(codec, "switch_input_src path nid 0x%02x activate\n",path->path[1]);
|
codec_dbg(codec, "switch_input_src path nid 0x%02x activate\n",path->path[1]);
|
||||||
snd_hda_activate_path(codec, path, true, false);
|
snd_hda_activate_path(codec, path, true, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mycodec_dbg(codec, "switch_input_src path NULL\n");
|
codec_dbg(codec, "switch_input_src path NULL\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mycodec_dbg(codec, "switch_input_src exit\n");
|
codec_dbg(codec, "switch_input_src exit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1059,8 +929,6 @@ static void cs_8409_play_data_ssm3(struct hda_codec *codec)
|
||||||
// 14,3 0x106b3900
|
// 14,3 0x106b3900
|
||||||
|
|
||||||
// imac subsystem ids
|
// imac subsystem ids
|
||||||
// 18,1 0x106b0e00
|
|
||||||
// 18,2 0x106b0f00
|
|
||||||
// 18,3 0x106b1000
|
// 18,3 0x106b1000
|
||||||
// 19,1 0x106b1000
|
// 19,1 0x106b1000
|
||||||
|
|
||||||
|
@ -1072,12 +940,12 @@ static int cs_8409_real_config(struct hda_codec *codec);
|
||||||
static int cs_8409_boot_setup(struct hda_codec *codec)
|
static int cs_8409_boot_setup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
// so it appears we break up the subsystem_id into 2 parts
|
// so it appears we break up the subsystem_id into 2 parts
|
||||||
// a codec vendor id (16 bits) and a subvendor id (8 bits) plus an assembly id
|
// a codec vendor id (16 bits) and a subvendor id (8 bits) plus an assembly id
|
||||||
// so here the codec vendor is 0x106b, the subvendor id is 0x39 and the assembly id is 0x00
|
// so here the codec vendor is 0x106b, the subvendor id is 0x39 and the assembly id is 0x00
|
||||||
if (codec->core.subsystem_id == 0x106b3900) {
|
if (codec->core.subsystem_id == 0x106b3900 || codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
myprintk("snd_hda_intel: cs_8409_boot_setup pre cs_8409_data_config\n");
|
myprintk("snd_hda_intel: cs_8409_boot_setup pre cs_8409_data_config\n");
|
||||||
|
|
||||||
|
@ -1101,13 +969,6 @@ static int cs_8409_boot_setup(struct hda_codec *codec)
|
||||||
err = cs_8409_real_config(codec);
|
err = cs_8409_real_config(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|
||||||
if (spec->use_data) {
|
|
||||||
printk("snd_hda_intel: cs_8409_boot_setup pre data not implemented for subsystem id 0x%08x",codec->core.subsystem_id);
|
|
||||||
} else {
|
|
||||||
err = cs_8409_real_config(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -1118,9 +979,8 @@ static int cs_8409_boot_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_play_setup(struct hda_codec *codec)
|
void cs_8409_play_setup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
myprintk_dbg("snd_hda_intel: cs_8409_play_setup\n");
|
if (codec->core.subsystem_id == 0x106b3900 || codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (codec->core.subsystem_id == 0x106b3900) {
|
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
//cs_8409_unmute_data(codec);
|
//cs_8409_unmute_data(codec);
|
||||||
//cs_8409_volup_data(codec);
|
//cs_8409_volup_data(codec);
|
||||||
|
@ -1137,13 +997,6 @@ void cs_8409_play_setup(struct hda_codec *codec)
|
||||||
cs_8409_play_real(codec);
|
cs_8409_play_real(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|
||||||
if (spec->use_data) {
|
|
||||||
printk("snd_hda_intel: cs_8409_play_setup data not implemented for subsystem id 0x%08x",codec->core.subsystem_id);
|
|
||||||
} else {
|
|
||||||
cs_8409_play_real(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
||||||
}
|
}
|
||||||
|
@ -1154,9 +1007,8 @@ void cs_8409_play_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_play_cleanup(struct hda_codec *codec)
|
void cs_8409_play_cleanup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
myprintk_dbg("snd_hda_intel: cs_8409_play_cleanup\n");
|
if (codec->core.subsystem_id == 0x106b3900 || codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (codec->core.subsystem_id == 0x106b3900) {
|
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
cs_8409_playstop_data(codec);
|
cs_8409_playstop_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1171,13 +1023,6 @@ void cs_8409_play_cleanup(struct hda_codec *codec)
|
||||||
cs_8409_playstop_real(codec);
|
cs_8409_playstop_real(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|
||||||
if (spec->use_data) {
|
|
||||||
printk("snd_hda_intel: cs_8409_play_cleanup data not implemented for subsystem id 0x%08x",codec->core.subsystem_id);
|
|
||||||
} else {
|
|
||||||
cs_8409_playstop_real(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
||||||
}
|
}
|
||||||
|
@ -1190,9 +1035,9 @@ void cs_8409_play_cleanup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_capture_setup(struct hda_codec *codec)
|
void cs_8409_capture_setup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
||||||
|| codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|| codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
//cs_8409_capture_data(codec);
|
//cs_8409_capture_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1208,9 +1053,9 @@ void cs_8409_capture_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_capture_cleanup(struct hda_codec *codec)
|
void cs_8409_capture_cleanup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
||||||
|| codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|| codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
//cs_8409_capturestop_data(codec);
|
//cs_8409_capturestop_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1229,11 +1074,10 @@ static void cs_8409_cs42l83_unsolicited_response_finalize(struct hda_codec *code
|
||||||
|
|
||||||
static void cs_8409_perform_external_device_unsolicited_responses(struct hda_codec *codec)
|
static void cs_8409_perform_external_device_unsolicited_responses(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
struct unsol_item *unsol_entry = NULL;
|
struct unsol_item *unsol_entry = NULL;
|
||||||
struct unsol_item *unsol_temp = NULL;
|
struct unsol_item *unsol_temp = NULL;
|
||||||
if (!list_empty(&spec->unsol_list)) {
|
mycodec_info(codec, "cs_8409_perform_external_device_unsolicited_responses UNSOL start\n");
|
||||||
codec_info(codec, "cs_8409_perform_external_device_unsolicited_responses UNSOL start\n");
|
|
||||||
list_for_each_entry_safe(unsol_entry, unsol_temp, &spec->unsol_list, list)
|
list_for_each_entry_safe(unsol_entry, unsol_temp, &spec->unsol_list, list)
|
||||||
{
|
{
|
||||||
list_del_init(&unsol_entry->list);
|
list_del_init(&unsol_entry->list);
|
||||||
|
@ -1242,13 +1086,12 @@ static void cs_8409_perform_external_device_unsolicited_responses(struct hda_cod
|
||||||
spec->unsol_items_prealloc_used[unsol_entry->idx] = 0;
|
spec->unsol_items_prealloc_used[unsol_entry->idx] = 0;
|
||||||
memset(unsol_entry, 0, sizeof(struct unsol_item));
|
memset(unsol_entry, 0, sizeof(struct unsol_item));
|
||||||
}
|
}
|
||||||
codec_info(codec, "cs_8409_perform_external_device_unsolicited_responses UNSOL end\n");
|
mycodec_info(codec, "cs_8409_perform_external_device_unsolicited_responses UNSOL end\n");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cs_8409_cs42l83_unsolicited_response(struct hda_codec *codec, unsigned int res)
|
static void cs_8409_cs42l83_unsolicited_response(struct hda_codec *codec, unsigned int res)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
// not clear if want to use the GPIO pins apparently passed in res to determine
|
// not clear if want to use the GPIO pins apparently passed in res to determine
|
||||||
// if want to do interrupt checking here and if no interrupts then to do
|
// if want to do interrupt checking here and if no interrupts then to do
|
||||||
|
@ -1265,12 +1108,12 @@ static void cs_8409_cs42l83_unsolicited_response(struct hda_codec *codec, unsign
|
||||||
{
|
{
|
||||||
int itm;
|
int itm;
|
||||||
int new_itm = -1;
|
int new_itm = -1;
|
||||||
codec_info(codec, "cs_8409_cs42l83_unsolicited_response - UNSOL BLOCKED\n");
|
mycodec_info(codec, "cs_8409_cs42l83_unsolicited_response - UNSOL BLOCKED\n");
|
||||||
for (itm=0; itm<10; itm++)
|
for (itm=0; itm<10; itm++)
|
||||||
if (spec->unsol_items_prealloc_used[itm] == 0) { new_itm = itm; break; }
|
if (spec->unsol_items_prealloc_used[itm] == 0) { new_itm = itm; break; }
|
||||||
if (new_itm < 0)
|
if (new_itm < 0)
|
||||||
{
|
{
|
||||||
codec_info(codec, "cs_8409_cs42l83_unsolicited_response - IGNORING UNSOL RESPONSE!!\n");
|
mycodec_info(codec, "cs_8409_cs42l83_unsolicited_response - IGNORING UNSOL RESPONSE!!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spec->unsol_items_prealloc_used[new_itm] = 1;
|
spec->unsol_items_prealloc_used[new_itm] = 1;
|
||||||
|
@ -1278,11 +1121,11 @@ static void cs_8409_cs42l83_unsolicited_response(struct hda_codec *codec, unsign
|
||||||
spec->unsol_items_prealloc[new_itm].res = res;
|
spec->unsol_items_prealloc[new_itm].res = res;
|
||||||
spec->unsol_items_prealloc[new_itm].idx = new_itm;
|
spec->unsol_items_prealloc[new_itm].idx = new_itm;
|
||||||
list_add_tail(&(spec->unsol_items_prealloc[new_itm].list), &spec->unsol_list);
|
list_add_tail(&(spec->unsol_items_prealloc[new_itm].list), &spec->unsol_list);
|
||||||
codec_info(codec, "cs_8409_cs42l83_unsolicited_response - UNSOL response stored\n");
|
mycodec_info(codec, "cs_8409_cs42l83_unsolicited_response - UNSOL response stored\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
codec_info(codec, "cs_8409_cs42l83_unsolicited_response - NOT UNSOL BLOCKED\n");
|
mycodec_info(codec, "cs_8409_cs42l83_unsolicited_response - NOT UNSOL BLOCKED\n");
|
||||||
|
|
||||||
// so it appears we need to block unsol responses while doing unsol responses
|
// so it appears we need to block unsol responses while doing unsol responses
|
||||||
// this is probably not the way to do this but still havent figured out how to use locking properly
|
// this is probably not the way to do this but still havent figured out how to use locking properly
|
||||||
|
@ -1305,7 +1148,7 @@ static void cs_8409_cs42l83_unsolicited_response(struct hda_codec *codec, unsign
|
||||||
|
|
||||||
static void cs_8409_cs42l83_unsolicited_response_finalize(struct hda_codec *codec, unsigned int res)
|
static void cs_8409_cs42l83_unsolicited_response_finalize(struct hda_codec *codec, unsigned int res)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
if (spec->use_data)
|
if (spec->use_data)
|
||||||
cs_8409_external_device_unsolicited_response_data(codec, res);
|
cs_8409_external_device_unsolicited_response_data(codec, res);
|
||||||
|
@ -1327,7 +1170,7 @@ static void cs_8409_cs42l83_unsolicited_response_finalize(struct hda_codec *code
|
||||||
|
|
||||||
static void cs_8409_headset_mike_setup_nouse(struct hda_codec *codec)
|
static void cs_8409_headset_mike_setup_nouse(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
cs_8409_intmike_linein_disable(codec);
|
cs_8409_intmike_linein_disable(codec);
|
||||||
|
|
||||||
|
@ -1338,8 +1181,8 @@ static void cs_8409_headset_mike_setup_nouse(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_headplay_setup(struct hda_codec *codec)
|
void cs_8409_headplay_setup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3900) {
|
if (codec->core.subsystem_id == 0x106b3900 || codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
cs_8409_headplay_data(codec);
|
cs_8409_headplay_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1354,13 +1197,6 @@ void cs_8409_headplay_setup(struct hda_codec *codec)
|
||||||
cs_8409_headplay_real(codec);
|
cs_8409_headplay_real(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|
||||||
if (spec->use_data) {
|
|
||||||
printk("snd_hda_intel: cs_8409_headplay_setup data not implemented for subsystem id 0x%08x",codec->core.subsystem_id);
|
|
||||||
} else {
|
|
||||||
cs_8409_headplay_real(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
||||||
}
|
}
|
||||||
|
@ -1370,7 +1206,7 @@ void cs_8409_headplay_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
//if (!list_empty(&spec->unsol_list))
|
//if (!list_empty(&spec->unsol_list))
|
||||||
//{
|
//{
|
||||||
// codec_info(codec, "cs_8409_headplay_setup - performing UNSOL responses\n");
|
// mycodec_info(codec, "cs_8409_headplay_setup - performing UNSOL responses\n");
|
||||||
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -1378,8 +1214,8 @@ void cs_8409_headplay_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_headplay_cleanup(struct hda_codec *codec)
|
void cs_8409_headplay_cleanup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3900) {
|
if (codec->core.subsystem_id == 0x106b3900 || codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
cs_8409_headplaystop_data(codec);
|
cs_8409_headplaystop_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1395,13 +1231,6 @@ void cs_8409_headplay_cleanup(struct hda_codec *codec)
|
||||||
cs_8409_headplaystop_real(codec);
|
cs_8409_headplaystop_real(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|
||||||
if (spec->use_data) {
|
|
||||||
printk("snd_hda_intel: cs_8409_headplay_cleanup data not implemented for subsystem id 0x%08x",codec->core.subsystem_id);
|
|
||||||
} else {
|
|
||||||
cs_8409_headplaystop_real(codec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
printk("snd_hda_intel: UNKNOWN subsystem id 0x%08x",codec->core.subsystem_id);
|
||||||
}
|
}
|
||||||
|
@ -1411,7 +1240,7 @@ void cs_8409_headplay_cleanup(struct hda_codec *codec)
|
||||||
|
|
||||||
//if (!list_empty(&spec->unsol_list))
|
//if (!list_empty(&spec->unsol_list))
|
||||||
//{
|
//{
|
||||||
// codec_info(codec, "cs_8409_headplay_cleanup - performing UNSOL responses\n");
|
// mycodec_info(codec, "cs_8409_headplay_cleanup - performing UNSOL responses\n");
|
||||||
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -1422,9 +1251,9 @@ void cs_8409_headplay_cleanup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_headcapture_setup(struct hda_codec *codec)
|
void cs_8409_headcapture_setup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
||||||
|| codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|| codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
//cs_8409_headcapture_data(codec);
|
//cs_8409_headcapture_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1440,7 +1269,7 @@ void cs_8409_headcapture_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
//if (!list_empty(&spec->unsol_list))
|
//if (!list_empty(&spec->unsol_list))
|
||||||
//{
|
//{
|
||||||
// codec_info(codec, "cs_8409_headcapture_setup - performing UNSOL responses\n");
|
// mycodec_info(codec, "cs_8409_headcapture_setup - performing UNSOL responses\n");
|
||||||
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -1448,9 +1277,9 @@ void cs_8409_headcapture_setup(struct hda_codec *codec)
|
||||||
|
|
||||||
void cs_8409_headcapture_cleanup(struct hda_codec *codec)
|
void cs_8409_headcapture_cleanup(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
if (codec->core.subsystem_id == 0x106b3300 || codec->core.subsystem_id == 0x106b3600 || codec->core.subsystem_id == 0x106b3900
|
||||||
|| codec->core.subsystem_id == 0x106b1000 || codec->core.subsystem_id == 0x106b0f00 || codec->core.subsystem_id == 0x106b0e00) {
|
|| codec->core.subsystem_id == 0x106b1000) {
|
||||||
if (spec->use_data) {
|
if (spec->use_data) {
|
||||||
//cs_8409_capturestop_data(codec);
|
//cs_8409_capturestop_data(codec);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1467,7 +1296,7 @@ void cs_8409_headcapture_cleanup(struct hda_codec *codec)
|
||||||
|
|
||||||
//if (!list_empty(&spec->unsol_list))
|
//if (!list_empty(&spec->unsol_list))
|
||||||
//{
|
//{
|
||||||
// codec_info(codec, "cs_8409_headcapturestop_cleanup - performing UNSOL responses\n");
|
// mycodec_info(codec, "cs_8409_headcapturestop_cleanup - performing UNSOL responses\n");
|
||||||
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
// cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -1477,19 +1306,15 @@ static void cs_8409_pcm_playback_pre_prepare_hook(struct hda_pcm_stream *hinfo,
|
||||||
unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream,
|
unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream,
|
||||||
int action)
|
int action)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
|
||||||
struct timespec64 curtim;
|
struct timespec64 curtim;
|
||||||
ktime_get_real_ts64(&curtim);
|
ktime_get_real_ts64(&curtim);
|
||||||
#else
|
myprintk("snd_hda_intel: command cs_8409_pcm_playback_pre_prepare_hook HOOK PREPARE init %d last %lld cur %lld",
|
||||||
struct timespec curtim;
|
spec->play_init,spec->last_play_time.tv_sec,curtim.tv_sec);
|
||||||
getnstimeofday(&curtim);
|
|
||||||
#endif
|
|
||||||
myprintk("snd_hda_intel: command cs_8409_pcm_playback_pre_prepare_hook HOOK PREPARE init %d last %lld cur %lld",spec->play_init,spec->last_play_time.tv_sec,curtim.tv_sec);
|
|
||||||
if (1) {
|
if (1) {
|
||||||
struct hda_cvt_setup_apple *p = NULL;
|
struct hda_cvt_setup *p = NULL;
|
||||||
//int power_chk = 0;
|
//int power_chk = 0;
|
||||||
|
|
||||||
// in the new way we set the stream up here using the passed data
|
// in the new way we set the stream up here using the passed data
|
||||||
|
@ -1497,17 +1322,11 @@ static void cs_8409_pcm_playback_pre_prepare_hook(struct hda_pcm_stream *hinfo,
|
||||||
// so the cs_8409_really_update_stream_format will cause the updates to occur
|
// so the cs_8409_really_update_stream_format will cause the updates to occur
|
||||||
// note we explicitly set the channel id - dont see another way yet
|
// note we explicitly set the channel id - dont see another way yet
|
||||||
|
|
||||||
//cs_8409_setup_stream_format(codec, 0x02, stream_tag, format);
|
cs_8409_setup_stream_format(codec, 0x02, stream_tag, format);
|
||||||
cs_8409_store_stream_format(codec, 0x02, stream_tag, format);
|
|
||||||
|
|
||||||
//cs_8409_setup_stream_format(codec, 0x03, stream_tag, format);
|
cs_8409_setup_stream_format(codec, 0x03, stream_tag, format);
|
||||||
cs_8409_store_stream_format(codec, 0x03, stream_tag, format);
|
|
||||||
|
|
||||||
//cs_8409_setup_stream_format(codec, 0x0a, stream_tag, format);
|
cs_8409_setup_stream_format(codec, 0x0a, stream_tag, format);
|
||||||
cs_8409_store_stream_format(codec, 0x0a, stream_tag, format);
|
|
||||||
|
|
||||||
// save number of actual stream channels
|
|
||||||
spec->stream_channels = substream->runtime->channels;
|
|
||||||
|
|
||||||
hda_check_power_state(codec, 0x1a, 1);
|
hda_check_power_state(codec, 0x1a, 1);
|
||||||
hda_check_power_state(codec, 0x3c, 1);
|
hda_check_power_state(codec, 0x3c, 1);
|
||||||
|
@ -1525,9 +1344,6 @@ static void cs_8409_pcm_playback_pre_prepare_hook(struct hda_pcm_stream *hinfo,
|
||||||
// first on Linux and we dont know at that stage if we will be playing
|
// first on Linux and we dont know at that stage if we will be playing
|
||||||
if (spec->have_mike)
|
if (spec->have_mike)
|
||||||
{
|
{
|
||||||
// actually we always need to do cs_8409_headplay_setup - here we are about to play
|
|
||||||
// - what this possibly would allow is the apple way of doing a pre-setup
|
|
||||||
// so here we would switch between doing a full setup or a partial setup
|
|
||||||
if (spec->headset_play_format_setup_needed)
|
if (spec->headset_play_format_setup_needed)
|
||||||
{
|
{
|
||||||
cs_8409_headplay_setup(codec);
|
cs_8409_headplay_setup(codec);
|
||||||
|
@ -1545,10 +1361,9 @@ static void cs_8409_pcm_playback_pre_prepare_hook(struct hda_pcm_stream *hinfo,
|
||||||
cs_8409_headplay_setup(codec);
|
cs_8409_headplay_setup(codec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
cs_8409_play_setup(codec);
|
cs_8409_play_setup(codec);
|
||||||
}
|
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook setup play called");
|
||||||
myprintk("snd_hda_intel: command cs_8409_pcm_playback_pre_prepare_hook setup play called");
|
|
||||||
|
|
||||||
hda_check_power_state(codec, 0x1a, 2);
|
hda_check_power_state(codec, 0x1a, 2);
|
||||||
hda_check_power_state(codec, 0x3c, 2);
|
hda_check_power_state(codec, 0x3c, 2);
|
||||||
|
@ -1589,7 +1404,7 @@ static void cs_8409_pcm_playback_pre_prepare_hook(struct hda_pcm_stream *hinfo,
|
||||||
static void cs_8409_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream, int action)
|
static void cs_8409_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream, int action)
|
||||||
{
|
{
|
||||||
|
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
// so finally getting a handle on ordering here
|
// so finally getting a handle on ordering here
|
||||||
// we need to do the OSX setup in the OPEN section
|
// we need to do the OSX setup in the OPEN section
|
||||||
|
@ -1605,20 +1420,16 @@ static void cs_8409_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_c
|
||||||
|
|
||||||
|
|
||||||
if (action == HDA_GEN_PCM_ACT_OPEN) {
|
if (action == HDA_GEN_PCM_ACT_OPEN) {
|
||||||
//struct hda_cvt_setup_apple *p = NULL;
|
//struct hda_cvt_setup *p = NULL;
|
||||||
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook open");
|
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook open");
|
||||||
|
|
||||||
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook open end");
|
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook open end");
|
||||||
} else if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
} else if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
||||||
// so this comes AFTER the stream format, frequency setup verbs are sent for the pcm stream
|
// so this comes AFTER the stream format, frequency setup verbs are sent for the pcm stream
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
|
||||||
struct timespec64 curtim;
|
struct timespec64 curtim;
|
||||||
ktime_get_real_ts64(&curtim);
|
ktime_get_real_ts64(&curtim);
|
||||||
#else
|
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook HOOK PREPARE init %d last %lld cur %lld",
|
||||||
struct timespec curtim;
|
spec->play_init,spec->last_play_time.tv_sec,curtim.tv_sec);
|
||||||
getnstimeofday(&curtim);
|
|
||||||
#endif
|
|
||||||
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook HOOK PREPARE init %d last %lld cur %lld",spec->play_init,spec->last_play_time.tv_sec,curtim.tv_sec);
|
|
||||||
//int power_chk = 0;
|
//int power_chk = 0;
|
||||||
//power_chk = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_POWER_STATE, 0);
|
//power_chk = snd_hda_codec_read(codec, codec->core.afg, 0, AC_VERB_GET_POWER_STATE, 0);
|
||||||
//myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook power check 0x01 2 %d", power_chk);
|
//myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook power check 0x01 2 %d", power_chk);
|
||||||
|
@ -1627,7 +1438,7 @@ static void cs_8409_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_c
|
||||||
spec->block_unsol = 0;
|
spec->block_unsol = 0;
|
||||||
if (!list_empty(&spec->unsol_list))
|
if (!list_empty(&spec->unsol_list))
|
||||||
{
|
{
|
||||||
codec_info(codec, "cs_8409_playback_pcm_hook - performing UNSOL responses\n");
|
mycodec_info(codec, "cs_8409_playback_pcm_hook - performing UNSOL responses\n");
|
||||||
cs_8409_perform_external_device_unsolicited_responses(codec);
|
cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
}
|
}
|
||||||
spec->playing = 1;
|
spec->playing = 1;
|
||||||
|
@ -1646,16 +1457,19 @@ static void cs_8409_playback_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_c
|
||||||
// note that so far only the headphone chip seems to generate unsol responses usually
|
// note that so far only the headphone chip seems to generate unsol responses usually
|
||||||
spec->block_unsol = 1;
|
spec->block_unsol = 1;
|
||||||
// so dont think need to anything about capturing here
|
// so dont think need to anything about capturing here
|
||||||
|
if (spec->headset_play_format_setup_needed == 0)
|
||||||
|
{
|
||||||
cs_8409_headplay_cleanup(codec);
|
cs_8409_headplay_cleanup(codec);
|
||||||
spec->headset_play_format_setup_needed = 1;
|
spec->headset_play_format_setup_needed = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
cs_8409_play_cleanup(codec);
|
cs_8409_play_cleanup(codec);
|
||||||
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook done play down");
|
myprintk("snd_hda_intel: command cs_8409_playback_pcm_hook done play down");
|
||||||
spec->block_unsol = 0;
|
spec->block_unsol = 0;
|
||||||
if (!list_empty(&spec->unsol_list))
|
if (!list_empty(&spec->unsol_list))
|
||||||
{
|
{
|
||||||
codec_info(codec, "cs_8409_playback_pcm_hook - performing UNSOL responses\n");
|
mycodec_info(codec, "cs_8409_playback_pcm_hook - performing UNSOL responses\n");
|
||||||
cs_8409_perform_external_device_unsolicited_responses(codec);
|
cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
}
|
}
|
||||||
// not sure of this position yet
|
// not sure of this position yet
|
||||||
|
@ -1675,7 +1489,7 @@ static void cs_8409_pcm_capture_pre_prepare_hook(struct hda_pcm_stream *hinfo, s
|
||||||
unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream,
|
unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream,
|
||||||
int action)
|
int action)
|
||||||
{
|
{
|
||||||
struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
if (action == HDA_GEN_PCM_ACT_PREPARE) {
|
||||||
myprintk("snd_hda_intel: command cs_8409_pcm_capture_pre_prepare_hook HOOK PREPARE init %d",spec->capture_init);
|
myprintk("snd_hda_intel: command cs_8409_pcm_capture_pre_prepare_hook HOOK PREPARE init %d",spec->capture_init);
|
||||||
|
@ -1695,8 +1509,7 @@ static void cs_8409_pcm_capture_pre_prepare_hook(struct hda_pcm_stream *hinfo, s
|
||||||
|
|
||||||
|
|
||||||
// I think this is the same for intmike or headset mike
|
// I think this is the same for intmike or headset mike
|
||||||
//cs_8409_setup_stream_format(codec, hinfo->nid, stream_tag, format);
|
cs_8409_setup_stream_format(codec, hinfo->nid, stream_tag, format);
|
||||||
cs_8409_store_stream_format(codec, hinfo->nid, stream_tag, format);
|
|
||||||
|
|
||||||
|
|
||||||
// for the moment have junky test here
|
// for the moment have junky test here
|
||||||
|
@ -1736,46 +1549,13 @@ static void cs_8409_pcm_capture_pre_prepare_hook(struct hda_pcm_stream *hinfo, s
|
||||||
static void cs_8409_capture_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream, int action)
|
static void cs_8409_capture_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream, int action)
|
||||||
{
|
{
|
||||||
|
|
||||||
//struct cs8409_apple_spec *spec = codec->spec;
|
struct cs_spec *spec = codec->spec;
|
||||||
|
|
||||||
struct cs8409_apple_spec *spec = NULL;
|
|
||||||
|
|
||||||
myprintk_dbg("snd_hda_intel: command cs_8409_capture_pcm_hook HOOK init called");
|
|
||||||
|
|
||||||
//dump_stack();
|
|
||||||
|
|
||||||
myprintk_dbg("snd_hda_intel: command cs_8409_capture_pcm_hook HOOK init post stack");
|
|
||||||
|
|
||||||
// - so this seems to be the critical issue - this can apparently be called with a NULL codec!!!
|
|
||||||
// only thing to do seems to be to return!!
|
|
||||||
if (codec == NULL) {
|
|
||||||
struct hda_codec *badptr = NULL;
|
|
||||||
printk("snd_hda_intel: command cs_8409_capture_pcm_hook HOOK init - CODEC NULL");
|
|
||||||
// so if we are here it looks as tho we have been called from call_hp_automute
|
|
||||||
// - in which the codec is the 1st arg
|
|
||||||
badptr = (struct hda_codec *) hinfo;
|
|
||||||
spec = badptr->spec;
|
|
||||||
printk("snd_hda_intel: cs_8409_capture_pcm_hook - pcm_playback_hook %p", spec->gen.pcm_playback_hook);
|
|
||||||
printk("snd_hda_intel: cs_8409_capture_pcm_hook - pcm_capture_hook %p", spec->gen.pcm_capture_hook);
|
|
||||||
printk("snd_hda_intel: cs_8409_capture_pcm_hook - hp_automute_hook %p", spec->gen.hp_automute_hook);
|
|
||||||
printk("snd_hda_intel: cs_8409_capture_pcm_hook - line_automute_hook %p", spec->gen.line_automute_hook);
|
|
||||||
printk("snd_hda_intel: cs_8409_capture_pcm_hook - line_automute_hook %p", spec->gen.mic_autoswitch_hook);
|
|
||||||
printk("snd_hda_intel: command cs_8409_capture_pcm_hook HOOK init - CODEC NULL exit");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
myprintk_dbg("snd_hda_intel: command cs_8409_capture_pcm_hook HOOK init - CODEC NOT NULL");
|
|
||||||
|
|
||||||
//dump_stack();
|
|
||||||
|
|
||||||
spec = codec->spec;
|
|
||||||
|
|
||||||
|
|
||||||
// so now no setup is done here - we only check for unsolicited responses
|
// so now no setup is done here - we only check for unsolicited responses
|
||||||
// - we do do cleanup for the CLEANUP action
|
// - we do do cleanup for the CLEANUP action
|
||||||
|
|
||||||
if (action == HDA_GEN_PCM_ACT_OPEN) {
|
if (action == HDA_GEN_PCM_ACT_OPEN) {
|
||||||
//struct hda_cvt_setup_apple *p = NULL;
|
//struct hda_cvt_setup *p = NULL;
|
||||||
myprintk("snd_hda_intel: command cs_8409_capture_pcm_hook open");
|
myprintk("snd_hda_intel: command cs_8409_capture_pcm_hook open");
|
||||||
|
|
||||||
myprintk("snd_hda_intel: command cs_8409_capture_pcm_hook open end");
|
myprintk("snd_hda_intel: command cs_8409_capture_pcm_hook open end");
|
||||||
|
@ -1787,7 +1567,7 @@ static void cs_8409_capture_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_co
|
||||||
spec->block_unsol = 0;
|
spec->block_unsol = 0;
|
||||||
if (!list_empty(&spec->unsol_list))
|
if (!list_empty(&spec->unsol_list))
|
||||||
{
|
{
|
||||||
codec_info(codec, "cs_8409_capture_pcm_hook - performing UNSOL responses\n");
|
mycodec_info(codec, "cs_8409_capture_pcm_hook - performing UNSOL responses\n");
|
||||||
cs_8409_perform_external_device_unsolicited_responses(codec);
|
cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
}
|
}
|
||||||
spec->capturing = 1;
|
spec->capturing = 1;
|
||||||
|
@ -1825,7 +1605,7 @@ static void cs_8409_capture_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_co
|
||||||
spec->block_unsol = 0;
|
spec->block_unsol = 0;
|
||||||
if (!list_empty(&spec->unsol_list))
|
if (!list_empty(&spec->unsol_list))
|
||||||
{
|
{
|
||||||
codec_info(codec, "cs_8409_capture_pcm_hook - performing UNSOL responses\n");
|
mycodec_info(codec, "cs_8409_capture_pcm_hook - performing UNSOL responses\n");
|
||||||
cs_8409_perform_external_device_unsolicited_responses(codec);
|
cs_8409_perform_external_device_unsolicited_responses(codec);
|
||||||
}
|
}
|
||||||
// not sure of this position yet
|
// not sure of this position yet
|
||||||
|
@ -1844,7 +1624,7 @@ static void cs_8409_capture_pcm_hook(struct hda_pcm_stream *hinfo, struct hda_co
|
||||||
// this version runs all explicit commands as logged on OSX
|
// this version runs all explicit commands as logged on OSX
|
||||||
static int cs_8409_data_config(struct hda_codec *codec)
|
static int cs_8409_data_config(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
//struct cs8409_apple_spec *spec = codec->spec;
|
//struct cs_spec *spec = codec->spec;
|
||||||
//hda_nid_t beep_nid = spec->beep_nid;
|
//hda_nid_t beep_nid = spec->beep_nid;
|
||||||
|
|
||||||
unsigned int tmpstate1 = -1;
|
unsigned int tmpstate1 = -1;
|
||||||
|
@ -1876,7 +1656,7 @@ static int cs_8409_data_config(struct hda_codec *codec)
|
||||||
// this version runs the setup using functions based on the setup using the logged data
|
// this version runs the setup using functions based on the setup using the logged data
|
||||||
static int cs_8409_real_config(struct hda_codec *codec)
|
static int cs_8409_real_config(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
//struct cs8409_apple_spec *spec = codec->spec;
|
//struct cs_spec *spec = codec->spec;
|
||||||
//hda_nid_t beep_nid = spec->beep_nid;
|
//hda_nid_t beep_nid = spec->beep_nid;
|
||||||
|
|
||||||
unsigned int tmpstate1 = -1;
|
unsigned int tmpstate1 = -1;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -546,7 +546,6 @@ static void cs42l83_power_hs_bias_off(struct hda_codec *codec)
|
||||||
static void cs42l83_enable_hsbias_auto_clamp_on(struct hda_codec *codec)
|
static void cs42l83_enable_hsbias_auto_clamp_on(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
|
|
||||||
//int updval;
|
|
||||||
//int retval;
|
//int retval;
|
||||||
|
|
||||||
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_on\n");
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_on\n");
|
||||||
|
@ -561,22 +560,15 @@ static void cs42l83_enable_hsbias_auto_clamp_on(struct hda_codec *codec)
|
||||||
// snd_hda i2cPagedRead i2c address 0x90 i2c reg hi 0x1b lo 0x7000 i2c data 0x7003
|
// 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 0x7003 i2c data 0x0003
|
||||||
|
|
||||||
// explicit coding
|
|
||||||
cs_8409_vendor_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
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, 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)
|
static void cs42l83_enable_hsbias_auto_clamp_off(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
|
|
||||||
int updval;
|
//int retval;
|
||||||
int retval;
|
|
||||||
|
|
||||||
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off\n");
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_off\n");
|
||||||
|
|
||||||
|
@ -588,45 +580,7 @@ static void cs42l83_enable_hsbias_auto_clamp_off(struct hda_codec *codec)
|
||||||
|
|
||||||
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
||||||
// changed from 0x03 to 0x03 (HS Sense Bias trip 52 microamps
|
// 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) )
|
// 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
|
|
||||||
|
|
||||||
// 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 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 0x7003 i2c data 0x0003
|
||||||
|
@ -748,7 +702,7 @@ static void cs42l83_enable_hsbias_auto_clamp_off1(struct hda_codec *codec)
|
||||||
|
|
||||||
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
||||||
// changed from 0x46 to 0x06
|
// changed from 0x46 to 0x06
|
||||||
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 -> 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 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 0x7006 i2c data 0x0006
|
||||||
|
@ -950,7 +904,6 @@ static void cs42l83_configure_int_mclk(struct hda_codec *codec)
|
||||||
|
|
||||||
static void cs42l83_headset_power_on_on_nouse(struct hda_codec *codec)
|
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");
|
mycodec_i2c_local_info(codec, "cs42l83_headset_power_on_on_nouse\n");
|
||||||
|
|
||||||
|
@ -1178,8 +1131,6 @@ static void cs42l83_headset_rcv_enable_on(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
// this function has been replaced by cs42l83_buffers_onoff
|
|
||||||
|
|
||||||
mycodec_i2c_local_info(codec, "cs42l83_headset_rcv_enable_on\n");
|
mycodec_i2c_local_info(codec, "cs42l83_headset_rcv_enable_on\n");
|
||||||
|
|
||||||
// AppleHDATDM_CS42L83::enable
|
// AppleHDATDM_CS42L83::enable
|
||||||
|
@ -1377,7 +1328,7 @@ static void cs42l83_enable_hsbias_auto_clamp_off3(struct hda_codec *codec)
|
||||||
|
|
||||||
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
||||||
// changed from 0xc6 to 0x06
|
// changed from 0xc6 to 0x06
|
||||||
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 ->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 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 0x7006 i2c data 0x0006
|
||||||
|
@ -1587,7 +1538,6 @@ static void cs42l83_power_off_codec_input(struct hda_codec *codec)
|
||||||
|
|
||||||
static void cs42l83_headset_rcv_enable_off(struct hda_codec *codec)
|
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");
|
mycodec_i2c_local_info(codec, "cs42l83_headset_rcv_enable_off\n");
|
||||||
|
|
||||||
|
@ -1607,7 +1557,6 @@ static void cs42l83_headset_rcv_enable_off(struct hda_codec *codec)
|
||||||
|
|
||||||
static void cs42l83_headset_power_off(struct hda_codec *codec)
|
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");
|
mycodec_i2c_local_info(codec, "cs42l83_headset_power_off\n");
|
||||||
|
|
||||||
|
@ -1898,7 +1847,7 @@ static void cs42l83_enable_hsbias_auto_clamp_off2(struct hda_codec *codec)
|
||||||
|
|
||||||
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
||||||
// changed from 0x46 to 0x06
|
// changed from 0x46 to 0x06
|
||||||
// then set to 0x46 (Tip Sense Enable (0x40) HS Sense Bias trip 93 microamps (0x06 ->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 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 0x7006 i2c data 0x0006
|
||||||
|
@ -1911,31 +1860,25 @@ static void cs42l83_enable_hsbias_auto_clamp_off2(struct hda_codec *codec)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cs42l83_hsbias_sense_on(struct hda_codec *codec)
|
static void cs42l83_enable_hsbias_auto_clamp_on3(struct hda_codec *codec)
|
||||||
{
|
{
|
||||||
|
|
||||||
int updval;
|
|
||||||
//int retval;
|
//int retval;
|
||||||
|
|
||||||
mycodec_i2c_local_info(codec, "cs42l83_hsbias_sense_on\n");
|
mycodec_i2c_local_info(codec, "cs42l83_enable_hsbias_auto_clamp_on3\n");
|
||||||
|
|
||||||
// in AppleHDAMikeyInternalCS8409::handleButtonDetectUR
|
// in AppleHDAMikeyInternalCS8409::setupButtonDetection
|
||||||
|
|
||||||
|
// AppleHDAMikeyInternalCS8409::enableHSBIASautoclamp
|
||||||
|
|
||||||
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
// register 0x1b70 - HSBIAS Sense and Hi-Z Autocontrol
|
||||||
// changed from 0x46 to 0xc6
|
// 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 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
|
// 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_i2cRead(codec, 0x90, 0x1b70, 1); // snd_hda
|
cs_8409_vendor_i2cWrite(codec, 0x90, 0x1b70, 0x00c6, 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
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,623 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
/*
|
|
||||||
* patch_cs8409-tables.c -- HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip
|
|
||||||
*
|
|
||||||
* Copyright (C) 2021 Cirrus Logic, Inc. and
|
|
||||||
* Cirrus Logic International Semiconductor Ltd.
|
|
||||||
*
|
|
||||||
* Author: Lucas Tanure <tanureal@opensource.cirrus.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "patch_cs8409.h"
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* CS42L42 Specific Data
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale, CS42L42_HP_VOL_REAL_MIN * 100, 100, 1);
|
|
||||||
|
|
||||||
static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale, CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1);
|
|
||||||
|
|
||||||
const struct snd_kcontrol_new cs42l42_dac_volume_mixer = {
|
|
||||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
|
||||||
.index = 0,
|
|
||||||
.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
|
|
||||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
|
|
||||||
.info = cs42l42_volume_info,
|
|
||||||
.get = cs42l42_volume_get,
|
|
||||||
.put = cs42l42_volume_put,
|
|
||||||
.tlv = { .p = cs42l42_dac_db_scale },
|
|
||||||
.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, CS8409_CODEC0,
|
|
||||||
HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct snd_kcontrol_new cs42l42_adc_volume_mixer = {
|
|
||||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
|
||||||
.index = 0,
|
|
||||||
.subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG),
|
|
||||||
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ),
|
|
||||||
.info = cs42l42_volume_info,
|
|
||||||
.get = cs42l42_volume_get,
|
|
||||||
.put = cs42l42_volume_put,
|
|
||||||
.tlv = { .p = cs42l42_adc_db_scale },
|
|
||||||
.private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, CS8409_CODEC0,
|
|
||||||
HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct hda_pcm_stream cs42l42_48k_pcm_analog_playback = {
|
|
||||||
.rates = SNDRV_PCM_RATE_48000, /* fixed rate */
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct hda_pcm_stream cs42l42_48k_pcm_analog_capture = {
|
|
||||||
.rates = SNDRV_PCM_RATE_48000, /* fixed rate */
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* BULLSEYE / WARLOCK / CYBORG Specific Arrays
|
|
||||||
* CS8409/CS42L42
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
const struct hda_verb cs8409_cs42l42_init_verbs[] = {
|
|
||||||
{ CS8409_PIN_AFG, AC_VERB_SET_GPIO_WAKE_MASK, 0x0018 }, /* WAKE from GPIO 3,4 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hda_pintbl cs8409_cs42l42_pincfgs[] = {
|
|
||||||
{ CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */
|
|
||||||
{ CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */
|
|
||||||
{ CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */
|
|
||||||
{ CS8409_PIN_DMIC1_IN, 0x90a00090 }, /* DMIC-1 */
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hda_pintbl cs8409_cs42l42_pincfgs_no_dmic[] = {
|
|
||||||
{ CS8409_PIN_ASP1_TRANSMITTER_A, 0x042120f0 }, /* ASP-1-TX */
|
|
||||||
{ CS8409_PIN_ASP1_RECEIVER_A, 0x04a12050 }, /* ASP-1-RX */
|
|
||||||
{ CS8409_PIN_ASP2_TRANSMITTER_A, 0x901000f0 }, /* ASP-2-TX */
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Vendor specific HW configuration for CS42L42 */
|
|
||||||
static const struct cs8409_i2c_param cs42l42_init_reg_seq[] = {
|
|
||||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
|
||||||
{ CS42L42_ADC_CTL, 0x00 },
|
|
||||||
{ 0x1D02, 0x06 },
|
|
||||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
|
||||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
|
||||||
{ CS42L42_MCLK_CTL, 0x02 },
|
|
||||||
{ CS42L42_SRC_CTL, 0x03 },
|
|
||||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
|
||||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
|
||||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
|
||||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
|
||||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
|
||||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH3_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH3_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH3_BIT_LSB, 0x80 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH4_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0xA0 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
|
||||||
{ CS42L42_ASP_TX_CH_EN, 0x01 },
|
|
||||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_SZ_EN, 0x01 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x0A },
|
|
||||||
{ CS42L42_PWR_CTL2, 0x84 },
|
|
||||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
|
||||||
{ CS42L42_HP_CTL, 0x0D },
|
|
||||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
|
||||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
|
||||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
|
||||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
|
||||||
{ CS42L42_PWR_CTL3, 0x20 },
|
|
||||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
|
||||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
|
||||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
|
||||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x02, 10000 },
|
|
||||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT2_MASK, 0xff },
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Vendor specific hw configuration for CS8409 */
|
|
||||||
const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[] = {
|
|
||||||
/* +PLL1/2_EN, +I2C_EN */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0xb008 },
|
|
||||||
/* ASP1/2_EN=0, ASP1_STP=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0002 },
|
|
||||||
/* ASP1/2_BUS_IDLE=10, +GPIO_I2C */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG3, 0x0a80 },
|
|
||||||
/* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL1, 0x0800 },
|
|
||||||
/* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL2, 0x0820 },
|
|
||||||
/* ASP2.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP2_A_TX_CTRL1, 0x0800 },
|
|
||||||
/* ASP2.A: TX.RAP=1, TX.RSZ=24 bits, TX.RCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP2_A_TX_CTRL2, 0x2800 },
|
|
||||||
/* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL1, 0x0800 },
|
|
||||||
/* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL2, 0x0800 },
|
|
||||||
/* ASP1: LCHI = 00h */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL1, 0x8000 },
|
|
||||||
/* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL2, 0x28ff },
|
|
||||||
/* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL3, 0x0062 },
|
|
||||||
/* ASP2: LCHI=1Fh */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL1, 0x801f },
|
|
||||||
/* ASP2: MC/SC_SRCSEL=PLL1, LCPR=3Fh */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL2, 0x283f },
|
|
||||||
/* ASP2: 5050=1, MCEN=0, FSD=010, SCPOL_IN/OUT=1, SCDIV=1:16 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP2_CLK_CTRL3, 0x805c },
|
|
||||||
/* DMIC1_MO=10b, DMIC1/2_SR=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DMIC_CFG, 0x0023 },
|
|
||||||
/* ASP1/2_BEEP=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_BEEP_CFG, 0x0000 },
|
|
||||||
/* ASP1/2_EN=1, ASP1_STP=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0062 },
|
|
||||||
/* -PLL2_EN */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0x9008 },
|
|
||||||
/* TX2.A: pre-scale att.=0 dB */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PRE_SCALE_ATTN2, 0x0000 },
|
|
||||||
/* ASP1/2_xxx_EN=1, ASP1/2_MCLK_EN=0, DMIC1_SCL_EN=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PAD_CFG_SLW_RATE_CTRL, 0xfc03 },
|
|
||||||
/* test mode on */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x9999 },
|
|
||||||
/* GPIO hysteresis = 30 us */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc5, 0x0000 },
|
|
||||||
/* test mode off */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x0000 },
|
|
||||||
{} /* Terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[] = {
|
|
||||||
/* EQ_SEL=1, EQ1/2_EN=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_CTRL1, 0x4000 },
|
|
||||||
/* +EQ_ACC */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0x4000 },
|
|
||||||
/* +EQ2_EN */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_CTRL1, 0x4010 },
|
|
||||||
/* EQ_DATA_HI=0x0647 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x0647 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=0, EQ_DATA_LO=0x67 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc0c7 },
|
|
||||||
/* EQ_DATA_HI=0x0647 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x0647 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=1, EQ_DATA_LO=0x67 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc1c7 },
|
|
||||||
/* EQ_DATA_HI=0xf370 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xf370 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=2, EQ_DATA_LO=0x71 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc271 },
|
|
||||||
/* EQ_DATA_HI=0x1ef8 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1ef8 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=3, EQ_DATA_LO=0x48 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc348 },
|
|
||||||
/* EQ_DATA_HI=0xc110 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc110 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=4, EQ_DATA_LO=0x5a */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc45a },
|
|
||||||
/* EQ_DATA_HI=0x1f29 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1f29 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=5, EQ_DATA_LO=0x74 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc574 },
|
|
||||||
/* EQ_DATA_HI=0x1d7a */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1d7a },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=6, EQ_DATA_LO=0x53 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc653 },
|
|
||||||
/* EQ_DATA_HI=0xc38c */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc38c },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=7, EQ_DATA_LO=0x14 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc714 },
|
|
||||||
/* EQ_DATA_HI=0x1ca3 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0x1ca3 },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=8, EQ_DATA_LO=0xc7 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc8c7 },
|
|
||||||
/* EQ_DATA_HI=0xc38c */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W1, 0xc38c },
|
|
||||||
/* +EQ_WRT, +EQ_ACC, EQ_ADR=9, EQ_DATA_LO=0x14 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0xc914 },
|
|
||||||
/* -EQ_ACC, -EQ_WRT */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PFE_COEF_W2, 0x0000 },
|
|
||||||
{} /* Terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sub_codec cs8409_cs42l42_codec = {
|
|
||||||
.addr = CS42L42_I2C_ADDR,
|
|
||||||
.reset_gpio = CS8409_CS42L42_RESET,
|
|
||||||
.irq_mask = CS8409_CS42L42_INT,
|
|
||||||
.init_seq = cs42l42_init_reg_seq,
|
|
||||||
.init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq),
|
|
||||||
.hp_jack_in = 0,
|
|
||||||
.mic_jack_in = 0,
|
|
||||||
.paged = 1,
|
|
||||||
.suspended = 1,
|
|
||||||
.no_type_dect = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Dolphin Specific Arrays
|
|
||||||
* CS8409/ 2 X CS42L42
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
const struct hda_verb dolphin_init_verbs[] = {
|
|
||||||
{ 0x01, AC_VERB_SET_GPIO_WAKE_MASK, DOLPHIN_WAKE }, /* WAKE from GPIO 0,4 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_STATE, 0x0001 }, /* Enable VPW processing */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x0002 }, /* Configure GPIO 6,7 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0080 }, /* I2C mode */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_COEF_INDEX, 0x005b }, /* Set I2C bus speed */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, AC_VERB_SET_PROC_COEF, 0x0200 }, /* 100kHz I2C_STO = 2 */
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct hda_pintbl dolphin_pincfgs[] = {
|
|
||||||
{ 0x24, 0x022210f0 }, /* ASP-1-TX-A */
|
|
||||||
{ 0x25, 0x010240f0 }, /* ASP-1-TX-B */
|
|
||||||
{ 0x34, 0x02a21050 }, /* ASP-1-RX */
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Vendor specific HW configuration for CS42L42 */
|
|
||||||
static const struct cs8409_i2c_param dolphin_c0_init_reg_seq[] = {
|
|
||||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
|
||||||
{ CS42L42_ADC_CTL, 0x00 },
|
|
||||||
{ 0x1D02, 0x06 },
|
|
||||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
|
||||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
|
||||||
{ CS42L42_MCLK_CTL, 0x02 },
|
|
||||||
{ CS42L42_SRC_CTL, 0x03 },
|
|
||||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
|
||||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
|
||||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
|
||||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
|
||||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
|
||||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0x20 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
|
||||||
{ CS42L42_ASP_TX_CH_EN, 0x01 },
|
|
||||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_SZ_EN, 0x01 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x0A },
|
|
||||||
{ CS42L42_PWR_CTL2, 0x84 },
|
|
||||||
{ CS42L42_HP_CTL, 0x0D },
|
|
||||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
|
||||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
|
||||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
|
||||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
|
||||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
|
||||||
{ CS42L42_PWR_CTL3, 0x20 },
|
|
||||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
|
||||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
|
||||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
|
||||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x02, 10000 },
|
|
||||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT2_MASK, 0xff }
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct cs8409_i2c_param dolphin_c1_init_reg_seq[] = {
|
|
||||||
{ CS42L42_I2C_TIMEOUT, 0xB0 },
|
|
||||||
{ CS42L42_ADC_CTL, 0x00 },
|
|
||||||
{ 0x1D02, 0x06 },
|
|
||||||
{ CS42L42_ADC_VOLUME, 0x9F },
|
|
||||||
{ CS42L42_OSC_SWITCH, 0x01 },
|
|
||||||
{ CS42L42_MCLK_CTL, 0x02 },
|
|
||||||
{ CS42L42_SRC_CTL, 0x03 },
|
|
||||||
{ CS42L42_MCLK_SRC_SEL, 0x00 },
|
|
||||||
{ CS42L42_ASP_FRM_CFG, 0x13 },
|
|
||||||
{ CS42L42_FSYNC_P_LOWER, 0xFF },
|
|
||||||
{ CS42L42_FSYNC_P_UPPER, 0x00 },
|
|
||||||
{ CS42L42_ASP_CLK_CFG, 0x20 },
|
|
||||||
{ CS42L42_SPDIF_CLK_CFG, 0x0D },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH1_BIT_LSB, 0x80 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_CH2_BIT_LSB, 0xA0 },
|
|
||||||
{ CS42L42_ASP_RX_DAI0_EN, 0x0C },
|
|
||||||
{ CS42L42_ASP_TX_CH_EN, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_CH_AP_RES, 0x02 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_MSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_CH1_BIT_LSB, 0x00 },
|
|
||||||
{ CS42L42_ASP_TX_SZ_EN, 0x00 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x0E },
|
|
||||||
{ CS42L42_PWR_CTL2, 0x84 },
|
|
||||||
{ CS42L42_HP_CTL, 0x0D },
|
|
||||||
{ CS42L42_MIXER_CHA_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_CHB_VOL, 0x3F },
|
|
||||||
{ CS42L42_MIXER_ADC_VOL, 0x3f },
|
|
||||||
{ CS42L42_MIC_DET_CTL1, 0xB6 },
|
|
||||||
{ CS42L42_TIPSENSE_CTL, 0xC2 },
|
|
||||||
{ CS42L42_HS_CLAMP_DISABLE, 0x01 },
|
|
||||||
{ CS42L42_HS_SWITCH_CTL, 0xF3 },
|
|
||||||
{ CS42L42_PWR_CTL3, 0x20 },
|
|
||||||
{ CS42L42_RSENSE_CTL2, 0x00 },
|
|
||||||
{ CS42L42_RSENSE_CTL3, 0x00 },
|
|
||||||
{ CS42L42_TSENSE_CTL, 0x80 },
|
|
||||||
{ CS42L42_HS_BIAS_CTL, 0xC0 },
|
|
||||||
{ CS42L42_PWR_CTL1, 0x06, 10000 },
|
|
||||||
{ CS42L42_ADC_OVFL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_MIXER_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_RX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_ASP_TX_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_CODEC_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_SRCPL_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_VPMON_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_PLL_LOCK_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_TSRS_PLUG_INT_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT1_MASK, 0xff },
|
|
||||||
{ CS42L42_DET_INT2_MASK, 0xff }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Vendor specific hw configuration for CS8409 */
|
|
||||||
const struct cs8409_cir_param dolphin_hw_cfg[] = {
|
|
||||||
/* +PLL1/2_EN, +I2C_EN */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0xb008 },
|
|
||||||
/* ASP1_EN=0, ASP1_STP=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0002 },
|
|
||||||
/* ASP1/2_BUS_IDLE=10, +GPIO_I2C */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG3, 0x0a80 },
|
|
||||||
/* ASP1.A: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL1, 0x0800 },
|
|
||||||
/* ASP1.A: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=32 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_TX_CTRL2, 0x0820 },
|
|
||||||
/* ASP1.B: TX.LAP=0, TX.LSZ=24 bits, TX.LCS=128 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_B_TX_CTRL1, 0x0880 },
|
|
||||||
/* ASP1.B: TX.RAP=0, TX.RSZ=24 bits, TX.RCS=160 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_B_TX_CTRL2, 0x08a0 },
|
|
||||||
/* ASP1.A: RX.LAP=0, RX.LSZ=24 bits, RX.LCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL1, 0x0800 },
|
|
||||||
/* ASP1.A: RX.RAP=0, RX.RSZ=24 bits, RX.RCS=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, ASP1_A_RX_CTRL2, 0x0800 },
|
|
||||||
/* ASP1: LCHI = 00h */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL1, 0x8000 },
|
|
||||||
/* ASP1: MC/SC_SRCSEL=PLL1, LCPR=FFh */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL2, 0x28ff },
|
|
||||||
/* ASP1: MCEN=0, FSD=011, SCPOL_IN/OUT=0, SCDIV=1:4 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_ASP1_CLK_CTRL3, 0x0062 },
|
|
||||||
/* ASP1/2_BEEP=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_BEEP_CFG, 0x0000 },
|
|
||||||
/* ASP1_EN=1, ASP1_STP=1 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG2, 0x0022 },
|
|
||||||
/* -PLL2_EN */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_DEV_CFG1, 0x9008 },
|
|
||||||
/* ASP1_xxx_EN=1, ASP1_MCLK_EN=0 */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, CS8409_PAD_CFG_SLW_RATE_CTRL, 0x5400 },
|
|
||||||
/* test mode on */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x9999 },
|
|
||||||
/* GPIO hysteresis = 30 us */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc5, 0x0000 },
|
|
||||||
/* test mode off */
|
|
||||||
{ CS8409_PIN_VENDOR_WIDGET, 0xc0, 0x0000 },
|
|
||||||
{} /* Terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sub_codec dolphin_cs42l42_0 = {
|
|
||||||
.addr = DOLPHIN_C0_I2C_ADDR,
|
|
||||||
.reset_gpio = DOLPHIN_C0_RESET,
|
|
||||||
.irq_mask = DOLPHIN_C0_INT,
|
|
||||||
.init_seq = dolphin_c0_init_reg_seq,
|
|
||||||
.init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq),
|
|
||||||
.hp_jack_in = 0,
|
|
||||||
.mic_jack_in = 0,
|
|
||||||
.paged = 1,
|
|
||||||
.suspended = 1,
|
|
||||||
.no_type_dect = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sub_codec dolphin_cs42l42_1 = {
|
|
||||||
.addr = DOLPHIN_C1_I2C_ADDR,
|
|
||||||
.reset_gpio = DOLPHIN_C1_RESET,
|
|
||||||
.irq_mask = DOLPHIN_C1_INT,
|
|
||||||
.init_seq = dolphin_c1_init_reg_seq,
|
|
||||||
.init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq),
|
|
||||||
.hp_jack_in = 0,
|
|
||||||
.mic_jack_in = 0,
|
|
||||||
.paged = 1,
|
|
||||||
.suspended = 1,
|
|
||||||
.no_type_dect = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* CS8409 Patch Driver Structs
|
|
||||||
* Arrays Used for all projects using CS8409
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
const struct hda_quirk cs8409_fixup_tbl[] = {
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A11, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A12, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A23, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A24, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A25, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A29, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A2A, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A2B, "Bullseye", CS8409_BULLSEYE),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A77, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A78, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A79, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A7A, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A7D, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A7E, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A7F, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0A80, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB0, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB2, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB1, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB3, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB4, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AB5, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0ACF, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AD0, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AD1, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AD2, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AD3, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AD9, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0ADA, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0ADB, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0ADC, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0ADF, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AE0, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AE1, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AE2, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AE9, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AEA, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AEB, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AEC, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AED, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AEE, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AEF, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AF0, "Cyborg", CS8409_CYBORG),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AF4, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0AF5, "Warlock", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B92, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B93, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B94, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B95, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B96, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0B97, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BA5, "Odin", CS8409_ODIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BA6, "Odin", CS8409_ODIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BA8, "Odin", CS8409_ODIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BAA, "Odin", CS8409_ODIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BAE, "Odin", CS8409_ODIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB2, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB3, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB4, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB5, "Warlock N3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB6, "Warlock V3 15 TGL-U Nuvoton EC", CS8409_WARLOCK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB8, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BB9, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BBA, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BBB, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BBC, "Warlock MLK", CS8409_WARLOCK_MLK),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BBD, "Warlock MLK Dual Mic", CS8409_WARLOCK_MLK_DUAL_MIC),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BD4, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BD5, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BD6, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BD7, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0BD8, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C43, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C50, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C51, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C52, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C73, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C75, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C7D, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
SND_PCI_QUIRK(0x1028, 0x0C7F, "Dolphin", CS8409_DOLPHIN),
|
|
||||||
{} /* terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Dell Inspiron models with cs8409/cs42l42 */
|
|
||||||
const struct hda_model_fixup cs8409_models[] = {
|
|
||||||
{ .id = CS8409_BULLSEYE, .name = "bullseye" },
|
|
||||||
{ .id = CS8409_WARLOCK, .name = "warlock" },
|
|
||||||
{ .id = CS8409_WARLOCK_MLK, .name = "warlock mlk" },
|
|
||||||
{ .id = CS8409_WARLOCK_MLK_DUAL_MIC, .name = "warlock mlk dual mic" },
|
|
||||||
{ .id = CS8409_CYBORG, .name = "cyborg" },
|
|
||||||
{ .id = CS8409_DOLPHIN, .name = "dolphin" },
|
|
||||||
{ .id = CS8409_ODIN, .name = "odin" },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct hda_fixup cs8409_fixups[] = {
|
|
||||||
[CS8409_BULLSEYE] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_WARLOCK] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_WARLOCK_MLK] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_WARLOCK_MLK_DUAL_MIC] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_CYBORG] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_FIXUPS] = {
|
|
||||||
.type = HDA_FIXUP_FUNC,
|
|
||||||
.v.func = cs8409_cs42l42_fixups,
|
|
||||||
},
|
|
||||||
[CS8409_DOLPHIN] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = dolphin_pincfgs,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_DOLPHIN_FIXUPS,
|
|
||||||
},
|
|
||||||
[CS8409_DOLPHIN_FIXUPS] = {
|
|
||||||
.type = HDA_FIXUP_FUNC,
|
|
||||||
.v.func = dolphin_fixups,
|
|
||||||
},
|
|
||||||
[CS8409_ODIN] = {
|
|
||||||
.type = HDA_FIXUP_PINS,
|
|
||||||
.v.pins = cs8409_cs42l42_pincfgs_no_dmic,
|
|
||||||
.chained = true,
|
|
||||||
.chain_id = CS8409_FIXUPS,
|
|
||||||
},
|
|
||||||
};
|
|
1503
patch_cs8409.c
1503
patch_cs8409.c
File diff suppressed because it is too large
Load diff
515
patch_cs8409.h
515
patch_cs8409.h
|
@ -1,515 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
||||||
/*
|
|
||||||
* HD audio interface patch for Cirrus Logic CS8409 HDA bridge chip
|
|
||||||
*
|
|
||||||
* Copyright (C) 2021 Cirrus Logic, Inc. and
|
|
||||||
* Cirrus Logic International Semiconductor Ltd.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __CS8409_PATCH_H
|
|
||||||
#define __CS8409_PATCH_H
|
|
||||||
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <sound/tlv.h>
|
|
||||||
#include <linux/workqueue.h>
|
|
||||||
#include <sound/cs42l42.h>
|
|
||||||
#include <sound/hda_codec.h>
|
|
||||||
#include "hda_local.h"
|
|
||||||
#include "hda_auto_parser.h"
|
|
||||||
#include "hda_jack.h"
|
|
||||||
#include "hda_generic.h"
|
|
||||||
|
|
||||||
/* CS8409 Specific Definitions */
|
|
||||||
|
|
||||||
enum cs8409_pins {
|
|
||||||
CS8409_PIN_ROOT,
|
|
||||||
CS8409_PIN_AFG,
|
|
||||||
CS8409_PIN_ASP1_OUT_A,
|
|
||||||
CS8409_PIN_ASP1_OUT_B,
|
|
||||||
CS8409_PIN_ASP1_OUT_C,
|
|
||||||
CS8409_PIN_ASP1_OUT_D,
|
|
||||||
CS8409_PIN_ASP1_OUT_E,
|
|
||||||
CS8409_PIN_ASP1_OUT_F,
|
|
||||||
CS8409_PIN_ASP1_OUT_G,
|
|
||||||
CS8409_PIN_ASP1_OUT_H,
|
|
||||||
CS8409_PIN_ASP2_OUT_A,
|
|
||||||
CS8409_PIN_ASP2_OUT_B,
|
|
||||||
CS8409_PIN_ASP2_OUT_C,
|
|
||||||
CS8409_PIN_ASP2_OUT_D,
|
|
||||||
CS8409_PIN_ASP2_OUT_E,
|
|
||||||
CS8409_PIN_ASP2_OUT_F,
|
|
||||||
CS8409_PIN_ASP2_OUT_G,
|
|
||||||
CS8409_PIN_ASP2_OUT_H,
|
|
||||||
CS8409_PIN_ASP1_IN_A,
|
|
||||||
CS8409_PIN_ASP1_IN_B,
|
|
||||||
CS8409_PIN_ASP1_IN_C,
|
|
||||||
CS8409_PIN_ASP1_IN_D,
|
|
||||||
CS8409_PIN_ASP1_IN_E,
|
|
||||||
CS8409_PIN_ASP1_IN_F,
|
|
||||||
CS8409_PIN_ASP1_IN_G,
|
|
||||||
CS8409_PIN_ASP1_IN_H,
|
|
||||||
CS8409_PIN_ASP2_IN_A,
|
|
||||||
CS8409_PIN_ASP2_IN_B,
|
|
||||||
CS8409_PIN_ASP2_IN_C,
|
|
||||||
CS8409_PIN_ASP2_IN_D,
|
|
||||||
CS8409_PIN_ASP2_IN_E,
|
|
||||||
CS8409_PIN_ASP2_IN_F,
|
|
||||||
CS8409_PIN_ASP2_IN_G,
|
|
||||||
CS8409_PIN_ASP2_IN_H,
|
|
||||||
CS8409_PIN_DMIC1,
|
|
||||||
CS8409_PIN_DMIC2,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_A,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_B,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_C,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_D,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_E,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_F,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_G,
|
|
||||||
CS8409_PIN_ASP1_TRANSMITTER_H,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_A,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_B,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_C,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_D,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_E,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_F,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_G,
|
|
||||||
CS8409_PIN_ASP2_TRANSMITTER_H,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_A,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_B,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_C,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_D,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_E,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_F,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_G,
|
|
||||||
CS8409_PIN_ASP1_RECEIVER_H,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_A,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_B,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_C,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_D,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_E,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_F,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_G,
|
|
||||||
CS8409_PIN_ASP2_RECEIVER_H,
|
|
||||||
CS8409_PIN_DMIC1_IN,
|
|
||||||
CS8409_PIN_DMIC2_IN,
|
|
||||||
CS8409_PIN_BEEP_GEN,
|
|
||||||
CS8409_PIN_VENDOR_WIDGET
|
|
||||||
};
|
|
||||||
|
|
||||||
enum cs8409_coefficient_index_registers {
|
|
||||||
CS8409_DEV_CFG1,
|
|
||||||
CS8409_DEV_CFG2,
|
|
||||||
CS8409_DEV_CFG3,
|
|
||||||
CS8409_ASP1_CLK_CTRL1,
|
|
||||||
CS8409_ASP1_CLK_CTRL2,
|
|
||||||
CS8409_ASP1_CLK_CTRL3,
|
|
||||||
CS8409_ASP2_CLK_CTRL1,
|
|
||||||
CS8409_ASP2_CLK_CTRL2,
|
|
||||||
CS8409_ASP2_CLK_CTRL3,
|
|
||||||
CS8409_DMIC_CFG,
|
|
||||||
CS8409_BEEP_CFG,
|
|
||||||
ASP1_RX_NULL_INS_RMV,
|
|
||||||
ASP1_Rx_RATE1,
|
|
||||||
ASP1_Rx_RATE2,
|
|
||||||
ASP1_Tx_NULL_INS_RMV,
|
|
||||||
ASP1_Tx_RATE1,
|
|
||||||
ASP1_Tx_RATE2,
|
|
||||||
ASP2_Rx_NULL_INS_RMV,
|
|
||||||
ASP2_Rx_RATE1,
|
|
||||||
ASP2_Rx_RATE2,
|
|
||||||
ASP2_Tx_NULL_INS_RMV,
|
|
||||||
ASP2_Tx_RATE1,
|
|
||||||
ASP2_Tx_RATE2,
|
|
||||||
ASP1_SYNC_CTRL,
|
|
||||||
ASP2_SYNC_CTRL,
|
|
||||||
ASP1_A_TX_CTRL1,
|
|
||||||
ASP1_A_TX_CTRL2,
|
|
||||||
ASP1_B_TX_CTRL1,
|
|
||||||
ASP1_B_TX_CTRL2,
|
|
||||||
ASP1_C_TX_CTRL1,
|
|
||||||
ASP1_C_TX_CTRL2,
|
|
||||||
ASP1_D_TX_CTRL1,
|
|
||||||
ASP1_D_TX_CTRL2,
|
|
||||||
ASP1_E_TX_CTRL1,
|
|
||||||
ASP1_E_TX_CTRL2,
|
|
||||||
ASP1_F_TX_CTRL1,
|
|
||||||
ASP1_F_TX_CTRL2,
|
|
||||||
ASP1_G_TX_CTRL1,
|
|
||||||
ASP1_G_TX_CTRL2,
|
|
||||||
ASP1_H_TX_CTRL1,
|
|
||||||
ASP1_H_TX_CTRL2,
|
|
||||||
ASP2_A_TX_CTRL1,
|
|
||||||
ASP2_A_TX_CTRL2,
|
|
||||||
ASP2_B_TX_CTRL1,
|
|
||||||
ASP2_B_TX_CTRL2,
|
|
||||||
ASP2_C_TX_CTRL1,
|
|
||||||
ASP2_C_TX_CTRL2,
|
|
||||||
ASP2_D_TX_CTRL1,
|
|
||||||
ASP2_D_TX_CTRL2,
|
|
||||||
ASP2_E_TX_CTRL1,
|
|
||||||
ASP2_E_TX_CTRL2,
|
|
||||||
ASP2_F_TX_CTRL1,
|
|
||||||
ASP2_F_TX_CTRL2,
|
|
||||||
ASP2_G_TX_CTRL1,
|
|
||||||
ASP2_G_TX_CTRL2,
|
|
||||||
ASP2_H_TX_CTRL1,
|
|
||||||
ASP2_H_TX_CTRL2,
|
|
||||||
ASP1_A_RX_CTRL1,
|
|
||||||
ASP1_A_RX_CTRL2,
|
|
||||||
ASP1_B_RX_CTRL1,
|
|
||||||
ASP1_B_RX_CTRL2,
|
|
||||||
ASP1_C_RX_CTRL1,
|
|
||||||
ASP1_C_RX_CTRL2,
|
|
||||||
ASP1_D_RX_CTRL1,
|
|
||||||
ASP1_D_RX_CTRL2,
|
|
||||||
ASP1_E_RX_CTRL1,
|
|
||||||
ASP1_E_RX_CTRL2,
|
|
||||||
ASP1_F_RX_CTRL1,
|
|
||||||
ASP1_F_RX_CTRL2,
|
|
||||||
ASP1_G_RX_CTRL1,
|
|
||||||
ASP1_G_RX_CTRL2,
|
|
||||||
ASP1_H_RX_CTRL1,
|
|
||||||
ASP1_H_RX_CTRL2,
|
|
||||||
ASP2_A_RX_CTRL1,
|
|
||||||
ASP2_A_RX_CTRL2,
|
|
||||||
ASP2_B_RX_CTRL1,
|
|
||||||
ASP2_B_RX_CTRL2,
|
|
||||||
ASP2_C_RX_CTRL1,
|
|
||||||
ASP2_C_RX_CTRL2,
|
|
||||||
ASP2_D_RX_CTRL1,
|
|
||||||
ASP2_D_RX_CTRL2,
|
|
||||||
ASP2_E_RX_CTRL1,
|
|
||||||
ASP2_E_RX_CTRL2,
|
|
||||||
ASP2_F_RX_CTRL1,
|
|
||||||
ASP2_F_RX_CTRL2,
|
|
||||||
ASP2_G_RX_CTRL1,
|
|
||||||
ASP2_G_RX_CTRL2,
|
|
||||||
ASP2_H_RX_CTRL1,
|
|
||||||
ASP2_H_RX_CTRL2,
|
|
||||||
CS8409_I2C_ADDR,
|
|
||||||
CS8409_I2C_DATA,
|
|
||||||
CS8409_I2C_CTRL,
|
|
||||||
CS8409_I2C_STS,
|
|
||||||
CS8409_I2C_QWRITE,
|
|
||||||
CS8409_I2C_QREAD,
|
|
||||||
CS8409_SPI_CTRL,
|
|
||||||
CS8409_SPI_TX_DATA,
|
|
||||||
CS8409_SPI_RX_DATA,
|
|
||||||
CS8409_SPI_STS,
|
|
||||||
CS8409_PFE_COEF_W1, /* Parametric filter engine coefficient write 1*/
|
|
||||||
CS8409_PFE_COEF_W2,
|
|
||||||
CS8409_PFE_CTRL1,
|
|
||||||
CS8409_PFE_CTRL2,
|
|
||||||
CS8409_PRE_SCALE_ATTN1,
|
|
||||||
CS8409_PRE_SCALE_ATTN2,
|
|
||||||
CS8409_PFE_COEF_MON1, /* Parametric filter engine coefficient monitor 1*/
|
|
||||||
CS8409_PFE_COEF_MON2,
|
|
||||||
CS8409_ASP1_INTRN_STS,
|
|
||||||
CS8409_ASP2_INTRN_STS,
|
|
||||||
CS8409_ASP1_RX_SCLK_COUNT,
|
|
||||||
CS8409_ASP1_TX_SCLK_COUNT,
|
|
||||||
CS8409_ASP2_RX_SCLK_COUNT,
|
|
||||||
CS8409_ASP2_TX_SCLK_COUNT,
|
|
||||||
CS8409_ASP_UNS_RESP_MASK,
|
|
||||||
CS8409_LOOPBACK_CTRL = 0x80,
|
|
||||||
CS8409_PAD_CFG_SLW_RATE_CTRL = 0x82, /* Pad Config and Slew Rate Control (CIR = 0x0082) */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* CS42L42 Specific Definitions */
|
|
||||||
|
|
||||||
#define CS8409_MAX_CODECS 8
|
|
||||||
#define CS42L42_VOLUMES (4U)
|
|
||||||
#define CS42L42_HP_VOL_REAL_MIN (-63)
|
|
||||||
#define CS42L42_HP_VOL_REAL_MAX (0)
|
|
||||||
#define CS42L42_AMIC_VOL_REAL_MIN (-97)
|
|
||||||
#define CS42L42_AMIC_VOL_REAL_MAX (12)
|
|
||||||
#define CS42L42_REG_AMIC_VOL_MASK (0x00FF)
|
|
||||||
#define CS42L42_HSTYPE_MASK (0x03)
|
|
||||||
#define CS42L42_I2C_TIMEOUT_US (20000)
|
|
||||||
#define CS42L42_I2C_SLEEP_US (2000)
|
|
||||||
#define CS42L42_PDN_TIMEOUT_US (250000)
|
|
||||||
#define CS42L42_PDN_SLEEP_US (2000)
|
|
||||||
#define CS42L42_ANA_MUTE_AB (0x0C)
|
|
||||||
#define CS42L42_FULL_SCALE_VOL_MASK (2)
|
|
||||||
#define CS42L42_FULL_SCALE_VOL_0DB (0)
|
|
||||||
#define CS42L42_FULL_SCALE_VOL_MINUS6DB (1)
|
|
||||||
|
|
||||||
/* Dell BULLSEYE / WARLOCK / CYBORG Specific Definitions */
|
|
||||||
|
|
||||||
#define CS42L42_I2C_ADDR (0x48 << 1)
|
|
||||||
#define CS8409_CS42L42_RESET GENMASK(5, 5) /* CS8409_GPIO5 */
|
|
||||||
#define CS8409_CS42L42_INT GENMASK(4, 4) /* CS8409_GPIO4 */
|
|
||||||
#define CS8409_CYBORG_SPEAKER_PDN GENMASK(2, 2) /* CS8409_GPIO2 */
|
|
||||||
#define CS8409_WARLOCK_SPEAKER_PDN GENMASK(1, 1) /* CS8409_GPIO1 */
|
|
||||||
#define CS8409_CS42L42_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A
|
|
||||||
#define CS8409_CS42L42_SPK_PIN_NID CS8409_PIN_ASP2_TRANSMITTER_A
|
|
||||||
#define CS8409_CS42L42_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A
|
|
||||||
#define CS8409_CS42L42_DMIC_PIN_NID CS8409_PIN_DMIC1_IN
|
|
||||||
#define CS8409_CS42L42_DMIC_ADC_PIN_NID CS8409_PIN_DMIC1
|
|
||||||
|
|
||||||
/* Dolphin */
|
|
||||||
|
|
||||||
#define DOLPHIN_C0_I2C_ADDR (0x48 << 1)
|
|
||||||
#define DOLPHIN_C1_I2C_ADDR (0x49 << 1)
|
|
||||||
#define DOLPHIN_HP_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_A
|
|
||||||
#define DOLPHIN_LO_PIN_NID CS8409_PIN_ASP1_TRANSMITTER_B
|
|
||||||
#define DOLPHIN_AMIC_PIN_NID CS8409_PIN_ASP1_RECEIVER_A
|
|
||||||
|
|
||||||
#define DOLPHIN_C0_INT GENMASK(4, 4)
|
|
||||||
#define DOLPHIN_C1_INT GENMASK(0, 0)
|
|
||||||
#define DOLPHIN_C0_RESET GENMASK(5, 5)
|
|
||||||
#define DOLPHIN_C1_RESET GENMASK(1, 1)
|
|
||||||
#define DOLPHIN_WAKE (DOLPHIN_C0_INT | DOLPHIN_C1_INT)
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CS8409_BULLSEYE,
|
|
||||||
CS8409_WARLOCK,
|
|
||||||
CS8409_WARLOCK_MLK,
|
|
||||||
CS8409_WARLOCK_MLK_DUAL_MIC,
|
|
||||||
CS8409_CYBORG,
|
|
||||||
CS8409_FIXUPS,
|
|
||||||
CS8409_DOLPHIN,
|
|
||||||
CS8409_DOLPHIN_FIXUPS,
|
|
||||||
CS8409_ODIN,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CS8409_CODEC0,
|
|
||||||
CS8409_CODEC1
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
CS42L42_VOL_ADC,
|
|
||||||
CS42L42_VOL_DAC,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CS42L42_ADC_VOL_OFFSET (CS42L42_VOL_ADC)
|
|
||||||
#define CS42L42_DAC_CH0_VOL_OFFSET (CS42L42_VOL_DAC)
|
|
||||||
#define CS42L42_DAC_CH1_VOL_OFFSET (CS42L42_VOL_DAC + 1)
|
|
||||||
|
|
||||||
struct cs8409_i2c_param {
|
|
||||||
unsigned int addr;
|
|
||||||
unsigned int value;
|
|
||||||
unsigned int delay;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cs8409_cir_param {
|
|
||||||
unsigned int nid;
|
|
||||||
unsigned int cir;
|
|
||||||
unsigned int coeff;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef APPLE_CODECS
|
|
||||||
struct unsol_item {
|
|
||||||
struct list_head list;
|
|
||||||
unsigned int idx;
|
|
||||||
unsigned int res;
|
|
||||||
};
|
|
||||||
struct hda_cvt_setup_apple {
|
|
||||||
hda_nid_t nid;
|
|
||||||
u8 stream_tag;
|
|
||||||
u8 channel_id;
|
|
||||||
u16 format_id;
|
|
||||||
unsigned char active; /* cvt is currently used */
|
|
||||||
unsigned char dirty; /* setups should be cleared */
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct sub_codec {
|
|
||||||
struct hda_codec *codec;
|
|
||||||
unsigned int addr;
|
|
||||||
unsigned int reset_gpio;
|
|
||||||
unsigned int irq_mask;
|
|
||||||
const struct cs8409_i2c_param *init_seq;
|
|
||||||
unsigned int init_seq_num;
|
|
||||||
|
|
||||||
unsigned int hp_jack_in:1;
|
|
||||||
unsigned int mic_jack_in:1;
|
|
||||||
#ifdef APPLE_CODECS
|
|
||||||
unsigned int linein_jack_in:1;
|
|
||||||
#endif
|
|
||||||
unsigned int suspended:1;
|
|
||||||
unsigned int paged:1;
|
|
||||||
unsigned int last_page;
|
|
||||||
unsigned int hsbias_hiz;
|
|
||||||
unsigned int full_scale_vol:1;
|
|
||||||
unsigned int no_type_dect:1;
|
|
||||||
|
|
||||||
s8 vol[CS42L42_VOLUMES];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cs8409_spec {
|
|
||||||
struct hda_gen_spec gen;
|
|
||||||
struct hda_codec *codec;
|
|
||||||
|
|
||||||
struct sub_codec *scodecs[CS8409_MAX_CODECS];
|
|
||||||
unsigned int num_scodecs;
|
|
||||||
|
|
||||||
unsigned int gpio_mask;
|
|
||||||
unsigned int gpio_dir;
|
|
||||||
unsigned int gpio_data;
|
|
||||||
|
|
||||||
int speaker_pdn_gpio;
|
|
||||||
|
|
||||||
struct mutex i2c_mux;
|
|
||||||
unsigned int i2c_clck_enabled;
|
|
||||||
unsigned int dev_addr;
|
|
||||||
struct delayed_work i2c_clk_work;
|
|
||||||
|
|
||||||
unsigned int playback_started:1;
|
|
||||||
unsigned int capture_started:1;
|
|
||||||
unsigned int init_done:1;
|
|
||||||
unsigned int build_ctrl_done:1;
|
|
||||||
|
|
||||||
#ifdef APPLE_CODECS
|
|
||||||
|
|
||||||
// additional data for Apple 8409 system
|
|
||||||
|
|
||||||
unsigned int spdif_detect:1;
|
|
||||||
unsigned int spdif_present:1;
|
|
||||||
unsigned int sense_b:1;
|
|
||||||
hda_nid_t vendor_nid;
|
|
||||||
|
|
||||||
/* digital beep */
|
|
||||||
hda_nid_t beep_nid;
|
|
||||||
|
|
||||||
/* for MBP SPDIF control */
|
|
||||||
int (*spdif_sw_put)(struct snd_kcontrol *kcontrol,
|
|
||||||
struct snd_ctl_elem_value *ucontrol);
|
|
||||||
|
|
||||||
// so it appears we have "concurrency" in the linux HDA code
|
|
||||||
// in that if unsolicited responses occur which perform extensive verbs
|
|
||||||
// the hda verbs are intermixed with eg extensive start playback verbs
|
|
||||||
// on OSX we appear to have blocks of verbs during which unsolicited responses
|
|
||||||
// are logged but the unsolicited verbs occur after the verb block
|
|
||||||
// this flag is used to flag such verb blocks and the list will store the
|
|
||||||
// responses
|
|
||||||
// we use a pre-allocated list - if we have more than 10 outstanding unsols
|
|
||||||
// we will drop
|
|
||||||
// not clear if mutexes would be the way to go
|
|
||||||
int block_unsol;
|
|
||||||
struct list_head unsol_list;
|
|
||||||
struct unsol_item unsol_items_prealloc[10];
|
|
||||||
int unsol_items_prealloc_used[10];
|
|
||||||
|
|
||||||
// add in specific nids for the intmike and linein as they seem to swap
|
|
||||||
// between macbook pros (14,3) and imacs (18,3)
|
|
||||||
int intmike_nid;
|
|
||||||
int linein_nid;
|
|
||||||
int intmike_adc_nid;
|
|
||||||
int linein_amp_nid;
|
|
||||||
|
|
||||||
// the following flag bits also need swapping
|
|
||||||
int reg9_intmike_dmic_mo;
|
|
||||||
int reg9_linein_dmic_mo;
|
|
||||||
int reg82_intmike_dmic_scl;
|
|
||||||
int reg82_linein_dmic_scl;
|
|
||||||
|
|
||||||
|
|
||||||
// add explicit stream format store entries as per hda_codec using a local definition
|
|
||||||
// of hda_cvt_setup (which is local to hda_codec.c)
|
|
||||||
// also use explicit nid versions
|
|
||||||
// (except that means either need explicit functions for each nid or have to lookup
|
|
||||||
// nid each time want to use in a generic function with nid argument)
|
|
||||||
struct hda_cvt_setup_apple nid_0x02;
|
|
||||||
struct hda_cvt_setup_apple nid_0x03;
|
|
||||||
struct hda_cvt_setup_apple nid_0x0a;
|
|
||||||
struct hda_cvt_setup_apple nid_0x22;
|
|
||||||
struct hda_cvt_setup_apple nid_0x23;
|
|
||||||
struct hda_cvt_setup_apple nid_0x1a;
|
|
||||||
|
|
||||||
|
|
||||||
// new item to deal with jack presence as Apple (and now Dell) seems to have barfed
|
|
||||||
// the HDA spec by using a separate headphone chip
|
|
||||||
int jack_present;
|
|
||||||
|
|
||||||
// save the type of headphone connected
|
|
||||||
int headset_type;
|
|
||||||
|
|
||||||
// if headphone has mike or not
|
|
||||||
int have_mike;
|
|
||||||
|
|
||||||
// if headphone has buttons or not
|
|
||||||
int have_buttons;
|
|
||||||
|
|
||||||
// current stream channel count
|
|
||||||
int stream_channels;
|
|
||||||
|
|
||||||
// set when playing for plug/unplug events while playing
|
|
||||||
int playing;
|
|
||||||
|
|
||||||
// set when capturing for plug/unplug events while capturing
|
|
||||||
int capturing;
|
|
||||||
|
|
||||||
// changing coding - OSX sets up the format on plugin
|
|
||||||
// then does some minimal setup when start play
|
|
||||||
// initial coding delayed any format setup till actually play
|
|
||||||
// this works for no mike but not for mike - we need to initialize
|
|
||||||
// the mike on plugin
|
|
||||||
// this flag will be set when we have done the format setup
|
|
||||||
// so know if need to do it on play or not
|
|
||||||
// now need 2 flags - one for play and one for capture
|
|
||||||
int headset_play_format_setup_needed;
|
|
||||||
int headset_capture_format_setup_needed;
|
|
||||||
|
|
||||||
int headset_presetup_done;
|
|
||||||
|
|
||||||
|
|
||||||
int use_data;
|
|
||||||
|
|
||||||
|
|
||||||
// this is new item for dealing with headset plugins
|
|
||||||
// so can distinguish which phase we are in if have multiple interrupts
|
|
||||||
// not really used now have analyzed interrupts properly
|
|
||||||
int headset_phase;
|
|
||||||
|
|
||||||
// another dirty hack item to manage the different headset enable codes
|
|
||||||
int headset_enable;
|
|
||||||
|
|
||||||
int play_init;
|
|
||||||
int capture_init;
|
|
||||||
|
|
||||||
|
|
||||||
// new item to limit times we redo unmute/play
|
|
||||||
struct timespec64 last_play_time;
|
|
||||||
// record the first play time - we have a problem there
|
|
||||||
// some initial plays that I dont understand - so skip any setup
|
|
||||||
// till sometime after the first play
|
|
||||||
struct timespec64 first_play_time;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* verb exec op override */
|
|
||||||
int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags,
|
|
||||||
unsigned int *res);
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer;
|
|
||||||
extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer;
|
|
||||||
|
|
||||||
int cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo);
|
|
||||||
int cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
|
|
||||||
int cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl);
|
|
||||||
|
|
||||||
extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_playback;
|
|
||||||
extern const struct hda_pcm_stream cs42l42_48k_pcm_analog_capture;
|
|
||||||
extern const struct hda_quirk cs8409_fixup_tbl[];
|
|
||||||
extern const struct hda_model_fixup cs8409_models[];
|
|
||||||
extern const struct hda_fixup cs8409_fixups[];
|
|
||||||
extern const struct hda_verb cs8409_cs42l42_init_verbs[];
|
|
||||||
extern const struct cs8409_cir_param cs8409_cs42l42_hw_cfg[];
|
|
||||||
extern const struct cs8409_cir_param cs8409_cs42l42_bullseye_atn[];
|
|
||||||
extern struct sub_codec cs8409_cs42l42_codec;
|
|
||||||
|
|
||||||
extern const struct hda_verb dolphin_init_verbs[];
|
|
||||||
extern const struct cs8409_cir_param dolphin_hw_cfg[];
|
|
||||||
extern struct sub_codec dolphin_cs42l42_0;
|
|
||||||
extern struct sub_codec dolphin_cs42l42_1;
|
|
||||||
|
|
||||||
void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action);
|
|
||||||
void dolphin_fixups(struct hda_codec *codec, const struct hda_fixup *fix, int action);
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue