1 /* 2 * Copyright 2022, Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #ifndef _OCORES_I2C_H_ 8 #define _OCORES_I2C_H_ 9 10 #include <i2c.h> 11 #include <ByteOrder.h> 12 #include <assert.h> 13 14 #include <AutoDeleterOS.h> 15 #include <lock.h> 16 17 18 #define CHECK_RET(err) {status_t _err = (err); if (_err < B_OK) return _err;} 19 20 #define OCORES_I2C_DRIVER_MODULE_NAME "busses/i2c/ocores_i2c/driver_v1" 21 22 23 static_assert(B_HOST_IS_LENDIAN); 24 25 union OcoresI2cRegsAddress7 { 26 struct { 27 uint8 read: 1; 28 uint8 address: 7; 29 }; 30 uint8 val; 31 }; 32 33 union OcoresI2cRegsControl { 34 struct { 35 uint8 unused1: 6; 36 uint8 intEnabled: 1; 37 uint8 enabled: 1; 38 }; 39 uint8 val; 40 }; 41 42 union OcoresI2cRegsCommand { 43 struct { 44 uint8 intAck: 1; 45 uint8 unused1: 2; 46 uint8 nack: 1; 47 uint8 write: 1; 48 uint8 read: 1; 49 uint8 stop: 1; 50 uint8 start: 1; 51 }; 52 uint8 val; 53 }; 54 55 union OcoresI2cRegsStatus { 56 struct { 57 uint8 interrupt: 1; 58 uint8 transferInProgress: 1; 59 uint8 reserved1: 3; 60 uint8 arbitrationLost: 1; 61 uint8 busy: 1; 62 uint8 nackReceived: 1; 63 }; 64 uint8 val; 65 }; 66 67 struct OcoresI2cRegs { 68 uint8 preLo; 69 uint8 align1[3]; 70 uint8 preHi; 71 uint8 align2[3]; 72 OcoresI2cRegsControl control; 73 uint8 align3[3]; 74 uint8 data; 75 uint8 align4[3]; 76 union { 77 OcoresI2cRegsCommand command; 78 OcoresI2cRegsStatus status; 79 }; 80 uint8 align5[3]; 81 }; 82 83 84 class OcoresI2c { 85 public: 86 static float SupportsDevice(device_node* parent); 87 static status_t RegisterDevice(device_node* parent); 88 static status_t InitDriver(device_node* node, OcoresI2c*& outDriver); 89 void UninitDriver(); 90 91 void SetI2cBus(i2c_bus bus); 92 status_t ExecCommand(i2c_op op, 93 i2c_addr slaveAddress, const uint8 *cmdBuffer, size_t cmdLength, 94 uint8* dataBuffer, size_t dataLength); 95 status_t AcquireBus(); 96 void ReleaseBus(); 97 98 private: 99 inline status_t InitDriverInt(device_node* node); 100 static int32 InterruptReceived(void* arg); 101 inline int32 InterruptReceivedInt(); 102 103 status_t WaitCompletion(); 104 status_t WriteByte(OcoresI2cRegsCommand cmd, uint8 val); 105 status_t ReadByte(OcoresI2cRegsCommand cmd, uint8& val); 106 status_t WriteAddress(i2c_addr address, bool isRead); 107 108 private: 109 struct mutex fLock = MUTEX_INITIALIZER("Opencores i2c"); 110 111 AreaDeleter fRegsArea; 112 volatile OcoresI2cRegs* fRegs{}; 113 long fIrqVector = -1; 114 115 device_node* fNode{}; 116 i2c_bus fBus{}; 117 }; 118 119 120 extern device_manager_info* gDeviceManager; 121 extern i2c_for_controller_interface* gI2c; 122 extern i2c_sim_interface gOcoresI2cDriver; 123 124 #endif // _OCORES_I2C_H_ 125