cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qcom_usb_vbus-regulator.c (3060B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2//
      3// Qualcomm PMIC VBUS output regulator driver
      4//
      5// Copyright (c) 2020, The Linux Foundation. All rights reserved.
      6
      7#include <linux/module.h>
      8#include <linux/err.h>
      9#include <linux/kernel.h>
     10#include <linux/of.h>
     11#include <linux/of_device.h>
     12#include <linux/platform_device.h>
     13#include <linux/regulator/driver.h>
     14#include <linux/regulator/of_regulator.h>
     15#include <linux/regmap.h>
     16
     17#define CMD_OTG				0x40
     18#define OTG_EN				BIT(0)
     19#define OTG_CURRENT_LIMIT_CFG		0x52
     20#define OTG_CURRENT_LIMIT_MASK		GENMASK(2, 0)
     21#define OTG_CFG				0x53
     22#define OTG_EN_SRC_CFG			BIT(1)
     23
     24static const unsigned int curr_table[] = {
     25	500000, 1000000, 1500000, 2000000, 2500000, 3000000,
     26};
     27
     28static const struct regulator_ops qcom_usb_vbus_reg_ops = {
     29	.enable = regulator_enable_regmap,
     30	.disable = regulator_disable_regmap,
     31	.is_enabled = regulator_is_enabled_regmap,
     32	.get_current_limit = regulator_get_current_limit_regmap,
     33	.set_current_limit = regulator_set_current_limit_regmap,
     34};
     35
     36static struct regulator_desc qcom_usb_vbus_rdesc = {
     37	.name = "usb_vbus",
     38	.ops = &qcom_usb_vbus_reg_ops,
     39	.owner = THIS_MODULE,
     40	.type = REGULATOR_VOLTAGE,
     41	.curr_table = curr_table,
     42	.n_current_limits = ARRAY_SIZE(curr_table),
     43};
     44
     45static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)
     46{
     47	struct device *dev = &pdev->dev;
     48	struct regulator_dev *rdev;
     49	struct regmap *regmap;
     50	struct regulator_config config = { };
     51	struct regulator_init_data *init_data;
     52	int ret;
     53	u32 base;
     54
     55	ret = of_property_read_u32(dev->of_node, "reg", &base);
     56	if (ret < 0) {
     57		dev_err(dev, "no base address found\n");
     58		return ret;
     59	}
     60
     61	regmap = dev_get_regmap(dev->parent, NULL);
     62	if (!regmap) {
     63		dev_err(dev, "Failed to get regmap\n");
     64		return -ENOENT;
     65	}
     66
     67	init_data = of_get_regulator_init_data(dev, dev->of_node,
     68					       &qcom_usb_vbus_rdesc);
     69	if (!init_data)
     70		return -ENOMEM;
     71
     72	qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;
     73	qcom_usb_vbus_rdesc.enable_mask = OTG_EN;
     74	qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG;
     75	qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK;
     76	config.dev = dev;
     77	config.init_data = init_data;
     78	config.of_node = dev->of_node;
     79	config.regmap = regmap;
     80
     81	rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);
     82	if (IS_ERR(rdev)) {
     83		ret = PTR_ERR(rdev);
     84		dev_err(dev, "not able to register vbus reg %d\n", ret);
     85		return ret;
     86	}
     87
     88	/* Disable HW logic for VBUS enable */
     89	regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0);
     90
     91	return 0;
     92}
     93
     94static const struct of_device_id qcom_usb_vbus_regulator_match[] = {
     95	{ .compatible = "qcom,pm8150b-vbus-reg" },
     96	{ }
     97};
     98MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);
     99
    100static struct platform_driver qcom_usb_vbus_regulator_driver = {
    101	.driver		= {
    102		.name	= "qcom-usb-vbus-regulator",
    103		.of_match_table = qcom_usb_vbus_regulator_match,
    104	},
    105	.probe		= qcom_usb_vbus_regulator_probe,
    106};
    107module_platform_driver(qcom_usb_vbus_regulator_driver);
    108
    109MODULE_DESCRIPTION("Qualcomm USB vbus regulator driver");
    110MODULE_LICENSE("GPL v2");