xref: /openbmc/linux/drivers/nfc/s3fwrn5/phy_common.c (revision cdd38c5f1ce4398ec58fec95904b75824daab7b5)
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