1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/debug.h>
6 #include <ddk/device.h>
7 #include <ddk/platform-defs.h>
8 #include <soc/aml-s912/s912-gpio.h>
9 #include <soc/aml-s912/s912-hw.h>
10
11 #include <limits.h>
12
13 #include "vim.h"
14
15 static const pbus_mmio_t i2c_mmios[] = {
16 {
17 .base = S912_I2C_A_BASE,
18 .length = S912_I2C_A_LENGTH,
19 },
20 {
21 .base = S912_I2C_B_BASE,
22 .length = S912_I2C_B_LENGTH,
23 },
24 {
25 .base = S912_I2C_C_BASE,
26 .length = S912_I2C_C_LENGTH,
27 },
28 /*
29 {
30 .base = S912_I2C_D_BASE,
31 .length = S912_I2C_D_LENGTH,
32 },
33 */
34 };
35
36 static const pbus_irq_t i2c_irqs[] = {
37 {
38 .irq = S912_M_I2C_0_IRQ,
39 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
40 },
41 {
42 .irq = S912_M_I2C_1_IRQ,
43 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
44 },
45 {
46 .irq = S912_M_I2C_2_IRQ,
47 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
48 },
49 /*
50 {
51 .irq = S912_M_I2C_3_IRQ,
52 .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
53 },
54 */
55 };
56
57 static const pbus_dev_t i2c_dev = {
58 .name = "i2c",
59 .vid = PDEV_VID_AMLOGIC,
60 .pid = PDEV_PID_GENERIC,
61 .did = PDEV_DID_AMLOGIC_I2C,
62 .mmio_list = i2c_mmios,
63 .mmio_count = countof(i2c_mmios),
64 .irq_list = i2c_irqs,
65 .irq_count = countof(i2c_irqs),
66 };
67
vim_i2c_init(vim_bus_t * bus)68 zx_status_t vim_i2c_init(vim_bus_t* bus) {
69 // setup pinmux for our I2C busses
70 // I2C_A and I2C_B are exposed on the 40 pin header and I2C_C on the FPC connector
71 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_A, S912_I2C_SDA_A_FN);
72 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_A, S912_I2C_SCK_A_FN);
73 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_B, S912_I2C_SDA_B_FN);
74 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_B, S912_I2C_SCK_B_FN);
75 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SDA_C, S912_I2C_SDA_C_FN);
76 gpio_impl_set_alt_function(&bus->gpio, S912_I2C_SCK_C, S912_I2C_SCK_C_FN);
77
78 zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_I2C_IMPL, &i2c_dev);
79 if (status != ZX_OK) {
80 zxlogf(ERROR, "vim_i2c_init: pbus_protocol_device_add failed: %d\n", status);
81 return status;
82 }
83
84 return ZX_OK;
85 }
86