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