blob: 7fb582092b1c76fe701260292509ca1b1e14e27b [file] [log] [blame]
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Joonwoo Parka8890262012-10-15 12:04:27 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#ifndef __WCD9XXX_COMMON_H__
13#define __WCD9XXX_COMMON_H__
14
15#include <linux/notifier.h>
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -070016#include <linux/mfd/wcd9xxx/core-resource.h>
Joonwoo Parka8890262012-10-15 12:04:27 -070017#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
18
19enum wcd9xxx_bandgap_type {
20 WCD9XXX_BANDGAP_OFF,
21 WCD9XXX_BANDGAP_AUDIO_MODE,
22 WCD9XXX_BANDGAP_MBHC_MODE,
23};
24
Bhalchandra Gajare8e5fe252013-07-15 19:42:21 -070025enum wcd9xxx_cdc_type {
26 WCD9XXX_CDC_TYPE_INVALID = 0,
27 WCD9XXX_CDC_TYPE_TAIKO,
28 WCD9XXX_CDC_TYPE_TAPAN,
29 WCD9XXX_CDC_TYPE_HELICON,
30};
31
Joonwoo Parka8890262012-10-15 12:04:27 -070032enum wcd9xxx_clock_type {
33 WCD9XXX_CLK_OFF,
34 WCD9XXX_CLK_RCO,
35 WCD9XXX_CLK_MCLK,
36};
37
38enum wcd9xxx_cfilt_sel {
39 WCD9XXX_CFILT1_SEL,
40 WCD9XXX_CFILT2_SEL,
41 WCD9XXX_CFILT3_SEL,
42 WCD9XXX_NUM_OF_CFILT,
43};
44
45struct wcd9xxx_reg_address {
46 u16 micb_4_ctl;
47 u16 micb_4_int_rbias;
48 u16 micb_4_mbhc;
49};
50
51enum wcd9xxx_notify_event {
52 WCD9XXX_EVENT_INVALID,
53
54 WCD9XXX_EVENT_PRE_RCO_ON,
55 WCD9XXX_EVENT_POST_RCO_ON,
56 WCD9XXX_EVENT_PRE_RCO_OFF,
57 WCD9XXX_EVENT_POST_RCO_OFF,
58
59 WCD9XXX_EVENT_PRE_MCLK_ON,
60 WCD9XXX_EVENT_POST_MCLK_ON,
61 WCD9XXX_EVENT_PRE_MCLK_OFF,
62 WCD9XXX_EVENT_POST_MCLK_OFF,
63
64 WCD9XXX_EVENT_PRE_BG_OFF,
65 WCD9XXX_EVENT_POST_BG_OFF,
66 WCD9XXX_EVENT_PRE_BG_AUDIO_ON,
67 WCD9XXX_EVENT_POST_BG_AUDIO_ON,
68 WCD9XXX_EVENT_PRE_BG_MBHC_ON,
69 WCD9XXX_EVENT_POST_BG_MBHC_ON,
70
71 WCD9XXX_EVENT_PRE_MICBIAS_1_OFF,
72 WCD9XXX_EVENT_POST_MICBIAS_1_OFF,
73 WCD9XXX_EVENT_PRE_MICBIAS_2_OFF,
74 WCD9XXX_EVENT_POST_MICBIAS_2_OFF,
75 WCD9XXX_EVENT_PRE_MICBIAS_3_OFF,
76 WCD9XXX_EVENT_POST_MICBIAS_3_OFF,
77 WCD9XXX_EVENT_PRE_MICBIAS_4_OFF,
78 WCD9XXX_EVENT_POST_MICBIAS_4_OFF,
79 WCD9XXX_EVENT_PRE_MICBIAS_1_ON,
80 WCD9XXX_EVENT_POST_MICBIAS_1_ON,
81 WCD9XXX_EVENT_PRE_MICBIAS_2_ON,
82 WCD9XXX_EVENT_POST_MICBIAS_2_ON,
83 WCD9XXX_EVENT_PRE_MICBIAS_3_ON,
84 WCD9XXX_EVENT_POST_MICBIAS_3_ON,
85 WCD9XXX_EVENT_PRE_MICBIAS_4_ON,
86 WCD9XXX_EVENT_POST_MICBIAS_4_ON,
87
88 WCD9XXX_EVENT_PRE_CFILT_1_OFF,
89 WCD9XXX_EVENT_POST_CFILT_1_OFF,
90 WCD9XXX_EVENT_PRE_CFILT_2_OFF,
91 WCD9XXX_EVENT_POST_CFILT_2_OFF,
92 WCD9XXX_EVENT_PRE_CFILT_3_OFF,
93 WCD9XXX_EVENT_POST_CFILT_3_OFF,
94 WCD9XXX_EVENT_PRE_CFILT_1_ON,
95 WCD9XXX_EVENT_POST_CFILT_1_ON,
96 WCD9XXX_EVENT_PRE_CFILT_2_ON,
97 WCD9XXX_EVENT_POST_CFILT_2_ON,
98 WCD9XXX_EVENT_PRE_CFILT_3_ON,
99 WCD9XXX_EVENT_POST_CFILT_3_ON,
100
101 WCD9XXX_EVENT_PRE_HPHL_PA_ON,
102 WCD9XXX_EVENT_POST_HPHL_PA_OFF,
103 WCD9XXX_EVENT_PRE_HPHR_PA_ON,
104 WCD9XXX_EVENT_POST_HPHR_PA_OFF,
105
106 WCD9XXX_EVENT_POST_RESUME,
107
108 WCD9XXX_EVENT_LAST,
109};
110
111struct wcd9xxx_resmgr {
112 struct snd_soc_codec *codec;
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -0700113 struct wcd9xxx_core_resource *core_res;
Joonwoo Parka8890262012-10-15 12:04:27 -0700114
115 u32 rx_bias_count;
116
Joonwoo Park533b3682013-06-13 11:41:21 -0700117 /*
118 * bandgap_type, bg_audio_users and bg_mbhc_users have to be
119 * referred/manipulated after acquiring codec_bg_clk_lock mutex
120 */
Joonwoo Parka8890262012-10-15 12:04:27 -0700121 enum wcd9xxx_bandgap_type bandgap_type;
122 u16 bg_audio_users;
123 u16 bg_mbhc_users;
124
Joonwoo Park533b3682013-06-13 11:41:21 -0700125 /*
126 * clk_type, clk_rco_users and clk_mclk_users have to be
127 * referred/manipulated after acquiring codec_bg_clk_lock mutex
128 */
Joonwoo Parka8890262012-10-15 12:04:27 -0700129 enum wcd9xxx_clock_type clk_type;
130 u16 clk_rco_users;
131 u16 clk_mclk_users;
132
133 /* cfilt users per cfilts */
134 u16 cfilt_users[WCD9XXX_NUM_OF_CFILT];
135
136 struct wcd9xxx_reg_address *reg_addr;
137
138 struct wcd9xxx_pdata *pdata;
139
140 struct blocking_notifier_head notifier;
141 /* Notifier needs mbhc pointer with resmgr */
142 struct wcd9xxx_mbhc *mbhc;
143
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800144 unsigned long cond_flags;
Joonwoo Park3b268ca2013-07-17 13:11:43 -0700145 unsigned long cond_avail_flags;
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800146 struct list_head update_bit_cond_h;
Joonwoo Parkccccba72013-04-26 11:19:46 -0700147 struct mutex update_bit_cond_lock;
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800148
Joonwoo Parka8890262012-10-15 12:04:27 -0700149 /*
150 * Currently, only used for mbhc purpose, to protect
151 * concurrent execution of mbhc threaded irq handlers and
152 * kill race between DAPM and MBHC. But can serve as a
153 * general lock to protect codec resource
154 */
155 struct mutex codec_resource_lock;
Joonwoo Park533b3682013-06-13 11:41:21 -0700156 struct mutex codec_bg_clk_lock;
Bhalchandra Gajare8e5fe252013-07-15 19:42:21 -0700157
158 enum wcd9xxx_cdc_type codec_type;
Joonwoo Parka8890262012-10-15 12:04:27 -0700159};
160
161int wcd9xxx_resmgr_init(struct wcd9xxx_resmgr *resmgr,
162 struct snd_soc_codec *codec,
Bhalchandra Gajare9b4eb3b2013-04-30 12:00:41 -0700163 struct wcd9xxx_core_resource *core_res,
Joonwoo Parka8890262012-10-15 12:04:27 -0700164 struct wcd9xxx_pdata *pdata,
Bhalchandra Gajare8e5fe252013-07-15 19:42:21 -0700165 struct wcd9xxx_reg_address *reg_addr,
166 enum wcd9xxx_cdc_type cdc_type);
Joonwoo Parka8890262012-10-15 12:04:27 -0700167void wcd9xxx_resmgr_deinit(struct wcd9xxx_resmgr *resmgr);
168
Bhalchandra Gajare8e5fe252013-07-15 19:42:21 -0700169int wcd9xxx_resmgr_enable_config_mode(struct wcd9xxx_resmgr *resmgr,
170 int enable);
Joonwoo Parka8890262012-10-15 12:04:27 -0700171
172void wcd9xxx_resmgr_enable_rx_bias(struct wcd9xxx_resmgr *resmgr, u32 enable);
173void wcd9xxx_resmgr_get_clk_block(struct wcd9xxx_resmgr *resmgr,
174 enum wcd9xxx_clock_type type);
175void wcd9xxx_resmgr_put_clk_block(struct wcd9xxx_resmgr *resmgr,
176 enum wcd9xxx_clock_type type);
177void wcd9xxx_resmgr_get_bandgap(struct wcd9xxx_resmgr *resmgr,
178 const enum wcd9xxx_bandgap_type choice);
179void wcd9xxx_resmgr_put_bandgap(struct wcd9xxx_resmgr *resmgr,
180 enum wcd9xxx_bandgap_type choice);
181void wcd9xxx_resmgr_cfilt_get(struct wcd9xxx_resmgr *resmgr,
182 enum wcd9xxx_cfilt_sel cfilt_sel);
183void wcd9xxx_resmgr_cfilt_put(struct wcd9xxx_resmgr *resmgr,
184 enum wcd9xxx_cfilt_sel cfilt_sel);
185
186void wcd9xxx_resmgr_bcl_lock(struct wcd9xxx_resmgr *resmgr);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -0800187void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -0700188#define WCD9XXX_BCL_LOCK(resmgr) \
189{ \
190 pr_debug("%s: Acquiring BCL\n", __func__); \
191 wcd9xxx_resmgr_bcl_lock(resmgr); \
192 pr_debug("%s: Acquiring BCL done\n", __func__); \
193}
194
195void wcd9xxx_resmgr_bcl_unlock(struct wcd9xxx_resmgr *resmgr);
196#define WCD9XXX_BCL_UNLOCK(resmgr) \
197{ \
198 pr_debug("%s: Release BCL\n", __func__); \
199 wcd9xxx_resmgr_bcl_unlock(resmgr); \
200}
201
202#define WCD9XXX_BCL_ASSERT_LOCKED(resmgr) \
203{ \
204 WARN_ONCE(!mutex_is_locked(&resmgr->codec_resource_lock), \
205 "%s: BCL should have acquired\n", __func__); \
206}
207
Joonwoo Park533b3682013-06-13 11:41:21 -0700208#define WCD9XXX_BG_CLK_LOCK(resmgr) \
209{ \
210 struct wcd9xxx_resmgr *__resmgr = resmgr; \
211 pr_debug("%s: Acquiring BG_CLK\n", __func__); \
212 mutex_lock(&__resmgr->codec_bg_clk_lock); \
213 pr_debug("%s: Acquiring BG_CLK done\n", __func__); \
214}
215
216#define WCD9XXX_BG_CLK_UNLOCK(resmgr) \
217{ \
218 struct wcd9xxx_resmgr *__resmgr = resmgr; \
219 pr_debug("%s: Releasing BG_CLK\n", __func__); \
220 mutex_unlock(&__resmgr->codec_bg_clk_lock); \
221}
222
223#define WCD9XXX_BG_CLK_ASSERT_LOCKED(resmgr) \
224{ \
225 WARN_ONCE(!mutex_is_locked(&resmgr->codec_bg_clk_lock), \
226 "%s: BG_CLK lock should have acquired\n", __func__); \
227}
228
Joonwoo Parka8890262012-10-15 12:04:27 -0700229const char *wcd9xxx_get_event_string(enum wcd9xxx_notify_event type);
230int wcd9xxx_resmgr_get_k_val(struct wcd9xxx_resmgr *resmgr,
231 unsigned int cfilt_mv);
232int wcd9xxx_resmgr_register_notifier(struct wcd9xxx_resmgr *resmgr,
233 struct notifier_block *nblock);
234int wcd9xxx_resmgr_unregister_notifier(struct wcd9xxx_resmgr *resmgr,
235 struct notifier_block *nblock);
236void wcd9xxx_resmgr_notifier_call(struct wcd9xxx_resmgr *resmgr,
237 const enum wcd9xxx_notify_event e);
238
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800239enum wcd9xxx_resmgr_cond {
Joonwoo Parkaf21f032013-03-05 18:07:40 -0800240 WCD9XXX_COND_HPH = 0x01, /* Headphone */
241 WCD9XXX_COND_HPH_MIC = 0x02, /* Microphone on the headset */
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800242};
Joonwoo Park3b268ca2013-07-17 13:11:43 -0700243void wcd9xxx_regmgr_cond_register(struct wcd9xxx_resmgr *resmgr,
244 unsigned long condbits);
245void wcd9xxx_regmgr_cond_deregister(struct wcd9xxx_resmgr *resmgr,
246 unsigned long condbits);
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800247int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
248 enum wcd9xxx_resmgr_cond cond,
249 unsigned short reg, int shift,
250 bool invert);
251int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
252 enum wcd9xxx_resmgr_cond cond,
253 unsigned short reg, int shift,
254 bool invert);
255void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
256 enum wcd9xxx_resmgr_cond cond, bool set);
257
Joonwoo Parka8890262012-10-15 12:04:27 -0700258#endif /* __WCD9XXX_COMMON_H__ */