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/protocol/i2c.h> 8 9#include <ddktl/device.h> 10#include <ddktl/protocol/i2c-impl.h> 11 12#include <fbl/atomic.h> 13#include <fbl/unique_ptr.h> 14 15#include <hw/reg.h> 16#include <hwreg/mmio.h> 17 18namespace imx_i2c { 19 20class ImxI2cDevice; 21using DeviceType = ddk::Device<ImxI2cDevice, ddk::Unbindable>; 22 23class ImxI2cDevice : public DeviceType, 24 public ddk::I2cImplProtocol<ImxI2cDevice> { 25public: 26 ImxI2cDevice(zx_device_t* parent, int dev_cnt) 27 : DeviceType(parent), dev_cnt_(dev_cnt) {} 28 29 zx_status_t Bind(int id); 30 31 // Methods required by the ddk mixins 32 void DdkUnbind(); 33 void DdkRelease(); 34 uint32_t I2cImplGetBusCount(); 35 zx_status_t I2cImplGetMaxTransferSize(uint32_t bus_id, size_t* out_size); 36 zx_status_t I2cImplSetBitRate(uint32_t bus_id, uint32_t bitrate); 37 zx_status_t I2cImplTransact(uint32_t bus_id, i2c_impl_op_t* ops, size_t count); 38 39private: 40 enum class Wait { 41 kBusy, 42 kIdle, 43 kInterruptPending 44 }; 45 static constexpr const char* WaitStr(Wait type) { 46 switch (type) { 47 case Wait::kBusy: 48 return "BUSY"; 49 case Wait::kIdle: 50 return "IDLE"; 51 case Wait::kInterruptPending: 52 return "INTERRUPT_PENDING"; 53 } 54 return "UNKNOWN"; 55 } 56 const uint32_t dev_cnt_; 57 thrd_t thread_; 58 io_buffer_t regs_iobuff_; 59 fbl::unique_ptr<hwreg::RegisterIo> mmio_; 60 fbl::atomic<bool> ready_; 61 62 void Reset(); 63 zx_status_t Read(uint8_t addr, void* buf, size_t len, bool stop); 64 zx_status_t Write(uint8_t addr, const void* buf, size_t len, bool stop); 65 zx_status_t Start(); 66 void Stop(); 67 zx_status_t RxData(uint8_t* buf, size_t length, bool stop); 68 zx_status_t TxData(const uint8_t* buf, size_t length, bool stop); 69 zx_status_t TxAddress(uint8_t addr, bool is_read); 70 zx_status_t WaitFor(Wait type); 71 int Thread(); 72 void ShutDown(); 73}; 74} // namespace imx_i2c 75