1 //
2 // Copyright (c) 2010-2025 Antmicro
3 //
4 // This file is licensed under the MIT License.
5 // Full license text is available in 'licenses/MIT.txt'.
6 //
7 using Antmicro.Renode.Core.Structure.Registers;
8 using Antmicro.Renode.Core;
9 using Antmicro.Renode.Peripherals.Bus;
10 using Antmicro.Renode.Core.Structure;
11 using Antmicro.Renode.Logging;
12 using Antmicro.Renode.Utilities;
13 
14 // minimal model compliant with u-boot rk_i2c driver
15 // does nothing except facilitating probe
16 namespace Antmicro.Renode.Peripherals.I2C
17 {
18     [AllowedTranslations(AllowedTranslation.WordToDoubleWord | AllowedTranslation.ByteToDoubleWord)]
19     public class RockchipI2C : SimpleContainer<II2CPeripheral>, IDoubleWordPeripheral, IKnownSize, IProvidesRegisterCollection<DoubleWordRegisterCollection>
20     {
RockchipI2C(IMachine machine)21         public RockchipI2C(IMachine machine) : base(machine)
22         {
23             IRQ = new GPIO();
24             RegistersCollection = new DoubleWordRegisterCollection(this);
25             DefineRegisters();
26             Reset();
27         }
28 
Reset()29         public override void Reset()
30         {
31             RegistersCollection.Reset();
32         }
33 
ReadDoubleWord(long offset)34         public uint ReadDoubleWord(long offset)
35         {
36             return RegistersCollection.Read(offset);
37         }
38 
WriteDoubleWord(long offset, uint value)39         public void WriteDoubleWord(long offset, uint value)
40         {
41             RegistersCollection.Write(offset, value);
42         }
43 
44         public DoubleWordRegisterCollection RegistersCollection { get; }
45         public long Size => 0x1000;
46         [IrqProvider]
47         public GPIO IRQ { get; private set; }
48 
DefineRegisters()49         private void DefineRegisters()
50         {
51             Registers.Con.Define(this)
52                 .WithTaggedFlag("i2c_en", 0)
53                 .WithTag("i2c_mode", 1, 2)
54                 .WithFlag(3, out startTransmission, name: "start")
55                 .WithFlag(4, out stopTransmission, name: "stop")
56                 .WithTaggedFlag("ack", 5)
57                 .WithTaggedFlag("act2nak", 6)
58                 .WithReservedBits(7, 25)
59             ;
60 
61             Registers.MrxAddr.Define(this)
62                 .WithTaggedFlag("Read/Write", 0)
63                 .WithTag("Master address register", 1, 23)
64                 .WithTaggedFlag("Address low byte valid (addlvld)", 24)
65                 .WithTaggedFlag("address middle byte valid (addmvld)", 25)
66                 .WithTaggedFlag("address high byte valid (addhvld)", 26)
67                 .WithReservedBits(27, 5)
68             ;
69 
70             Registers.ClkDiv.Define(this)
71                 .WithTag("SCL low level clock count (CLKDIVL)", 0, 16)
72                 .WithTag("SCL high level clock count (CLKDIVH)", 16, 16)
73             ;
74 
75             Registers.Ien.Define(this)
76                 .WithTaggedFlag("Byte trasmit finished interrupt enable (btfien)", 0)
77                 .WithTaggedFlag("Byte receive finished interrupt enable (brfien)", 1)
78                 .WithTaggedFlag("MTXCNT data transmit finished interrupt enable (mbtfien)", 2)
79                 .WithTaggedFlag("MRXCNT data received finished interrupt enable (mbrfien)", 3)
80                 .WithTaggedFlag("Start operation finished interrupt enable (startien)", 4)
81                 .WithTaggedFlag("Stop operation finished interrupt enable (stopien)", 5)
82                 .WithTaggedFlag("NAK handshake received interrupt enable (nakrcvien)", 6)
83                 .WithReservedBits(7, 25)
84             ;
85 
86             Registers.Ipd.Define(this)
87                 .WithTaggedFlag("Byte trasmit finished interrupt pending bit (btfipd)", 0)
88                 .WithTaggedFlag("Byte receive finished interrupt pending bit (brfipd)", 1)
89                 .WithFlag(2, name: "MTXCNT data transmit finished interrupt pending bit (mbtfipd)", valueProviderCallback: _ => true)
90                 .WithFlag(3, name: "MRXCNT data received finished interrupt pending bit (mbrfipd)", valueProviderCallback: _ => true)
91                 .WithFlag(4, name: "Start operation finished interrupt pending bit (startipd)", valueProviderCallback: _ => startTransmission.Value)
92                 .WithFlag(5, name: "Stop operation finished interrupt pending bit (stopipd)", valueProviderCallback: _ => stopTransmission.Value)
93                 .WithTaggedFlag("NAK handshake received interrupt pending bit (nakrcvipd)", 6)
94                 .WithReservedBits(7, 25)
95             ;
96         }
97 
98         private IFlagRegisterField stopTransmission;
99         private IFlagRegisterField startTransmission;
100         private enum Registers
101         {
102             Con = 0x0, // config
103             ClkDiv = 0x04, // clock divisor
104             MrxAddr = 0x08, // slave address accessed
105             Ien = 0x18, // interrupt enabled
106             Ipd = 0x1C, // interrupt pending
107             TxData0 = 0x100,
108         }
109     }
110 }
111