1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
#include <linux/init.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <soc/sprd/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include <soc/sprd/regulator.h>
#include <linux/clk.h>
#include <linux/gpio.h>
static struct device *gps_dev;
extern struct class *sec_class;
static void gps_clk_init(void)
{
struct clk *gps_clk;
struct clk *clk_parent;
const char *clk_32k= "clk_aux0";
gps_clk = clk_get(NULL, clk_32k);
if (IS_ERR(gps_clk)) {
printk("clock: failed to get clk_aux0\n");
}
clk_parent = clk_get(NULL, "ext_32k");
if (IS_ERR(clk_parent)) {
printk("failed to get parent ext_32k\n");
}
clk_set_parent(gps_clk, clk_parent);
clk_set_rate(gps_clk, 32000);
if(!clk_prepare_enable(gps_clk))
printk("%s: %s enabled!!\n", __func__, clk_32k);
//clk_enable(gps_clk);
}
static int gps_regulator_on(void)
{
int ret = 0;
const char *gps_node = "lsi,s5n6420";
struct device_node *root_node = NULL;
static struct regulator *gps_regulator = NULL;
const char *reg = NULL;
root_node = of_find_compatible_node(NULL, NULL, gps_node);
if(!root_node) {
WARN(1, "[GPS] failed to get device node of %s\n", gps_node);
return -ENODEV;
}
/* regulator enable from dts */
if(of_property_read_string(root_node, "gps-regulator", ®)) {
pr_err("%s: main(1.8v) regulator field is not exsit\n", __func__);
ret = -ENODEV;
goto err_find_node;
} else {
gps_regulator = regulator_get(NULL, reg);
if (IS_ERR(gps_regulator)){
gps_regulator = NULL;
return -EIO;
} else {
regulator_set_voltage(gps_regulator, 1800000, 1800000);
if(!regulator_enable(gps_regulator))
printk("%s: (%s) main(1.8v) regulator turned ON!!\n", __func__, reg);
}
}
return 0;
err_find_node:
of_node_put(root_node);
return ret;
}
static unsigned int gps_pwr_on = 0;
static unsigned int gps_reset = 0;
static int __init gps_s5n6420_init(void)
{
pr_info("%s\n", __func__);
gps_regulator_on();
gps_clk_init();
int ret = 0;
const char *gps_node = "lsi,s5n6420";
const char *gps_pwr_en = "gps-pwr-en";
const char *gps_nRst = "gps-reset";
struct device_node *root_node = NULL;
BUG_ON(!sec_class);
gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
BUG_ON(!gps_dev);
root_node = of_find_compatible_node(NULL, NULL, gps_node);
if(!root_node) {
WARN(1, "failed to get device node of bcm4752\n");
ret = -ENODEV;
goto err_sec_device_create;
}
gps_pwr_on = of_get_named_gpio(root_node, gps_pwr_en, 0);
if(!gpio_is_valid(gps_pwr_on)) {
WARN(1, "Invalid gpio pin : %d\n", gps_pwr_on);
ret = -ENODEV;
goto err_find_node;
}
if (gpio_request(gps_pwr_on, "GPS_PWR_EN")) {
WARN(1, "fail to request gpio(GPS_PWR_EN)\n");
ret = -ENODEV;
goto err_find_node;
}
gps_reset= of_get_named_gpio(root_node, gps_nRst, 0);
if(!gpio_is_valid(gps_reset)) {
WARN(1, "Invalid gpio pin : %d\n", gps_reset);
ret = -ENODEV;
goto err_find_node;
}
if (gpio_request(gps_reset, "GPS_RESET")) {
WARN(1, "fail to request gpio(GPS_RESET)\n");
ret = -ENODEV;
goto err_find_node;
}
gpio_direction_output(gps_pwr_on, 0);
gpio_export(gps_pwr_on, 1);
gpio_export_link(gps_dev, "GPS_PWR_EN", gps_pwr_on);
gpio_direction_output(gps_reset, 1);
gpio_export(gps_reset, 1);
gpio_export_link(gps_dev, "GPS_RESET", gps_reset);
return 0;
err_find_node:
of_node_put(root_node);
err_sec_device_create:
device_destroy(gps_dev, gps_dev->devt);
return ret;
}
device_initcall(gps_s5n6420_init);
|