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-s905d2/s905d2-gpio.h>
9 #include <soc/aml-s905d2/s905d2-hw.h>
10 
11 #include <limits.h>
12 
13 #include "astro.h"
14 
15 static const pbus_mmio_t i2c_mmios[] = {
16     {
17         .base = S905D2_I2C_AO_0_BASE,
18         .length = 0x20,
19     },
20     {
21         .base = S905D2_I2C2_BASE,
22         .length = 0x20,
23     },
24     {
25         .base = S905D2_I2C3_BASE,
26         .length = 0x20,
27     },
28 };
29 
30 static const pbus_irq_t i2c_irqs[] = {
31     {
32         .irq = S905D2_I2C_AO_0_IRQ,
33         .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
34     },
35     {
36         .irq = S905D2_I2C2_IRQ,
37         .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
38     },
39     {
40         .irq = S905D2_I2C3_IRQ,
41         .mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
42     },
43 };
44 
45 static const pbus_dev_t i2c_dev = {
46     .name = "i2c",
47     .vid = PDEV_VID_AMLOGIC,
48     .pid = PDEV_PID_GENERIC,
49     .did = PDEV_DID_AMLOGIC_I2C,
50     .mmio_list = i2c_mmios,
51     .mmio_count = countof(i2c_mmios),
52     .irq_list = i2c_irqs,
53     .irq_count = countof(i2c_irqs),
54 };
55 
aml_i2c_init(aml_bus_t * bus)56 zx_status_t aml_i2c_init(aml_bus_t* bus) {
57     // setup pinmux for our I2C busses
58 
59     //i2c_ao_0
60     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOAO(2), 1);
61     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOAO(3), 1);
62     //i2c2
63     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOZ(14), 3);
64     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOZ(15), 3);
65     //i2c3
66     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOA(14), 2);
67     gpio_impl_set_alt_function(&bus->gpio, S905D2_GPIOA(15), 2);
68 
69     zx_status_t status = pbus_protocol_device_add(&bus->pbus, ZX_PROTOCOL_I2C_IMPL, &i2c_dev);
70     if (status != ZX_OK) {
71         zxlogf(ERROR, "aml_i2c_init: pbus_protocol_device_add failed: %d\n", status);
72         return status;
73     }
74 
75     return ZX_OK;
76 }
77