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 #pragma once
6 
7 #include <ddk/platform-defs.h>
8 #include <ddk/protocol/gpioimpl.h>
9 #include <ddk/protocol/platform/bus.h>
10 #include <ddk/protocol/platform-device-lib.h>
11 #include <ddk/protocol/platform/device.h>
12 
13 #include <ddktl/device.h>
14 #include <ddktl/protocol/gpioimpl.h>
15 
16 #include <fbl/array.h>
17 
18 #include <hw/reg.h>
19 #include <hwreg/mmio.h>
20 
21 #include <lib/zx/interrupt.h>
22 #include <lib/zx/port.h>
23 
24 namespace gpio {
25 
26 class Mt8167GpioDevice;
27 using DeviceType = ddk::Device<Mt8167GpioDevice, ddk::Unbindable>;
28 
29 class Mt8167GpioDevice : public DeviceType,
30                          public ddk::GpioImplProtocol<Mt8167GpioDevice, ddk::base_protocol> {
31 public:
32     static zx_status_t Create(zx_device_t* parent);
33 
Mt8167GpioDevice(zx_device_t * parent,mmio_buffer_t gpio_mmio,mmio_buffer_t iocfg_mmio,mmio_buffer_t eint_mmio)34     explicit Mt8167GpioDevice(zx_device_t* parent, mmio_buffer_t gpio_mmio,
35                               mmio_buffer_t iocfg_mmio, mmio_buffer_t eint_mmio)
36         : DeviceType(parent),
37           gpio_mmio_(gpio_mmio),
38           dir_(gpio_mmio),
39           out_(gpio_mmio),
40           in_(gpio_mmio),
41           pull_en_(gpio_mmio),
42           pull_sel_(gpio_mmio),
43           iocfg_(iocfg_mmio),
44           eint_(eint_mmio) {}
45 
46     zx_status_t Bind();
47     zx_status_t Init();
48 
49     // Methods required by the ddk mixins
50     void DdkUnbind();
51     void DdkRelease();
52 
53     zx_status_t GpioImplConfigIn(uint32_t index, uint32_t flags);
54     zx_status_t GpioImplConfigOut(uint32_t index, uint8_t initial_value);
55     zx_status_t GpioImplSetAltFunction(uint32_t index, uint64_t function);
56     zx_status_t GpioImplRead(uint32_t index, uint8_t* out_value);
57     zx_status_t GpioImplWrite(uint32_t index, uint8_t value);
58     zx_status_t GpioImplGetInterrupt(uint32_t index, uint32_t flags, zx::interrupt* out_irq);
59     zx_status_t GpioImplReleaseInterrupt(uint32_t index);
60     zx_status_t GpioImplSetPolarity(uint32_t index, uint32_t polarity);
61 
62 private:
63     void ShutDown();
64     int Thread();
65 
66     ddk::MmioBuffer gpio_mmio_;
67     const GpioDirReg dir_;
68     const GpioOutReg out_;
69     const GpioInReg in_;
70     const GpioPullEnReg pull_en_;
71     const GpioPullSelReg pull_sel_;
72     const IoConfigReg iocfg_;
73     const ExtendedInterruptReg eint_;
74     zx::interrupt int_;
75     zx::port port_;
76     thrd_t thread_;
77     fbl::Array<zx::interrupt> interrupts_;
78 };
79 } // namespace gpio
80