blob: f242acf2bb42870ec068ca9ebef6c287e1f0ac82 [file] [log] [blame]
Rodrigo Caballero5903f232016-02-06 15:19:43 -06001/**
2 * @file
3 *
4 * @brief Public APIs for the I2C drivers.
5 */
Dan Kalowsky8c85f012015-06-30 09:44:34 -07006
7/*
8 * Copyright (c) 2015 Intel Corporation
9 *
David B. Kinderac74d8b2017-01-18 17:01:01 -080010 * SPDX-License-Identifier: Apache-2.0
Dan Kalowsky8c85f012015-06-30 09:44:34 -070011 */
12#ifndef __DRIVERS_I2C_H
13#define __DRIVERS_I2C_H
14
Anas Nashif75482aa2015-10-26 06:18:44 -040015/**
16 * @brief I2C Interface
17 * @defgroup i2c_interface I2C Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
Dan Kalowsky8c85f012015-06-30 09:44:34 -070022#ifdef __cplusplus
23extern "C" {
24#endif
25
Kumar Gala78908162017-04-19 10:32:08 -050026#include <zephyr/types.h>
Dan Kalowsky8c85f012015-06-30 09:44:34 -070027#include <device.h>
28
Daniel Leungf6646e22016-02-17 11:31:11 -080029/*
30 * The following #defines are used to configure the I2C controller.
Rodrigo Caballero5903f232016-02-06 15:19:43 -060031 */
Daniel Leungf6646e22016-02-17 11:31:11 -080032
33/** I2C Standard Speed */
Dan Kalowsky9c215672015-08-24 11:30:06 -070034#define I2C_SPEED_STANDARD (0x1)
Daniel Leungf6646e22016-02-17 11:31:11 -080035
36/** I2C Fast Speed */
Dan Kalowsky9c215672015-08-24 11:30:06 -070037#define I2C_SPEED_FAST (0x2)
Daniel Leungf6646e22016-02-17 11:31:11 -080038
39/** I2C Fast Plus Speed */
Dan Kalowsky9c215672015-08-24 11:30:06 -070040#define I2C_SPEED_FAST_PLUS (0x3)
Daniel Leungf6646e22016-02-17 11:31:11 -080041
42/** I2C High Speed */
Dan Kalowsky9c215672015-08-24 11:30:06 -070043#define I2C_SPEED_HIGH (0x4)
Daniel Leungf6646e22016-02-17 11:31:11 -080044
45/** I2C Ultra Fast Speed */
Dan Kalowsky9c215672015-08-24 11:30:06 -070046#define I2C_SPEED_ULTRA (0x5)
Dan Kalowsky8c85f012015-06-30 09:44:34 -070047
Kumar Gala10acdb52017-08-15 09:42:01 -050048#define I2C_SPEED_SHIFT (1)
Kumar Gala0bfd8102017-09-13 11:54:43 -050049#define I2C_SPEED_SET(speed) (((speed) << I2C_SPEED_SHIFT) \
50 & I2C_SPEED_MASK)
Kumar Gala10acdb52017-08-15 09:42:01 -050051#define I2C_SPEED_MASK (0x7 << I2C_SPEED_SHIFT) /* 3 bits */
Kumar Gala83643a22017-09-13 11:31:00 -050052#define I2C_SPEED_GET(cfg) (((cfg) & I2C_SPEED_MASK) \
53 >> I2C_SPEED_SHIFT)
Daniel Leungf6646e22016-02-17 11:31:11 -080054
55/** Use 10-bit addressing. */
56#define I2C_ADDR_10_BITS (1 << 0)
57
58/** Controller to act as Master. */
Dan Kalowsky9c215672015-08-24 11:30:06 -070059#define I2C_MODE_MASTER (1 << 4)
Daniel Leungf6646e22016-02-17 11:31:11 -080060
Daniel Leungf6646e22016-02-17 11:31:11 -080061/*
62 * I2C_MSG_* are I2C Message flags.
Rodrigo Caballero5903f232016-02-06 15:19:43 -060063 */
Daniel Leungf6646e22016-02-17 11:31:11 -080064
65/** Write message to I2C bus. */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080066#define I2C_MSG_WRITE (0 << 0)
Daniel Leungf6646e22016-02-17 11:31:11 -080067
68/** Read message from I2C bus. */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080069#define I2C_MSG_READ (1 << 0)
Daniel Leungf6646e22016-02-17 11:31:11 -080070
Marcus Shawcroft3c95ce62016-11-25 14:43:29 +000071/** @cond INTERNAL_HIDDEN */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080072#define I2C_MSG_RW_MASK (1 << 0)
Marcus Shawcroft3c95ce62016-11-25 14:43:29 +000073/** @endcond */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080074
Daniel Leungf6646e22016-02-17 11:31:11 -080075/** Send STOP after this message. */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080076#define I2C_MSG_STOP (1 << 1)
Rodrigo Caballero5903f232016-02-06 15:19:43 -060077
Daniel Leungf6646e22016-02-17 11:31:11 -080078/** RESTART I2C transaction for this message. */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080079#define I2C_MSG_RESTART (1 << 2)
80
Daniel Leungf6646e22016-02-17 11:31:11 -080081/**
82 * @brief One I2C Message.
83 *
84 * This defines one I2C message to transact on the I2C bus.
85 */
Daniel Leungdff5f6a2016-01-11 15:35:39 -080086struct i2c_msg {
Daniel Leungf6646e22016-02-17 11:31:11 -080087 /** Data buffer in bytes */
Kumar Galacc334c72017-04-21 10:55:34 -050088 u8_t *buf;
Daniel Leungdff5f6a2016-01-11 15:35:39 -080089
Daniel Leungf6646e22016-02-17 11:31:11 -080090 /** Length of buffer in bytes */
Kumar Galacc334c72017-04-21 10:55:34 -050091 u32_t len;
Daniel Leungdff5f6a2016-01-11 15:35:39 -080092
Daniel Leungf6646e22016-02-17 11:31:11 -080093 /** Flags for this message */
Kumar Galacc334c72017-04-21 10:55:34 -050094 u8_t flags;
Daniel Leungdff5f6a2016-01-11 15:35:39 -080095};
Dan Kalowsky8c85f012015-06-30 09:44:34 -070096
Kumar Gala0bfd8102017-09-13 11:54:43 -050097union __deprecated dev_config {
Kumar Galacc334c72017-04-21 10:55:34 -050098 u32_t raw;
Inaky Perez-Gonzalezecc4c762016-06-16 14:52:44 -070099 struct __bits {
Kumar Galacc334c72017-04-21 10:55:34 -0500100 u32_t use_10_bit_addr : 1;
101 u32_t speed : 3;
102 u32_t is_master_device : 1;
Kumar Galacc334c72017-04-21 10:55:34 -0500103 u32_t reserved : 26;
Dan Kalowsky9c215672015-08-24 11:30:06 -0700104 } bits;
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700105};
106
Daniel Leungf6646e22016-02-17 11:31:11 -0800107/**
108 * @cond INTERNAL_HIDDEN
109 *
110 * These are for internal use only, so skip these in
111 * public documentation.
112 */
Dan Kalowsky9c215672015-08-24 11:30:06 -0700113typedef int (*i2c_api_configure_t)(struct device *dev,
Kumar Galacc334c72017-04-21 10:55:34 -0500114 u32_t dev_config);
Daniel Leungac0beb72015-10-07 15:08:17 -0700115typedef int (*i2c_api_full_io_t)(struct device *dev,
Daniel Leungdff5f6a2016-01-11 15:35:39 -0800116 struct i2c_msg *msgs,
Kumar Galacc334c72017-04-21 10:55:34 -0500117 u8_t num_msgs,
118 u16_t addr);
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700119
120struct i2c_driver_api {
Dan Kalowsky9c215672015-08-24 11:30:06 -0700121 i2c_api_configure_t configure;
Daniel Leungac0beb72015-10-07 15:08:17 -0700122 i2c_api_full_io_t transfer;
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700123};
Daniel Leungf6646e22016-02-17 11:31:11 -0800124/**
125 * @endcond
126 */
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700127
Anas Nashif20764a22015-07-01 16:47:13 -0400128/**
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600129 * @brief Configure operation of a host controller.
Tomasz Bursztykace31c522015-12-08 12:16:41 +0100130 *
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600131 * @param dev Pointer to the device structure for the driver instance.
Dan Kalowsky9c215672015-08-24 11:30:06 -0700132 * @param dev_config Bit-packed 32-bit value to the device runtime configuration
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600133 * for the I2C controller.
Dan Kalowskye728cad2015-10-01 14:16:47 -0700134 *
Andre Guedes024cfe72016-03-09 14:01:20 -0300135 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000136 * @retval -EIO General input / output error, failed to configure device.
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700137 */
Andrew Boie2a2a8552017-10-23 10:05:09 -0700138__syscall int i2c_configure(struct device *dev, u32_t dev_config);
139
140static inline int _impl_i2c_configure(struct device *dev, u32_t dev_config)
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700141{
Marcus Shawcrofte7a24452016-10-22 10:02:48 +0100142 const struct i2c_driver_api *api = dev->driver_api;
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700143
Dan Kalowsky9c215672015-08-24 11:30:06 -0700144 return api->configure(dev, dev_config);
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700145}
146
Anas Nashif20764a22015-07-01 16:47:13 -0400147/**
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600148 * @brief Perform data transfer to another I2C device.
Daniel Leungac0beb72015-10-07 15:08:17 -0700149 *
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600150 * This routine provides a generic interface to perform data transfer
151 * to another I2C device synchronously. Use i2c_read()/i2c_write()
152 * for simple read or write.
Daniel Leungac0beb72015-10-07 15:08:17 -0700153 *
Marcus Shawcroftddb6b942017-02-05 23:33:37 +0000154 * The array of message @a msgs must not be NULL. The number of
155 * message @a num_msgs may be zero,in which case no transfer occurs.
156 *
Rodrigo Caballero5903f232016-02-06 15:19:43 -0600157 * @param dev Pointer to the device structure for the driver instance.
158 * @param msgs Array of messages to transfer.
159 * @param num_msgs Number of messages to transfer.
160 * @param addr Address of the I2C target device.
Daniel Leungac0beb72015-10-07 15:08:17 -0700161 *
Andre Guedes024cfe72016-03-09 14:01:20 -0300162 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000163 * @retval -EIO General input / output error.
Daniel Leungac0beb72015-10-07 15:08:17 -0700164 */
Andrew Boie2a2a8552017-10-23 10:05:09 -0700165__syscall int i2c_transfer(struct device *dev,
166 struct i2c_msg *msgs, u8_t num_msgs,
167 u16_t addr);
168
169static inline int _impl_i2c_transfer(struct device *dev,
170 struct i2c_msg *msgs, u8_t num_msgs,
171 u16_t addr)
Daniel Leungac0beb72015-10-07 15:08:17 -0700172{
Marcus Shawcrofte7a24452016-10-22 10:02:48 +0100173 const struct i2c_driver_api *api = dev->driver_api;
Daniel Leungac0beb72015-10-07 15:08:17 -0700174
Daniel Leungdff5f6a2016-01-11 15:35:39 -0800175 return api->transfer(dev, msgs, num_msgs, addr);
Daniel Leungac0beb72015-10-07 15:08:17 -0700176}
177
Andrew Boie2a2a8552017-10-23 10:05:09 -0700178/*
179 * Derived i2c APIs -- all implemented in terms of i2c_transfer()
180 */
181
182/**
183 * @brief Write a set amount of data to an I2C device.
184 *
185 * This routine writes a set amount of data synchronously.
186 *
187 * @param dev Pointer to the device structure for the driver instance.
188 * @param buf Memory pool from which the data is transferred.
189 * @param num_bytes Number of bytes to write.
190 * @param addr Address to the target I2C device for writing.
191 *
192 * @retval 0 If successful.
193 * @retval -EIO General input / output error.
194 */
195static inline int i2c_write(struct device *dev, u8_t *buf,
196 u32_t num_bytes, u16_t addr)
197{
198 struct i2c_msg msg;
199
200 msg.buf = buf;
201 msg.len = num_bytes;
202 msg.flags = I2C_MSG_WRITE | I2C_MSG_STOP;
203
204 return i2c_transfer(dev, &msg, 1, addr);
205}
206
207/**
208 * @brief Read a set amount of data from an I2C device.
209 *
210 * This routine reads a set amount of data synchronously.
211 *
212 * @param dev Pointer to the device structure for the driver instance.
213 * @param buf Memory pool that stores the retrieved data.
214 * @param num_bytes Number of bytes to read.
215 * @param addr Address of the I2C device being read.
216 *
217 * @retval 0 If successful.
218 * @retval -EIO General input / output error.
219 */
220static inline int i2c_read(struct device *dev, u8_t *buf,
221 u32_t num_bytes, u16_t addr)
222{
223 struct i2c_msg msg;
224
225 msg.buf = buf;
226 msg.len = num_bytes;
227 msg.flags = I2C_MSG_READ | I2C_MSG_STOP;
228
229 return i2c_transfer(dev, &msg, 1, addr);
230}
231
232
Daniel Leungac0beb72015-10-07 15:08:17 -0700233/**
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300234 * @brief Read multiple bytes from an internal address of an I2C device.
235 *
236 * This routine reads multiple bytes from an internal address of an
237 * I2C device synchronously.
238 *
239 * @param dev Pointer to the device structure for the driver instance.
240 * @param dev_addr Address of the I2C device for reading.
241 * @param start_addr Internal address from which the data is being read.
242 * @param buf Memory pool that stores the retrieved data.
243 * @param num_bytes Number of bytes being read.
244 *
245 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000246 * @retval -EIO General input / output error.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300247 */
Kumar Galacc334c72017-04-21 10:55:34 -0500248static inline int i2c_burst_read(struct device *dev, u16_t dev_addr,
249 u8_t start_addr, u8_t *buf,
250 u8_t num_bytes)
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300251{
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300252 struct i2c_msg msg[2];
253
254 msg[0].buf = &start_addr;
255 msg[0].len = 1;
Maureen Helm92de81c2016-04-29 16:17:03 -0500256 msg[0].flags = I2C_MSG_WRITE;
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300257
258 msg[1].buf = buf;
259 msg[1].len = num_bytes;
Maureen Helm92de81c2016-04-29 16:17:03 -0500260 msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300261
Andrew Boie2a2a8552017-10-23 10:05:09 -0700262 return i2c_transfer(dev, msg, 2, dev_addr);
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300263}
264
265/**
266 * @brief Write multiple bytes to an internal address of an I2C device.
267 *
268 * This routine writes multiple bytes to an internal address of an
269 * I2C device synchronously.
270 *
271 * @param dev Pointer to the device structure for the driver instance.
272 * @param dev_addr Address of the I2C device for writing.
273 * @param start_addr Internal address to which the data is being written.
274 * @param buf Memory pool from which the data is transferred.
275 * @param num_bytes Number of bytes being written.
276 *
277 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000278 * @retval -EIO General input / output error.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300279 */
Kumar Galacc334c72017-04-21 10:55:34 -0500280static inline int i2c_burst_write(struct device *dev, u16_t dev_addr,
281 u8_t start_addr, u8_t *buf,
282 u8_t num_bytes)
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300283{
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300284 struct i2c_msg msg[2];
285
286 msg[0].buf = &start_addr;
287 msg[0].len = 1;
288 msg[0].flags = I2C_MSG_WRITE;
289
290 msg[1].buf = buf;
291 msg[1].len = num_bytes;
292 msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
293
Andrew Boie2a2a8552017-10-23 10:05:09 -0700294 return i2c_transfer(dev, msg, 2, dev_addr);
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300295}
296
297/**
298 * @brief Read internal register of an I2C device.
299 *
300 * This routine reads the value of an 8-bit internal register of an I2C
301 * device synchronously.
302 *
303 * @param dev Pointer to the device structure for the driver instance.
304 * @param dev_addr Address of the I2C device for reading.
305 * @param reg_addr Address of the internal register being read.
306 * @param value Memory pool that stores the retrieved register value.
307 *
308 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000309 * @retval -EIO General input / output error.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300310 */
Kumar Galacc334c72017-04-21 10:55:34 -0500311static inline int i2c_reg_read_byte(struct device *dev, u16_t dev_addr,
312 u8_t reg_addr, u8_t *value)
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300313{
314 return i2c_burst_read(dev, dev_addr, reg_addr, value, 1);
315}
316
317/**
318 * @brief Write internal register of an I2C device.
319 *
320 * This routine writes a value to an 8-bit internal register of an I2C
321 * device synchronously.
322 *
323 * @param dev Pointer to the device structure for the driver instance.
324 * @param dev_addr Address of the I2C device for writing.
325 * @param reg_addr Address of the internal register being written.
326 * @param value Value to be written to internal register.
327 *
328 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000329 * @retval -EIO General input / output error.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300330 */
Kumar Galacc334c72017-04-21 10:55:34 -0500331static inline int i2c_reg_write_byte(struct device *dev, u16_t dev_addr,
332 u8_t reg_addr, u8_t value)
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300333{
Kumar Galacc334c72017-04-21 10:55:34 -0500334 u8_t tx_buf[2] = {reg_addr, value};
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300335
336 return i2c_write(dev, tx_buf, 2, dev_addr);
337}
338
339/**
340 * @brief Update internal register of an I2C device.
341 *
342 * This routine updates the value of a set of bits from an 8-bit internal
343 * register of an I2C device synchronously.
344 *
345 * @param dev Pointer to the device structure for the driver instance.
346 * @param dev_addr Address of the I2C device for updating.
347 * @param reg_addr Address of the internal register being updated.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300348 * @param mask Bitmask for updating internal register.
Bogdan Davidoaia9496ec62016-04-25 18:58:41 +0300349 * @param value Value for updating internal register.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300350 *
351 * @retval 0 If successful.
Marcus Shawcroftcf990c12017-02-05 23:57:43 +0000352 * @retval -EIO General input / output error.
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300353 */
Kumar Galacc334c72017-04-21 10:55:34 -0500354static inline int i2c_reg_update_byte(struct device *dev, u8_t dev_addr,
355 u8_t reg_addr, u8_t mask,
356 u8_t value)
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300357{
Kumar Galacc334c72017-04-21 10:55:34 -0500358 u8_t old_value, new_value;
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300359 int rc;
360
Bogdan Davidoaia6f6e65b2016-04-25 16:33:06 +0300361 rc = i2c_reg_read_byte(dev, dev_addr, reg_addr, &old_value);
Bogdan Davidoaiaef26bf72016-04-21 11:45:36 +0300362 if (rc != 0) {
363 return rc;
364 }
365
366 new_value = (old_value & ~mask) | (value & mask);
367 if (new_value == old_value) {
368 return 0;
369 }
370
371 return i2c_reg_write_byte(dev, dev_addr, reg_addr, new_value);
372}
373
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600374/**
375 * @brief Read multiple bytes from an internal 16 bit address of an I2C device.
376 *
377 * This routine reads multiple bytes from a 16 bit internal address of an
378 * I2C device synchronously.
379 *
380 * @param dev Pointer to the device structure for the driver instance.
381 * @param dev_addr Address of the I2C device for reading.
382 * @param start_addr Internal 16 bit address from which the data is being read.
383 * @param buf Memory pool that stores the retrieved data.
384 * @param num_bytes Number of bytes being read.
385 *
386 * @retval 0 If successful.
387 * @retval Negative errno code if failure.
388 */
Kumar Galacc334c72017-04-21 10:55:34 -0500389static inline int i2c_burst_read16(struct device *dev, u16_t dev_addr,
390 u16_t start_addr, u8_t *buf,
391 u8_t num_bytes)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600392{
Kumar Galacc334c72017-04-21 10:55:34 -0500393 u8_t addr_buffer[2];
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600394 struct i2c_msg msg[2];
395
396 addr_buffer[1] = start_addr & 0xFF;
397 addr_buffer[0] = start_addr >> 8;
398 msg[0].buf = addr_buffer;
399 msg[0].len = 2;
400 msg[0].flags = I2C_MSG_WRITE;
401
402 msg[1].buf = buf;
403 msg[1].len = num_bytes;
404 msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
405
Andrew Boie2a2a8552017-10-23 10:05:09 -0700406 return i2c_transfer(dev, msg, 2, dev_addr);
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600407}
408
409/**
410 * @brief Write multiple bytes to a 16 bit internal address of an I2C device.
411 *
412 * This routine writes multiple bytes to a 16 bit internal address of an
413 * I2C device synchronously.
414 *
415 * @param dev Pointer to the device structure for the driver instance.
416 * @param dev_addr Address of the I2C device for writing.
417 * @param start_addr Internal 16 bit address to which the data is being written.
418 * @param buf Memory pool from which the data is transferred.
419 * @param num_bytes Number of bytes being written.
420 *
421 * @retval 0 If successful.
422 * @retval Negative errno code if failure.
423 */
Kumar Galacc334c72017-04-21 10:55:34 -0500424static inline int i2c_burst_write16(struct device *dev, u16_t dev_addr,
425 u16_t start_addr, u8_t *buf,
426 u8_t num_bytes)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600427{
Kumar Galacc334c72017-04-21 10:55:34 -0500428 u8_t addr_buffer[2];
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600429 struct i2c_msg msg[2];
430
431 addr_buffer[1] = start_addr & 0xFF;
432 addr_buffer[0] = start_addr >> 8;
433 msg[0].buf = addr_buffer;
434 msg[0].len = 2;
435 msg[0].flags = I2C_MSG_WRITE;
436
437 msg[1].buf = buf;
438 msg[1].len = num_bytes;
439 msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
440
Andrew Boie2a2a8552017-10-23 10:05:09 -0700441 return i2c_transfer(dev, msg, 2, dev_addr);
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600442}
443
444/**
445 * @brief Read internal 16 bit address register of an I2C device.
446 *
447 * This routine reads the value of an 16-bit internal register of an I2C
448 * device synchronously.
449 *
450 * @param dev Pointer to the device structure for the driver instance.
451 * @param dev_addr Address of the I2C device for reading.
452 * @param reg_addr 16 bit address of the internal register being read.
453 * @param value Memory pool that stores the retrieved register value.
454 *
455 * @retval 0 If successful.
456 * @retval Negative errno code if failure.
457 */
Kumar Galacc334c72017-04-21 10:55:34 -0500458static inline int i2c_reg_read16(struct device *dev, u16_t dev_addr,
459 u16_t reg_addr, u8_t *value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600460{
461 return i2c_burst_read16(dev, dev_addr, reg_addr, value, 1);
462}
463
464/**
465 * @brief Write internal 16 bit address register of an I2C device.
466 *
467 * This routine writes a value to an 16-bit internal register of an I2C
468 * device synchronously.
469 *
470 * @param dev Pointer to the device structure for the driver instance.
471 * @param dev_addr Address of the I2C device for writing.
472 * @param reg_addr 16 bit address of the internal register being written.
473 * @param value Value to be written to internal register.
474 *
475 * @retval 0 If successful.
476 * @retval Negative errno code if failure.
477 */
Kumar Galacc334c72017-04-21 10:55:34 -0500478static inline int i2c_reg_write16(struct device *dev, u16_t dev_addr,
479 u16_t reg_addr, u8_t value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600480{
481 return i2c_burst_write16(dev, dev_addr, reg_addr, &value, 1);
482}
483
484/**
485 * @brief Update internal 16 bit address register of an I2C device.
486 *
487 * This routine updates the value of a set of bits from a 16-bit internal
488 * register of an I2C device synchronously.
489 *
490 * @param dev Pointer to the device structure for the driver instance.
491 * @param dev_addr Address of the I2C device for updating.
492 * @param reg_addr 16 bit address of the internal register being updated.
493 * @param mask Bitmask for updating internal register.
494 * @param value Value for updating internal register.
495 *
496 * @retval 0 If successful.
497 * @retval Negative errno code if failure.
498 */
Kumar Galacc334c72017-04-21 10:55:34 -0500499static inline int i2c_reg_update16(struct device *dev, u16_t dev_addr,
500 u16_t reg_addr, u8_t mask,
501 u8_t value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600502{
Kumar Galacc334c72017-04-21 10:55:34 -0500503 u8_t old_value, new_value;
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600504 int rc;
505
506 rc = i2c_reg_read16(dev, dev_addr, reg_addr, &old_value);
507 if (rc != 0) {
508 return rc;
509 }
510
511 new_value = (old_value & ~mask) | (value & mask);
512 if (new_value == old_value) {
513 return 0;
514 }
515
516 return i2c_reg_write16(dev, dev_addr, reg_addr, new_value);
517}
518
519/**
520 * @brief Read multiple bytes from an internal variable byte size
521 * address of an I2C device.
522 *
523 * This routine reads multiple bytes from an addr_size byte internal
524 * address of an I2C device synchronously.
525 *
526 * @param dev Pointer to the device structure for the driver instance.
527 * @param dev_addr Address of the I2C device for reading.
528 * @param start_addr Array to an internal register address from which
529 * the data is being read.
530 * @param addr_size Size in bytes of the register address.
531 * @param buf Memory pool that stores the retrieved data.
532 * @param num_bytes Number of bytes being read.
533 *
534 * @retval 0 If successful.
535 * @retval Negative errno code if failure.
536 */
Kumar Galacc334c72017-04-21 10:55:34 -0500537static inline int i2c_burst_read_addr(struct device *dev, u16_t dev_addr,
538 u8_t *start_addr,
539 const u8_t addr_size,
540 u8_t *buf, u8_t num_bytes)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600541{
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600542 struct i2c_msg msg[2];
543
544 msg[0].buf = start_addr;
545 msg[0].len = addr_size;
546 msg[0].flags = I2C_MSG_WRITE;
547
548 msg[1].buf = buf;
549 msg[1].len = num_bytes;
550 msg[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;
551
Andrew Boie2a2a8552017-10-23 10:05:09 -0700552 return i2c_transfer(dev, msg, 2, dev_addr);
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600553}
554
555/**
556 * @brief Write multiple bytes to an internal variable bytes size
557 * address of an I2C device.
558 * This routine writes multiple bytes to an addr_size byte internal
559 * address of an I2C device synchronously.
560 *
561 * @param dev Pointer to the device structure for the driver instance.
562 * @param dev_addr Address of the I2C device for writing.
563 * @param start_addr Array to an internal register address from which
564 * the data is being read.
565 * @param addr_size Size in bytes of the register address.
566 * @param buf Memory pool from which the data is transferred.
567 * @param num_bytes Number of bytes being written.
568 *
569 * @retval 0 If successful.
570 * @retval Negative errno code if failure.
571 */
Kumar Galacc334c72017-04-21 10:55:34 -0500572static inline int i2c_burst_write_addr(struct device *dev, u16_t dev_addr,
573 u8_t *start_addr,
574 const u8_t addr_size,
575 u8_t *buf, u8_t num_bytes)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600576{
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600577 struct i2c_msg msg[2];
578
579 msg[0].buf = start_addr;
580 msg[0].len = addr_size;
581 msg[0].flags = I2C_MSG_WRITE;
582
583 msg[1].buf = buf;
584 msg[1].len = num_bytes;
585 msg[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
586
Andrew Boie2a2a8552017-10-23 10:05:09 -0700587 return i2c_transfer(dev, msg, 2, dev_addr);
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600588}
589
590/**
591 * @brief Read internal variable byte size address register
592 * of an I2C device.
593 *
594 * This routine reads the value of an addr_size byte internal register
595 * of an I2C device synchronously.
596 *
597 * @param dev Pointer to the device structure for the driver instance.
598 * @param dev_addr Address of the I2C device for reading.
599 * @param reg_addr Array to an internal register address from which
600 * the data is being read.
601 * @param addr_size Size in bytes of the register address.
602 * @param value Memory pool that stores the retrieved register value.
603 *
604 * @retval 0 If successful.
605 * @retval Negative errno code if failure.
606 */
607static inline int i2c_reg_read_addr(struct device *dev,
Kumar Galacc334c72017-04-21 10:55:34 -0500608 u16_t dev_addr,
609 u8_t *reg_addr,
610 const u8_t addr_size,
611 u8_t *value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600612{
613 return i2c_burst_read_addr(dev, dev_addr, reg_addr,
614 addr_size, value, 1);
615}
616
617/**
618 * @brief Write internal variable byte size address register
619 * of an I2C device.
620 *
621 * This routine writes a value to an addr_size byte internal register
622 * of an I2C device synchronously.
623 *
624 * @param dev Pointer to the device structure for the driver instance.
625 * @param dev_addr Address of the I2C device for writing.
626 * @param reg_addr Array to an internal register address from which
627 * the data is being read.
628 * @param addr_size Size in bytes of the register address.
629 * @param value Value to be written to internal register.
630 *
631 * @retval 0 If successful.
632 * @retval Negative errno code if failure.
633 */
634static inline int i2c_reg_write_addr(struct device *dev,
Kumar Galacc334c72017-04-21 10:55:34 -0500635 u16_t dev_addr,
636 u8_t *reg_addr,
637 const u8_t addr_size,
638 u8_t value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600639{
640 return i2c_burst_write_addr(dev, dev_addr, reg_addr,
641 addr_size, &value, 1);
642}
643
644/**
645 * @brief Update internal variable byte size address register
646 * of an I2C device.
647 *
648 * This routine updates the value of a set of bits from a addr_size byte
649 * internal register of an I2C device synchronously.
650 *
651 * @param dev Pointer to the device structure for the driver instance.
652 * @param dev_addr Address of the I2C device for updating.
653 * @param reg_addr Array to an internal register address from which
654 * the data is being read.
655 * @param addr_size Size in bytes of the register address.
656 * @param mask Bitmask for updating internal register.
657 * @param value Value for updating internal register.
658 *
659 * @retval 0 If successful.
660 * @retval Negative errno code if failure.
661 */
662static inline int i2c_reg_update_addr(struct device *dev,
Kumar Galacc334c72017-04-21 10:55:34 -0500663 u16_t dev_addr,
664 u8_t *reg_addr,
665 u8_t addr_size,
666 u8_t mask,
667 u8_t value)
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600668{
Kumar Galacc334c72017-04-21 10:55:34 -0500669 u8_t old_value, new_value;
Juan Manuel Cruz Alcaraz75be5032017-01-10 17:07:06 -0600670 int rc;
671
672 rc = i2c_reg_read_addr(dev, dev_addr, reg_addr,
673 addr_size, &old_value);
674 if (rc != 0) {
675 return rc;
676 }
677
678 new_value = (old_value & ~mask) | (value & mask);
679 if (new_value == old_value) {
680 return 0;
681 }
682
683 return i2c_reg_write_addr(dev, dev_addr, reg_addr,
684 addr_size, new_value);
685}
686
Vlad Dogaru8fed55f2016-04-21 17:22:27 +0300687struct i2c_client_config {
688 char *i2c_master;
Kumar Galacc334c72017-04-21 10:55:34 -0500689 u16_t i2c_addr;
Vlad Dogaru8fed55f2016-04-21 17:22:27 +0300690};
691
692#define I2C_DECLARE_CLIENT_CONFIG struct i2c_client_config i2c_client
693
694#define I2C_CLIENT(_master, _addr) \
695 .i2c_client = { \
696 .i2c_master = (_master), \
697 .i2c_addr = (_addr), \
698 }
699
700#define I2C_GET_MASTER(_conf) ((_conf)->i2c_client.i2c_master)
701#define I2C_GET_ADDR(_conf) ((_conf)->i2c_client.i2c_addr)
702
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700703#ifdef __cplusplus
704}
705#endif
706
Anas Nashif75482aa2015-10-26 06:18:44 -0400707/**
708 * @}
709 */
710
Andrew Boie2a2a8552017-10-23 10:05:09 -0700711#include <syscalls/i2c.h>
Anas Nashif75482aa2015-10-26 06:18:44 -0400712
Dan Kalowsky8c85f012015-06-30 09:44:34 -0700713#endif /* __DRIVERS_I2C_H */