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_ASP_MAX_CHANNELS 6 32 #define CS42L43_N_EQ_COEFFS 15 33 34 #define CS42L43_N_BUTTONS 6 35 36 struct cs42l43_codec { 37 struct device *dev; 38 struct cs42l43 *core; 39 struct snd_soc_component *component; 40 41 struct clk *mclk; 42 43 int n_slots; 44 int slot_width; 45 int tx_slots[CS42L43_ASP_MAX_CHANNELS]; 46 int rx_slots[CS42L43_ASP_MAX_CHANNELS]; 47 struct snd_pcm_hw_constraint_list constraint; 48 49 u32 eq_coeffs[CS42L43_N_EQ_COEFFS]; 50 51 unsigned int refclk_src; 52 unsigned int refclk_freq; 53 struct completion pll_ready; 54 55 unsigned int decim_cache[4]; 56 unsigned int adc_ena; 57 unsigned int hp_ena; 58 59 struct completion hp_startup; 60 struct completion hp_shutdown; 61 struct completion spkr_shutdown; 62 struct completion spkl_shutdown; 63 struct completion spkr_startup; 64 struct completion spkl_startup; 65 // Lock to ensure speaker VU updates don't clash 66 struct mutex spk_vu_lock; 67 68 // Lock for all jack detect operations 69 struct mutex jack_lock; 70 struct snd_soc_jack *jack_hp; 71 72 bool use_ring_sense; 73 unsigned int tip_debounce_ms; 74 unsigned int bias_low; 75 unsigned int bias_sense_ua; 76 unsigned int bias_ramp_ms; 77 unsigned int detect_us; 78 unsigned int buttons[CS42L43_N_BUTTONS]; 79 80 struct delayed_work tip_sense_work; 81 struct delayed_work bias_sense_timeout; 82 struct delayed_work button_press_work; 83 struct work_struct button_release_work; 84 struct completion type_detect; 85 struct completion load_detect; 86 87 bool load_detect_running; 88 bool button_detect_running; 89 bool jack_present; 90 int jack_override; 91 }; 92 93 #if IS_REACHABLE(CONFIG_SND_SOC_CS42L43_SDW) 94 95 int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream, 96 struct snd_pcm_hw_params *params, 97 struct snd_soc_dai *dai); 98 int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream, 99 struct snd_soc_dai *dai); 100 int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direction); 101 102 #else 103 104 static inline int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream, 105 struct snd_pcm_hw_params *params, 106 struct snd_soc_dai *dai) 107 { 108 return -EINVAL; 109 } 110 111 #define cs42l43_sdw_remove_peripheral NULL 112 #define cs42l43_sdw_set_stream NULL 113 114 #endif 115 116 int cs42l43_set_jack(struct snd_soc_component *component, 117 struct snd_soc_jack *jack, void *d); 118 void cs42l43_bias_sense_timeout(struct work_struct *work); 119 void cs42l43_tip_sense_work(struct work_struct *work); 120 void cs42l43_button_press_work(struct work_struct *work); 121 void cs42l43_button_release_work(struct work_struct *work); 122 irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data); 123 irqreturn_t cs42l43_button_press(int irq, void *data); 124 irqreturn_t cs42l43_button_release(int irq, void *data); 125 irqreturn_t cs42l43_tip_sense(int irq, void *data); 126 int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 127 int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); 128 129 extern const struct soc_enum cs42l43_jack_enum; 130 131 #endif /* CS42L43_ASOC_INT_H */ 132