1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2022, Microchip 4 */ 5 6 #ifndef __DRIVERS_I2C_H 7 #define __DRIVERS_I2C_H 8 9 #include <kernel/dt_driver.h> 10 #include <libfdt.h> 11 #include <tee_api_types.h> 12 13 /** 14 * DEFINE_I2C_DEV_DRIVER - Declare an I2C driver 15 * 16 * @__name: I2C device driver name 17 * @__match_table: match table associated to the driver 18 * @__i2c_probe: I2C probe function with the following prototype: 19 * TEE_Result (*probe)(struct i2c_dev *i2c_dev, const void *fdt, 20 * int node, const void *compat_data); 21 */ 22 #define DEFINE_I2C_DEV_DRIVER(__name, __match_table, __i2c_probe) \ 23 static TEE_Result __name ## _probe_i2c_dev(const void *fdt, int node, \ 24 const void *compat_data) \ 25 { \ 26 struct i2c_dev *i2c_dev = NULL; \ 27 TEE_Result res = TEE_ERROR_GENERIC; \ 28 \ 29 res = i2c_dt_get_dev(fdt, node, &i2c_dev); \ 30 if (res) \ 31 return res; \ 32 return __i2c_probe(i2c_dev, fdt, node, compat_data); \ 33 } \ 34 DEFINE_DT_DRIVER(__name ## _dt_driver) = { \ 35 .name = # __name, \ 36 .type = DT_DRIVER_I2C, \ 37 .match_table = __match_table, \ 38 .probe = __name ## _probe_i2c_dev, \ 39 } 40 41 #define I2C_SMBUS_MAX_BUF_SIZE 32 42 43 enum i2c_smbus_dir { 44 I2C_SMBUS_READ, 45 I2C_SMBUS_WRITE, 46 }; 47 48 enum i2c_smbus_protocol { 49 I2C_SMBUS_PROTO_BYTE, 50 /* 51 * Like block but does not insert "count" in sent data, useful for 52 * EEPROM read for instance which is not SMBus but requires such 53 * sequence. 54 */ 55 I2C_SMBUS_PROTO_BLOCK_RAW, 56 }; 57 58 struct i2c_ctrl; 59 60 /** 61 * struct i2c_dev - I2C device 62 * 63 * @ctrl: I2C controller associated to the device 64 * @addr: device address on the I2C bus 65 */ 66 struct i2c_dev { 67 struct i2c_ctrl *ctrl; 68 uint16_t addr; 69 }; 70 71 /** 72 * struct i2c_ctrl_ops - Operations provided by I2C controller drivers 73 * 74 * @read: I2C read operation 75 * @write: I2C write operation 76 * @smbus: SMBus protocol operation 77 */ 78 struct i2c_ctrl_ops { 79 TEE_Result (*read)(struct i2c_dev *i2c_dev, uint8_t *buf, size_t len); 80 TEE_Result (*write)(struct i2c_dev *i2c_dev, const uint8_t *buf, 81 size_t len); 82 TEE_Result (*smbus)(struct i2c_dev *i2c_dev, enum i2c_smbus_dir dir, 83 enum i2c_smbus_protocol proto, uint8_t cmd_code, 84 uint8_t *buf, size_t len); 85 }; 86 87 /** 88 * struct i2c_ctrl - I2C controller 89 * 90 * @ops: Operations associated to the I2C controller 91 */ 92 struct i2c_ctrl { 93 const struct i2c_ctrl_ops *ops; 94 }; 95 96 #ifdef CFG_DRIVERS_I2C 97 /** 98 * i2c_create_dev - Create and i2c_dev struct from device-tree 99 * 100 * @i2c_ctrl: Controller to be used with this device 101 * @fdt: Device-tree to work on 102 * @node: Node to work on in @fdt provided device-tree 103 * 104 * Return an i2c_dev struct filled from device-tree description 105 */ 106 struct i2c_dev *i2c_create_dev(struct i2c_ctrl *i2c_ctrl, const void *fdt, 107 int node); 108 109 /** 110 * i2c_write() - Execute an I2C write on the I2C bus 111 * 112 * @i2c_dev: I2C device used for writing 113 * @buf: Buffer of data to be written 114 * @len: Length of data to be written 115 * 116 * Return a TEE_Result compliant value 117 */ 118 static inline TEE_Result i2c_write(struct i2c_dev *i2c_dev, const uint8_t *buf, 119 size_t len) 120 { 121 if (!i2c_dev->ctrl->ops->write) 122 return TEE_ERROR_NOT_SUPPORTED; 123 124 return i2c_dev->ctrl->ops->write(i2c_dev, buf, len); 125 } 126 127 /** 128 * i2c_read() - Execute an I2C read on the I2C bus 129 * 130 * @i2c_dev: I2C device used for reading 131 * @buf: Buffer containing the read data 132 * @len: Length of data to be read 133 * 134 * Return a TEE_Result compliant value 135 */ 136 static inline TEE_Result i2c_read(struct i2c_dev *i2c_dev, uint8_t *buf, 137 size_t len) 138 { 139 if (!i2c_dev->ctrl->ops->read) 140 return TEE_ERROR_NOT_SUPPORTED; 141 142 return i2c_dev->ctrl->ops->read(i2c_dev, buf, len); 143 } 144 145 /** 146 * i2c_smbus_raw() - Execute a raw SMBUS request 147 * 148 * @i2c_dev: I2C device used for SMBus operation 149 * @dir: Direction for the SMBus transfer 150 * @proto: SMBus Protocol to be executed 151 * @cmd_code: Command code 152 * @buf: Buffer used for read/write operation 153 * @len: Length of buffer to be read/write 154 * 155 * Return a TEE_Result compliant value 156 */ 157 static inline TEE_Result i2c_smbus_raw(struct i2c_dev *i2c_dev, 158 enum i2c_smbus_dir dir, 159 enum i2c_smbus_protocol proto, 160 uint8_t cmd_code, uint8_t *buf, 161 size_t len) 162 { 163 if (!i2c_dev->ctrl->ops->smbus) 164 return TEE_ERROR_NOT_SUPPORTED; 165 166 if (len > I2C_SMBUS_MAX_BUF_SIZE) 167 return TEE_ERROR_BAD_PARAMETERS; 168 169 return i2c_dev->ctrl->ops->smbus(i2c_dev, dir, proto, cmd_code, buf, 170 len); 171 } 172 173 /** 174 * i2c_dt_get_dev - Get an I2C device from a DT node 175 * 176 * @fdt: Device tree to work on 177 * @nodeoffset: Node offset of the I2C bus consumer 178 * @i2c_dev: Output I2C bus device upon success 179 * 180 * Return TEE_SUCCESS in case of success 181 * Return TEE_ERROR_DEFER_DRIVER_INIT if I2C controller is not initialized 182 * Return TEE_ERROR_ITEM_NOT_FOUND if the I2C controller node does not exist 183 * Return a TEE_Result compliant code in case of error 184 */ 185 static inline TEE_Result i2c_dt_get_dev(const void *fdt, int nodeoffset, 186 struct i2c_dev **out_i2c_dev) 187 { 188 TEE_Result res = TEE_ERROR_GENERIC; 189 void *i2c_dev = NULL; 190 191 res = dt_driver_device_from_parent(fdt, nodeoffset, DT_DRIVER_I2C, 192 &i2c_dev); 193 if (!res) 194 *out_i2c_dev = i2c_dev; 195 196 return res; 197 } 198 #else 199 static inline TEE_Result i2c_write(struct i2c_dev *i2c_dev __unused, 200 const uint8_t *buf __unused, 201 size_t len __unused) 202 { 203 return TEE_ERROR_NOT_SUPPORTED; 204 } 205 206 static inline TEE_Result i2c_read(struct i2c_dev *i2c_dev __unused, 207 uint8_t *buf __unused, size_t len __unused) 208 { 209 return TEE_ERROR_NOT_SUPPORTED; 210 } 211 212 static inline TEE_Result i2c_smbus_raw(struct i2c_dev *i2c_dev __unused, 213 enum i2c_smbus_dir dir __unused, 214 enum i2c_smbus_protocol proto __unused, 215 uint8_t cmd_code __unused, 216 uint8_t *buf __unused, 217 size_t len __unused) 218 { 219 return TEE_ERROR_NOT_SUPPORTED; 220 } 221 222 static inline TEE_Result i2c_dt_get_dev(const void *fdt __unused, 223 int nodeoffset __unused, 224 struct i2c_dev **i2c_dev __unused) 225 { 226 return TEE_ERROR_NOT_SUPPORTED; 227 } 228 #endif 229 230 /** 231 * i2c_dt_get_func - Typedef of function to get I2C bus device from 232 * devicetree properties 233 * 234 * @args: Pointer to devicetree description of the I2C bus device to parse 235 * @data: Pointer to data given at i2c_dt_register_provider() call 236 * @out_device: Output pointer to I2C device upon success 237 */ 238 typedef TEE_Result (*i2c_dt_get_func)(struct dt_pargs *args, void *data, 239 struct i2c_dev **out_device); 240 241 /** 242 * i2c_dt_register_provider - Register a I2C controller provider and add all the 243 * child nodes of this controller in the DT probe list. 244 * 245 * @fdt: Device tree to work on 246 * @nodeoffset: Node offset of the I2C controller 247 * @get_dt_i2c: Callback to match the I2C controller with a struct i2c 248 * @data: Data which will be passed to the get_dt_i2c callback 249 * Returns TEE_Result value 250 */ 251 static inline TEE_Result i2c_register_provider(const void *fdt, int nodeoffset, 252 i2c_dt_get_func get_dt_i2c, 253 void *data) 254 { 255 int subnode = -1; 256 TEE_Result res = TEE_ERROR_GENERIC; 257 258 res = dt_driver_register_provider(fdt, nodeoffset, 259 (get_of_device_func)get_dt_i2c, 260 data, DT_DRIVER_I2C); 261 if (res) 262 return res; 263 264 fdt_for_each_subnode(subnode, fdt, nodeoffset) 265 dt_driver_maybe_add_probe_node(fdt, subnode); 266 267 return TEE_SUCCESS; 268 } 269 270 /** 271 * i2c_smbus_read_byte_data() - Execute a read byte SMBus protocol operation 272 * 273 * @i2c_dev: I2C device used for SMBus operation 274 * @cmd_code: Command code to read 275 * @byte: Returned byte value read from device 276 * 277 * Return a TEE_Result compliant value 278 */ 279 static inline TEE_Result i2c_smbus_read_byte_data(struct i2c_dev *i2c_dev, 280 uint8_t cmd_code, 281 uint8_t *byte) 282 { 283 return i2c_smbus_raw(i2c_dev, I2C_SMBUS_READ, I2C_SMBUS_PROTO_BYTE, 284 cmd_code, byte, 1); 285 } 286 287 /** 288 * i2c_smbus_write_byte_data() - Execute a write byte SMBus protocol operation 289 * 290 * @i2c_dev: I2C device used for SMBus operation 291 * @cmd_code: Command code for write operation 292 * @byte: Byte to be written to the device 293 * 294 * Return a TEE_Result compliant value 295 */ 296 static inline TEE_Result i2c_smbus_write_byte_data(struct i2c_dev *i2c_dev, 297 uint8_t cmd_code, 298 uint8_t byte) 299 { 300 return i2c_smbus_raw(i2c_dev, I2C_SMBUS_WRITE, I2C_SMBUS_PROTO_BYTE, 301 cmd_code, &byte, 1); 302 } 303 304 /** 305 * i2c_bus_read_block_raw() - Execute a non-standard SMBus raw block read. 306 * This does not insert the "count" of byte to be written unlike the SMBus block 307 * read operation. 308 * 309 * @i2c_dev: I2C device used for SMBus operation 310 * @cmd_code: Command code for read operation 311 * @buf: Buffer of data read from device 312 * @len: Length of data to be read from the device 313 * 314 * Return a TEE_Result compliant value 315 */ 316 static inline TEE_Result i2c_bus_read_block_raw(struct i2c_dev *i2c_dev, 317 uint8_t cmd_code, uint8_t *buf, 318 size_t len) 319 { 320 return i2c_smbus_raw(i2c_dev, I2C_SMBUS_READ, I2C_SMBUS_PROTO_BLOCK_RAW, 321 cmd_code, buf, len); 322 } 323 324 /** 325 * i2c_bus_write_block_raw() - Execute a non-standard SMBus raw block write. 326 * This does not insert the "count" of byte to be written unlike the SMBus block 327 * write operation. 328 * 329 * @i2c_dev: I2C device used for SMBus operation 330 * @cmd_code: Command code for write operation 331 * @buf: Buffer of data to be written to the device 332 * @len: Length of data to be written to the device 333 * 334 * Return a TEE_Result compliant value 335 */ 336 static inline TEE_Result i2c_bus_write_block_raw(struct i2c_dev *i2c_dev, 337 uint8_t cmd_code, 338 uint8_t *buf, size_t len) 339 { 340 return i2c_smbus_raw(i2c_dev, I2C_SMBUS_WRITE, 341 I2C_SMBUS_PROTO_BLOCK_RAW, cmd_code, buf, len); 342 } 343 344 #endif 345