1 /*
2 * Copyright (c) 2021 Microchip Technology Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/sys_io.h>
9 #include <zephyr/sys/__assert.h>
10 #include <soc.h>
11 #include "soc_i2c.h"
12
13 /* pinctrl Node contains the base address of the GPIO Control Registers */
14 #define MCHP_XEC_GPIO_REG_BASE ((struct gpio_regs *)DT_REG_ADDR(DT_NODELABEL(pinctrl)))
15
16 /* Too many MEC1501 HAL bugs */
17 #ifndef MEC_I2C_PORT_MASK
18 #define MEC_I2C_PORT_MASK 0xFFFFU
19 #endif
20
21 /* encode GPIO pin number and alternate function for an I2C port */
22 struct mec_i2c_port {
23 uint8_t scl_pin_no;
24 uint8_t scl_func;
25 uint8_t sda_pin_no;
26 uint8_t sda_func;
27 };
28
29 /*
30 * indexed by port number: all on VTR1 except as commented
31 * NOTE: MCHP MECxxxx data sheets specify GPIO pin numbers in octal.
32 * TODO: MEC15xx and MEC172x handle ports with alternate pins.
33 */
34 static const struct mec_i2c_port mec_i2c_ports[] = {
35 #if defined(CONFIG_SOC_SERIES_MEC172X) || defined(CONFIG_SOC_SERIES_MEC15XX)
36 { 0004, 1, 0003, 1 },
37 { 0131, 1, 0130, 1 }, /* VTR2. ALT on eSPI VTR3 {0073, 2, 0072, 2} */
38 { 0155, 1, 0154, 1 },
39 { 0010, 1, 0007, 1 },
40 { 0144, 1, 0143, 1 },
41 { 0142, 1, 0141, 1 },
42 { 0140, 1, 0132, 1 },
43 { 0013, 1, 0012, 1 }, /* VTR2. ALT { 0024, 3, 0152, 3 } VTR1 */
44 #if defined(CONFIG_SOC_SERIES_MEC172X)
45 { 0230, 1, 0231, 1 }, /* VTR2 176 pin only */
46 #else
47 { 0212, 1, 0211, 1 }, /* VTR1 MEC1523 SZ and 3Y only */
48 #endif
49 { 0146, 1, 0145, 1 },
50 { 0107, 3, 0030, 2 },
51 { 0062, 2, 0000, 3 }, /* SCL on VTR1, SDA on VBAT. ALT 176 pin only */
52 { 0027, 3, 0026, 3 },
53 { 0065, 2, 0066, 2 }, /* VTR3 */
54 { 0071, 2, 0070, 2 }, /* VTR3 */
55 { 0150, 1, 0147, 1 }
56 #endif
57 };
58
59 /*
60 * Read pin states of specified I2C port.
61 * We GPIO control register always active RO pad input bit.
62 * lines b[0]=SCL pin state at pad, b[1]=SDA pin state at pad
63 */
soc_i2c_port_lines_get(uint8_t port,uint32_t * lines)64 int soc_i2c_port_lines_get(uint8_t port, uint32_t *lines)
65 {
66 struct gpio_regs *regs = MCHP_XEC_GPIO_REG_BASE;
67 uint32_t idx_scl = 0;
68 uint32_t idx_sda = 0;
69 uint32_t pinval = 0;
70
71 if (!(BIT(port) & MEC_I2C_PORT_MASK) || !lines) {
72 return -EINVAL;
73 }
74
75 idx_scl = (uint32_t)mec_i2c_ports[port].scl_pin_no;
76 idx_sda = (uint32_t)mec_i2c_ports[port].sda_pin_no;
77
78 if ((idx_scl == 0xFF) || (idx_sda == 0xFF)) {
79 return -EINVAL;
80 }
81
82 if (regs->CTRL[idx_scl] & BIT(MCHP_GPIO_CTRL_INPAD_VAL_POS)) {
83 pinval |= BIT(SOC_I2C_SCL_POS);
84 }
85 if (regs->CTRL[idx_sda] & BIT(MCHP_GPIO_CTRL_INPAD_VAL_POS)) {
86 pinval |= BIT(SOC_I2C_SDA_POS);
87 }
88
89 *lines = pinval;
90
91 return 0;
92 }
93