1b3799d59SBongsu Jeon // SPDX-License-Identifier: GPL-2.0-or-later
2b3799d59SBongsu Jeon /*
3b3799d59SBongsu Jeon * Link Layer for Samsung S3FWRN5 NCI based Driver
4b3799d59SBongsu Jeon *
5b3799d59SBongsu Jeon * Copyright (C) 2015 Samsung Electrnoics
6b3799d59SBongsu Jeon * Robert Baldyga <r.baldyga@samsung.com>
7b3799d59SBongsu Jeon * Copyright (C) 2020 Samsung Electrnoics
8b3799d59SBongsu Jeon * Bongsu Jeon <bongsu.jeon@samsung.com>
9b3799d59SBongsu Jeon */
10b3799d59SBongsu Jeon
11b3799d59SBongsu Jeon #include <linux/gpio.h>
12b3799d59SBongsu Jeon #include <linux/delay.h>
13b3799d59SBongsu Jeon #include <linux/module.h>
14b3799d59SBongsu Jeon
15b3799d59SBongsu Jeon #include "phy_common.h"
16b3799d59SBongsu Jeon
s3fwrn5_phy_set_wake(void * phy_id,bool wake)17b3799d59SBongsu Jeon void s3fwrn5_phy_set_wake(void *phy_id, bool wake)
18b3799d59SBongsu Jeon {
19b3799d59SBongsu Jeon struct phy_common *phy = phy_id;
20b3799d59SBongsu Jeon
21b3799d59SBongsu Jeon mutex_lock(&phy->mutex);
22b3799d59SBongsu Jeon gpio_set_value(phy->gpio_fw_wake, wake);
23*7ec27c9eSBongsu Jeon if (wake)
24b3799d59SBongsu Jeon msleep(S3FWRN5_EN_WAIT_TIME);
25b3799d59SBongsu Jeon mutex_unlock(&phy->mutex);
26b3799d59SBongsu Jeon }
27b3799d59SBongsu Jeon EXPORT_SYMBOL(s3fwrn5_phy_set_wake);
28b3799d59SBongsu Jeon
s3fwrn5_phy_power_ctrl(struct phy_common * phy,enum s3fwrn5_mode mode)29b3799d59SBongsu Jeon bool s3fwrn5_phy_power_ctrl(struct phy_common *phy, enum s3fwrn5_mode mode)
30b3799d59SBongsu Jeon {
31b3799d59SBongsu Jeon if (phy->mode == mode)
32b3799d59SBongsu Jeon return false;
33b3799d59SBongsu Jeon
34b3799d59SBongsu Jeon phy->mode = mode;
35b3799d59SBongsu Jeon
36b3799d59SBongsu Jeon gpio_set_value(phy->gpio_en, 1);
37b3799d59SBongsu Jeon gpio_set_value(phy->gpio_fw_wake, 0);
38b3799d59SBongsu Jeon if (mode == S3FWRN5_MODE_FW)
39b3799d59SBongsu Jeon gpio_set_value(phy->gpio_fw_wake, 1);
40b3799d59SBongsu Jeon
41b3799d59SBongsu Jeon if (mode != S3FWRN5_MODE_COLD) {
42b3799d59SBongsu Jeon msleep(S3FWRN5_EN_WAIT_TIME);
43b3799d59SBongsu Jeon gpio_set_value(phy->gpio_en, 0);
44b3799d59SBongsu Jeon msleep(S3FWRN5_EN_WAIT_TIME);
45b3799d59SBongsu Jeon }
46b3799d59SBongsu Jeon
47b3799d59SBongsu Jeon return true;
48b3799d59SBongsu Jeon }
49b3799d59SBongsu Jeon EXPORT_SYMBOL(s3fwrn5_phy_power_ctrl);
50b3799d59SBongsu Jeon
s3fwrn5_phy_set_mode(void * phy_id,enum s3fwrn5_mode mode)513f52c2cbSBongsu Jeon void s3fwrn5_phy_set_mode(void *phy_id, enum s3fwrn5_mode mode)
523f52c2cbSBongsu Jeon {
533f52c2cbSBongsu Jeon struct phy_common *phy = phy_id;
543f52c2cbSBongsu Jeon
553f52c2cbSBongsu Jeon mutex_lock(&phy->mutex);
563f52c2cbSBongsu Jeon
573f52c2cbSBongsu Jeon s3fwrn5_phy_power_ctrl(phy, mode);
583f52c2cbSBongsu Jeon
593f52c2cbSBongsu Jeon mutex_unlock(&phy->mutex);
603f52c2cbSBongsu Jeon }
613f52c2cbSBongsu Jeon EXPORT_SYMBOL(s3fwrn5_phy_set_mode);
623f52c2cbSBongsu Jeon
s3fwrn5_phy_get_mode(void * phy_id)63b3799d59SBongsu Jeon enum s3fwrn5_mode s3fwrn5_phy_get_mode(void *phy_id)
64b3799d59SBongsu Jeon {
65b3799d59SBongsu Jeon struct phy_common *phy = phy_id;
66b3799d59SBongsu Jeon enum s3fwrn5_mode mode;
67b3799d59SBongsu Jeon
68b3799d59SBongsu Jeon mutex_lock(&phy->mutex);
69b3799d59SBongsu Jeon
70b3799d59SBongsu Jeon mode = phy->mode;
71b3799d59SBongsu Jeon
72b3799d59SBongsu Jeon mutex_unlock(&phy->mutex);
73b3799d59SBongsu Jeon
74b3799d59SBongsu Jeon return mode;
75b3799d59SBongsu Jeon }
76b3799d59SBongsu Jeon EXPORT_SYMBOL(s3fwrn5_phy_get_mode);
77