0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clk.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of_device.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/consumer.h>
0016
0017 #include "qcom_wcnss.h"
0018
0019 struct qcom_iris {
0020 struct device dev;
0021
0022 struct clk *xo_clk;
0023
0024 struct regulator_bulk_data *vregs;
0025 size_t num_vregs;
0026 };
0027
0028 struct iris_data {
0029 const struct wcnss_vreg_info *vregs;
0030 size_t num_vregs;
0031
0032 bool use_48mhz_xo;
0033 };
0034
0035 static const struct iris_data wcn3620_data = {
0036 .vregs = (struct wcnss_vreg_info[]) {
0037 { "vddxo", 1800000, 1800000, 10000 },
0038 { "vddrfa", 1300000, 1300000, 100000 },
0039 { "vddpa", 3300000, 3300000, 515000 },
0040 { "vdddig", 1800000, 1800000, 10000 },
0041 },
0042 .num_vregs = 4,
0043 .use_48mhz_xo = false,
0044 };
0045
0046 static const struct iris_data wcn3660_data = {
0047 .vregs = (struct wcnss_vreg_info[]) {
0048 { "vddxo", 1800000, 1800000, 10000 },
0049 { "vddrfa", 1300000, 1300000, 100000 },
0050 { "vddpa", 2900000, 3000000, 515000 },
0051 { "vdddig", 1200000, 1225000, 10000 },
0052 },
0053 .num_vregs = 4,
0054 .use_48mhz_xo = true,
0055 };
0056
0057 static const struct iris_data wcn3680_data = {
0058 .vregs = (struct wcnss_vreg_info[]) {
0059 { "vddxo", 1800000, 1800000, 10000 },
0060 { "vddrfa", 1300000, 1300000, 100000 },
0061 { "vddpa", 3300000, 3300000, 515000 },
0062 { "vdddig", 1800000, 1800000, 10000 },
0063 },
0064 .num_vregs = 4,
0065 .use_48mhz_xo = true,
0066 };
0067
0068 int qcom_iris_enable(struct qcom_iris *iris)
0069 {
0070 int ret;
0071
0072 ret = regulator_bulk_enable(iris->num_vregs, iris->vregs);
0073 if (ret)
0074 return ret;
0075
0076 ret = clk_prepare_enable(iris->xo_clk);
0077 if (ret) {
0078 dev_err(&iris->dev, "failed to enable xo clk\n");
0079 goto disable_regulators;
0080 }
0081
0082 return 0;
0083
0084 disable_regulators:
0085 regulator_bulk_disable(iris->num_vregs, iris->vregs);
0086
0087 return ret;
0088 }
0089
0090 void qcom_iris_disable(struct qcom_iris *iris)
0091 {
0092 clk_disable_unprepare(iris->xo_clk);
0093 regulator_bulk_disable(iris->num_vregs, iris->vregs);
0094 }
0095
0096 static const struct of_device_id iris_of_match[] = {
0097 { .compatible = "qcom,wcn3620", .data = &wcn3620_data },
0098 { .compatible = "qcom,wcn3660", .data = &wcn3660_data },
0099 { .compatible = "qcom,wcn3660b", .data = &wcn3680_data },
0100 { .compatible = "qcom,wcn3680", .data = &wcn3680_data },
0101 {}
0102 };
0103
0104 static void qcom_iris_release(struct device *dev)
0105 {
0106 struct qcom_iris *iris = container_of(dev, struct qcom_iris, dev);
0107
0108 of_node_put(iris->dev.of_node);
0109 kfree(iris);
0110 }
0111
0112 struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo)
0113 {
0114 const struct of_device_id *match;
0115 const struct iris_data *data;
0116 struct device_node *of_node;
0117 struct qcom_iris *iris;
0118 int ret;
0119 int i;
0120
0121 of_node = of_get_child_by_name(parent->of_node, "iris");
0122 if (!of_node) {
0123 dev_err(parent, "No child node \"iris\" found\n");
0124 return ERR_PTR(-EINVAL);
0125 }
0126
0127 iris = kzalloc(sizeof(*iris), GFP_KERNEL);
0128 if (!iris) {
0129 of_node_put(of_node);
0130 return ERR_PTR(-ENOMEM);
0131 }
0132
0133 device_initialize(&iris->dev);
0134 iris->dev.parent = parent;
0135 iris->dev.release = qcom_iris_release;
0136 iris->dev.of_node = of_node;
0137
0138 dev_set_name(&iris->dev, "%s.iris", dev_name(parent));
0139
0140 ret = device_add(&iris->dev);
0141 if (ret) {
0142 put_device(&iris->dev);
0143 return ERR_PTR(ret);
0144 }
0145
0146 match = of_match_device(iris_of_match, &iris->dev);
0147 if (!match) {
0148 dev_err(&iris->dev, "no matching compatible for iris\n");
0149 ret = -EINVAL;
0150 goto err_device_del;
0151 }
0152
0153 data = match->data;
0154
0155 iris->xo_clk = devm_clk_get(&iris->dev, "xo");
0156 if (IS_ERR(iris->xo_clk)) {
0157 ret = PTR_ERR(iris->xo_clk);
0158 if (ret != -EPROBE_DEFER)
0159 dev_err(&iris->dev, "failed to acquire xo clk\n");
0160 goto err_device_del;
0161 }
0162
0163 iris->num_vregs = data->num_vregs;
0164 iris->vregs = devm_kcalloc(&iris->dev,
0165 iris->num_vregs,
0166 sizeof(struct regulator_bulk_data),
0167 GFP_KERNEL);
0168 if (!iris->vregs) {
0169 ret = -ENOMEM;
0170 goto err_device_del;
0171 }
0172
0173 for (i = 0; i < iris->num_vregs; i++)
0174 iris->vregs[i].supply = data->vregs[i].name;
0175
0176 ret = devm_regulator_bulk_get(&iris->dev, iris->num_vregs, iris->vregs);
0177 if (ret) {
0178 dev_err(&iris->dev, "failed to get regulators\n");
0179 goto err_device_del;
0180 }
0181
0182 for (i = 0; i < iris->num_vregs; i++) {
0183 if (data->vregs[i].max_voltage)
0184 regulator_set_voltage(iris->vregs[i].consumer,
0185 data->vregs[i].min_voltage,
0186 data->vregs[i].max_voltage);
0187
0188 if (data->vregs[i].load_uA)
0189 regulator_set_load(iris->vregs[i].consumer,
0190 data->vregs[i].load_uA);
0191 }
0192
0193 *use_48mhz_xo = data->use_48mhz_xo;
0194
0195 return iris;
0196
0197 err_device_del:
0198 device_del(&iris->dev);
0199
0200 return ERR_PTR(ret);
0201 }
0202
0203 void qcom_iris_remove(struct qcom_iris *iris)
0204 {
0205 device_del(&iris->dev);
0206 }