summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cs42l43.h
blob: 9924c13e1eb539a24efdcb2d5ed27c3f11cc9ed2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * CS42L43 CODEC driver internal data
 *
 * Copyright (C) 2022-2023 Cirrus Logic, Inc. and
 *                         Cirrus Logic International Semiconductor Ltd.
 */

#ifndef CS42L43_ASOC_INT_H
#define CS42L43_ASOC_INT_H

#include <linux/completion.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include <sound/pcm.h>

#define CS42L43_INTERNAL_SYSCLK		24576000
#define CS42L43_DEFAULT_SLOTS		0x3F

#define CS42L43_PLL_TIMEOUT_MS		200
#define CS42L43_SPK_TIMEOUT_MS		100
#define CS42L43_HP_TIMEOUT_MS		2000
#define CS42L43_LOAD_TIMEOUT_MS		1000

#define CS42L43_HP_ILIMIT_BACKOFF_MS	1000
#define CS42L43_HP_ILIMIT_DECAY_MS	300
#define CS42L43_HP_ILIMIT_MAX_COUNT	4

#define CS42L43_ASP_MAX_CHANNELS	6
#define CS42L43_N_EQ_COEFFS		15

#define CS42L43_N_BUTTONS	6

struct clk;
struct device;

struct snd_soc_component;
struct snd_soc_jack;

struct cs42l43;

struct cs42l43_codec {
	struct device *dev;
	struct cs42l43 *core;
	struct snd_soc_component *component;

	struct clk *mclk;

	int n_slots;
	int slot_width;
	int tx_slots[CS42L43_ASP_MAX_CHANNELS];
	int rx_slots[CS42L43_ASP_MAX_CHANNELS];
	struct snd_pcm_hw_constraint_list constraint;

	u32 eq_coeffs[CS42L43_N_EQ_COEFFS];

	unsigned int refclk_src;
	unsigned int refclk_freq;
	struct completion pll_ready;

	unsigned int decim_cache[4];
	unsigned int adc_ena;
	unsigned int hp_ena;

	struct completion hp_startup;
	struct completion hp_shutdown;
	struct completion spkr_shutdown;
	struct completion spkl_shutdown;
	struct completion spkr_startup;
	struct completion spkl_startup;
	// Lock to ensure speaker VU updates don't clash
	struct mutex spk_vu_lock;

	// Lock for all jack detect operations
	struct mutex jack_lock;
	struct snd_soc_jack *jack_hp;

	bool use_ring_sense;
	unsigned int tip_debounce_ms;
	unsigned int bias_low;
	unsigned int bias_sense_ua;
	unsigned int bias_ramp_ms;
	unsigned int detect_us;
	unsigned int buttons[CS42L43_N_BUTTONS];

	struct delayed_work tip_sense_work;
	struct delayed_work bias_sense_timeout;
	struct delayed_work button_press_work;
	struct work_struct button_release_work;
	struct completion type_detect;
	struct completion load_detect;

	bool load_detect_running;
	bool button_detect_running;
	bool jack_present;
	int jack_override;

	struct work_struct hp_ilimit_work;
	struct delayed_work hp_ilimit_clear_work;
	bool hp_ilimited;
	int hp_ilimit_count;
};

#if IS_REACHABLE(CONFIG_SND_SOC_CS42L43_SDW)

int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params,
			       struct snd_soc_dai *dai);
int cs42l43_sdw_remove_peripheral(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai);
int cs42l43_sdw_set_stream(struct snd_soc_dai *dai, void *sdw_stream, int direction);

#else

static inline int cs42l43_sdw_add_peripheral(struct snd_pcm_substream *substream,
					     struct snd_pcm_hw_params *params,
					     struct snd_soc_dai *dai)
{
	return -EINVAL;
}

#define cs42l43_sdw_remove_peripheral NULL
#define cs42l43_sdw_set_stream NULL

#endif

int cs42l43_set_jack(struct snd_soc_component *component,
		     struct snd_soc_jack *jack, void *d);
void cs42l43_bias_sense_timeout(struct work_struct *work);
void cs42l43_tip_sense_work(struct work_struct *work);
void cs42l43_button_press_work(struct work_struct *work);
void cs42l43_button_release_work(struct work_struct *work);
irqreturn_t cs42l43_bias_detect_clamp(int irq, void *data);
irqreturn_t cs42l43_button_press(int irq, void *data);
irqreturn_t cs42l43_button_release(int irq, void *data);
irqreturn_t cs42l43_tip_sense(int irq, void *data);
int cs42l43_jack_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
int cs42l43_jack_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);

extern const struct soc_enum cs42l43_jack_enum;

#endif /* CS42L43_ASOC_INT_H */