@@ -22,6 +22,7 @@ struct pwrseq_qcom_wcn_pdata {
2222 size_t num_vregs ;
2323 unsigned int pwup_delay_ms ;
2424 unsigned int gpio_enable_delay_ms ;
25+ const struct pwrseq_target_data * * targets ;
2526};
2627
2728struct pwrseq_qcom_wcn_ctx {
@@ -31,6 +32,7 @@ struct pwrseq_qcom_wcn_ctx {
3132 struct regulator_bulk_data * regs ;
3233 struct gpio_desc * bt_gpio ;
3334 struct gpio_desc * wlan_gpio ;
35+ struct gpio_desc * xo_clk_gpio ;
3436 struct clk * clk ;
3537 unsigned long last_gpio_enable_jf ;
3638};
@@ -98,6 +100,33 @@ static const struct pwrseq_unit_data *pwrseq_qcom_wcn_unit_deps[] = {
98100 NULL
99101};
100102
103+ static int pwrseq_qcom_wcn6855_clk_assert (struct pwrseq_device * pwrseq )
104+ {
105+ struct pwrseq_qcom_wcn_ctx * ctx = pwrseq_device_get_drvdata (pwrseq );
106+
107+ if (!ctx -> xo_clk_gpio )
108+ return 0 ;
109+
110+ msleep (1 );
111+
112+ gpiod_set_value_cansleep (ctx -> xo_clk_gpio , 1 );
113+ usleep_range (100 , 200 );
114+
115+ return 0 ;
116+ }
117+
118+ static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_xo_clk_assert = {
119+ .name = "xo-clk-assert" ,
120+ .enable = pwrseq_qcom_wcn6855_clk_assert ,
121+ };
122+
123+ static const struct pwrseq_unit_data * pwrseq_qcom_wcn6855_unit_deps [] = {
124+ & pwrseq_qcom_wcn_vregs_unit_data ,
125+ & pwrseq_qcom_wcn_clk_unit_data ,
126+ & pwrseq_qcom_wcn6855_xo_clk_assert ,
127+ NULL
128+ };
129+
101130static int pwrseq_qcom_wcn_bt_enable (struct pwrseq_device * pwrseq )
102131{
103132 struct pwrseq_qcom_wcn_ctx * ctx = pwrseq_device_get_drvdata (pwrseq );
@@ -125,6 +154,13 @@ static const struct pwrseq_unit_data pwrseq_qcom_wcn_bt_unit_data = {
125154 .disable = pwrseq_qcom_wcn_bt_disable ,
126155};
127156
157+ static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_bt_unit_data = {
158+ .name = "wlan-enable" ,
159+ .deps = pwrseq_qcom_wcn6855_unit_deps ,
160+ .enable = pwrseq_qcom_wcn_bt_enable ,
161+ .disable = pwrseq_qcom_wcn_bt_disable ,
162+ };
163+
128164static int pwrseq_qcom_wcn_wlan_enable (struct pwrseq_device * pwrseq )
129165{
130166 struct pwrseq_qcom_wcn_ctx * ctx = pwrseq_device_get_drvdata (pwrseq );
@@ -152,6 +188,13 @@ static const struct pwrseq_unit_data pwrseq_qcom_wcn_wlan_unit_data = {
152188 .disable = pwrseq_qcom_wcn_wlan_disable ,
153189};
154190
191+ static const struct pwrseq_unit_data pwrseq_qcom_wcn6855_wlan_unit_data = {
192+ .name = "wlan-enable" ,
193+ .deps = pwrseq_qcom_wcn6855_unit_deps ,
194+ .enable = pwrseq_qcom_wcn_wlan_enable ,
195+ .disable = pwrseq_qcom_wcn_wlan_disable ,
196+ };
197+
155198static int pwrseq_qcom_wcn_pwup_delay (struct pwrseq_device * pwrseq )
156199{
157200 struct pwrseq_qcom_wcn_ctx * ctx = pwrseq_device_get_drvdata (pwrseq );
@@ -162,6 +205,18 @@ static int pwrseq_qcom_wcn_pwup_delay(struct pwrseq_device *pwrseq)
162205 return 0 ;
163206}
164207
208+ static int pwrseq_qcom_wcn6855_xo_clk_deassert (struct pwrseq_device * pwrseq )
209+ {
210+ struct pwrseq_qcom_wcn_ctx * ctx = pwrseq_device_get_drvdata (pwrseq );
211+
212+ if (ctx -> xo_clk_gpio ) {
213+ usleep_range (2000 , 5000 );
214+ gpiod_set_value_cansleep (ctx -> xo_clk_gpio , 0 );
215+ }
216+
217+ return pwrseq_qcom_wcn_pwup_delay (pwrseq );
218+ }
219+
165220static const struct pwrseq_target_data pwrseq_qcom_wcn_bt_target_data = {
166221 .name = "bluetooth" ,
167222 .unit = & pwrseq_qcom_wcn_bt_unit_data ,
@@ -174,12 +229,30 @@ static const struct pwrseq_target_data pwrseq_qcom_wcn_wlan_target_data = {
174229 .post_enable = pwrseq_qcom_wcn_pwup_delay ,
175230};
176231
232+ static const struct pwrseq_target_data pwrseq_qcom_wcn6855_bt_target_data = {
233+ .name = "bluetooth" ,
234+ .unit = & pwrseq_qcom_wcn6855_bt_unit_data ,
235+ .post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert ,
236+ };
237+
238+ static const struct pwrseq_target_data pwrseq_qcom_wcn6855_wlan_target_data = {
239+ .name = "wlan" ,
240+ .unit = & pwrseq_qcom_wcn6855_wlan_unit_data ,
241+ .post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert ,
242+ };
243+
177244static const struct pwrseq_target_data * pwrseq_qcom_wcn_targets [] = {
178245 & pwrseq_qcom_wcn_bt_target_data ,
179246 & pwrseq_qcom_wcn_wlan_target_data ,
180247 NULL
181248};
182249
250+ static const struct pwrseq_target_data * pwrseq_qcom_wcn6855_targets [] = {
251+ & pwrseq_qcom_wcn6855_bt_target_data ,
252+ & pwrseq_qcom_wcn6855_wlan_target_data ,
253+ NULL
254+ };
255+
183256static const char * const pwrseq_qca6390_vregs [] = {
184257 "vddio" ,
185258 "vddaon" ,
@@ -196,13 +269,28 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_qca6390_of_data = {
196269 .num_vregs = ARRAY_SIZE (pwrseq_qca6390_vregs ),
197270 .pwup_delay_ms = 60 ,
198271 .gpio_enable_delay_ms = 100 ,
272+ .targets = pwrseq_qcom_wcn_targets ,
273+ };
274+
275+ static const char * const pwrseq_wcn6855_vregs [] = {
276+ "vddio" ,
277+ "vddaon" ,
278+ "vddpmu" ,
279+ "vddpmumx" ,
280+ "vddpmucx" ,
281+ "vddrfa0p95" ,
282+ "vddrfa1p3" ,
283+ "vddrfa1p9" ,
284+ "vddpcie1p3" ,
285+ "vddpcie1p9" ,
199286};
200287
201288static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn6855_of_data = {
202- .vregs = pwrseq_qca6390_vregs ,
203- .num_vregs = ARRAY_SIZE (pwrseq_qca6390_vregs ),
289+ .vregs = pwrseq_wcn6855_vregs ,
290+ .num_vregs = ARRAY_SIZE (pwrseq_wcn6855_vregs ),
204291 .pwup_delay_ms = 50 ,
205292 .gpio_enable_delay_ms = 5 ,
293+ .targets = pwrseq_qcom_wcn6855_targets ,
206294};
207295
208296static const char * const pwrseq_wcn7850_vregs [] = {
@@ -219,6 +307,7 @@ static const struct pwrseq_qcom_wcn_pdata pwrseq_wcn7850_of_data = {
219307 .vregs = pwrseq_wcn7850_vregs ,
220308 .num_vregs = ARRAY_SIZE (pwrseq_wcn7850_vregs ),
221309 .pwup_delay_ms = 50 ,
310+ .targets = pwrseq_qcom_wcn_targets ,
222311};
223312
224313static int pwrseq_qcom_wcn_match (struct pwrseq_device * pwrseq ,
@@ -295,6 +384,12 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
295384 return dev_err_probe (dev , PTR_ERR (ctx -> wlan_gpio ),
296385 "Failed to get the WLAN enable GPIO\n" );
297386
387+ ctx -> xo_clk_gpio = devm_gpiod_get_optional (dev , "xo-clk" ,
388+ GPIOD_OUT_LOW );
389+ if (IS_ERR (ctx -> xo_clk_gpio ))
390+ return dev_err_probe (dev , PTR_ERR (ctx -> xo_clk_gpio ),
391+ "Failed to get the XO_CLK GPIO\n" );
392+
298393 /*
299394 * Set direction to output but keep the current value in order to not
300395 * disable the WLAN module accidentally if it's already powered on.
@@ -313,7 +408,7 @@ static int pwrseq_qcom_wcn_probe(struct platform_device *pdev)
313408 config .owner = THIS_MODULE ;
314409 config .drvdata = ctx ;
315410 config .match = pwrseq_qcom_wcn_match ;
316- config .targets = pwrseq_qcom_wcn_targets ;
411+ config .targets = ctx -> pdata -> targets ;
317412
318413 ctx -> pwrseq = devm_pwrseq_device_register (dev , & config );
319414 if (IS_ERR (ctx -> pwrseq ))
0 commit comments