blob: 7ef3dc624915a8d9060325f0720a326959c99f9b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * PCIe rfkill driver for ASR1803 SoCs
4 *
5 * Copyright (c) 2021 ASRMicro Inc.
6 */
7
8#include <linux/debugfs.h>
9#include <linux/device.h>
10
11#include <linux/err.h>
12#include <linux/slab.h>
13#include <linux/delay.h>
14#include <linux/platform_device.h>
15#include <linux/pci.h>
16#include <linux/pcie8x_rfkill.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/clk.h>
20#include <linux/of_device.h>
21#include <linux/of_gpio.h>
22#include <linux/of_platform.h>
23#include <linux/edge_wakeup_mmp.h>
24#include <linux/regulator/consumer.h>
25
26#define PCIE8X_DEV_NAME "pcie-rfkill"
27
28static DEFINE_MUTEX(pcie8x_pwr_mutex);
29
30static void pcie_rfkill_plat_data_init(
31 struct pcie_rfkill_plat_data *pdata)
32{
33 /* all intems are invalid just after alloc */
34 pdata->gpio_power_down = -1; /* alias of wlan_en */
35 pdata->gpio_reset = -1;
36 pdata->gpio_reset2 = -1;
37 pdata->gpio_edge_wakeup = -1;
38 pdata->gpio_3v3_en = -1;
39 pdata->gpio_1v8_en = -1;
40 pdata->gpio2_3v3_en = -1;
41 pdata->gpio2_1v8_en = -1;
42 pdata->edge_requested = 0;
43 /* power status, unknown status at first */
44 pdata->is_on = -1;
45 pdata->is_on2 = -1;
46}
47
48static struct pcie_rfkill_plat_data
49 *pcie_rfkill_plat_data_alloc(struct platform_device *pdev)
50{
51 struct pcie_rfkill_plat_data *pdata;
52
53 /* create a new one and init it */
54 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
55 if (pdata) {
56 pcie_rfkill_plat_data_init(pdata);
57 return pdata;
58 }
59
60 return NULL;
61}
62
63static int pcie_3v3_1v8_ctrl(int gpio_3v3_en, int gpio_1v8_en, int on)
64{
65 if (gpio_3v3_en >= 0) {
66 if (gpio_request(gpio_3v3_en, "pcie_wlan 3v3 on")) {
67 pr_err("gpio %d request failed\n", gpio_3v3_en);
68 return -1;
69 } else {
70 if (on)
71 gpio_direction_output(gpio_3v3_en, 1);
72 else
73 gpio_direction_output(gpio_3v3_en, 0);
74 gpio_free(gpio_3v3_en);
75 }
76 }
77
78 if (gpio_1v8_en >= 0) {
79 if (gpio_request(gpio_1v8_en, "pcie_wlan 1v8 on")) {
80 pr_err("gpio %d request failed\n", gpio_1v8_en);
81 return -1;
82 } else {
83 if (on)
84 gpio_direction_output(gpio_1v8_en, 1);
85 else
86 gpio_direction_output(gpio_1v8_en, 0);
87 gpio_free(gpio_1v8_en);
88 }
89 }
90 return 0;
91}
92
93static void pcie_regulator(struct pcie_rfkill_plat_data *pdata, int on)
94{
95 if (on) {
96 if (pdata->wib_3v3) {
97 if (regulator_set_voltage(pdata->wib_3v3, 3300000, 3300000))
98 printk(KERN_DEBUG "fail to set regulator wib_3v3 to 3.3v\n");
99 if (!regulator_is_enabled(pdata->wib_3v3)) {
100 if (regulator_enable(pdata->wib_3v3))
101 printk(KERN_DEBUG "fail to enable regulator wib_3v3\n");
102 }
103 }
104 } else {
105 if (pdata->wib_3v3) {
106 if (regulator_is_enabled(pdata->wib_3v3)) {
107 if (regulator_disable(pdata->wib_3v3))
108 printk(KERN_DEBUG "fail to disable regulator wib_3v3\n");
109 }
110 }
111 }
112}
113
114static int slot0_pwr_ctrl(struct pcie_rfkill_plat_data *pdata, int on)
115{
116 int gpio_reset = pdata->gpio_reset;
117
118 if(gpio_reset < 0){
119 return -1;
120 }
121 if (on) {
122 if (!gpio_request(gpio_reset, "pcie_dev reset")) {
123 gpio_direction_output(gpio_reset, 0);
124 gpio_free(gpio_reset);
125 } else {
126 pr_err("pcie slot0 perst request failed %d.\n",
127 gpio_reset);
128 }
129 mdelay(10);
130 pcie_3v3_1v8_ctrl(pdata->gpio_3v3_en, pdata->gpio_1v8_en, 0);
131 mdelay(50);
132 pcie_3v3_1v8_ctrl(pdata->gpio_3v3_en, pdata->gpio_1v8_en, 1);
133 mdelay(10);
134 } else {
135 pcie_3v3_1v8_ctrl(pdata->gpio_3v3_en, pdata->gpio_1v8_en, 0);
136 if (!gpio_request(gpio_reset, "pcie_dev reset")) {
137 gpio_direction_output(gpio_reset, 0);
138 gpio_free(gpio_reset);
139 } else {
140 pr_err("pcie slot0 perst request failed %d.\n",
141 gpio_reset);
142 }
143 msleep(500); /*Toff-time, min: 500*/
144 }
145
146 return 0;
147}
148
149static int slot1_pwr_ctrl(struct pcie_rfkill_plat_data *pdata, int on)
150{
151 int gpio_reset2 = pdata->gpio_reset2;
152
153 if(gpio_reset2 < 0){
154 return -1;
155 }
156 if (on) {
157 if (!gpio_request(gpio_reset2, "pcie_dev reset")) {
158 gpio_direction_output(gpio_reset2, 0);
159 gpio_free(gpio_reset2);
160 } else {
161 pr_err("pcie slot1 perst request failed %d.\n",
162 gpio_reset2);
163 }
164 mdelay(10);
165 pcie_3v3_1v8_ctrl(pdata->gpio2_3v3_en, pdata->gpio2_1v8_en, 0);
166 mdelay(50);
167 pcie_3v3_1v8_ctrl(pdata->gpio2_3v3_en, pdata->gpio2_1v8_en, 1);
168 mdelay(10);
169 } else {
170 pcie_3v3_1v8_ctrl(pdata->gpio2_3v3_en, pdata->gpio2_1v8_en, 0);
171 if (!gpio_request(gpio_reset2, "pcie_dev reset")) {
172 gpio_direction_output(gpio_reset2, 0);
173 gpio_free(gpio_reset2);
174 } else {
175 pr_err("pcie slot1 perst gpio request failed %d.\n",
176 gpio_reset2);
177 }
178 msleep(500); /*Toff-time, min: 500*/
179 }
180
181 return 0;
182}
183
184static int pcie_slot1_pwr_on(struct pcie_rfkill_plat_data *pdata)
185{
186 int ret = 0;
187
188 if (pdata->is_on2)
189 return 0;
190
191 pr_info("%s: on=%d\n", __func__, 1);
192 pcie_regulator(pdata, 1);
193 slot1_pwr_ctrl(pdata, 1);
194 pdata->is_on2 = 1;
195 pr_info("pcie_dev set_power on end\n");
196
197 return ret;
198}
199
200static int pcie_slot1_pwr_off(struct pcie_rfkill_plat_data *pdata)
201{
202 int ret = 0;
203
204 if (!pdata->is_on2)
205 return 0;
206
207 pr_info("pcie slot1 set_power off start\n");
208 slot1_pwr_ctrl(pdata, 0);
209 pcie_regulator(pdata, 0);
210 pdata->is_on2 = 0;
211 pr_info("pcie_dev set_power off end\n");
212
213 return ret;
214}
215
216static int pcie_slot0_pwr_on(struct pcie_rfkill_plat_data *pdata)
217{
218 int ret = 0;
219
220 if (pdata->is_on)
221 return 0;
222
223 pr_info("%s: on=%d\n", __func__, 1);
224 pcie_regulator(pdata, 1);
225 slot0_pwr_ctrl(pdata, 1);
226 pdata->is_on = 1;
227 pr_info("pcie_dev set_power on end\n");
228
229 return ret;
230}
231
232static int pcie_slot0_pwr_off(struct pcie_rfkill_plat_data *pdata)
233{
234 int ret = 0;
235
236 if (!pdata->is_on)
237 return 0;
238
239 pr_info("pcie slot0 set_power off start\n");
240 slot0_pwr_ctrl(pdata, 0);
241 pcie_regulator(pdata, 0);
242 pdata->is_on = 0;
243 pr_info("pcie_dev set_power off end\n");
244
245 return ret;
246}
247
248static ssize_t pcie_slot0_pwr_show(struct device *dev,
249 struct device_attribute *attr, char *buf)
250{
251 int len = 0;
252 struct pcie_rfkill_plat_data *pdata = dev->platform_data;
253
254 mutex_lock(&pcie8x_pwr_mutex);
255 len = sprintf(buf, "PCIe Device is power %s\n",
256 pdata->is_on ? "on" : "off");
257 mutex_unlock(&pcie8x_pwr_mutex);
258
259 return (ssize_t)len;
260}
261
262static ssize_t pcie_slot0_pwr_store(struct device *dev,
263 struct device_attribute *attr, const char *buf, size_t size)
264{
265 int pwr_ctrl;
266 int valid_ctrl = 0;
267 struct pcie_rfkill_plat_data *pdata = dev->platform_data;
268
269 mutex_lock(&pcie8x_pwr_mutex);
270 if (sscanf(buf, "%d", &pwr_ctrl) == 1) {
271 if ((pwr_ctrl == 1) || (pwr_ctrl == 0))
272 valid_ctrl = 1;
273 }
274
275 if (valid_ctrl != 1) {
276 pr_err("Please input valid ctrl: 0: Close, 1: Open\n");
277 mutex_unlock(&pcie8x_pwr_mutex);
278 return size;
279 }
280 if (pwr_ctrl)
281 pcie_slot0_pwr_on(pdata);
282 else
283 pcie_slot0_pwr_off(pdata);
284
285 pr_info("Now PCIe Device is power %s\n", pdata->is_on ? "on" : "off");
286 mutex_unlock(&pcie8x_pwr_mutex);
287
288 return size;
289}
290
291static ssize_t pcie_slot1_pwr_show(struct device *dev,
292 struct device_attribute *attr, char *buf)
293{
294 int len = 0;
295 struct pcie_rfkill_plat_data *pdata = dev->platform_data;
296
297 mutex_lock(&pcie8x_pwr_mutex);
298 len = sprintf(buf, "PCIe Device is power %s\n",
299 pdata->is_on2 ? "on" : "off");
300 mutex_unlock(&pcie8x_pwr_mutex);
301
302 return (ssize_t)len;
303}
304
305static ssize_t pcie_slot1_pwr_store(struct device *dev,
306 struct device_attribute *attr, const char *buf, size_t size)
307{
308 int pwr_ctrl;
309 int valid_ctrl = 0;
310 struct pcie_rfkill_plat_data *pdata = dev->platform_data;
311
312 mutex_lock(&pcie8x_pwr_mutex);
313 if (sscanf(buf, "%d", &pwr_ctrl) == 1) {
314 if ((pwr_ctrl == 1) || (pwr_ctrl == 0))
315 valid_ctrl = 1;
316 }
317
318 if (valid_ctrl != 1) {
319 pr_err("Please input valid ctrl: 0: Close, 1: Open\n");
320 mutex_unlock(&pcie8x_pwr_mutex);
321 return size;
322 }
323 if (pwr_ctrl)
324 pcie_slot1_pwr_on(pdata);
325 else
326 pcie_slot1_pwr_off(pdata);
327
328 pr_info("Now PCIe Device is power %s\n", pdata->is_on2 ? "on" : "off");
329 mutex_unlock(&pcie8x_pwr_mutex);
330
331 return size;
332}
333
334static DEVICE_ATTR(pwr_ctrl2, 0660,
335 pcie_slot1_pwr_show, pcie_slot1_pwr_store);
336static DEVICE_ATTR(pwr_ctrl, 0660,
337 pcie_slot0_pwr_show, pcie_slot0_pwr_store);
338
339#ifdef CONFIG_OF
340static const struct of_device_id pcie8x_rfkill_of_match[] = {
341 {
342 .compatible = "mrvl,pcie-rfkill",
343 },
344 {},
345};
346
347MODULE_DEVICE_TABLE(of, pcie8x_rfkill_of_match);
348
349static int pcie8x_rfkill_probe_dt(struct platform_device *pdev)
350{
351 struct device_node *np = pdev->dev.of_node;
352 struct pcie_rfkill_plat_data *pdata = pdev->dev.platform_data;
353 const char *wifi_device;
354 struct regulator *wib_3v3;
355 int gpio;
356
357 /* Get PD/RST pins status */
358 pdata->pinctrl = devm_pinctrl_get(&pdev->dev);
359 if (IS_ERR(pdata->pinctrl)) {
360 pdata->pinctrl = NULL;
361 dev_warn(&pdev->dev, "could not get PD/RST pinctrl.\n");
362 } else {
363 pdata->pin_off = pinctrl_lookup_state(pdata->pinctrl, "off");
364 if (IS_ERR(pdata->pin_off)) {
365 pdata->pin_off = NULL;
366 dev_err(&pdev->dev, "could not get off pinstate.\n");
367 }
368
369 pdata->pin_on = pinctrl_lookup_state(pdata->pinctrl, "on");
370 if (IS_ERR(pdata->pin_on)) {
371 pdata->pin_on = NULL;
372 dev_err(&pdev->dev, "could not get on pinstate.\n");
373 }
374 }
375
376 if (pdata->pinctrl && pdata->pin_off)
377 pinctrl_select_state(pdata->pinctrl, pdata->pin_off);
378
379 gpio = of_get_named_gpio(np, "rst-gpio", 0);
380 if (unlikely(gpio < 0)) {
381 pr_debug("pcie rfkill: rst-gpio undefined\n");
382 pdata->gpio_reset = -1;
383 } else {
384 pdata->gpio_reset = gpio;
385 }
386 gpio = of_get_named_gpio(np, "rst-gpio2", 0);
387 if (unlikely(gpio < 0)) {
388 pr_debug("pcie rfkill: rst-gpio2 undefined\n");
389 pdata->gpio_reset2 = -1;
390 } else {
391 pdata->gpio_reset2 = gpio;
392 }
393
394 gpio = of_get_named_gpio(np, "3v3-ldo-gpio", 0);
395 if (unlikely(gpio < 0)) {
396 pr_debug("pcie rfkill: 3v3-ldo-gpio undefined\n");
397 pdata->gpio_3v3_en = -1;
398 } else {
399 pdata->gpio_3v3_en = gpio;
400 }
401 gpio = of_get_named_gpio(np, "3v3-ldo-gpio2", 0);
402 if (unlikely(gpio < 0)) {
403 pr_debug("pcie rfkill: 3v3-ldo-gpio2 undefined\n");
404 pdata->gpio2_3v3_en = -1;
405 } else {
406 pdata->gpio2_3v3_en = gpio;
407 }
408
409 gpio = of_get_named_gpio(np, "1v8-ldo-gpio", 0);
410 if (unlikely(gpio < 0)) {
411 pr_debug("pcie rfkill: 1v8-ldo-gpio undefined\n");
412 pdata->gpio_1v8_en = -1;
413 } else {
414 pdata->gpio_1v8_en = gpio;
415 }
416 gpio = of_get_named_gpio(np, "1v8-ldo-gpio2", 0);
417 if (unlikely(gpio < 0)) {
418 pr_debug("pcie rfkill: 1v8-ldo-gpio2 undefined\n");
419 pdata->gpio2_1v8_en = -1;
420 } else {
421 pdata->gpio2_1v8_en = gpio;
422 }
423
424 if (of_property_read_string(np, "wifi-device", &wifi_device)) {
425 wifi_device = "dummy";
426 }
427
428 if (strcmp(wifi_device, "slot1") == 0)
429 pdata->pwr_ctrl = slot1_pwr_ctrl;
430 else if (strcmp(wifi_device, "slot0") == 0)
431 pdata->pwr_ctrl = slot0_pwr_ctrl;
432 else
433 pdata->pwr_ctrl = slot0_pwr_ctrl;
434
435 /* get regulators from dt */
436 wib_3v3 = regulator_get_optional(&pdev->dev, "wib_3v3");
437 if (IS_ERR_OR_NULL(wib_3v3)) {
438 printk(KERN_DEBUG "%s: the regulator for wib_3v3 not found\n",
439 __func__);
440 } else {
441 pdata->wib_3v3 = wib_3v3;
442 }
443 return 0;
444}
445#else
446static int pcie8x_rfkill_probe_dt(struct platform_device *pdev)
447{
448 return 0;
449}
450#endif
451
452static int pcie8x_rfkill_probe(struct platform_device *pdev)
453{
454 struct pcie_rfkill_plat_data *pdata = NULL;
455 /* flag: whether pdata is passed from platfrom_data */
456 int pdata_passed = 1;
457 const struct of_device_id *match = NULL;
458 int ret = -1;
459
460 /* make sure pcie_rfkill_plat_data is valid */
461 pdata = pdev->dev.platform_data;
462 if (!pdata) {
463 /* if platfrom data do not pass the struct to us */
464 pdata_passed = 0;
465 pdata = pcie_rfkill_plat_data_alloc(pdev);
466
467 if (!pdata) {
468 pr_err("can't get pcie_rfkill_plat_data struct during probe\n");
469 goto err_pdata;
470 }
471 pdev->dev.platform_data = pdata;
472 }
473
474 /* set value to pcie_rfkill_plat_data if DT pass them to us */
475#ifdef CONFIG_OF
476 match = of_match_device(of_match_ptr(pcie8x_rfkill_of_match),
477 &pdev->dev);
478#endif
479 if (match) {
480 ret = pcie8x_rfkill_probe_dt(pdev);
481 if (ret)
482 goto err_dt;
483 }
484
485 pdata->is_on = 0;
486 pdata->is_on2 = 0;
487
488 pcie_slot0_pwr_off(pdata);
489 pcie_slot1_pwr_off(pdata);
490 mdelay(100);
491 pcie_slot0_pwr_on(pdata);
492 pcie_slot1_pwr_on(pdata);
493
494 device_create_file(&pdev->dev, &dev_attr_pwr_ctrl);
495 device_create_file(&pdev->dev, &dev_attr_pwr_ctrl2);
496 return 0;
497
498err_dt:
499 if (!pdata_passed)
500 pdev->dev.platform_data = NULL;
501err_pdata:
502
503 return ret;
504}
505
506static int pcie8x_rfkill_suspend(struct platform_device *pdev,
507 pm_message_t pm_state)
508{
509 return 0;
510}
511
512static int pcie8x_rfkill_resume(struct platform_device *pdev)
513{
514 return 0;
515}
516
517static struct platform_driver pcie8x_rfkill_platform_driver = {
518 .probe = pcie8x_rfkill_probe,
519 .driver = {
520 .name = PCIE8X_DEV_NAME,
521 .owner = THIS_MODULE,
522#ifdef CONFIG_OF
523 .of_match_table = pcie8x_rfkill_of_match,
524#endif
525 },
526 .suspend = pcie8x_rfkill_suspend,
527 .resume = pcie8x_rfkill_resume,
528};
529
530static int __init pcie8x_rfkill_init(void)
531{
532 return platform_driver_register(&pcie8x_rfkill_platform_driver);
533}
534device_initcall(pcie8x_rfkill_init);