xref: /aosp_15_r20/external/coreboot/src/soc/nvidia/tegra/software_i2c.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/i2c_simple.h>
4 #include <gpio.h>
5 #include <soc/pinmux.h>
6 
7 #include "i2c.h"
8 
9 static struct {
10 	int pinmux_func;
11 	gpio_t sda;
12 	gpio_t scl;
13 } pins[] = {
14 	[0]{.pinmux_func = PINMUX_GEN1_I2C_SCL_FUNC_I2C1,
15 	    .sda = GPIO(C5), .scl = GPIO(C4)},
16 	[1]{.pinmux_func = PINMUX_GEN2_I2C_SCL_FUNC_I2C2,
17 	    .sda = GPIO(T6), .scl = GPIO(T5)},
18 	[2]{.pinmux_func = PINMUX_CAM_I2C_SCL_FUNC_I2C3,
19 	    .sda = GPIO(BB2), .scl = GPIO(BB1)},
20 	[3]{.pinmux_func = PINMUX_DDC_SCL_FUNC_I2C4,
21 	    .sda = GPIO(V5), .scl = GPIO(V4)},
22 	[4]{.pinmux_func = PINMUX_PWR_I2C_SCL_FUNC_I2CPMU,
23 	    .sda = GPIO(Z7), .scl = GPIO(Z6)},
24 };
25 
tegra_set_sda(unsigned int bus,int high)26 static void tegra_set_sda(unsigned int bus, int high)
27 {
28 	if (high)
29 		gpio_input_pullup(pins[bus].sda);
30 	else
31 		gpio_output(pins[bus].sda, 0);
32 }
33 
tegra_set_scl(unsigned int bus,int high)34 static void tegra_set_scl(unsigned int bus, int high)
35 {
36 	if (high)
37 		gpio_input_pullup(pins[bus].scl);
38 	else
39 		gpio_output(pins[bus].scl, 0);
40 }
41 
tegra_get_sda(unsigned int bus)42 static int tegra_get_sda(unsigned int bus)
43 {
44 	return gpio_get(pins[bus].sda);
45 }
46 
tegra_get_scl(unsigned int bus)47 static int tegra_get_scl(unsigned int bus)
48 {
49 	return gpio_get(pins[bus].scl);
50 }
51 
52 static struct software_i2c_ops tegra_ops = {
53 	.set_sda = tegra_set_sda,
54 	.set_scl = tegra_set_scl,
55 	.get_sda = tegra_get_sda,
56 	.get_scl = tegra_get_scl,
57 };
58 
tegra_software_i2c_init(unsigned int bus)59 void tegra_software_i2c_init(unsigned int bus)
60 {
61 	software_i2c[bus] = &tegra_ops;
62 
63 	/* Initialize bus to idle state. */
64 	tegra_set_sda(bus, 1);
65 	tegra_set_scl(bus, 1);
66 }
67 
tegra_software_i2c_disable(unsigned int bus)68 void tegra_software_i2c_disable(unsigned int bus)
69 {
70 	software_i2c[bus] = NULL;
71 
72 	/* Return pins to I2C controller. */
73 	pinmux_set_config(pins[bus].sda >> GPIO_PINMUX_SHIFT,
74 			  pins[bus].pinmux_func | PINMUX_INPUT_ENABLE);
75 	pinmux_set_config(pins[bus].scl >> GPIO_PINMUX_SHIFT,
76 			  pins[bus].pinmux_func | PINMUX_INPUT_ENABLE);
77 	gpio_set_mode(pins[bus].sda, GPIO_MODE_SPIO);
78 	gpio_set_mode(pins[bus].scl, GPIO_MODE_SPIO);
79 }
80