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