brintos

brintos / linux-shallow public Read only

0
0
Text · 3.0 KiB · cd94ed6 Raw
111 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// Qualcomm PMIC VBUS output regulator driver4//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/platform_device.h>12#include <linux/regulator/driver.h>13#include <linux/regulator/of_regulator.h>14#include <linux/regmap.h>15 16#define CMD_OTG				0x4017#define OTG_EN				BIT(0)18#define OTG_CURRENT_LIMIT_CFG		0x5219#define OTG_CURRENT_LIMIT_MASK		GENMASK(2, 0)20#define OTG_CFG				0x5321#define OTG_EN_SRC_CFG			BIT(1)22 23static const unsigned int curr_table[] = {24	500000, 1000000, 1500000, 2000000, 2500000, 3000000,25};26 27static const struct regulator_ops qcom_usb_vbus_reg_ops = {28	.enable = regulator_enable_regmap,29	.disable = regulator_disable_regmap,30	.is_enabled = regulator_is_enabled_regmap,31	.get_current_limit = regulator_get_current_limit_regmap,32	.set_current_limit = regulator_set_current_limit_regmap,33};34 35static struct regulator_desc qcom_usb_vbus_rdesc = {36	.name = "usb_vbus",37	.ops = &qcom_usb_vbus_reg_ops,38	.owner = THIS_MODULE,39	.type = REGULATOR_VOLTAGE,40	.curr_table = curr_table,41	.n_current_limits = ARRAY_SIZE(curr_table),42};43 44static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev)45{46	struct device *dev = &pdev->dev;47	struct regulator_dev *rdev;48	struct regmap *regmap;49	struct regulator_config config = { };50	struct regulator_init_data *init_data;51	int ret;52	u32 base;53 54	ret = of_property_read_u32(dev->of_node, "reg", &base);55	if (ret < 0) {56		dev_err(dev, "no base address found\n");57		return ret;58	}59 60	regmap = dev_get_regmap(dev->parent, NULL);61	if (!regmap) {62		dev_err(dev, "Failed to get regmap\n");63		return -ENOENT;64	}65 66	init_data = of_get_regulator_init_data(dev, dev->of_node,67					       &qcom_usb_vbus_rdesc);68	if (!init_data)69		return -ENOMEM;70 71	qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG;72	qcom_usb_vbus_rdesc.enable_mask = OTG_EN;73	qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG;74	qcom_usb_vbus_rdesc.csel_mask = OTG_CURRENT_LIMIT_MASK;75	config.dev = dev;76	config.init_data = init_data;77	config.of_node = dev->of_node;78	config.regmap = regmap;79 80	rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config);81	if (IS_ERR(rdev)) {82		ret = PTR_ERR(rdev);83		dev_err(dev, "not able to register vbus reg %d\n", ret);84		return ret;85	}86 87	/* Disable HW logic for VBUS enable */88	regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0);89 90	return 0;91}92 93static const struct of_device_id qcom_usb_vbus_regulator_match[] = {94	{ .compatible = "qcom,pm8150b-vbus-reg" },95	{ }96};97MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);98 99static struct platform_driver qcom_usb_vbus_regulator_driver = {100	.driver		= {101		.name	= "qcom-usb-vbus-regulator",102		.probe_type = PROBE_PREFER_ASYNCHRONOUS,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");111