Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Qualcomm Wireless Connectivity Subsystem Iris driver
0004  *
0005  * Copyright (C) 2016 Linaro Ltd
0006  * Copyright (C) 2014 Sony Mobile Communications AB
0007  * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
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 }