Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:11

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @brief Inter-Integrated Circuit (I2C) Driver API
0007  *
0008  * @ingroup I2C
0009  */
0010 
0011 /*
0012  * Copyright (C) 2014, 2017 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef _DEV_I2C_I2C_H
0037 #define _DEV_I2C_I2C_H
0038 
0039 #include <linux/i2c.h>
0040 #include <linux/i2c-dev.h>
0041 
0042 #include <rtems.h>
0043 #include <rtems/seterr.h>
0044 #include <rtems/thread.h>
0045 
0046 #include <sys/ioctl.h>
0047 #include <sys/stat.h>
0048 
0049 #ifdef __cplusplus
0050 extern "C" {
0051 #endif /* __cplusplus */
0052 
0053 typedef struct i2c_msg i2c_msg;
0054 
0055 typedef struct i2c_bus i2c_bus;
0056 
0057 typedef struct i2c_dev i2c_dev;
0058 
0059 typedef struct i2c_rdwr_ioctl_data i2c_rdwr_ioctl_data;
0060 
0061 /**
0062  * @defgroup I2C Inter-Integrated Circuit (I2C) Driver
0063  *
0064  * @ingroup RTEMSDeviceDrivers
0065  *
0066  * @brief Inter-Integrated Circuit (I2C) bus and device driver support.
0067  *
0068  * @{
0069  */
0070 
0071 /**
0072  * @defgroup I2CBus I2C Bus Driver
0073  *
0074  * @ingroup I2C
0075  *
0076  * @{
0077  */
0078 
0079 /**
0080  * @name I2C IO Control Commands
0081  *
0082  * @{
0083  */
0084 
0085 /**
0086  * @brief Obtains the bus.
0087  *
0088  * This command has no argument.
0089  */
0090 #define I2C_BUS_OBTAIN 0x800
0091 
0092 /**
0093  * @brief Releases the bus.
0094  *
0095  * This command has no argument.
0096  */
0097 #define I2C_BUS_RELEASE 0x801
0098 
0099 /**
0100  * @brief Gets the bus control.
0101  *
0102  * The argument type is a pointer to i2c_bus pointer.
0103  */
0104 #define I2C_BUS_GET_CONTROL 0x802
0105 
0106 /**
0107  * @brief Sets the bus clock in Hz.
0108  *
0109  * The argument type is unsigned long.
0110  */
0111 #define I2C_BUS_SET_CLOCK 0x803
0112 
0113 /** @} */
0114 
0115 /**
0116  * @brief Default I2C bus clock in Hz.
0117  */
0118 #define I2C_BUS_CLOCK_DEFAULT 100000
0119 
0120 /**
0121  * @brief I2C bus control.
0122  */
0123 struct i2c_bus {
0124   /**
0125    * @brief Transfers I2C messages.
0126    *
0127    * @param[in] bus The bus control.
0128    * @param[in] msgs The messages to transfer.
0129    * @param[in] msg_count The count of messages to transfer.  It must be
0130    * positive.
0131    *
0132    * @retval 0 Successful operation.
0133    * @retval negative Negative error number in case of an error.
0134    */
0135   int (*transfer)(i2c_bus *bus, i2c_msg *msgs, uint32_t msg_count);
0136 
0137   /**
0138    * @brief Sets the bus clock.
0139    *
0140    * @param[in] bus The bus control.
0141    * @param[in] clock The desired bus clock in Hz.
0142    *
0143    * @retval 0 Successful operation.
0144    * @retval negative Negative error number in case of an error.
0145    */
0146   int (*set_clock)(i2c_bus *bus, unsigned long clock);
0147 
0148   /**
0149    * @brief Destroys the bus.
0150    *
0151    * @param[in] bus The bus control.
0152    */
0153   void (*destroy)(i2c_bus *bus);
0154 
0155   /**
0156    * @brief Mutex to protect the bus access.
0157    */
0158   rtems_recursive_mutex mutex;
0159 
0160   /**
0161    * @brief Default slave device address.
0162    */
0163   uint16_t default_address;
0164 
0165   /**
0166    * @brief Use 10-bit addresses.
0167    */
0168   bool ten_bit_address;
0169 
0170   /**
0171    * @brief Use SMBus PEC.
0172    */
0173   bool use_pec;
0174 
0175   /**
0176    * @brief Transfer retry count.
0177    */
0178   unsigned long retries;
0179 
0180   /**
0181    * @brief Transaction timeout in ticks.
0182    */
0183   rtems_interval timeout;
0184 
0185   /**
0186    * @brief Controller functionality.
0187    */
0188   unsigned long functionality;
0189 };
0190 
0191 /**
0192  * @brief Initializes a bus control.
0193  *
0194  * After a sucessful initialization the bus control must be destroyed via
0195  * i2c_bus_destroy().  A registered bus control will be automatically destroyed
0196  * in case the device file is unlinked.  Make sure to call i2c_bus_destroy() in
0197  * a custom destruction handler.
0198  *
0199  * @param[in] bus The bus control.
0200  *
0201  * @retval 0 Successful operation.
0202  * @retval -1 An error occurred.  The errno is set to indicate the error.
0203  *
0204  * @see i2c_bus_register()
0205  */
0206 int i2c_bus_init(i2c_bus *bus);
0207 
0208 /**
0209  * @brief Allocates a bus control from the heap and initializes it.
0210  *
0211  * After a sucessful allocation and initialization the bus control must be
0212  * destroyed via i2c_bus_destroy_and_free().  A registered bus control will be
0213  * automatically destroyed in case the device file is unlinked.  Make sure to
0214  * call i2c_bus_destroy_and_free() in a custom destruction handler.
0215  *
0216  * @param[in] size The size of the bus control.  This enables the addition of
0217  * bus controller specific data to the base bus control.  The bus control is
0218  * zero initialized.
0219  *
0220  * @retval non-NULL The new bus control.
0221  * @retval NULL An error occurred.  The errno is set to indicate the error.
0222  *
0223  * @see i2c_bus_register()
0224  */
0225 i2c_bus *i2c_bus_alloc_and_init(size_t size);
0226 
0227 /**
0228  * @brief Destroys a bus control.
0229  *
0230  * @param[in] bus The bus control.
0231  */
0232 void i2c_bus_destroy(i2c_bus *bus);
0233 
0234 /**
0235  * @brief Destroys a bus control and frees its memory.
0236  *
0237  * @param[in] bus The bus control.
0238  */
0239 void i2c_bus_destroy_and_free(i2c_bus *bus);
0240 
0241 /**
0242  * @brief Registers a bus control.
0243  *
0244  * This function claims ownership of the bus control regardless if the
0245  * registration is successful or not.
0246  *
0247  * @param[in] bus The bus control.
0248  * @param[in] bus_path The path to the bus device file.
0249  *
0250  * @retval 0 Successful operation.
0251  * @retval -1 An error occurred.  The errno is set to indicate the error.
0252  */
0253 int i2c_bus_register(
0254   i2c_bus *bus,
0255   const char *bus_path
0256 );
0257 
0258 /**
0259  * @brief Try to obtain the bus.
0260  *
0261  * @param[in] bus The bus control.
0262  *
0263  * @retval 0 Successful operation.
0264  * @retval EBUSY if mutex is already locked.
0265  */
0266 int i2c_bus_try_obtain(i2c_bus *bus);
0267 
0268 /**
0269  * @brief Obtains the bus.
0270  *
0271  * @param[in] bus The bus control.
0272  */
0273 void i2c_bus_obtain(i2c_bus *bus);
0274 
0275 /**
0276  * @brief Releases the bus.
0277  *
0278  * @param[in] bus The bus control.
0279  */
0280 void i2c_bus_release(i2c_bus *bus);
0281 
0282 /**
0283  * @brief Transfers I2C messages.
0284  *
0285  * The bus is obtained before the transfer and released afterwards. This is the
0286  * same like calling @ref i2c_bus_do_transfer with flags set to 0.
0287  *
0288  * @param[in] bus The bus control.
0289  * @param[in] msgs The messages to transfer.
0290  * @param[in] msg_count The count of messages to transfer.  It must be
0291  * positive.
0292  *
0293  * @retval 0 Successful operation.
0294  * @retval negative Negative error number in case of an error.
0295  */
0296 int i2c_bus_transfer(i2c_bus *bus, i2c_msg *msgs, uint32_t msg_count);
0297 
0298 /**
0299  * @brief Transfers I2C messages with optional flags.
0300  *
0301  * The bus is obtained before the transfer and released afterwards. If the flag
0302  * I2C_BUS_NOBLOCK is set and the bus is already obtained, nothing will be
0303  * transfered and the function returns with an -EAGAIN.
0304  *
0305  * @param[in] bus The bus control.
0306  * @param[in] msgs The messages to transfer.
0307  * @param[in] msg_count The count of messages to transfer.  It must be
0308  * positive.
0309  * @param[in] flags Options for the whole transfer.
0310  *
0311  * @retval 0 Successful operation.
0312  * @retval -EAGAIN if @ref I2C_BUS_NOBLOCK is set and the bus is already
0313  * obtained.
0314  * @retval negative Negative error number in case of an error.
0315  */
0316 int i2c_bus_do_transfer(
0317   i2c_bus *bus,
0318   i2c_msg *msgs,
0319   uint32_t msg_count,
0320   uint32_t flags
0321 );
0322 
0323 /**
0324  * @brief I2C bus transfer flag to indicate that the task should not block if
0325  * the bus is busy on a new transfer.
0326  */
0327 #define I2C_BUS_NOBLOCK (1u << 0)
0328 
0329 /** @} */
0330 
0331 /**
0332  * @defgroup I2CDevice I2C Device Driver
0333  *
0334  * @ingroup I2C
0335  *
0336  * @{
0337  */
0338 
0339 /**
0340  * @brief Base number for device IO control commands.
0341  */
0342 #define I2C_DEV_IO_CONTROL 0x900
0343 
0344 /**
0345  * @brief I2C slave device control.
0346  */
0347 struct i2c_dev {
0348   /**
0349    * @brief Reads from the device.
0350    *
0351    * @retval non-negative Bytes transferred from device.
0352    * @retval negative Negative error number in case of an error.
0353    */
0354   ssize_t (*read)(i2c_dev *dev, void *buf, size_t n, off_t offset);
0355 
0356   /**
0357    * @brief Writes to the device.
0358    *
0359    * @retval non-negative Bytes transferred to device.
0360    * @retval negative Negative error number in case of an error.
0361    */
0362   ssize_t (*write)(i2c_dev *dev, const void *buf, size_t n, off_t offset);
0363 
0364   /**
0365    * @brief Device IO control.
0366    *
0367    * @retval 0 Successful operation.
0368    * @retval negative Negative error number in case of an error.
0369    */
0370   int (*ioctl)(i2c_dev *dev, ioctl_command_t command, void *arg);
0371 
0372   /**
0373    * @brief Gets the file size.
0374    */
0375   off_t (*get_size)(i2c_dev *dev);
0376 
0377   /**
0378    * @brief Gets the file block size.
0379    */
0380   blksize_t (*get_block_size)(i2c_dev *dev);
0381 
0382   /**
0383    * @brief Destroys the device.
0384    */
0385   void (*destroy)(i2c_dev *dev);
0386 
0387   /**
0388    * @brief The bus control.
0389    */
0390   i2c_bus *bus;
0391 
0392   /**
0393    * @brief The device address.
0394    */
0395   uint16_t address;
0396 
0397   /**
0398    * @brief File descriptor of the bus.
0399    *
0400    * This prevents destruction of the bus since we hold a reference to it with
0401    * this.
0402    */
0403   int bus_fd;
0404 };
0405 
0406 
0407 /**
0408  * @brief Initializes a device control.
0409  *
0410  * After a sucessful initialization the device control must be destroyed via
0411  * i2c_dev_destroy().  A registered device control will be automatically
0412  * destroyed in case the device file is unlinked.  Make sure to call
0413  * i2c_dev_destroy_and_free() in a custom destruction handler.
0414  *
0415  * @param[in] device The device control.
0416  * @param[in] bus_path The path to the bus device file.
0417  * @param[in] address The address of the device.
0418  *
0419  * @retval 0 Successful operation.
0420  * @retval -1 An error occurred.  The errno is set to indicate the error.
0421  *
0422  * @see i2c_dev_register()
0423  */
0424 int i2c_dev_init(i2c_dev *dev, const char *bus_path, uint16_t address);
0425 
0426 /**
0427  * @brief Allocates a device control from the heap and initializes it.
0428  *
0429  * After a sucessful allocation and initialization the device control must be
0430  * destroyed via i2c_dev_destroy_and_free().  A registered device control will
0431  * be automatically destroyed in case the device file is unlinked.  Make sure
0432  * to call i2c_dev_destroy_and_free() in a custom destruction handler.
0433  *
0434  * @param[in] size The size of the device control.  This enables the addition
0435  * of device specific data to the base device control.  The device control is
0436  * zero initialized.
0437  * @param[in] bus_path The path to the bus device file.
0438  * @param[in] address The address of the device.
0439  *
0440  * @retval non-NULL The new device control.
0441  * @retval NULL An error occurred.  The errno is set to indicate the error.
0442  *
0443  * @see i2c_dev_register()
0444  */
0445 i2c_dev *i2c_dev_alloc_and_init(
0446   size_t size,
0447   const char *bus_path,
0448   uint16_t address
0449 );
0450 
0451 /**
0452  * @brief Destroys a device control.
0453  *
0454  * @param[in] dev The device control.
0455  */
0456 void i2c_dev_destroy(i2c_dev *dev);
0457 
0458 /**
0459  * @brief Destroys a device control and frees its memory.
0460  *
0461  * @param[in] dev The device control.
0462  */
0463 void i2c_dev_destroy_and_free(i2c_dev *dev);
0464 
0465 /**
0466  * @brief Registers a device control.
0467  *
0468  * This function claims ownership of the device control regardless if the
0469  * registration is successful or not.
0470  *
0471  * @param[in] dev The dev control.
0472  * @param[in] dev_path The path to the device file of the device.
0473  *
0474  * @retval 0 Successful operation.
0475  * @retval -1 An error occurred.  The errno is set to indicate the error.
0476  */
0477 int i2c_dev_register(
0478   i2c_dev *dev,
0479   const char *dev_path
0480 );
0481 
0482 /** @} */  /* end of i2c device driver */
0483 
0484 /** @} */
0485 
0486 #ifdef __cplusplus
0487 }
0488 #endif /* __cplusplus */
0489 
0490 #endif /* _DEV_I2C_I2C_H */