1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Qualcomm generic pmic gpio driver
4  *
5  * (C) Copyright 2015 Mateusz Kulikowski <mateusz.kulikowski@gmail.com>
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <power/pmic.h>
12 #include <spmi/spmi.h>
13 #include <asm/io.h>
14 #include <asm/gpio.h>
15 #include <linux/bitops.h>
16 
17 /* Register offset for each gpio */
18 #define REG_OFFSET(x)          ((x) * 0x100)
19 
20 /* Register maps */
21 
22 /* Type and subtype are shared for all PMIC peripherals */
23 #define REG_TYPE               0x4
24 #define REG_SUBTYPE            0x5
25 
26 /* GPIO peripheral type and subtype out_values */
27 #define REG_TYPE_VAL		0x10
28 #define REG_SUBTYPE_GPIO_4CH	0x1
29 #define REG_SUBTYPE_GPIOC_4CH	0x5
30 #define REG_SUBTYPE_GPIO_8CH	0x9
31 #define REG_SUBTYPE_GPIOC_8CH	0xd
32 #define REG_SUBTYPE_GPIO_LV	0x10
33 #define REG_SUBTYPE_GPIO_MV	0x11
34 
35 #define REG_STATUS             0x08
36 #define REG_STATUS_VAL_MASK    0x1
37 
38 /* MODE_CTL */
39 #define REG_CTL		0x40
40 #define REG_CTL_MODE_MASK       0x70
41 #define REG_CTL_MODE_INPUT      0x00
42 #define REG_CTL_MODE_INOUT      0x20
43 #define REG_CTL_MODE_OUTPUT     0x10
44 #define REG_CTL_OUTPUT_MASK     0x0F
45 #define REG_CTL_LV_MV_MODE_MASK		0x3
46 #define REG_CTL_LV_MV_MODE_INPUT	0x0
47 #define REG_CTL_LV_MV_MODE_INOUT	0x2
48 #define REG_CTL_LV_MV_MODE_OUTPUT	0x1
49 
50 #define REG_DIG_VIN_CTL        0x41
51 #define REG_DIG_VIN_VIN0       0
52 
53 #define REG_DIG_PULL_CTL       0x42
54 #define REG_DIG_PULL_NO_PU     0x5
55 
56 #define REG_LV_MV_OUTPUT_CTL	0x44
57 #define REG_LV_MV_OUTPUT_CTL_MASK	0x80
58 #define REG_LV_MV_OUTPUT_CTL_SHIFT	7
59 
60 #define REG_DIG_OUT_CTL        0x45
61 #define REG_DIG_OUT_CTL_CMOS   (0x0 << 4)
62 #define REG_DIG_OUT_CTL_DRIVE_L 0x1
63 
64 #define REG_EN_CTL             0x46
65 #define REG_EN_CTL_ENABLE      (1 << 7)
66 
67 struct qcom_gpio_bank {
68 	uint32_t pid; /* Peripheral ID on SPMI bus */
69 	bool     lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */
70 };
71 
qcom_gpio_set_direction(struct udevice * dev,unsigned offset,bool input,int value)72 static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset,
73 				   bool input, int value)
74 {
75 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
76 	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
77 	uint32_t reg_ctl_val;
78 	int ret;
79 
80 	/* Disable the GPIO */
81 	ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL,
82 			      REG_EN_CTL_ENABLE, 0);
83 	if (ret < 0)
84 		return ret;
85 
86 	/* Select the mode and output */
87 	if (priv->lv_mv_type) {
88 		if (input)
89 			reg_ctl_val = REG_CTL_LV_MV_MODE_INPUT;
90 		else
91 			reg_ctl_val = REG_CTL_LV_MV_MODE_INOUT;
92 	} else {
93 		if (input)
94 			reg_ctl_val = REG_CTL_MODE_INPUT;
95 		else
96 			reg_ctl_val = REG_CTL_MODE_INOUT | !!value;
97 	}
98 
99 	ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, reg_ctl_val);
100 	if (ret < 0)
101 		return ret;
102 
103 	if (priv->lv_mv_type && !input) {
104 		ret = pmic_reg_write(dev->parent,
105 				     gpio_base + REG_LV_MV_OUTPUT_CTL,
106 				     !!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
107 		if (ret < 0)
108 			return ret;
109 	}
110 
111 	/* Set the right pull (no pull) */
112 	ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL,
113 			     REG_DIG_PULL_NO_PU);
114 	if (ret < 0)
115 		return ret;
116 
117 	/* Configure output pin drivers if needed */
118 	if (!input) {
119 		/* Select the VIN - VIN0, pin is input so it doesn't matter */
120 		ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL,
121 				     REG_DIG_VIN_VIN0);
122 		if (ret < 0)
123 			return ret;
124 
125 		/* Set the right dig out control */
126 		ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL,
127 				     REG_DIG_OUT_CTL_CMOS |
128 				     REG_DIG_OUT_CTL_DRIVE_L);
129 		if (ret < 0)
130 			return ret;
131 	}
132 
133 	/* Enable the GPIO */
134 	return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0,
135 			       REG_EN_CTL_ENABLE);
136 }
137 
qcom_gpio_direction_input(struct udevice * dev,unsigned offset)138 static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset)
139 {
140 	return qcom_gpio_set_direction(dev, offset, true, 0);
141 }
142 
qcom_gpio_direction_output(struct udevice * dev,unsigned offset,int value)143 static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset,
144 				      int value)
145 {
146 	return qcom_gpio_set_direction(dev, offset, false, value);
147 }
148 
qcom_gpio_get_function(struct udevice * dev,unsigned offset)149 static int qcom_gpio_get_function(struct udevice *dev, unsigned offset)
150 {
151 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
152 	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
153 	int reg;
154 
155 	reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL);
156 	if (reg < 0)
157 		return reg;
158 
159 	if (priv->lv_mv_type) {
160 		switch (reg & REG_CTL_LV_MV_MODE_MASK) {
161 		case REG_CTL_LV_MV_MODE_INPUT:
162 			return GPIOF_INPUT;
163 		case REG_CTL_LV_MV_MODE_INOUT: /* Fallthrough */
164 		case REG_CTL_LV_MV_MODE_OUTPUT:
165 			return GPIOF_OUTPUT;
166 		default:
167 			return GPIOF_UNKNOWN;
168 		}
169 	} else {
170 		switch (reg & REG_CTL_MODE_MASK) {
171 		case REG_CTL_MODE_INPUT:
172 			return GPIOF_INPUT;
173 		case REG_CTL_MODE_INOUT: /* Fallthrough */
174 		case REG_CTL_MODE_OUTPUT:
175 			return GPIOF_OUTPUT;
176 		default:
177 			return GPIOF_UNKNOWN;
178 		}
179 	}
180 }
181 
qcom_gpio_get_value(struct udevice * dev,unsigned offset)182 static int qcom_gpio_get_value(struct udevice *dev, unsigned offset)
183 {
184 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
185 	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
186 	int reg;
187 
188 	reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS);
189 	if (reg < 0)
190 		return reg;
191 
192 	return !!(reg & REG_STATUS_VAL_MASK);
193 }
194 
qcom_gpio_set_value(struct udevice * dev,unsigned offset,int value)195 static int qcom_gpio_set_value(struct udevice *dev, unsigned offset,
196 			       int value)
197 {
198 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
199 	uint32_t gpio_base = priv->pid + REG_OFFSET(offset);
200 
201 	/* Set the output value of the gpio */
202 	if (priv->lv_mv_type)
203 		return pmic_clrsetbits(dev->parent,
204 				       gpio_base + REG_LV_MV_OUTPUT_CTL,
205 				       REG_LV_MV_OUTPUT_CTL_MASK,
206 				       !!value << REG_LV_MV_OUTPUT_CTL_SHIFT);
207 	else
208 		return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL,
209 				       REG_CTL_OUTPUT_MASK, !!value);
210 }
211 
212 static const struct dm_gpio_ops qcom_gpio_ops = {
213 	.direction_input	= qcom_gpio_direction_input,
214 	.direction_output	= qcom_gpio_direction_output,
215 	.get_value		= qcom_gpio_get_value,
216 	.set_value		= qcom_gpio_set_value,
217 	.get_function		= qcom_gpio_get_function,
218 };
219 
qcom_gpio_probe(struct udevice * dev)220 static int qcom_gpio_probe(struct udevice *dev)
221 {
222 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
223 	int reg;
224 
225 	priv->pid = dev_read_addr(dev);
226 	if (priv->pid == FDT_ADDR_T_NONE)
227 		return log_msg_ret("bad address", -EINVAL);
228 
229 	/* Do a sanity check */
230 	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
231 	if (reg != REG_TYPE_VAL)
232 		return log_msg_ret("bad type", -ENXIO);
233 
234 	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
235 	if (reg != REG_SUBTYPE_GPIO_4CH && reg != REG_SUBTYPE_GPIOC_4CH &&
236 	    reg != REG_SUBTYPE_GPIO_LV && reg != REG_SUBTYPE_GPIO_MV)
237 		return log_msg_ret("bad subtype", -ENXIO);
238 
239 	priv->lv_mv_type = reg == REG_SUBTYPE_GPIO_LV ||
240 			   reg == REG_SUBTYPE_GPIO_MV;
241 
242 	return 0;
243 }
244 
qcom_gpio_of_to_plat(struct udevice * dev)245 static int qcom_gpio_of_to_plat(struct udevice *dev)
246 {
247 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
248 
249 	uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0);
250 	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
251 	if (uc_priv->bank_name == NULL)
252 		uc_priv->bank_name = "qcom_pmic";
253 
254 	return 0;
255 }
256 
257 static const struct udevice_id qcom_gpio_ids[] = {
258 	{ .compatible = "qcom,pm8916-gpio" },
259 	{ .compatible = "qcom,pm8994-gpio" },	/* 22 GPIO's */
260 	{ .compatible = "qcom,pm8998-gpio" },
261 	{ .compatible = "qcom,pms405-gpio" },
262 	{ }
263 };
264 
265 U_BOOT_DRIVER(qcom_pmic_gpio) = {
266 	.name	= "qcom_pmic_gpio",
267 	.id	= UCLASS_GPIO,
268 	.of_match = qcom_gpio_ids,
269 	.of_to_plat = qcom_gpio_of_to_plat,
270 	.probe	= qcom_gpio_probe,
271 	.ops	= &qcom_gpio_ops,
272 	.priv_auto	= sizeof(struct qcom_gpio_bank),
273 };
274 
275 
276 /* Add pmic buttons as GPIO as well - there is no generic way for now */
277 #define PON_INT_RT_STS                        0x10
278 #define KPDPWR_ON_INT_BIT                     0
279 #define RESIN_ON_INT_BIT                      1
280 
qcom_pwrkey_get_function(struct udevice * dev,unsigned offset)281 static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset)
282 {
283 	return GPIOF_INPUT;
284 }
285 
qcom_pwrkey_get_value(struct udevice * dev,unsigned offset)286 static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset)
287 {
288 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
289 
290 	int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS);
291 
292 	if (reg < 0)
293 		return 0;
294 
295 	switch (offset) {
296 	case 0: /* Power button */
297 		return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0;
298 		break;
299 	case 1: /* Reset button */
300 	default:
301 		return (reg & BIT(RESIN_ON_INT_BIT)) != 0;
302 		break;
303 	}
304 }
305 
306 /*
307  * Since pmic buttons modelled as GPIO, we need empty direction functions
308  * to trick u-boot button driver
309  */
qcom_pwrkey_direction_input(struct udevice * dev,unsigned int offset)310 static int qcom_pwrkey_direction_input(struct udevice *dev, unsigned int offset)
311 {
312 	return 0;
313 }
314 
qcom_pwrkey_direction_output(struct udevice * dev,unsigned int offset,int value)315 static int qcom_pwrkey_direction_output(struct udevice *dev, unsigned int offset, int value)
316 {
317 	return -EOPNOTSUPP;
318 }
319 
320 static const struct dm_gpio_ops qcom_pwrkey_ops = {
321 	.get_value		= qcom_pwrkey_get_value,
322 	.get_function		= qcom_pwrkey_get_function,
323 	.direction_input	= qcom_pwrkey_direction_input,
324 	.direction_output	= qcom_pwrkey_direction_output,
325 };
326 
qcom_pwrkey_probe(struct udevice * dev)327 static int qcom_pwrkey_probe(struct udevice *dev)
328 {
329 	struct qcom_gpio_bank *priv = dev_get_priv(dev);
330 	int reg;
331 
332 	priv->pid = dev_read_addr(dev);
333 	if (priv->pid == FDT_ADDR_T_NONE)
334 		return log_msg_ret("bad address", -EINVAL);
335 
336 	/* Do a sanity check */
337 	reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE);
338 	if (reg != 0x1)
339 		return log_msg_ret("bad type", -ENXIO);
340 
341 	reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE);
342 	if ((reg & 0x5) == 0)
343 		return log_msg_ret("bad subtype", -ENXIO);
344 
345 	return 0;
346 }
347 
qcom_pwrkey_of_to_plat(struct udevice * dev)348 static int qcom_pwrkey_of_to_plat(struct udevice *dev)
349 {
350 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
351 
352 	uc_priv->gpio_count = 2;
353 	uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
354 	if (uc_priv->bank_name == NULL)
355 		uc_priv->bank_name = "pwkey_qcom";
356 
357 	return 0;
358 }
359 
360 static const struct udevice_id qcom_pwrkey_ids[] = {
361 	{ .compatible = "qcom,pm8916-pwrkey" },
362 	{ .compatible = "qcom,pm8994-pwrkey" },
363 	{ .compatible = "qcom,pm8998-pwrkey" },
364 	{ }
365 };
366 
367 U_BOOT_DRIVER(pwrkey_qcom) = {
368 	.name	= "pwrkey_qcom",
369 	.id	= UCLASS_GPIO,
370 	.of_match = qcom_pwrkey_ids,
371 	.of_to_plat = qcom_pwrkey_of_to_plat,
372 	.probe	= qcom_pwrkey_probe,
373 	.ops	= &qcom_pwrkey_ops,
374 	.priv_auto	= sizeof(struct qcom_gpio_bank),
375 };
376