From aa6f92b5599eb29e4121522889dc0ee2b039c464 Mon Sep 17 00:00:00 2001
From: mma <mma@msdmarkwort.de>
Date: Thu, 9 May 2024 21:14:21 +0200
Subject: [PATCH] Driver for TPS63101X added

---
 README.md                                     |   4 +-
 components/tps63101x/.eil.yml                 |  19 ++
 components/tps63101x/CMakeLists.txt           |   5 +
 components/tps63101x/LICENSE                  |  26 +++
 components/tps63101x/component.mk             |   2 +
 components/tps63101x/tps63101x.c              | 168 +++++++++++++++
 components/tps63101x/tps63101x.h              | 201 ++++++++++++++++++
 docs/source/chips.rst                         |   4 +
 docs/source/groups/tps63101x.rst              |   8 +
 docs/source/index.rst                         |   1 +
 examples/tps63101x/default/CMakeLists.txt     |   8 +
 examples/tps63101x/default/Makefile           |   6 +
 examples/tps63101x/default/README.md          |  55 +++++
 .../tps63101x/default/main/CMakeLists.txt     |   2 +
 .../tps63101x/default/main/Kconfig.projbuild  |  17 ++
 examples/tps63101x/default/main/component.mk  |   1 +
 examples/tps63101x/default/main/main.c        | 168 +++++++++++++++
 .../default/sdkconfig.defaults.esp8266        |   1 +
 18 files changed, 694 insertions(+), 2 deletions(-)
 create mode 100644 components/tps63101x/.eil.yml
 create mode 100644 components/tps63101x/CMakeLists.txt
 create mode 100644 components/tps63101x/LICENSE
 create mode 100644 components/tps63101x/component.mk
 create mode 100644 components/tps63101x/tps63101x.c
 create mode 100644 components/tps63101x/tps63101x.h
 create mode 100644 docs/source/groups/tps63101x.rst
 create mode 100644 examples/tps63101x/default/CMakeLists.txt
 create mode 100644 examples/tps63101x/default/Makefile
 create mode 100644 examples/tps63101x/default/README.md
 create mode 100644 examples/tps63101x/default/main/CMakeLists.txt
 create mode 100644 examples/tps63101x/default/main/Kconfig.projbuild
 create mode 100644 examples/tps63101x/default/main/component.mk
 create mode 100644 examples/tps63101x/default/main/main.c
 create mode 100644 examples/tps63101x/default/sdkconfig.defaults.esp8266

diff --git a/README.md b/README.md
index 1164667e7..d866f8158 100644
--- a/README.md
+++ b/README.md
@@ -242,7 +242,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example
 | **tda74xx**              | Driver for TDA7439/TDA7439DS/TDA7440D audioprocessors                            | MIT     | esp32, esp8266, esp32s2, esp32c3 | yes           |
 | **ultrasonic**           | Driver for ultrasonic range meters, e.g. HC-SR04, HY-SRF05                       | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | no            |
 | **wiegand**              | Wiegand protocol receiver                                                        | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | no            |
-
+| **tps63101x**            | Driver for TI TPS631012/3 1.6-V-5.5-V Input Voltage Buck-boost Converter         | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes           |
 
 ### Pressure sensors
 
@@ -330,7 +330,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example
 - [jsuiker](https://github.com/jsuiker): `dht` 
 - [Julian Doerner](https://github.com/juliandoerner): `tsl2591` 
 - [Lucio Tarantino](https://github.com/dianlight): `ads111x` 
-- [Manuel Markwort](https://github.com/mmarkwort): `mp2660` 
+- [Manuel Markwort](https://github.com/mmarkwort): `mp2660` `tps63101x`
 - [Marc Luehr](https://github.com/th3link): `veml7700` 
 - [Nate Usher](https://github.com/nated0g): `scd30` 
 - Pavel Merzlyakov: `ds1302` 
diff --git a/components/tps63101x/.eil.yml b/components/tps63101x/.eil.yml
new file mode 100644
index 000000000..6c1274b90
--- /dev/null
+++ b/components/tps63101x/.eil.yml
@@ -0,0 +1,19 @@
+name: tps63101x
+description: Driver for Texas Instruments TPS631012 and TPS631013 1.6-V to 5.5-V Input Voltage 1.5-A Buck-boost Converter with I2C
+version: 1.0.0
+groups:
+  - misc
+code_owners:
+  - mmarkwort
+depends:
+  - i2cdev
+  - esp_idf_lib_helpers
+thread_safe: yes
+targets:
+  - esp32
+  - esp32s2
+  - esp32c3
+license: BSD-3
+copyrights:
+  - name: mmarkwort
+    year: 2024
diff --git a/components/tps63101x/CMakeLists.txt b/components/tps63101x/CMakeLists.txt
new file mode 100644
index 000000000..3e29d1f5f
--- /dev/null
+++ b/components/tps63101x/CMakeLists.txt
@@ -0,0 +1,5 @@
+idf_component_register(
+    SRCS tps63101x.c
+    INCLUDE_DIRS .
+    REQUIRES i2cdev esp_idf_lib_helpers
+)
diff --git a/components/tps63101x/LICENSE b/components/tps63101x/LICENSE
new file mode 100644
index 000000000..7dbb7cd48
--- /dev/null
+++ b/components/tps63101x/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2024 Manuel Markwort (https://github.com/mmarkwort)
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of itscontributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/components/tps63101x/component.mk b/components/tps63101x/component.mk
new file mode 100644
index 000000000..60e16f4b0
--- /dev/null
+++ b/components/tps63101x/component.mk
@@ -0,0 +1,2 @@
+COMPONENT_ADD_INCLUDEDIRS = .
+COMPONENT_DEPENDS = i2cdev esp_idf_lib_helpers
diff --git a/components/tps63101x/tps63101x.c b/components/tps63101x/tps63101x.c
new file mode 100644
index 000000000..4ec4b6a2a
--- /dev/null
+++ b/components/tps63101x/tps63101x.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2024 Manuel Markwort <https://github.com/mmarkwort>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of itscontributors
+ *    may be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file tps63101x.c
+ *
+ * ESP-IDF driver for Texas Instruments TPS631012 and TPS631013 1.6-V to 5.5-V Input Voltage 1.5-A Buck-boost Converter with I2C
+ *
+ * Copyright (c) 2024 Manuel Markwort <https://github.com/mmarkwort>\n
+ *
+ * BSD Licensed as described in the file LICENSE
+ */
+
+#include <esp_idf_lib_helpers.h>
+#include "tps63101x.h"
+
+#define I2C_FREQ_HZ 400000 //!< 400kHz bus speed
+
+#define TPS63101X_CONTROL_1_REG_ADDR 0x02 //!< Address of Control 1 register
+#define TPS63101X_VOUT_REG_ADDR 0x03 //!< Address of VOUT register
+#define TPS63101X_CONTROL_2_REG_ADDR 0x05 //!< Address of Control 2 register
+
+#define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0)
+
+esp_err_t tps63101x_init_desc(i2c_dev_t *dev, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio)
+{
+    CHECK_ARG(dev);
+
+    dev->port = port;
+    dev->addr = TPS63101X_I2C_ADDR;
+    dev->cfg.sda_io_num = sda_gpio;
+    dev->cfg.scl_io_num = scl_gpio;
+#if HELPER_TARGET_IS_ESP32
+    dev->cfg.master.clk_speed = I2C_FREQ_HZ;
+#endif
+
+    return i2c_dev_create_mutex(dev);
+}
+
+esp_err_t tps63101x_free_desc(i2c_dev_t *dev)
+{
+    CHECK_ARG(dev);
+
+    return i2c_dev_delete_mutex(dev);
+}
+
+esp_err_t tps63101x_read(i2c_dev_t *dev, uint8_t addr, void* data)
+{
+    CHECK_ARG(dev);
+
+    I2C_DEV_TAKE_MUTEX(dev);
+    I2C_DEV_CHECK(dev, i2c_dev_read_reg(dev, addr, data, 1));
+    I2C_DEV_GIVE_MUTEX(dev);
+
+    return ESP_OK;
+}
+
+esp_err_t tps63101x_write(i2c_dev_t *dev, uint8_t addr, void* data)
+{
+    CHECK_ARG(dev);
+
+    I2C_DEV_TAKE_MUTEX(dev);
+    I2C_DEV_CHECK(dev, i2c_dev_write_reg(dev, addr, data, 1));
+    I2C_DEV_GIVE_MUTEX(dev);
+
+    return ESP_OK;
+}
+
+esp_err_t tps63101x_get_control_1(i2c_dev_t *dev, tps63101x_control_1_t* control_1)
+{
+    return tps63101x_read(dev, TPS63101X_CONTROL_1_REG_ADDR, control_1);
+}
+
+esp_err_t tps63101x_set_control_1(i2c_dev_t *dev, tps63101x_control_1_t* control_1)
+{
+    return tps63101x_write(dev, TPS63101X_CONTROL_1_REG_ADDR, control_1);
+}
+
+esp_err_t tps63101x_get_vout(i2c_dev_t *dev, tps63101x_vout_t* vout)
+{
+    return tps63101x_read(dev, TPS63101X_VOUT_REG_ADDR, vout);
+}
+
+esp_err_t tps63101x_set_vout(i2c_dev_t *dev, tps63101x_vout_t* vout)
+{
+    return tps63101x_write(dev, TPS63101X_VOUT_REG_ADDR, vout);
+}
+
+esp_err_t tps63101x_get_control_2(i2c_dev_t *dev, tps63101x_control_2_t* control_2)
+{
+    return tps63101x_read(dev, TPS63101X_CONTROL_2_REG_ADDR, control_2);
+}
+
+esp_err_t tps63101x_set_control_2(i2c_dev_t *dev, tps63101x_control_2_t* control_2)
+{
+    return tps63101x_write(dev, TPS63101X_CONTROL_2_REG_ADDR, control_2);
+}
+
+esp_err_t tps63101x_reset(i2c_dev_t *dev)
+{
+    esp_err_t err;
+
+    tps63101x_control_1_t control_1;
+    tps63101x_vout_t vout;
+    tps63101x_control_2_t control_2;
+
+    control_1.register_data.reg = TPS63101X_CONTROL_1_DEFAULT;
+    vout.register_data.reg = TPS63101X_VOUT_DEFAULT;
+    control_2.register_data.reg = TPS63101X_CONTROL_2_DEFAULT;
+
+    err = tps63101x_set_control_1(dev, &control_1);
+    if(err != ESP_OK)
+    {
+        return err;
+    }
+
+    vTaskDelay(pdMS_TO_TICKS(1500));
+
+    err = tps63101x_set_control_2(dev, &control_2);
+    if(err != ESP_OK)
+    {
+        return err;
+    }
+
+    vTaskDelay(pdMS_TO_TICKS(1500));
+
+    err = tps63101x_set_vout(dev, &vout);
+    if(err != ESP_OK)
+    {
+        return err;
+    }
+
+    return err;
+}
+
+uint8_t tps63101x_to_register_voltage(float voltage)
+{
+    if(voltage < 1.0f || voltage > 5.5f)
+    {
+        return 0xff;
+    }
+
+    return (voltage - 1.0f) / 0.025;
+}
\ No newline at end of file
diff --git a/components/tps63101x/tps63101x.h b/components/tps63101x/tps63101x.h
new file mode 100644
index 000000000..a4d6b2ba8
--- /dev/null
+++ b/components/tps63101x/tps63101x.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2024 Manuel Markwort <https://github.com/mmarkwort>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of itscontributors
+ *    may be used to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file tps63101x.h
+ * @defgroup tps63101x tps63101x
+ * @{
+ *
+ * ESP-IDF driver for Texas Instruments TPS631012 and TPS631013 1.6-V to 5.5-V Input Voltage 1.5-A Buck-boost Converter with I2C
+ *
+ * Copyright (c) 2024 Manuel Markwort <https://github.com/mmarkwort>\n
+ *
+ * BSD Licensed as described in the file LICENSE
+ */
+
+#ifndef __TPS63101X_H__
+#define __TPS63101X_H__
+
+#include <stdbool.h>
+#include <i2cdev.h>
+#include <esp_err.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TPS63101X_I2C_ADDR 0x2A //!< I2C address
+
+#define TPS63101X_CONTROL_1_DEFAULT 0x8 //!< Default value of Control 1 register
+#define TPS63101X_VOUT_DEFAULT 0x5C //!< Default value of VOUT register
+#define TPS63101X_CONTROL_2_DEFAULT 0x45 //!< Default value of Control 2 register
+
+/**
+ * Control 1 Register/Address: 02h (Default: 0x8)
+ */
+typedef struct
+{
+    union {
+        struct {
+            uint8_t converter_en : 1;   //!< Enable Converter ('AND'ed with EN-pin): 0 : DISABLE, 1 : ENABLE / Default: 0 / RW
+            uint8_t nil2 : 1;           //!< Not used. / Default: 0 / R
+            uint8_t en_scp : 1;         //!< Enable short circuit hiccup protection: 0 : DISABLE, 1 : ENABLE / Default: 0 / RW
+            uint8_t en_fast_dvs : 1;    //!< Sets DVS to fast mode: 0 : DISABLE, 1 : ENABLE / Default: 1 / RW
+            uint8_t nil : 4;            //!< Not used. During write operations data for these bits are ignored. During read operations 0 is returned. / Default: 0 / R
+        } data_fields;
+        struct {
+            uint8_t reg;                //!< Register data
+        } register_data;
+    };
+    
+} tps63101x_control_1_t;
+
+/**
+ * Control 1 Register/Address: 03h (Default: 0x5C)
+ */
+typedef struct
+{
+    union {
+        struct {
+            uint8_t vout;               //!< These bits set the output voltage: Output voltage = 1.000 + (VOUT[7 :0] × 0.025) V when 0x00<=VOUT[7 :0]<=0xB4, Output voltage = 5.5 V when 0xB5<=VOUT[7 :0]<=0xFF / Default: 5C / RW
+        } data_fields;
+        struct {
+            uint8_t reg;                //!< Register data
+        } register_data;
+    };
+    
+} tps63101x_vout_t;
+
+/**
+ * Control 2 Register/Address: 05h (Default: 0x45)
+ */
+typedef struct
+{
+    union {
+        struct {
+            uint8_t td_ramp : 3;        //!< Defines the ramp time for the Vo soft start ramp: 000: 0.256ms, 001: 0.512ms, 010: 1.024ms, 011: 1.920ms, 100: 3.584ms, 101: 7.552ms, 110: 9.600ms, 111: 24.320ms / Default: 101 / RW
+            uint8_t cl_ramp_min : 1;    //!< Define the minimum current limit during the soft start ramp: 0 : Low (500mA), 1 : High (2x Low) / Default: 0 / RW
+            uint8_t en_disch_vout : 2;  //!< Enable of BUBO Vout Discharge: 00 : DISABLE, 01 : SLOW (34mA), 10 : MEDIUM (67mA), 11 : FAST (100mA) / Default: 0 / RW
+            uint8_t fast_ramp_en : 1;   //!< Device can start-up faster than VOUT ramp: 0 : DISABLE, 1 : ENABLE / Default: 1 / RW
+            uint8_t fpwm : 1;           //!< Force PWM operation: 0 : DISABLE, 1 : ENABLE / Default: 0 / RW
+        } data_fields;
+        struct {
+            uint8_t reg;                //!< Register data
+        } register_data;
+    };
+    
+} tps63101x_control_2_t;
+
+
+/**
+ * @brief Initialize device descriptor
+ *
+ * @param dev       Device descriptor
+ * @param port      I2C port
+ * @param sda_gpio  SDA GPIO pin
+ * @param scl_gpio  SCL GPIO pin
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_init_desc(i2c_dev_t *dev, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio);
+
+/**
+ * @brief Free device descriptor
+ *
+ * @param dev Device descriptor
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_free_desc(i2c_dev_t *dev);
+
+/**
+ * @brief Reads control 1 register
+ * @param dev Device descriptor
+ * @param control_1 Target buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_get_control_1(i2c_dev_t *dev, tps63101x_control_1_t* control_1);
+
+/**
+ * @brief Writes control 1 register
+ * @param dev Device descriptor
+ * @param control_1 Source buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_set_control_1(i2c_dev_t *dev, tps63101x_control_1_t* control_1);
+
+/**
+ * @brief Reads vout register
+ * @param dev Device descriptor
+ * @param vout Target buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_get_vout(i2c_dev_t *dev, tps63101x_vout_t* vout);
+
+/**
+ * @brief Writes vout register
+ * @param dev Device descriptor
+ * @param vout Source buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_set_vout(i2c_dev_t *dev, tps63101x_vout_t* vout);
+
+/**
+ * @brief Reads control 2 register
+ * @param dev Device descriptor
+ * @param control_2 Target buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_get_control_2(i2c_dev_t *dev, tps63101x_control_2_t* control_2);
+
+/**
+ * @brief Writes control 2 register
+ * @param dev Device descriptor
+ * @param control_2 Source buffer
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_set_control_2(i2c_dev_t *dev, tps63101x_control_2_t* control_2);
+
+/**
+ * @brief Resets all registers to default vaules
+ * @param dev Device descriptor
+ * @return `ESP_OK` on success
+ */
+esp_err_t tps63101x_reset(i2c_dev_t *dev);
+
+/**
+ * @brief Calculates the register value for the given value (min. voltage = 1.0, max. volatge = 5.5)
+ * @param voltage Device descriptor
+ * @return returns the register value of the given voltage on success `0xFF` on failure
+ */
+uint8_t tps63101x_to_register_voltage(float voltage);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
\ No newline at end of file
diff --git a/docs/source/chips.rst b/docs/source/chips.rst
index 4248535eb..f21e778ab 100644
--- a/docs/source/chips.rst
+++ b/docs/source/chips.rst
@@ -167,6 +167,10 @@ Supported devices
 +---------------+----------------------------------------+----------------------+
 | TDA7440       | NXP                                    | :ref:`tda74xx`       |
 +---------------+----------------------------------------+----------------------+
+| TPS631012     | Texas Instruments                      | :ref:`tps63101x      |
++---------------+----------------------------------------+----------------------+
+| TPS631013     | Texas Instruments                      | :ref:`tps63101x      |
++---------------+----------------------------------------+----------------------+
 | TSL2561       | TAOS                                   | :ref:`tsl2561`       |
 +---------------+----------------------------------------+----------------------+
 | TSL2591       | TAOS                                   | :ref:`tsl2591`       |
diff --git a/docs/source/groups/tps63101x.rst b/docs/source/groups/tps63101x.rst
new file mode 100644
index 000000000..7dbd898a7
--- /dev/null
+++ b/docs/source/groups/tps63101x.rst
@@ -0,0 +1,8 @@
+.. _tps63101x:
+
+tps63101x - Texas Instruments TPS631012 and TPS631013 1.6-V to 5.5-V Input Voltage 1.5-A Buck-boost Converter with I2C
+===============================================================================================================
+
+.. doxygengroup:: tps63101x
+   :members:
+
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 2f39f6b04..115053651 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -253,6 +253,7 @@ Other
    groups/ds3502
    groups/wiegand
    groups/impulse_sensor
+   groups/tps63101x
 
 
 ===========
diff --git a/examples/tps63101x/default/CMakeLists.txt b/examples/tps63101x/default/CMakeLists.txt
new file mode 100644
index 000000000..6dae7b26d
--- /dev/null
+++ b/examples/tps63101x/default/CMakeLists.txt
@@ -0,0 +1,8 @@
+# The following lines of boilerplate have to be in your project's
+# CMakeLists in this exact order for cmake to work correctly
+cmake_minimum_required(VERSION 3.5)
+
+set(EXTRA_COMPONENT_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../../../components)
+
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+project(example-tps63101x)
diff --git a/examples/tps63101x/default/Makefile b/examples/tps63101x/default/Makefile
new file mode 100644
index 000000000..30787a267
--- /dev/null
+++ b/examples/tps63101x/default/Makefile
@@ -0,0 +1,6 @@
+#V := 1
+PROJECT_NAME := example-tps63101x
+
+EXTRA_COMPONENT_DIRS := $(CURDIR)/../../../components
+
+include $(IDF_PATH)/make/project.mk
diff --git a/examples/tps63101x/default/README.md b/examples/tps63101x/default/README.md
new file mode 100644
index 000000000..69372b5c5
--- /dev/null
+++ b/examples/tps63101x/default/README.md
@@ -0,0 +1,55 @@
+# Example for `tps63101x` driver
+
+## What it does
+
+Resets all registers to their default values and then reads all registers from IC.
+
+## Wiring
+
+Connect `SCL` and `SDA` pins to the following pins with appropriate pull-up
+resistors.
+
+| Name | Description | Defaults |
+|------|-------------|----------|
+| `CONFIG_EXAMPLE_I2C_MASTER_SCL` | GPIO number for `SCL` | "18" for `esp32`, `esp32s2`, and `esp32s3` |
+| `CONFIG_EXAMPLE_I2C_MASTER_SDA` | GPIO number for `SDA` | "17" for `esp32`, `esp32s2`, and `esp32s3` |
+
+## Example log
+
+```console
+I (0) cpu_start: App cpu up.
+I (222) cpu_start: Pro cpu start user code
+I (223) cpu_start: cpu freq: 160000000 Hz
+I (223) cpu_start: Application information:
+I (227) cpu_start: Project name:     example-tps63101x
+I (233) cpu_start: App version:      0.9.4-133-gc6da185
+I (239) cpu_start: Compile time:     May  9 2024 20:01:30
+I (245) cpu_start: ELF file SHA256:  87fa1391764c6f1b...
+I (251) cpu_start: ESP-IDF:          v5.1.2
+I (256) cpu_start: Min chip rev:     v0.0
+I (261) cpu_start: Max chip rev:     v3.99 
+I (265) cpu_start: Chip rev:         v3.0
+I (270) heap_init: Initializing. RAM available for dynamic allocation:
+I (278) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
+I (283) heap_init: At 3FFB2A50 len 0002D5B0 (181 KiB): DRAM
+I (290) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
+I (296) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
+I (303) heap_init: At 4008D590 len 00012A70 (74 KiB): IRAM
+I (310) spi_flash: detected chip: generic
+I (313) spi_flash: flash io: dio
+W (317) spi_flash: Detected size(16384k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
+I (331) app_start: Starting scheduler on CPU0
+I (336) app_start: Starting scheduler on CPU1
+I (336) main_task: Started on CPU0
+I (346) main_task: Calling app_main()
+I (346) main_task: Returned from app_main()
+I (346) Main: TPS63101X initialized.
+I (2356) Main: Reset to defaults.
+I (5356) Main: Reading control 1 register.
+I (5356) Main: Result: 00000008, enable fast DVS: 1, enable SCP: 0, enable converter: 0
+I (7356) Main: Reading vout register.
+I (7356) Main: Result: 0000005c
+I (9356) Main: Reading control 2 register.
+I (9356) Main: Result: 00000045, force pwm: 0, fast ramp enable: 1, enable vout discharge: 0, cl ramp minimum: 0, ramp: 5
+I (11366) Main: Finished.
+```
diff --git a/examples/tps63101x/default/main/CMakeLists.txt b/examples/tps63101x/default/main/CMakeLists.txt
new file mode 100644
index 000000000..87fff61e5
--- /dev/null
+++ b/examples/tps63101x/default/main/CMakeLists.txt
@@ -0,0 +1,2 @@
+idf_component_register(SRCS "main.c"
+                        INCLUDE_DIRS ".")
diff --git a/examples/tps63101x/default/main/Kconfig.projbuild b/examples/tps63101x/default/main/Kconfig.projbuild
new file mode 100644
index 000000000..a58b3fb3b
--- /dev/null
+++ b/examples/tps63101x/default/main/Kconfig.projbuild
@@ -0,0 +1,17 @@
+menu "Example configuration"
+    config EXAMPLE_I2C_MASTER_SCL
+        int "SCL GPIO Number"
+        default 5 if IDF_TARGET_ESP8266
+        default 6 if IDF_TARGET_ESP32C3
+        default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
+        help
+            GPIO number for I2C Master clock line.
+
+    config EXAMPLE_I2C_MASTER_SDA
+        int "SDA GPIO Number"
+        default 4 if IDF_TARGET_ESP8266
+        default 5 if IDF_TARGET_ESP32C3
+        default 17 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
+        help
+            GPIO number for I2C Master data line.
+endmenu
diff --git a/examples/tps63101x/default/main/component.mk b/examples/tps63101x/default/main/component.mk
new file mode 100644
index 000000000..7700ea99b
--- /dev/null
+++ b/examples/tps63101x/default/main/component.mk
@@ -0,0 +1 @@
+COMPONENT_ADD_INCLUDEDIRS = . include/
diff --git a/examples/tps63101x/default/main/main.c b/examples/tps63101x/default/main/main.c
new file mode 100644
index 000000000..c09992696
--- /dev/null
+++ b/examples/tps63101x/default/main/main.c
@@ -0,0 +1,168 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <freertos/FreeRTOS.h>
+#include <freertos/task.h>
+#include <tps63101x.h>
+#include <string.h>
+#include <esp_err.h>
+#include <esp_log.h>
+
+#ifndef APP_CPU_NUM
+#define APP_CPU_NUM PRO_CPU_NUM
+#endif
+
+static const char *MAIN_LOG_TAG = "Main";
+
+void read_control_1_register(i2c_dev_t* buckBoostConverter)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Reading control 1 register.");
+    
+    tps63101x_control_1_t control_1;
+
+    esp_err_t err = tps63101x_get_control_1(buckBoostConverter, &control_1);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error reading control 1 register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+
+    ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, enable fast DVS: %d, enable SCP: %d, enable converter: %d", control_1.register_data.reg, control_1.data_fields.en_fast_dvs, control_1.data_fields.en_scp, control_1.data_fields.converter_en);
+}
+
+void write_control_1_register(i2c_dev_t* buckBoostConverter, tps63101x_control_1_t* control_1)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Writing control 1 register.");
+    
+    esp_err_t err = tps63101x_set_control_1(buckBoostConverter, control_1);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error writing control 1 register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+}
+
+void read_vout_register(i2c_dev_t* buckBoostConverter)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Reading vout register.");
+    
+    tps63101x_vout_t vout;
+
+    esp_err_t err = tps63101x_get_vout(buckBoostConverter, &vout);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error reading vout register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+
+    ESP_LOGI(MAIN_LOG_TAG, "Result: %08x", vout.register_data.reg);
+}
+
+void write_vout_register(i2c_dev_t* buckBoostConverter, tps63101x_vout_t* vout)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Writing vout register.");
+    
+    esp_err_t err = tps63101x_set_vout(buckBoostConverter, vout);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error writing vout register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+}
+
+void read_control_2_register(i2c_dev_t* buckBoostConverter)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Reading control 2 register.");
+    
+    tps63101x_control_2_t control_2;
+
+    esp_err_t err = tps63101x_get_control_2(buckBoostConverter, &control_2);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error reading control 2 register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+
+    ESP_LOGI(MAIN_LOG_TAG, "Result: %08x, force pwm: %d, fast ramp enable: %d, enable vout discharge: %d, cl ramp minimum: %d, ramp: %d", control_2.register_data.reg, control_2.data_fields.fpwm, control_2.data_fields.fast_ramp_en, control_2.data_fields.en_disch_vout, control_2.data_fields.cl_ramp_min, control_2.data_fields.td_ramp);
+}
+
+void write_control_2_register(i2c_dev_t* buckBoostConverter, tps63101x_control_2_t* control_2)
+{
+    ESP_LOGI(MAIN_LOG_TAG, "Writing control 2 register.");
+    
+    esp_err_t err = tps63101x_set_control_2(buckBoostConverter, control_2);
+
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Error writing control 2 register: %s", esp_err_to_name(err));
+
+        vTaskDelete(NULL);
+        return;
+    }
+}
+
+void task(void *pvParameters)
+{
+    i2c_dev_t buckBoostConverter;
+    memset(&buckBoostConverter, 0, sizeof(i2c_dev_t));
+
+    i2cdev_init();
+
+    esp_err_t err = tps63101x_init_desc(&buckBoostConverter, 0, CONFIG_EXAMPLE_I2C_MASTER_SDA, CONFIG_EXAMPLE_I2C_MASTER_SCL);
+    if (err != ESP_OK)
+    {
+        ESP_LOGI(MAIN_LOG_TAG, "Cannot init TPS63101X: %s", esp_err_to_name(err));
+        vTaskDelete(NULL);
+        
+        return;
+    }
+
+    ESP_LOGI(MAIN_LOG_TAG, "TPS63101X initialized.");
+
+    vTaskDelay(pdMS_TO_TICKS(2000));
+
+    // Reset to defaults
+    ESP_LOGI(MAIN_LOG_TAG, "Reset to defaults.");
+
+    tps63101x_reset(&buckBoostConverter);
+
+    // Control 1 register
+    read_control_1_register(&buckBoostConverter);
+
+    vTaskDelay(pdMS_TO_TICKS(2000));
+   
+    // Vout register
+    read_vout_register(&buckBoostConverter);
+
+    vTaskDelay(pdMS_TO_TICKS(2000));
+
+    // Control 2 register
+    read_control_2_register(&buckBoostConverter);
+
+    vTaskDelay(pdMS_TO_TICKS(2000));
+   
+    ESP_LOGI(MAIN_LOG_TAG, "Finished.");
+
+    vTaskDelete(NULL);
+}
+
+void app_main()
+{
+    ESP_ERROR_CHECK(i2cdev_init());
+
+    xTaskCreatePinnedToCore(task, "test", configMINIMAL_STACK_SIZE * 8, NULL, 5, NULL, APP_CPU_NUM);
+}
diff --git a/examples/tps63101x/default/sdkconfig.defaults.esp8266 b/examples/tps63101x/default/sdkconfig.defaults.esp8266
new file mode 100644
index 000000000..79a53171f
--- /dev/null
+++ b/examples/tps63101x/default/sdkconfig.defaults.esp8266
@@ -0,0 +1 @@
+CONFIG_NEWLIB_LIBRARY_LEVEL_NORMAL=y