1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2019 Intel Corporation. All rights reserved.
4 //
5 // Author: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
6 
7 #include <sof/drivers/gpio.h>
8 #include <sof/drivers/iomux.h>
9 #include <sof/lib/io.h>
10 #include <sof/lib/memory.h>
11 #include <errno.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #define PORTA_DAT_REG	0x00
16 #define PORTA_DIR_REG	0x04
17 #define PORTA_CTL_REG	0x08
18 
19 struct gpio {
20 	uint32_t base;
21 };
22 
23 static struct gpio dw_gpio = {
24 	.base = DW_GPIO_BASE,
25 };
26 
gpio_write(const struct gpio * gpio,unsigned int port,enum gpio_level level)27 int gpio_write(const struct gpio *gpio, unsigned int port,
28 	       enum gpio_level level)
29 {
30 	io_reg_update_bits(gpio->base + PORTA_DAT_REG, 1 << port,
31 			   (level == GPIO_LEVEL_HIGH) << port);
32 
33 	return 0;
34 }
35 
gpio_read(const struct gpio * gpio,unsigned int port)36 int gpio_read(const struct gpio *gpio, unsigned int port)
37 {
38 	return ((io_reg_read(gpio->base + PORTA_DAT_REG) >> port) & 1) ?
39 		GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
40 }
41 
gpio_configure(const struct gpio * gpio,unsigned int port,const struct gpio_config * config)42 int gpio_configure(const struct gpio *gpio, unsigned int port,
43 		   const struct gpio_config *config)
44 {
45 	const struct gpio_pin_config *gpio_cfg = gpio_data + port;
46 	const struct iomux_pin_config *pin_cfg = &gpio_cfg->mux_config;
47 	struct iomux *mux = iomux_get(gpio_cfg->mux_id);
48 	int ret;
49 
50 	if (!mux)
51 		return -ENODEV;
52 
53 	ret = iomux_configure(mux, pin_cfg);
54 	if (ret < 0)
55 		return ret;
56 
57 	/* set the direction of GPIO */
58 	io_reg_update_bits(gpio->base + PORTA_DIR_REG, 1 << port,
59 			(config->direction == GPIO_DIRECTION_OUTPUT) << port);
60 
61 	return 0;
62 }
63 
gpio_get(unsigned int id)64 const struct gpio *gpio_get(unsigned int id)
65 {
66 	return id ? NULL : &dw_gpio;
67 }
68 
gpio_probe(const struct gpio * gpio)69 int gpio_probe(const struct gpio *gpio)
70 {
71 	return gpio == &dw_gpio ? 0 : -ENODEV;
72 }
73