1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (c) 2022 Analog Devices, Inc. |
4 | * ADI Regulator driver for the MAX77540 and MAX77541 |
5 | */ |
6 | |
7 | #include <linux/mfd/max77541.h> |
8 | #include <linux/mod_devicetable.h> |
9 | #include <linux/platform_device.h> |
10 | #include <linux/regmap.h> |
11 | #include <linux/regulator/driver.h> |
12 | |
13 | static const struct regulator_ops max77541_buck_ops = { |
14 | .enable = regulator_enable_regmap, |
15 | .disable = regulator_disable_regmap, |
16 | .is_enabled = regulator_is_enabled_regmap, |
17 | .list_voltage = regulator_list_voltage_pickable_linear_range, |
18 | .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, |
19 | .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, |
20 | }; |
21 | |
22 | static const struct linear_range max77540_buck_ranges[] = { |
23 | /* Ranges when VOLT_SEL bits are 0x00 */ |
24 | REGULATOR_LINEAR_RANGE(500000, 0x00, 0x8B, 5000), |
25 | REGULATOR_LINEAR_RANGE(1200000, 0x8C, 0xFF, 0), |
26 | /* Ranges when VOLT_SEL bits are 0x40 */ |
27 | REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x8B, 10000), |
28 | REGULATOR_LINEAR_RANGE(2400000, 0x8C, 0xFF, 0), |
29 | /* Ranges when VOLT_SEL bits are 0x80 */ |
30 | REGULATOR_LINEAR_RANGE(2000000, 0x00, 0x9F, 20000), |
31 | REGULATOR_LINEAR_RANGE(5200000, 0xA0, 0xFF, 0), |
32 | }; |
33 | |
34 | static const struct linear_range max77541_buck_ranges[] = { |
35 | /* Ranges when VOLT_SEL bits are 0x00 */ |
36 | REGULATOR_LINEAR_RANGE(300000, 0x00, 0xB3, 5000), |
37 | REGULATOR_LINEAR_RANGE(1200000, 0xB4, 0xFF, 0), |
38 | /* Ranges when VOLT_SEL bits are 0x40 */ |
39 | REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x8B, 10000), |
40 | REGULATOR_LINEAR_RANGE(2400000, 0x8C, 0xFF, 0), |
41 | /* Ranges when VOLT_SEL bits are 0x80 */ |
42 | REGULATOR_LINEAR_RANGE(2000000, 0x00, 0x9F, 20000), |
43 | REGULATOR_LINEAR_RANGE(5200000, 0xA0, 0xFF, 0), |
44 | }; |
45 | |
46 | static const unsigned int max77541_buck_volt_range_sel[] = { |
47 | 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, |
48 | }; |
49 | |
50 | enum max77541_regulators { |
51 | MAX77541_BUCK1 = 1, |
52 | MAX77541_BUCK2, |
53 | }; |
54 | |
55 | #define MAX77540_BUCK(_id, _ops) \ |
56 | { .id = MAX77541_BUCK ## _id, \ |
57 | .name = "buck"#_id, \ |
58 | .of_match = "buck"#_id, \ |
59 | .regulators_node = "regulators", \ |
60 | .enable_reg = MAX77541_REG_EN_CTRL, \ |
61 | .enable_mask = MAX77541_BIT_M ## _id ## _EN, \ |
62 | .ops = &(_ops), \ |
63 | .type = REGULATOR_VOLTAGE, \ |
64 | .linear_ranges = max77540_buck_ranges, \ |
65 | .n_linear_ranges = ARRAY_SIZE(max77540_buck_ranges), \ |
66 | .vsel_reg = MAX77541_REG_M ## _id ## _VOUT, \ |
67 | .vsel_mask = MAX77541_BITS_MX_VOUT, \ |
68 | .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ |
69 | .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ |
70 | .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \ |
71 | .owner = THIS_MODULE, \ |
72 | } |
73 | |
74 | #define MAX77541_BUCK(_id, _ops) \ |
75 | { .id = MAX77541_BUCK ## _id, \ |
76 | .name = "buck"#_id, \ |
77 | .of_match = "buck"#_id, \ |
78 | .regulators_node = "regulators", \ |
79 | .enable_reg = MAX77541_REG_EN_CTRL, \ |
80 | .enable_mask = MAX77541_BIT_M ## _id ## _EN, \ |
81 | .ops = &(_ops), \ |
82 | .type = REGULATOR_VOLTAGE, \ |
83 | .linear_ranges = max77541_buck_ranges, \ |
84 | .n_linear_ranges = ARRAY_SIZE(max77541_buck_ranges), \ |
85 | .vsel_reg = MAX77541_REG_M ## _id ## _VOUT, \ |
86 | .vsel_mask = MAX77541_BITS_MX_VOUT, \ |
87 | .vsel_range_reg = MAX77541_REG_M ## _id ## _CFG1, \ |
88 | .vsel_range_mask = MAX77541_BITS_MX_CFG1_RNG, \ |
89 | .linear_range_selectors_bitfield = max77541_buck_volt_range_sel, \ |
90 | .owner = THIS_MODULE, \ |
91 | } |
92 | |
93 | static const struct regulator_desc max77540_regulators_desc[] = { |
94 | MAX77540_BUCK(1, max77541_buck_ops), |
95 | MAX77540_BUCK(2, max77541_buck_ops), |
96 | }; |
97 | |
98 | static const struct regulator_desc max77541_regulators_desc[] = { |
99 | MAX77541_BUCK(1, max77541_buck_ops), |
100 | MAX77541_BUCK(2, max77541_buck_ops), |
101 | }; |
102 | |
103 | static int max77541_regulator_probe(struct platform_device *pdev) |
104 | { |
105 | struct regulator_config config = {}; |
106 | const struct regulator_desc *desc; |
107 | struct device *dev = &pdev->dev; |
108 | struct regulator_dev *rdev; |
109 | struct max77541 *max77541 = dev_get_drvdata(dev: dev->parent); |
110 | unsigned int i; |
111 | |
112 | config.dev = dev->parent; |
113 | |
114 | switch (max77541->id) { |
115 | case MAX77540: |
116 | desc = max77540_regulators_desc; |
117 | break; |
118 | case MAX77541: |
119 | desc = max77541_regulators_desc; |
120 | break; |
121 | default: |
122 | return -EINVAL; |
123 | } |
124 | |
125 | for (i = 0; i < MAX77541_MAX_REGULATORS; i++) { |
126 | rdev = devm_regulator_register(dev, regulator_desc: &desc[i], config: &config); |
127 | if (IS_ERR(ptr: rdev)) |
128 | return dev_err_probe(dev, err: PTR_ERR(ptr: rdev), |
129 | fmt: "Failed to register regulator\n" ); |
130 | } |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | static const struct platform_device_id max77541_regulator_platform_id[] = { |
136 | { "max77540-regulator" }, |
137 | { "max77541-regulator" }, |
138 | { } |
139 | }; |
140 | MODULE_DEVICE_TABLE(platform, max77541_regulator_platform_id); |
141 | |
142 | static struct platform_driver max77541_regulator_driver = { |
143 | .driver = { |
144 | .name = "max77541-regulator" , |
145 | }, |
146 | .probe = max77541_regulator_probe, |
147 | .id_table = max77541_regulator_platform_id, |
148 | }; |
149 | module_platform_driver(max77541_regulator_driver); |
150 | |
151 | MODULE_AUTHOR("Okan Sahin <Okan.Sahin@analog.com>" ); |
152 | MODULE_DESCRIPTION("MAX77540/MAX77541 regulator driver" ); |
153 | MODULE_LICENSE("GPL" ); |
154 | |