blob: b5f950c7077f19c7a158b30bf15f1c7ad0d38235 [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>
16#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
17
18enum wcd9xxx_bandgap_type {
19 WCD9XXX_BANDGAP_OFF,
20 WCD9XXX_BANDGAP_AUDIO_MODE,
21 WCD9XXX_BANDGAP_MBHC_MODE,
22};
23
24enum wcd9xxx_clock_type {
25 WCD9XXX_CLK_OFF,
26 WCD9XXX_CLK_RCO,
27 WCD9XXX_CLK_MCLK,
28};
29
30enum wcd9xxx_cfilt_sel {
31 WCD9XXX_CFILT1_SEL,
32 WCD9XXX_CFILT2_SEL,
33 WCD9XXX_CFILT3_SEL,
34 WCD9XXX_NUM_OF_CFILT,
35};
36
37struct wcd9xxx_reg_address {
38 u16 micb_4_ctl;
39 u16 micb_4_int_rbias;
40 u16 micb_4_mbhc;
41};
42
43enum wcd9xxx_notify_event {
44 WCD9XXX_EVENT_INVALID,
45
46 WCD9XXX_EVENT_PRE_RCO_ON,
47 WCD9XXX_EVENT_POST_RCO_ON,
48 WCD9XXX_EVENT_PRE_RCO_OFF,
49 WCD9XXX_EVENT_POST_RCO_OFF,
50
51 WCD9XXX_EVENT_PRE_MCLK_ON,
52 WCD9XXX_EVENT_POST_MCLK_ON,
53 WCD9XXX_EVENT_PRE_MCLK_OFF,
54 WCD9XXX_EVENT_POST_MCLK_OFF,
55
56 WCD9XXX_EVENT_PRE_BG_OFF,
57 WCD9XXX_EVENT_POST_BG_OFF,
58 WCD9XXX_EVENT_PRE_BG_AUDIO_ON,
59 WCD9XXX_EVENT_POST_BG_AUDIO_ON,
60 WCD9XXX_EVENT_PRE_BG_MBHC_ON,
61 WCD9XXX_EVENT_POST_BG_MBHC_ON,
62
63 WCD9XXX_EVENT_PRE_MICBIAS_1_OFF,
64 WCD9XXX_EVENT_POST_MICBIAS_1_OFF,
65 WCD9XXX_EVENT_PRE_MICBIAS_2_OFF,
66 WCD9XXX_EVENT_POST_MICBIAS_2_OFF,
67 WCD9XXX_EVENT_PRE_MICBIAS_3_OFF,
68 WCD9XXX_EVENT_POST_MICBIAS_3_OFF,
69 WCD9XXX_EVENT_PRE_MICBIAS_4_OFF,
70 WCD9XXX_EVENT_POST_MICBIAS_4_OFF,
71 WCD9XXX_EVENT_PRE_MICBIAS_1_ON,
72 WCD9XXX_EVENT_POST_MICBIAS_1_ON,
73 WCD9XXX_EVENT_PRE_MICBIAS_2_ON,
74 WCD9XXX_EVENT_POST_MICBIAS_2_ON,
75 WCD9XXX_EVENT_PRE_MICBIAS_3_ON,
76 WCD9XXX_EVENT_POST_MICBIAS_3_ON,
77 WCD9XXX_EVENT_PRE_MICBIAS_4_ON,
78 WCD9XXX_EVENT_POST_MICBIAS_4_ON,
79
80 WCD9XXX_EVENT_PRE_CFILT_1_OFF,
81 WCD9XXX_EVENT_POST_CFILT_1_OFF,
82 WCD9XXX_EVENT_PRE_CFILT_2_OFF,
83 WCD9XXX_EVENT_POST_CFILT_2_OFF,
84 WCD9XXX_EVENT_PRE_CFILT_3_OFF,
85 WCD9XXX_EVENT_POST_CFILT_3_OFF,
86 WCD9XXX_EVENT_PRE_CFILT_1_ON,
87 WCD9XXX_EVENT_POST_CFILT_1_ON,
88 WCD9XXX_EVENT_PRE_CFILT_2_ON,
89 WCD9XXX_EVENT_POST_CFILT_2_ON,
90 WCD9XXX_EVENT_PRE_CFILT_3_ON,
91 WCD9XXX_EVENT_POST_CFILT_3_ON,
92
93 WCD9XXX_EVENT_PRE_HPHL_PA_ON,
94 WCD9XXX_EVENT_POST_HPHL_PA_OFF,
95 WCD9XXX_EVENT_PRE_HPHR_PA_ON,
96 WCD9XXX_EVENT_POST_HPHR_PA_OFF,
97
98 WCD9XXX_EVENT_POST_RESUME,
99
100 WCD9XXX_EVENT_LAST,
101};
102
103struct wcd9xxx_resmgr {
104 struct snd_soc_codec *codec;
105 struct wcd9xxx *core;
106
107 u32 rx_bias_count;
108
109 enum wcd9xxx_bandgap_type bandgap_type;
110 u16 bg_audio_users;
111 u16 bg_mbhc_users;
112
113 enum wcd9xxx_clock_type clk_type;
114 u16 clk_rco_users;
115 u16 clk_mclk_users;
116
117 /* cfilt users per cfilts */
118 u16 cfilt_users[WCD9XXX_NUM_OF_CFILT];
119
120 struct wcd9xxx_reg_address *reg_addr;
121
122 struct wcd9xxx_pdata *pdata;
123
124 struct blocking_notifier_head notifier;
125 /* Notifier needs mbhc pointer with resmgr */
126 struct wcd9xxx_mbhc *mbhc;
127
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800128 unsigned long cond_flags;
129 struct list_head update_bit_cond_h;
Joonwoo Parkccccba72013-04-26 11:19:46 -0700130 struct mutex update_bit_cond_lock;
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800131
Joonwoo Parka8890262012-10-15 12:04:27 -0700132 /*
133 * Currently, only used for mbhc purpose, to protect
134 * concurrent execution of mbhc threaded irq handlers and
135 * kill race between DAPM and MBHC. But can serve as a
136 * general lock to protect codec resource
137 */
138 struct mutex codec_resource_lock;
139};
140
141int wcd9xxx_resmgr_init(struct wcd9xxx_resmgr *resmgr,
142 struct snd_soc_codec *codec,
143 struct wcd9xxx *wcd9xxx,
144 struct wcd9xxx_pdata *pdata,
145 struct wcd9xxx_reg_address *reg_addr);
146void wcd9xxx_resmgr_deinit(struct wcd9xxx_resmgr *resmgr);
147
148int wcd9xxx_resmgr_enable_config_mode(struct snd_soc_codec *codec, int enable);
149
150void wcd9xxx_resmgr_enable_rx_bias(struct wcd9xxx_resmgr *resmgr, u32 enable);
151void wcd9xxx_resmgr_get_clk_block(struct wcd9xxx_resmgr *resmgr,
152 enum wcd9xxx_clock_type type);
153void wcd9xxx_resmgr_put_clk_block(struct wcd9xxx_resmgr *resmgr,
154 enum wcd9xxx_clock_type type);
155void wcd9xxx_resmgr_get_bandgap(struct wcd9xxx_resmgr *resmgr,
156 const enum wcd9xxx_bandgap_type choice);
157void wcd9xxx_resmgr_put_bandgap(struct wcd9xxx_resmgr *resmgr,
158 enum wcd9xxx_bandgap_type choice);
159void wcd9xxx_resmgr_cfilt_get(struct wcd9xxx_resmgr *resmgr,
160 enum wcd9xxx_cfilt_sel cfilt_sel);
161void wcd9xxx_resmgr_cfilt_put(struct wcd9xxx_resmgr *resmgr,
162 enum wcd9xxx_cfilt_sel cfilt_sel);
163
164void wcd9xxx_resmgr_bcl_lock(struct wcd9xxx_resmgr *resmgr);
Ravishankar Sarawadi839fcf32012-11-14 12:13:00 -0800165void wcd9xxx_resmgr_post_ssr(struct wcd9xxx_resmgr *resmgr);
Joonwoo Parka8890262012-10-15 12:04:27 -0700166#define WCD9XXX_BCL_LOCK(resmgr) \
167{ \
168 pr_debug("%s: Acquiring BCL\n", __func__); \
169 wcd9xxx_resmgr_bcl_lock(resmgr); \
170 pr_debug("%s: Acquiring BCL done\n", __func__); \
171}
172
173void wcd9xxx_resmgr_bcl_unlock(struct wcd9xxx_resmgr *resmgr);
174#define WCD9XXX_BCL_UNLOCK(resmgr) \
175{ \
176 pr_debug("%s: Release BCL\n", __func__); \
177 wcd9xxx_resmgr_bcl_unlock(resmgr); \
178}
179
180#define WCD9XXX_BCL_ASSERT_LOCKED(resmgr) \
181{ \
182 WARN_ONCE(!mutex_is_locked(&resmgr->codec_resource_lock), \
183 "%s: BCL should have acquired\n", __func__); \
184}
185
186const char *wcd9xxx_get_event_string(enum wcd9xxx_notify_event type);
187int wcd9xxx_resmgr_get_k_val(struct wcd9xxx_resmgr *resmgr,
188 unsigned int cfilt_mv);
189int wcd9xxx_resmgr_register_notifier(struct wcd9xxx_resmgr *resmgr,
190 struct notifier_block *nblock);
191int wcd9xxx_resmgr_unregister_notifier(struct wcd9xxx_resmgr *resmgr,
192 struct notifier_block *nblock);
193void wcd9xxx_resmgr_notifier_call(struct wcd9xxx_resmgr *resmgr,
194 const enum wcd9xxx_notify_event e);
195
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800196enum wcd9xxx_resmgr_cond {
Joonwoo Parkaf21f032013-03-05 18:07:40 -0800197 WCD9XXX_COND_HPH = 0x01, /* Headphone */
198 WCD9XXX_COND_HPH_MIC = 0x02, /* Microphone on the headset */
Joonwoo Parkcc52d472013-01-28 10:10:12 -0800199};
200int wcd9xxx_resmgr_rm_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
201 enum wcd9xxx_resmgr_cond cond,
202 unsigned short reg, int shift,
203 bool invert);
204int wcd9xxx_resmgr_add_cond_update_bits(struct wcd9xxx_resmgr *resmgr,
205 enum wcd9xxx_resmgr_cond cond,
206 unsigned short reg, int shift,
207 bool invert);
208void wcd9xxx_resmgr_cond_update_cond(struct wcd9xxx_resmgr *resmgr,
209 enum wcd9xxx_resmgr_cond cond, bool set);
210
Joonwoo Parka8890262012-10-15 12:04:27 -0700211#endif /* __WCD9XXX_COMMON_H__ */