1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * CS42L43 CODEC driver internal data 4 * 5 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and 6 * Cirrus Logic International Semiconductor Ltd. 7 */ 8 9 #include <linux/clk.h> 10 #include <linux/completion.h> 11 #include <linux/device.h> 12 #include <linux/mutex.h> 13 #include <linux/regmap.h> 14 #include <linux/soundwire/sdw.h> 15 #include <linux/types.h> 16 #include <sound/cs42l43.h> 17 #include <sound/pcm.h> 18 #include <sound/soc-jack.h> 19 20 #ifndef CS42L43_ASOC_INT_H 21 #define CS42L43_ASOC_INT_H 22 23 #define CS42L43_INTERNAL_SYSCLK 24576000 24 #define CS42L43_DEFAULT_SLOTS 0x3F 25 26 #define CS42L43_PLL_TIMEOUT_MS 200 27 #define CS42L43_SPK_TIMEOUT_MS 100 28 #define CS42L43_HP_TIMEOUT_MS 2000 29 #define CS42L43_LOAD_TIMEOUT_MS 1000 30 31 #define CS42L43_HP_ILIMIT_BACKOFF_MS 1000 32 #define CS42L43_HP_ILIMIT_DECAY_MS 300 33 #define CS42L43_HP_ILIMIT_MAX_COUNT 4 34 35 #define CS42L43_ASP_MAX_CHANNELS 6 36 #define CS42L43_N_EQ_COEFFS 15 37 38 #define CS42L43_N_BUTTONS 6 39 40 struct cs42l43_codec { 41 struct device *dev; 42 struct cs42l43 *core; 43 struct snd_soc_component *component; 44 45 struct clk *mclk; 46 47 int n_slots; 48 int slot_width; 49 int tx_slots[CS42L43_ASP_MAX_CHANNELS]; 50 int rx_slots[CS42L43_ASP_MAX_CHANNELS]; 51 struct snd_pcm_hw_constraint_list constraint; 52 53 u32 eq_coeffs[CS42L43_N_EQ_COEFFS]; 54 55 unsigned int refclk_src; 56 unsigned int refclk_freq; 57 struct completion pll_ready; 58 59 unsigned int decim_cache[4]; 60 unsigned int adc_ena; 61 unsigned int hp_ena; 62 63 struct completion hp_startup; 64 struct completion hp_shutdown; 65 struct completion spkr_shutdown; 66 struct completion spkl_shutdown; 67 struct completion spkr_startup; 68 struct completion spkl_startup; 69 // Lock to ensure speaker VU updates don't clash 70 struct mutex spk_vu_lock; 71 72 // Lock for all jack detect operations 73 struct mutex jack_lock; 74 struct snd_soc_jack *jack_hp; 75 76 bool use_ring_sense; 77 unsigned int tip_debounce_ms; 78 unsigned int bias_low; 79 unsigned int bias_sense_ua; 80 unsigned int bias_ramp_ms; 81 unsigned int detect_us; 82 unsigned int buttons[CS42L43_N_BUTTONS]; 83 84 struct delayed_work tip_sense_work; 85 struct delayed_work bias_sense_timeout; 86 struct delayed_work button_press_work; 87 struct work_struct button_release_work; 88 struct completion type_detect; 89 struct completion load_detect; 90 91 bool load_detect_running; 92 bool button_detect_running; 93 bool jack_present; 94 int jack_override; 95 96 struct work_struct hp_ilimit_work; 97 struct delayed_work hp_ilimit_clear_work; 98 bool hp_ilimited; 99 int hp_ilimit_count; 100 }; 101 102 #if IS_REACHABLE(CONFIG_SND_SOC_CS42L43_SDW) 103 104 int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream, 105 struct snd_pcm_hw_params *params, 106 struct snd_soc_dai *dai); 107 int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream, 108 struct snd_soc_dai *dai); 109 int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direction); 110 111 #else 112 113 static inline int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream, 114 struct snd_pcm_hw_params *params, 115 struct snd_soc_dai *dai) 116 { 117 return -EINVAL; 118 } 119 120 #define cs42l43_sdw_remove_peripheral NULL 121 #define cs42l43_sdw_set_stream NULL 122 123 #endif 124 125 int cs42l43_set_jack(struct snd_soc_component *component, 126 struct snd_soc_jack *jack, void *d); 127 void cs42l43_bias_sense_timeout(struct work_struct *work); 128 void cs42l43_tip_sense_work(struct work_struct *work); 129 void cs42l43_button_press_work(struct work_struct *work); 130 void cs42l43_button_release_work(struct work_struct *work); 131 irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data); 132 irqreturn_t cs42l43_button_press(int irq, void *data); 133 irqreturn_t cs42l43_button_release(int irq, void *data); 134 irqreturn_t cs42l43_tip_sense(int irq, void *data); 135 int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 136 int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 137 138 extern const struct soc_enum cs42l43_jack_enum; 139 140 #endif /* CS42L43_ASOC_INT_H */ 141