1 /* 2 * IBM CFF power supplies device 3 * 4 * Copyright (c) 2019 IBM Corporation. 5 * 6 * This code is licensed under the GPL version 2 or later. See the 7 * COPYING file in the top-level directory. 8 */ 9 10 #include "qemu/osdep.h" 11 #include "hw/hw.h" 12 #include "hw/i2c/i2c.h" 13 #include "qapi/error.h" 14 #include "qapi/visitor.h" 15 #include "hw/misc/pmbus_regs.h" 16 #include "migration/vmstate.h" 17 18 #define IR35221_MFR_VIN_PEAK 0xc5 19 #define IR35221_MFR_VOUT_PEAK 0xc6 20 #define IR35221_MFR_IOUT_PEAK 0xc7 21 #define IR35221_MFR_TEMP_PEAK 0xc8 22 #define IR35221_MFR_VIN_VALLEY 0xc9 23 #define IR35221_MFR_VOUT_VALLEY 0xca 24 #define IR35221_MFR_IOUT_VALLEY 0xcb 25 #define IR35221_MFR_TEMP_VALLEY 0xcc 26 27 typedef struct Ir35221State { 28 /*< private >*/ 29 I2CSlave i2c; 30 /*< public >*/ 31 32 uint8_t regs[0x100]; 33 34 uint8_t len; 35 uint8_t buf[32]; 36 uint8_t pointer; 37 38 } Ir35221State; 39 40 #define TYPE_IR35221 "ir35221" 41 #define IR35221(obj) OBJECT_CHECK(Ir35221State, (obj), TYPE_IR35221) 42 43 static void ir35221_read(Ir35221State *s) 44 { 45 s->len = 0; 46 47 switch (s->pointer) { 48 case PMBUS_MFR_ID: 49 s->buf[s->len++] = 2; /* Byte count */ 50 s->buf[s->len++] = 'R'; 51 s->buf[s->len++] = 'I'; 52 break; 53 case PMBUS_MFR_MODEL: 54 s->buf[s->len++] = 2; /* Byte count */ 55 s->buf[s->len++] = 0x6c; 56 s->buf[s->len++] = 0x00; 57 break; 58 default: 59 s->buf[s->len++] = s->regs[s->pointer]; 60 break; 61 } 62 } 63 64 static void ir35221_write(Ir35221State *s) 65 { 66 /* No writes */ 67 } 68 69 static uint8_t ir35221_recv(I2CSlave *i2c) 70 { 71 Ir35221State *s = IR35221(i2c); 72 73 if (s->len < sizeof(s->buf)) { 74 return s->buf[s->len++]; 75 } else { 76 return 0xff; 77 } 78 } 79 80 static int ir35221_send(I2CSlave *i2c, uint8_t data) 81 { 82 Ir35221State *s = IR35221(i2c); 83 84 if (s->len == 0) { 85 /* 86 * first byte is the register pointer for a read or write 87 * operation 88 */ 89 s->pointer = data; 90 s->len++; 91 } else { 92 /* 93 * next bytes are data to write. 94 */ 95 if (s->len <= sizeof(s->buf)) { 96 s->buf[s->len - 1] = data; 97 } 98 s->len++; 99 ir35221_write(s); 100 } 101 102 return 0; 103 } 104 105 static int ir35221_event(I2CSlave *i2c, enum i2c_event event) 106 { 107 Ir35221State *s = IR35221(i2c); 108 109 /* TODO: handle SMBus "block read" */ 110 111 switch (event) { 112 case I2C_START_RECV: 113 ir35221_read(s); 114 break; 115 case I2C_START_SEND: 116 case I2C_NACK: 117 case I2C_FINISH: 118 s->pointer = 0xFF; 119 break; 120 default: 121 return -1; 122 } 123 124 s->len = 0; 125 return 0; 126 } 127 128 static const VMStateDescription vmstate_ir35221 = { 129 .name = TYPE_IR35221, 130 .version_id = 0, 131 .minimum_version_id = 0, 132 .fields = (VMStateField[]) { 133 VMSTATE_UINT8(len, Ir35221State), 134 VMSTATE_UINT8_ARRAY(buf, Ir35221State, 32), 135 VMSTATE_UINT8(pointer, Ir35221State), 136 VMSTATE_UINT8_ARRAY(regs, Ir35221State, 0x100), 137 VMSTATE_I2C_SLAVE(i2c, Ir35221State), 138 VMSTATE_END_OF_LIST() 139 } 140 }; 141 142 static void ir35221_reset(DeviceState *dev) 143 { 144 Ir35221State *s = IR35221(dev); 145 146 memset(s->regs, 0, sizeof(s->regs)); 147 s->pointer = 0xFF; 148 } 149 150 static void ir35221_realize(DeviceState *dev, Error **errp) 151 { 152 ; 153 } 154 155 static void ir35221_class_init(ObjectClass *klass, void *data) 156 { 157 DeviceClass *dc = DEVICE_CLASS(klass); 158 I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); 159 160 dc->realize = ir35221_realize; 161 device_class_set_legacy_reset(dc, ir35221_reset); 162 k->event = ir35221_event; 163 k->recv = ir35221_recv; 164 k->send = ir35221_send; 165 dc->vmsd = &vmstate_ir35221; 166 } 167 168 static const TypeInfo ir35221_info = { 169 .name = TYPE_IR35221, 170 .parent = TYPE_I2C_SLAVE, 171 .instance_size = sizeof(Ir35221State), 172 .class_init = ir35221_class_init, 173 }; 174 175 static void ir35221_register_types(void) 176 { 177 type_register_static(&ir35221_info); 178 } 179 180 type_init(ir35221_register_types) 181