xref: /optee_os/core/include/drivers/i2c.h (revision 5395fe8961bcd59dcdaed0748ff101b01dff18f2)
18bc9c9e2SClément Léger /* SPDX-License-Identifier: BSD-2-Clause */
28bc9c9e2SClément Léger /*
38bc9c9e2SClément Léger  * Copyright (c) 2022, Microchip
48bc9c9e2SClément Léger  */
58bc9c9e2SClément Léger 
68bc9c9e2SClément Léger #ifndef __DRIVERS_I2C_H
78bc9c9e2SClément Léger #define __DRIVERS_I2C_H
88bc9c9e2SClément Léger 
98bc9c9e2SClément Léger #include <kernel/dt_driver.h>
108bc9c9e2SClément Léger #include <libfdt.h>
118bc9c9e2SClément Léger #include <tee_api_types.h>
128bc9c9e2SClément Léger 
138bc9c9e2SClément Léger /**
148bc9c9e2SClément Léger  * DEFINE_I2C_DEV_DRIVER - Declare an I2C driver
158bc9c9e2SClément Léger  *
168bc9c9e2SClément Léger  * @__name: I2C device driver name
178bc9c9e2SClément Léger  * @__match_table: match table associated to the driver
188bc9c9e2SClément Léger  * @__i2c_probe: I2C probe function with the following prototype:
198bc9c9e2SClément Léger  *	TEE_Result (*probe)(struct i2c_dev *i2c_dev, const void *fdt,
208bc9c9e2SClément Léger  *			    int node, const void *compat_data);
218bc9c9e2SClément Léger  */
228bc9c9e2SClément Léger #define DEFINE_I2C_DEV_DRIVER(__name, __match_table, __i2c_probe) \
238bc9c9e2SClément Léger 	static TEE_Result __name ## _probe_i2c_dev(const void *fdt, int node, \
248bc9c9e2SClément Léger 						   const void *compat_data) \
258bc9c9e2SClément Léger 	{ \
268bc9c9e2SClément Léger 		struct i2c_dev *i2c_dev = NULL; \
278bc9c9e2SClément Léger 		TEE_Result res = TEE_ERROR_GENERIC; \
288bc9c9e2SClément Léger 		\
298bc9c9e2SClément Léger 		res = i2c_dt_get_dev(fdt, node, &i2c_dev); \
308bc9c9e2SClément Léger 		if (res) \
318bc9c9e2SClément Léger 			return res; \
328bc9c9e2SClément Léger 		return __i2c_probe(i2c_dev, fdt, node, compat_data); \
338bc9c9e2SClément Léger 	} \
348bc9c9e2SClément Léger 	DEFINE_DT_DRIVER(__name ## _dt_driver) = { \
358bc9c9e2SClément Léger 		.name = # __name, \
368bc9c9e2SClément Léger 		.type = DT_DRIVER_I2C, \
378bc9c9e2SClément Léger 		.match_table = __match_table, \
388bc9c9e2SClément Léger 		.probe = __name ## _probe_i2c_dev, \
398bc9c9e2SClément Léger 	}
408bc9c9e2SClément Léger 
418bc9c9e2SClément Léger #define I2C_SMBUS_MAX_BUF_SIZE	32
428bc9c9e2SClément Léger 
438bc9c9e2SClément Léger enum i2c_smbus_dir {
448bc9c9e2SClément Léger 	I2C_SMBUS_READ,
458bc9c9e2SClément Léger 	I2C_SMBUS_WRITE,
468bc9c9e2SClément Léger };
478bc9c9e2SClément Léger 
488bc9c9e2SClément Léger enum i2c_smbus_protocol {
498bc9c9e2SClément Léger 	I2C_SMBUS_PROTO_BYTE,
508bc9c9e2SClément Léger 	/*
518bc9c9e2SClément Léger 	 * Like block but does not insert "count" in sent data, useful for
528bc9c9e2SClément Léger 	 * EEPROM read for instance which is not SMBus but requires such
538bc9c9e2SClément Léger 	 * sequence.
548bc9c9e2SClément Léger 	 */
558bc9c9e2SClément Léger 	I2C_SMBUS_PROTO_BLOCK_RAW,
568bc9c9e2SClément Léger };
578bc9c9e2SClément Léger 
588bc9c9e2SClément Léger struct i2c_ctrl;
598bc9c9e2SClément Léger 
608bc9c9e2SClément Léger /**
618bc9c9e2SClément Léger  * struct i2c_dev - I2C device
628bc9c9e2SClément Léger  *
638bc9c9e2SClément Léger  * @ctrl: I2C controller associated to the device
648bc9c9e2SClément Léger  * @addr: device address on the I2C bus
658bc9c9e2SClément Léger  */
668bc9c9e2SClément Léger struct i2c_dev {
678bc9c9e2SClément Léger 	struct i2c_ctrl *ctrl;
688bc9c9e2SClément Léger 	uint16_t addr;
698bc9c9e2SClément Léger };
708bc9c9e2SClément Léger 
718bc9c9e2SClément Léger /**
728bc9c9e2SClément Léger  * struct i2c_ctrl_ops - Operations provided by I2C controller drivers
738bc9c9e2SClément Léger  *
748bc9c9e2SClément Léger  * @read: I2C read operation
758bc9c9e2SClément Léger  * @write: I2C write operation
768bc9c9e2SClément Léger  * @smbus: SMBus protocol operation
778bc9c9e2SClément Léger  */
788bc9c9e2SClément Léger struct i2c_ctrl_ops {
798bc9c9e2SClément Léger 	TEE_Result (*read)(struct i2c_dev *i2c_dev, uint8_t *buf, size_t len);
808bc9c9e2SClément Léger 	TEE_Result (*write)(struct i2c_dev *i2c_dev, const uint8_t *buf,
818bc9c9e2SClément Léger 			    size_t len);
828bc9c9e2SClément Léger 	TEE_Result (*smbus)(struct i2c_dev *i2c_dev, enum i2c_smbus_dir dir,
838bc9c9e2SClément Léger 			    enum i2c_smbus_protocol proto, uint8_t cmd_code,
848bc9c9e2SClément Léger 			    uint8_t *buf, size_t len);
858bc9c9e2SClément Léger };
868bc9c9e2SClément Léger 
878bc9c9e2SClément Léger /**
888bc9c9e2SClément Léger  * struct i2c_ctrl - I2C controller
898bc9c9e2SClément Léger  *
908bc9c9e2SClément Léger  * @ops: Operations associated to the I2C controller
918bc9c9e2SClément Léger  */
928bc9c9e2SClément Léger struct i2c_ctrl {
938bc9c9e2SClément Léger 	const struct i2c_ctrl_ops *ops;
948bc9c9e2SClément Léger };
958bc9c9e2SClément Léger 
968bc9c9e2SClément Léger #ifdef CFG_DRIVERS_I2C
978bc9c9e2SClément Léger /**
988bc9c9e2SClément Léger  * i2c_create_dev - Create and i2c_dev struct from device-tree
998bc9c9e2SClément Léger  *
1008bc9c9e2SClément Léger  * @i2c_ctrl: Controller to be used with this device
1018bc9c9e2SClément Léger  * @fdt: Device-tree to work on
1028bc9c9e2SClément Léger  * @node: Node to work on in @fdt provided device-tree
1038bc9c9e2SClément Léger  *
1048bc9c9e2SClément Léger  * Return an i2c_dev struct filled from device-tree description
1058bc9c9e2SClément Léger  */
1068bc9c9e2SClément Léger struct i2c_dev *i2c_create_dev(struct i2c_ctrl *i2c_ctrl, const void *fdt,
1078bc9c9e2SClément Léger 			       int node);
1088bc9c9e2SClément Léger 
1098bc9c9e2SClément Léger /**
1108bc9c9e2SClément Léger  * i2c_write() - Execute an I2C write on the I2C bus
1118bc9c9e2SClément Léger  *
1128bc9c9e2SClément Léger  * @i2c_dev: I2C device used for writing
1138bc9c9e2SClément Léger  * @buf: Buffer of data to be written
1148bc9c9e2SClément Léger  * @len: Length of data to be written
1158bc9c9e2SClément Léger  *
1168bc9c9e2SClément Léger  * Return a TEE_Result compliant value
1178bc9c9e2SClément Léger  */
i2c_write(struct i2c_dev * i2c_dev,const uint8_t * buf,size_t len)1188bc9c9e2SClément Léger static inline TEE_Result i2c_write(struct i2c_dev *i2c_dev, const uint8_t *buf,
1198bc9c9e2SClément Léger 				   size_t len)
1208bc9c9e2SClément Léger {
1218bc9c9e2SClément Léger 	if (!i2c_dev->ctrl->ops->write)
1228bc9c9e2SClément Léger 		return TEE_ERROR_NOT_SUPPORTED;
1238bc9c9e2SClément Léger 
1248bc9c9e2SClément Léger 	return i2c_dev->ctrl->ops->write(i2c_dev, buf, len);
1258bc9c9e2SClément Léger }
1268bc9c9e2SClément Léger 
1278bc9c9e2SClément Léger /**
1288bc9c9e2SClément Léger  * i2c_read() - Execute an I2C read on the I2C bus
1298bc9c9e2SClément Léger  *
1308bc9c9e2SClément Léger  * @i2c_dev: I2C device used for reading
1318bc9c9e2SClément Léger  * @buf: Buffer containing the read data
1328bc9c9e2SClément Léger  * @len: Length of data to be read
1338bc9c9e2SClément Léger  *
1348bc9c9e2SClément Léger  * Return a TEE_Result compliant value
1358bc9c9e2SClément Léger  */
i2c_read(struct i2c_dev * i2c_dev,uint8_t * buf,size_t len)1368bc9c9e2SClément Léger static inline TEE_Result i2c_read(struct i2c_dev *i2c_dev, uint8_t *buf,
1378bc9c9e2SClément Léger 				  size_t len)
1388bc9c9e2SClément Léger {
1398bc9c9e2SClément Léger 	if (!i2c_dev->ctrl->ops->read)
1408bc9c9e2SClément Léger 		return TEE_ERROR_NOT_SUPPORTED;
1418bc9c9e2SClément Léger 
1428bc9c9e2SClément Léger 	return i2c_dev->ctrl->ops->read(i2c_dev, buf, len);
1438bc9c9e2SClément Léger }
1448bc9c9e2SClément Léger 
1458bc9c9e2SClément Léger /**
1468bc9c9e2SClément Léger  * i2c_smbus_raw() - Execute a raw SMBUS request
1478bc9c9e2SClément Léger  *
1488bc9c9e2SClément Léger  * @i2c_dev: I2C device used for SMBus operation
1498bc9c9e2SClément Léger  * @dir: Direction for the SMBus transfer
1508bc9c9e2SClément Léger  * @proto: SMBus Protocol to be executed
1518bc9c9e2SClément Léger  * @cmd_code: Command code
1528bc9c9e2SClément Léger  * @buf: Buffer used for read/write operation
1538bc9c9e2SClément Léger  * @len: Length of buffer to be read/write
1548bc9c9e2SClément Léger  *
1558bc9c9e2SClément Léger  * Return a TEE_Result compliant value
1568bc9c9e2SClément Léger  */
i2c_smbus_raw(struct i2c_dev * i2c_dev,enum i2c_smbus_dir dir,enum i2c_smbus_protocol proto,uint8_t cmd_code,uint8_t * buf,size_t len)1578bc9c9e2SClément Léger static inline TEE_Result i2c_smbus_raw(struct i2c_dev *i2c_dev,
1588bc9c9e2SClément Léger 				       enum i2c_smbus_dir dir,
1598bc9c9e2SClément Léger 				       enum i2c_smbus_protocol proto,
1608bc9c9e2SClément Léger 				       uint8_t cmd_code, uint8_t *buf,
1618bc9c9e2SClément Léger 				       size_t len)
1628bc9c9e2SClément Léger {
1638bc9c9e2SClément Léger 	if (!i2c_dev->ctrl->ops->smbus)
1648bc9c9e2SClément Léger 		return TEE_ERROR_NOT_SUPPORTED;
1658bc9c9e2SClément Léger 
1668bc9c9e2SClément Léger 	if (len > I2C_SMBUS_MAX_BUF_SIZE)
1678bc9c9e2SClément Léger 		return TEE_ERROR_BAD_PARAMETERS;
1688bc9c9e2SClément Léger 
1698bc9c9e2SClément Léger 	return i2c_dev->ctrl->ops->smbus(i2c_dev, dir, proto, cmd_code, buf,
1708bc9c9e2SClément Léger 					 len);
1718bc9c9e2SClément Léger }
1728bc9c9e2SClément Léger 
1738bc9c9e2SClément Léger /**
1748bc9c9e2SClément Léger  * i2c_dt_get_dev - Get an I2C device from a DT node
1758bc9c9e2SClément Léger  *
1768bc9c9e2SClément Léger  * @fdt: Device tree to work on
1778bc9c9e2SClément Léger  * @nodeoffset: Node offset of the I2C bus consumer
1788bc9c9e2SClément Léger  * @i2c_dev: Output I2C bus device upon success
1798bc9c9e2SClément Léger  *
1808bc9c9e2SClément Léger  * Return TEE_SUCCESS in case of success
1818bc9c9e2SClément Léger  * Return TEE_ERROR_DEFER_DRIVER_INIT if I2C controller is not initialized
1828bc9c9e2SClément Léger  * Return TEE_ERROR_ITEM_NOT_FOUND if the I2C controller node does not exist
1838bc9c9e2SClément Léger  * Return a TEE_Result compliant code in case of error
1848bc9c9e2SClément Léger  */
i2c_dt_get_dev(const void * fdt,int nodeoffset,struct i2c_dev ** out_i2c_dev)1858bc9c9e2SClément Léger static inline TEE_Result i2c_dt_get_dev(const void *fdt, int nodeoffset,
186b357d34fSEtienne Carriere 					struct i2c_dev **out_i2c_dev)
1878bc9c9e2SClément Léger {
1888bc9c9e2SClément Léger 	TEE_Result res = TEE_ERROR_GENERIC;
189b357d34fSEtienne Carriere 	void *i2c_dev = NULL;
1908bc9c9e2SClément Léger 
191b357d34fSEtienne Carriere 	res = dt_driver_device_from_parent(fdt, nodeoffset, DT_DRIVER_I2C,
192b357d34fSEtienne Carriere 					   &i2c_dev);
193b357d34fSEtienne Carriere 	if (!res)
194b357d34fSEtienne Carriere 		*out_i2c_dev = i2c_dev;
195b357d34fSEtienne Carriere 
1968bc9c9e2SClément Léger 	return res;
1978bc9c9e2SClément Léger }
1988bc9c9e2SClément Léger #else
i2c_write(struct i2c_dev * i2c_dev __unused,const uint8_t * buf __unused,size_t len __unused)1998bc9c9e2SClément Léger static inline TEE_Result i2c_write(struct i2c_dev *i2c_dev __unused,
2008bc9c9e2SClément Léger 				   const uint8_t *buf __unused,
2018bc9c9e2SClément Léger 				   size_t len __unused)
2028bc9c9e2SClément Léger {
2038bc9c9e2SClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
2048bc9c9e2SClément Léger }
2058bc9c9e2SClément Léger 
i2c_read(struct i2c_dev * i2c_dev __unused,uint8_t * buf __unused,size_t len __unused)2068bc9c9e2SClément Léger static inline TEE_Result i2c_read(struct i2c_dev *i2c_dev __unused,
2078bc9c9e2SClément Léger 				  uint8_t *buf __unused, size_t len __unused)
2088bc9c9e2SClément Léger {
2098bc9c9e2SClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
2108bc9c9e2SClément Léger }
2118bc9c9e2SClément Léger 
i2c_smbus_raw(struct i2c_dev * i2c_dev __unused,enum i2c_smbus_dir dir __unused,enum i2c_smbus_protocol proto __unused,uint8_t cmd_code __unused,uint8_t * buf __unused,size_t len __unused)2128bc9c9e2SClément Léger static inline TEE_Result i2c_smbus_raw(struct i2c_dev *i2c_dev __unused,
2138bc9c9e2SClément Léger 				       enum i2c_smbus_dir dir __unused,
2148bc9c9e2SClément Léger 				       enum i2c_smbus_protocol proto __unused,
2158bc9c9e2SClément Léger 				       uint8_t cmd_code __unused,
2168bc9c9e2SClément Léger 				       uint8_t *buf __unused,
2178bc9c9e2SClément Léger 				       size_t len __unused)
2188bc9c9e2SClément Léger {
2198bc9c9e2SClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
2208bc9c9e2SClément Léger }
2218bc9c9e2SClément Léger 
i2c_dt_get_dev(const void * fdt __unused,int nodeoffset __unused,struct i2c_dev ** i2c_dev __unused)2228bc9c9e2SClément Léger static inline TEE_Result i2c_dt_get_dev(const void *fdt __unused,
2238bc9c9e2SClément Léger 					int nodeoffset __unused,
224*5395fe89SEtienne Carriere 					struct i2c_dev **i2c_dev __unused)
2258bc9c9e2SClément Léger {
2268bc9c9e2SClément Léger 	return TEE_ERROR_NOT_SUPPORTED;
2278bc9c9e2SClément Léger }
2288bc9c9e2SClément Léger #endif
2298bc9c9e2SClément Léger 
2308bc9c9e2SClément Léger /**
2318bc9c9e2SClément Léger  * i2c_dt_get_func - Typedef of function to get I2C bus device from
2328bc9c9e2SClément Léger  * devicetree properties
2338bc9c9e2SClément Léger  *
2348fd620f7SEtienne Carriere  * @args: Pointer to devicetree description of the I2C bus device to parse
2358bc9c9e2SClément Léger  * @data: Pointer to data given at i2c_dt_register_provider() call
236b357d34fSEtienne Carriere  * @out_device: Output pointer to I2C device upon success
2378bc9c9e2SClément Léger  */
238b357d34fSEtienne Carriere typedef TEE_Result (*i2c_dt_get_func)(struct dt_pargs *args, void *data,
239b357d34fSEtienne Carriere 				      struct i2c_dev **out_device);
2408bc9c9e2SClément Léger 
2418bc9c9e2SClément Léger /**
2428bc9c9e2SClément Léger  * i2c_dt_register_provider - Register a I2C controller provider and add all the
2438bc9c9e2SClément Léger  *	child nodes of this controller in the DT probe list.
2448bc9c9e2SClément Léger  *
2458bc9c9e2SClément Léger  * @fdt: Device tree to work on
2468bc9c9e2SClément Léger  * @nodeoffset: Node offset of the I2C controller
2478bc9c9e2SClément Léger  * @get_dt_i2c: Callback to match the I2C controller with a struct i2c
2488bc9c9e2SClément Léger  * @data: Data which will be passed to the get_dt_i2c callback
2498bc9c9e2SClément Léger  * Returns TEE_Result value
2508bc9c9e2SClément Léger  */
i2c_register_provider(const void * fdt,int nodeoffset,i2c_dt_get_func get_dt_i2c,void * data)251b357d34fSEtienne Carriere static inline TEE_Result i2c_register_provider(const void *fdt, int nodeoffset,
252b357d34fSEtienne Carriere 					       i2c_dt_get_func get_dt_i2c,
253b357d34fSEtienne Carriere 					       void *data)
2548bc9c9e2SClément Léger {
2558bc9c9e2SClément Léger 	int subnode = -1;
2568bc9c9e2SClément Léger 	TEE_Result res = TEE_ERROR_GENERIC;
2578bc9c9e2SClément Léger 
2588bc9c9e2SClément Léger 	res = dt_driver_register_provider(fdt, nodeoffset,
2598bc9c9e2SClément Léger 					  (get_of_device_func)get_dt_i2c,
2608bc9c9e2SClément Léger 					  data, DT_DRIVER_I2C);
2618bc9c9e2SClément Léger 	if (res)
2628bc9c9e2SClément Léger 		return res;
2638bc9c9e2SClément Léger 
2648bc9c9e2SClément Léger 	fdt_for_each_subnode(subnode, fdt, nodeoffset)
2658bc9c9e2SClément Léger 		dt_driver_maybe_add_probe_node(fdt, subnode);
2668bc9c9e2SClément Léger 
2678bc9c9e2SClément Léger 	return TEE_SUCCESS;
2688bc9c9e2SClément Léger }
2698bc9c9e2SClément Léger 
2708bc9c9e2SClément Léger /**
2718bc9c9e2SClément Léger  * i2c_smbus_read_byte_data() - Execute a read byte SMBus protocol operation
2728bc9c9e2SClément Léger  *
2738bc9c9e2SClément Léger  * @i2c_dev: I2C device used for SMBus operation
2748bc9c9e2SClément Léger  * @cmd_code: Command code to read
2758bc9c9e2SClément Léger  * @byte: Returned byte value read from device
2768bc9c9e2SClément Léger  *
2778bc9c9e2SClément Léger  * Return a TEE_Result compliant value
2788bc9c9e2SClément Léger  */
i2c_smbus_read_byte_data(struct i2c_dev * i2c_dev,uint8_t cmd_code,uint8_t * byte)2798bc9c9e2SClément Léger static inline TEE_Result i2c_smbus_read_byte_data(struct i2c_dev *i2c_dev,
2808bc9c9e2SClément Léger 						  uint8_t cmd_code,
2818bc9c9e2SClément Léger 						  uint8_t *byte)
2828bc9c9e2SClément Léger {
2838bc9c9e2SClément Léger 	return i2c_smbus_raw(i2c_dev, I2C_SMBUS_READ, I2C_SMBUS_PROTO_BYTE,
2848bc9c9e2SClément Léger 			     cmd_code, byte, 1);
2858bc9c9e2SClément Léger }
2868bc9c9e2SClément Léger 
2878bc9c9e2SClément Léger /**
2888bc9c9e2SClément Léger  * i2c_smbus_write_byte_data() - Execute a write byte SMBus protocol operation
2898bc9c9e2SClément Léger  *
2908bc9c9e2SClément Léger  * @i2c_dev: I2C device used for SMBus operation
2918bc9c9e2SClément Léger  * @cmd_code: Command code for write operation
2928bc9c9e2SClément Léger  * @byte: Byte to be written to the device
2938bc9c9e2SClément Léger  *
2948bc9c9e2SClément Léger  * Return a TEE_Result compliant value
2958bc9c9e2SClément Léger  */
i2c_smbus_write_byte_data(struct i2c_dev * i2c_dev,uint8_t cmd_code,uint8_t byte)2968bc9c9e2SClément Léger static inline TEE_Result i2c_smbus_write_byte_data(struct i2c_dev *i2c_dev,
2978bc9c9e2SClément Léger 						   uint8_t cmd_code,
2988bc9c9e2SClément Léger 						   uint8_t byte)
2998bc9c9e2SClément Léger {
3008bc9c9e2SClément Léger 	return i2c_smbus_raw(i2c_dev, I2C_SMBUS_WRITE, I2C_SMBUS_PROTO_BYTE,
3018bc9c9e2SClément Léger 			     cmd_code, &byte, 1);
3028bc9c9e2SClément Léger }
3038bc9c9e2SClément Léger 
3048bc9c9e2SClément Léger /**
3058bc9c9e2SClément Léger  * i2c_bus_read_block_raw() - Execute a non-standard SMBus raw block read.
3068bc9c9e2SClément Léger  * This does not insert the "count" of byte to be written unlike the SMBus block
3078bc9c9e2SClément Léger  * read operation.
3088bc9c9e2SClément Léger  *
3098bc9c9e2SClément Léger  * @i2c_dev: I2C device used for SMBus operation
3108bc9c9e2SClément Léger  * @cmd_code: Command code for read operation
3118bc9c9e2SClément Léger  * @buf: Buffer of data read from device
3128bc9c9e2SClément Léger  * @len: Length of data to be read from the device
3138bc9c9e2SClément Léger  *
3148bc9c9e2SClément Léger  * Return a TEE_Result compliant value
3158bc9c9e2SClément Léger  */
i2c_bus_read_block_raw(struct i2c_dev * i2c_dev,uint8_t cmd_code,uint8_t * buf,size_t len)3168bc9c9e2SClément Léger static inline TEE_Result i2c_bus_read_block_raw(struct i2c_dev *i2c_dev,
3178bc9c9e2SClément Léger 						uint8_t cmd_code, uint8_t *buf,
3188bc9c9e2SClément Léger 						size_t len)
3198bc9c9e2SClément Léger {
3208bc9c9e2SClément Léger 	return i2c_smbus_raw(i2c_dev, I2C_SMBUS_READ, I2C_SMBUS_PROTO_BLOCK_RAW,
3218bc9c9e2SClément Léger 			     cmd_code, buf, len);
3228bc9c9e2SClément Léger }
3238bc9c9e2SClément Léger 
3248bc9c9e2SClément Léger /**
3258bc9c9e2SClément Léger  * i2c_bus_write_block_raw() - Execute a non-standard SMBus raw block write.
3268bc9c9e2SClément Léger  * This does not insert the "count" of byte to be written unlike the SMBus block
3278bc9c9e2SClément Léger  * write operation.
3288bc9c9e2SClément Léger  *
3298bc9c9e2SClément Léger  * @i2c_dev: I2C device used for SMBus operation
3308bc9c9e2SClément Léger  * @cmd_code: Command code for write operation
3318bc9c9e2SClément Léger  * @buf: Buffer of data to be written to the device
3328bc9c9e2SClément Léger  * @len: Length of data to be written to the device
3338bc9c9e2SClément Léger  *
3348bc9c9e2SClément Léger  * Return a TEE_Result compliant value
3358bc9c9e2SClément Léger  */
i2c_bus_write_block_raw(struct i2c_dev * i2c_dev,uint8_t cmd_code,uint8_t * buf,size_t len)3368bc9c9e2SClément Léger static inline TEE_Result i2c_bus_write_block_raw(struct i2c_dev *i2c_dev,
3378bc9c9e2SClément Léger 						 uint8_t cmd_code,
3388bc9c9e2SClément Léger 						 uint8_t *buf, size_t len)
3398bc9c9e2SClément Léger {
3408bc9c9e2SClément Léger 	return i2c_smbus_raw(i2c_dev, I2C_SMBUS_WRITE,
3418bc9c9e2SClément Léger 			     I2C_SMBUS_PROTO_BLOCK_RAW, cmd_code, buf, len);
3428bc9c9e2SClément Léger }
3438bc9c9e2SClément Léger 
3448bc9c9e2SClément Léger #endif
345