1 // SPDX-License-Identifier: GPL-2.0-only
3 * Qualcomm Wireless Connectivity Subsystem Iris driver
5 * Copyright (C) 2016 Linaro Ltd
6 * Copyright (C) 2014 Sony Mobile Communications AB
7 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
10 #include <linux/clk.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
14 #include <linux/of_device.h>
15 #include <linux/platform_device.h>
16 #include <linux/regulator/consumer.h>
18 #include "qcom_wcnss.h"
25 struct regulator_bulk_data
*vregs
;
30 const struct wcnss_vreg_info
*vregs
;
36 static const struct iris_data wcn3620_data
= {
37 .vregs
= (struct wcnss_vreg_info
[]) {
38 { "vddxo", 1800000, 1800000, 10000 },
39 { "vddrfa", 1300000, 1300000, 100000 },
40 { "vddpa", 3300000, 3300000, 515000 },
41 { "vdddig", 1800000, 1800000, 10000 },
44 .use_48mhz_xo
= false,
47 static const struct iris_data wcn3660_data
= {
48 .vregs
= (struct wcnss_vreg_info
[]) {
49 { "vddxo", 1800000, 1800000, 10000 },
50 { "vddrfa", 1300000, 1300000, 100000 },
51 { "vddpa", 2900000, 3000000, 515000 },
52 { "vdddig", 1200000, 1225000, 10000 },
58 static const struct iris_data wcn3680_data
= {
59 .vregs
= (struct wcnss_vreg_info
[]) {
60 { "vddxo", 1800000, 1800000, 10000 },
61 { "vddrfa", 1300000, 1300000, 100000 },
62 { "vddpa", 3300000, 3300000, 515000 },
63 { "vdddig", 1800000, 1800000, 10000 },
69 int qcom_iris_enable(struct qcom_iris
*iris
)
73 ret
= regulator_bulk_enable(iris
->num_vregs
, iris
->vregs
);
77 ret
= clk_prepare_enable(iris
->xo_clk
);
79 dev_err(&iris
->dev
, "failed to enable xo clk\n");
80 goto disable_regulators
;
86 regulator_bulk_disable(iris
->num_vregs
, iris
->vregs
);
91 void qcom_iris_disable(struct qcom_iris
*iris
)
93 clk_disable_unprepare(iris
->xo_clk
);
94 regulator_bulk_disable(iris
->num_vregs
, iris
->vregs
);
97 static const struct of_device_id iris_of_match
[] = {
98 { .compatible
= "qcom,wcn3620", .data
= &wcn3620_data
},
99 { .compatible
= "qcom,wcn3660", .data
= &wcn3660_data
},
100 { .compatible
= "qcom,wcn3660b", .data
= &wcn3680_data
},
101 { .compatible
= "qcom,wcn3680", .data
= &wcn3680_data
},
105 static void qcom_iris_release(struct device
*dev
)
107 struct qcom_iris
*iris
= container_of(dev
, struct qcom_iris
, dev
);
109 of_node_put(iris
->dev
.of_node
);
113 struct qcom_iris
*qcom_iris_probe(struct device
*parent
, bool *use_48mhz_xo
)
115 const struct of_device_id
*match
;
116 const struct iris_data
*data
;
117 struct device_node
*of_node
;
118 struct qcom_iris
*iris
;
122 of_node
= of_get_child_by_name(parent
->of_node
, "iris");
124 dev_err(parent
, "No child node \"iris\" found\n");
125 return ERR_PTR(-EINVAL
);
128 iris
= kzalloc(sizeof(*iris
), GFP_KERNEL
);
130 of_node_put(of_node
);
131 return ERR_PTR(-ENOMEM
);
134 device_initialize(&iris
->dev
);
135 iris
->dev
.parent
= parent
;
136 iris
->dev
.release
= qcom_iris_release
;
137 iris
->dev
.of_node
= of_node
;
139 dev_set_name(&iris
->dev
, "%s.iris", dev_name(parent
));
141 ret
= device_add(&iris
->dev
);
143 put_device(&iris
->dev
);
147 match
= of_match_device(iris_of_match
, &iris
->dev
);
149 dev_err(&iris
->dev
, "no matching compatible for iris\n");
156 iris
->xo_clk
= devm_clk_get(&iris
->dev
, "xo");
157 if (IS_ERR(iris
->xo_clk
)) {
158 ret
= PTR_ERR(iris
->xo_clk
);
159 if (ret
!= -EPROBE_DEFER
)
160 dev_err(&iris
->dev
, "failed to acquire xo clk\n");
164 iris
->num_vregs
= data
->num_vregs
;
165 iris
->vregs
= devm_kcalloc(&iris
->dev
,
167 sizeof(struct regulator_bulk_data
),
174 for (i
= 0; i
< iris
->num_vregs
; i
++)
175 iris
->vregs
[i
].supply
= data
->vregs
[i
].name
;
177 ret
= devm_regulator_bulk_get(&iris
->dev
, iris
->num_vregs
, iris
->vregs
);
179 dev_err(&iris
->dev
, "failed to get regulators\n");
183 for (i
= 0; i
< iris
->num_vregs
; i
++) {
184 if (data
->vregs
[i
].max_voltage
)
185 regulator_set_voltage(iris
->vregs
[i
].consumer
,
186 data
->vregs
[i
].min_voltage
,
187 data
->vregs
[i
].max_voltage
);
189 if (data
->vregs
[i
].load_uA
)
190 regulator_set_load(iris
->vregs
[i
].consumer
,
191 data
->vregs
[i
].load_uA
);
194 *use_48mhz_xo
= data
->use_48mhz_xo
;
199 device_del(&iris
->dev
);
204 void qcom_iris_remove(struct qcom_iris
*iris
)
206 device_del(&iris
->dev
);