1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2011 The Chromium OS Authors.
4 */
5
6#include <dm.h>
7#include <fdtdec.h>
8#include <log.h>
9#include <malloc.h>
10#include <acpi/acpi_device.h>
11#include <asm/gpio.h>
12#include <dm/acpi.h>
13#include <dm/device-internal.h>
14#include <dm/device_compat.h>
15#include <dm/lists.h>
16#include <dm/of.h>
17#include <dm/pinctrl.h>
18#include <dt-bindings/gpio/gpio.h>
19#include <dt-bindings/gpio/sandbox-gpio.h>
20
21struct gpio_state {
22	const char *label;	/* label given by requester */
23	ulong flags;		/* flags (GPIOD_...) */
24};
25
26/* Access routines for GPIO info */
27static struct gpio_state *get_gpio_state(struct udevice *dev, uint offset)
28{
29	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
30	struct gpio_state *state = dev_get_priv(dev);
31
32	if (offset >= uc_priv->gpio_count) {
33		printf("sandbox_gpio: error: invalid gpio %u\n", offset);
34		return NULL;
35	}
36
37	return &state[offset];
38}
39
40/* Access routines for GPIO flags */
41static ulong *get_gpio_flags(struct udevice *dev, unsigned int offset)
42{
43	struct gpio_state *state = get_gpio_state(dev, offset);
44
45	if (!state)
46		return NULL;
47
48	return &state->flags;
49
50}
51
52static int get_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag)
53{
54	return (*get_gpio_flags(dev, offset) & flag) != 0;
55}
56
57static int set_gpio_flag(struct udevice *dev, unsigned int offset, ulong flag,
58			 int value)
59{
60	struct gpio_state *state = get_gpio_state(dev, offset);
61
62	if (value)
63		state->flags |= flag;
64	else
65		state->flags &= ~flag;
66
67	return 0;
68}
69
70/*
71 * Back-channel sandbox-internal-only access to GPIO state
72 */
73
74int sandbox_gpio_get_value(struct udevice *dev, unsigned offset)
75{
76	struct gpio_state *state = get_gpio_state(dev, offset);
77	bool val;
78
79	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
80		debug("sandbox_gpio: get_value on output gpio %u\n", offset);
81
82	if (state->flags & GPIOD_EXT_DRIVEN) {
83		val = state->flags & GPIOD_EXT_HIGH;
84	} else {
85		if (state->flags & GPIOD_EXT_PULL_UP)
86			val = true;
87		else if (state->flags & GPIOD_EXT_PULL_DOWN)
88			val = false;
89		else
90			val = state->flags & GPIOD_PULL_UP;
91	}
92
93	return val;
94}
95
96int sandbox_gpio_set_value(struct udevice *dev, unsigned offset, int value)
97{
98	set_gpio_flag(dev, offset, GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
99
100	return 0;
101}
102
103int sandbox_gpio_get_direction(struct udevice *dev, unsigned offset)
104{
105	return get_gpio_flag(dev, offset, GPIOD_IS_OUT);
106}
107
108int sandbox_gpio_set_direction(struct udevice *dev, unsigned offset, int output)
109{
110	set_gpio_flag(dev, offset, GPIOD_IS_OUT, output);
111	set_gpio_flag(dev, offset, GPIOD_IS_IN, !output);
112
113	return 0;
114}
115
116ulong sandbox_gpio_get_flags(struct udevice *dev, uint offset)
117{
118	ulong flags = *get_gpio_flags(dev, offset);
119
120	return flags & ~GPIOD_SANDBOX_MASK;
121}
122
123int sandbox_gpio_set_flags(struct udevice *dev, uint offset, ulong flags)
124{
125	struct gpio_state *state = get_gpio_state(dev, offset);
126
127	state->flags = flags;
128
129	return 0;
130}
131
132/*
133 * These functions implement the public interface within U-Boot
134 */
135
136/* set GPIO port 'offset' as an input */
137static int sb_gpio_direction_input(struct udevice *dev, unsigned offset)
138{
139	debug("%s: offset:%u\n", __func__, offset);
140
141	return sandbox_gpio_set_direction(dev, offset, 0);
142}
143
144/* set GPIO port 'offset' as an output, with polarity 'value' */
145static int sb_gpio_direction_output(struct udevice *dev, unsigned offset,
146				    int value)
147{
148	int ret;
149
150	debug("%s: offset:%u, value = %d\n", __func__, offset, value);
151
152	ret = sandbox_gpio_set_direction(dev, offset, 1);
153	if (ret)
154		return ret;
155	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
156			    GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
157	if (ret)
158		return ret;
159
160	return 0;
161}
162
163/* read GPIO IN value of port 'offset' */
164static int sb_gpio_get_value(struct udevice *dev, unsigned offset)
165{
166	debug("%s: offset:%u\n", __func__, offset);
167
168	return sandbox_gpio_get_value(dev, offset);
169}
170
171/* write GPIO OUT value to port 'offset' */
172static int sb_gpio_set_value(struct udevice *dev, unsigned offset, int value)
173{
174	int ret;
175
176	debug("%s: offset:%u, value = %d\n", __func__, offset, value);
177
178	if (!sandbox_gpio_get_direction(dev, offset)) {
179		printf("sandbox_gpio: error: set_value on input gpio %u\n",
180		       offset);
181		return -1;
182	}
183
184	ret = set_gpio_flag(dev, offset, GPIOD_IS_OUT_ACTIVE |
185			    GPIOD_EXT_DRIVEN | GPIOD_EXT_HIGH, value);
186	if (ret)
187		return ret;
188
189	return 0;
190}
191
192static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
193{
194	if (get_gpio_flag(dev, offset, GPIOD_IS_OUT))
195		return GPIOF_OUTPUT;
196	if (get_gpio_flag(dev, offset, GPIOD_IS_IN))
197		return GPIOF_INPUT;
198	if (get_gpio_flag(dev, offset, GPIOD_IS_AF))
199		return GPIOF_FUNC;
200
201	return GPIOF_INPUT; /*GPIO is not configurated */
202}
203
204static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
205			 struct ofnode_phandle_args *args)
206{
207	desc->offset = args->args[0];
208	if (args->args_count < 2)
209		return 0;
210	/* treat generic binding with gpio uclass */
211	gpio_xlate_offs_flags(dev, desc, args);
212
213	/* sandbox test specific, not defined in gpio.h */
214	if (args->args[1] & GPIO_IN)
215		desc->flags |= GPIOD_IS_IN;
216
217	if (args->args[1] & GPIO_OUT)
218		desc->flags |= GPIOD_IS_OUT;
219
220	if (args->args[1] & GPIO_OUT_ACTIVE)
221		desc->flags |= GPIOD_IS_OUT_ACTIVE;
222
223	if (args->args[1] & GPIO_AF)
224		desc->flags |= GPIOD_IS_AF;
225
226	return 0;
227}
228
229static int sb_gpio_set_flags(struct udevice *dev, unsigned int offset,
230			     ulong flags)
231{
232	debug("%s: offset:%u, flags = %lx\n", __func__, offset, flags);
233	struct gpio_state *state = get_gpio_state(dev, offset);
234
235	if (flags & GPIOD_IS_OUT) {
236		flags |= GPIOD_EXT_DRIVEN;
237		if (flags & GPIOD_IS_OUT_ACTIVE)
238			flags |= GPIOD_EXT_HIGH;
239		else
240			flags &= ~GPIOD_EXT_HIGH;
241	} else {
242		flags |= state->flags & GPIOD_SANDBOX_MASK;
243	}
244	state->flags = flags;
245
246	return 0;
247}
248
249static int sb_gpio_get_flags(struct udevice *dev, uint offset, ulong *flagsp)
250{
251	debug("%s: offset:%u\n", __func__, offset);
252	*flagsp = *get_gpio_flags(dev, offset) & ~GPIOD_SANDBOX_MASK;
253
254	return 0;
255}
256
257#if CONFIG_IS_ENABLED(ACPIGEN)
258static int sb_gpio_get_acpi(const struct gpio_desc *desc,
259			    struct acpi_gpio *gpio)
260{
261	int ret;
262
263	/* Note that gpio_get_acpi() zeroes *gpio before calling here */
264	gpio->pin_count = 1;
265	gpio->pins[0] = desc->offset;
266	ret = acpi_device_scope(desc->dev, gpio->resource,
267				sizeof(gpio->resource));
268	if (ret)
269		return log_ret(ret);
270
271	/* All of these values are just used for testing */
272	if (desc->flags & GPIOD_ACTIVE_LOW) {
273		gpio->pin0_addr = 0x80012 + desc->offset;
274		gpio->type = ACPI_GPIO_TYPE_INTERRUPT;
275		gpio->pull = ACPI_GPIO_PULL_DOWN;
276		gpio->interrupt_debounce_timeout = 4321;
277
278		/* We use the GpioInt part */
279		gpio->irq.pin = desc->offset;
280		gpio->irq.polarity = ACPI_IRQ_ACTIVE_BOTH;
281		gpio->irq.shared = ACPI_IRQ_SHARED;
282		gpio->irq.wake = ACPI_IRQ_WAKE;
283
284		/* The GpioIo part is only used for testing */
285		gpio->polarity = ACPI_GPIO_ACTIVE_LOW;
286	} else {
287		gpio->pin0_addr = 0xc00dc + desc->offset;
288		gpio->type = ACPI_GPIO_TYPE_IO;
289		gpio->pull = ACPI_GPIO_PULL_UP;
290		gpio->interrupt_debounce_timeout = 0;
291
292		/* The GpioInt part is not used */
293
294		/* We use the GpioIo part */
295		gpio->output_drive_strength = 1234;
296		gpio->io_shared = true;
297		gpio->io_restrict = ACPI_GPIO_IO_RESTRICT_INPUT;
298		gpio->polarity = 0;
299	}
300
301	return 0;
302}
303
304static int sb_gpio_get_name(const struct udevice *dev, char *out_name)
305{
306	return acpi_copy_name(out_name, "GPIO");
307}
308
309struct acpi_ops gpio_sandbox_acpi_ops = {
310	.get_name	= sb_gpio_get_name,
311};
312#endif /* ACPIGEN */
313
314static const struct dm_gpio_ops gpio_sandbox_ops = {
315	.direction_input	= sb_gpio_direction_input,
316	.direction_output	= sb_gpio_direction_output,
317	.get_value		= sb_gpio_get_value,
318	.set_value		= sb_gpio_set_value,
319	.get_function		= sb_gpio_get_function,
320	.xlate			= sb_gpio_xlate,
321	.set_flags		= sb_gpio_set_flags,
322	.get_flags		= sb_gpio_get_flags,
323#if CONFIG_IS_ENABLED(ACPIGEN)
324	.get_acpi		= sb_gpio_get_acpi,
325#endif
326};
327
328static int sandbox_gpio_of_to_plat(struct udevice *dev)
329{
330	if (CONFIG_IS_ENABLED(OF_REAL)) {
331		struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
332
333		uc_priv->gpio_count =
334			dev_read_u32_default(dev, "sandbox,gpio-count", 0);
335		uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name");
336	}
337
338	return 0;
339}
340
341static int gpio_sandbox_probe(struct udevice *dev)
342{
343	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
344
345	if (!dev_has_ofnode(dev))
346		/* Tell the uclass how many GPIOs we have */
347		uc_priv->gpio_count = CONFIG_SANDBOX_GPIO_COUNT;
348
349	dev_set_priv(dev,
350		     calloc(sizeof(struct gpio_state), uc_priv->gpio_count));
351
352	return 0;
353}
354
355static int gpio_sandbox_remove(struct udevice *dev)
356{
357	free(dev_get_priv(dev));
358
359	return 0;
360}
361
362static const struct udevice_id sandbox_gpio_ids[] = {
363	{ .compatible = "sandbox,gpio" },
364	{ }
365};
366
367U_BOOT_DRIVER(sandbox_gpio) = {
368	.name	= "sandbox_gpio",
369	.id	= UCLASS_GPIO,
370	.of_match = sandbox_gpio_ids,
371	.of_to_plat = sandbox_gpio_of_to_plat,
372	.probe	= gpio_sandbox_probe,
373	.remove	= gpio_sandbox_remove,
374	.ops	= &gpio_sandbox_ops,
375	ACPI_OPS_PTR(&gpio_sandbox_acpi_ops)
376};
377
378DM_DRIVER_ALIAS(sandbox_gpio, sandbox_gpio_alias)
379
380#if CONFIG_IS_ENABLED(PINCTRL)
381
382/* pincontrol: used only to check GPIO pin configuration (pinmux command) */
383
384struct sb_pinctrl_priv {
385	int pinctrl_ngpios;
386	struct list_head gpio_dev;
387};
388
389struct sb_gpio_bank {
390	struct udevice *gpio_dev;
391	struct list_head list;
392};
393
394static int sb_populate_gpio_dev_list(struct udevice *dev)
395{
396	struct sb_pinctrl_priv *priv = dev_get_priv(dev);
397	struct udevice *gpio_dev;
398	struct udevice *child;
399	struct sb_gpio_bank *gpio_bank;
400	int ret;
401
402	/*
403	 * parse pin-controller sub-nodes (ie gpio bank nodes) and fill
404	 * a list with all gpio device reference which belongs to the
405	 * current pin-controller. This list is used to find pin_name and
406	 * pin muxing
407	 */
408	list_for_each_entry(child, &dev->child_head, sibling_node) {
409		ret = uclass_get_device_by_name(UCLASS_GPIO, child->name,
410						&gpio_dev);
411		if (ret < 0)
412			continue;
413
414		gpio_bank = malloc(sizeof(*gpio_bank));
415		if (!gpio_bank) {
416			dev_err(dev, "Not enough memory\n");
417			return -ENOMEM;
418		}
419
420		gpio_bank->gpio_dev = gpio_dev;
421		list_add_tail(&gpio_bank->list, &priv->gpio_dev);
422	}
423
424	return 0;
425}
426
427static int sb_pinctrl_get_pins_count(struct udevice *dev)
428{
429	struct sb_pinctrl_priv *priv = dev_get_priv(dev);
430	struct gpio_dev_priv *uc_priv;
431	struct sb_gpio_bank *gpio_bank;
432
433	/*
434	 * if get_pins_count has already been executed once on this
435	 * pin-controller, no need to run it again
436	 */
437	if (priv->pinctrl_ngpios)
438		return priv->pinctrl_ngpios;
439
440	if (list_empty(&priv->gpio_dev))
441		sb_populate_gpio_dev_list(dev);
442	/*
443	 * walk through all banks to retrieve the pin-controller
444	 * pins number
445	 */
446	list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
447		uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
448
449		priv->pinctrl_ngpios += uc_priv->gpio_count;
450	}
451
452	return priv->pinctrl_ngpios;
453}
454
455static struct udevice *sb_pinctrl_get_gpio_dev(struct udevice *dev,
456					       unsigned int selector,
457					       unsigned int *idx)
458{
459	struct sb_pinctrl_priv *priv = dev_get_priv(dev);
460	struct sb_gpio_bank *gpio_bank;
461	struct gpio_dev_priv *uc_priv;
462	int pin_count = 0;
463
464	if (list_empty(&priv->gpio_dev))
465		sb_populate_gpio_dev_list(dev);
466
467	/* look up for the bank which owns the requested pin */
468	list_for_each_entry(gpio_bank, &priv->gpio_dev, list) {
469		uc_priv = dev_get_uclass_priv(gpio_bank->gpio_dev);
470
471		if (selector < (pin_count + uc_priv->gpio_count)) {
472			/*
473			 * we found the bank, convert pin selector to
474			 * gpio bank index
475			 */
476			*idx = selector - pin_count;
477
478			return gpio_bank->gpio_dev;
479		}
480		pin_count += uc_priv->gpio_count;
481	}
482
483	return NULL;
484}
485
486static const char *sb_pinctrl_get_pin_name(struct udevice *dev,
487					   unsigned int selector)
488{
489	struct gpio_dev_priv *uc_priv;
490	struct udevice *gpio_dev;
491	unsigned int gpio_idx;
492	static char pin_name[PINNAME_SIZE];
493
494	/* look up for the bank which owns the requested pin */
495	gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
496	if (!gpio_dev) {
497		snprintf(pin_name, PINNAME_SIZE, "Error");
498	} else {
499		uc_priv = dev_get_uclass_priv(gpio_dev);
500
501		snprintf(pin_name, PINNAME_SIZE, "%s%d",
502			 uc_priv->bank_name,
503			 gpio_idx);
504	}
505
506	return pin_name;
507}
508
509static char *get_flags_string(ulong flags)
510{
511	if (flags & GPIOD_OPEN_DRAIN)
512		return "drive-open-drain";
513	if (flags & GPIOD_OPEN_SOURCE)
514		return "drive-open-source";
515	if (flags & GPIOD_PULL_UP)
516		return "bias-pull-up";
517	if (flags & GPIOD_PULL_DOWN)
518		return "bias-pull-down";
519	return ".";
520}
521
522static int sb_pinctrl_get_pin_muxing(struct udevice *dev,
523				     unsigned int selector,
524				     char *buf, int size)
525{
526	struct udevice *gpio_dev;
527	unsigned int gpio_idx;
528	ulong flags;
529	int function;
530
531	/* look up for the bank which owns the requested pin */
532	gpio_dev = sb_pinctrl_get_gpio_dev(dev, selector, &gpio_idx);
533	if (!gpio_dev) {
534		snprintf(buf, size, "Error");
535	} else {
536		function = sb_gpio_get_function(gpio_dev, gpio_idx);
537		flags = *get_gpio_flags(gpio_dev, gpio_idx);
538
539		snprintf(buf, size, "gpio %s %s",
540			 function == GPIOF_OUTPUT ? "output" : "input",
541			 get_flags_string(flags));
542	}
543
544	return 0;
545}
546
547#if CONFIG_IS_ENABLED(ACPIGEN)
548static int sb_pinctrl_get_name(const struct udevice *dev, char *out_name)
549{
550	return acpi_copy_name(out_name, "PINC");
551}
552#endif
553
554static int sandbox_pinctrl_probe(struct udevice *dev)
555{
556	struct sb_pinctrl_priv *priv = dev_get_priv(dev);
557
558	INIT_LIST_HEAD(&priv->gpio_dev);
559
560	return 0;
561}
562
563static struct pinctrl_ops sandbox_pinctrl_gpio_ops = {
564	.get_pin_name		= sb_pinctrl_get_pin_name,
565	.get_pins_count		= sb_pinctrl_get_pins_count,
566	.get_pin_muxing		= sb_pinctrl_get_pin_muxing,
567};
568
569#if CONFIG_IS_ENABLED(ACPIGEN)
570struct acpi_ops pinctrl_sandbox_acpi_ops = {
571	.get_name	= sb_pinctrl_get_name,
572};
573#endif
574
575static const struct udevice_id sandbox_pinctrl_gpio_match[] = {
576	{ .compatible = "sandbox,pinctrl-gpio" },
577	{ /* sentinel */ }
578};
579
580U_BOOT_DRIVER(sandbox_pinctrl_gpio) = {
581	.name = "sandbox_pinctrl_gpio",
582	.id = UCLASS_PINCTRL,
583	.of_match = sandbox_pinctrl_gpio_match,
584	.ops = &sandbox_pinctrl_gpio_ops,
585	.bind = dm_scan_fdt_dev,
586	.probe = sandbox_pinctrl_probe,
587	.priv_auto	= sizeof(struct sb_pinctrl_priv),
588	ACPI_OPS_PTR(&pinctrl_sandbox_acpi_ops)
589};
590
591#endif /* PINCTRL */
592