Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/develop/api/overview.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ between major releases are available in the :ref:`zephyr_release_notes`.
- Stable
- 1.14

* - :ref:`charger_api`
- Experimental
- 3.3

* - :ref:`counter_api`
- Unstable
- 1.14
Expand Down
38 changes: 38 additions & 0 deletions doc/hardware/peripherals/charger.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.. _charger_api:

Chargers (Experimental API Stub Doc)
#######################################

The charger subsystem exposes an API to uniformly access battery charger devices. Currently,
only reading data is supported.

Note: This API is currently experimental and this doc will be significantly changed as new features
are added to the API.

Basic Operation
***************

Properties
==========

Fundamentally, a property is a configurable setting, state, or quantity that a charger device can
measure.

Chargers typically support multiple properties, such as temperature readings of the battery-pack
or present-time current/voltage.

Properties are fetched using a client allocated array of :c:struct:`charger_get_property`. This
array is then populated by values as according to its `property_type` field.

Caching
=======

The Charger API explicitly provides no caching for its clients.


.. _charger_api_reference:

API Reference
*************

.. doxygengroup:: charger_interface
1 change: 1 addition & 0 deletions doc/hardware/peripherals/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Peripherals
adc.rst
audio/index.rst
canbus/index.rst
charger.rst
coredump.rst
counter.rst
clock_control.rst
Expand Down
1 change: 1 addition & 0 deletions drivers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth)
add_subdirectory_ifdef(CONFIG_CACHE_MANAGEMENT cache)
add_subdirectory_ifdef(CONFIG_CAN can)
add_subdirectory_ifdef(CONFIG_CLOCK_CONTROL clock_control)
add_subdirectory_ifdef(CONFIG_CHARGER charger)
add_subdirectory_ifdef(CONFIG_CONSOLE console)
add_subdirectory_ifdef(CONFIG_COREDUMP_DEVICE coredump)
add_subdirectory_ifdef(CONFIG_COUNTER counter)
Expand Down
1 change: 1 addition & 0 deletions drivers/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ source "drivers/bluetooth/Kconfig"
source "drivers/cache/Kconfig"
source "drivers/can/Kconfig"
source "drivers/clock_control/Kconfig"
source "drivers/charger/Kconfig"
source "drivers/console/Kconfig"
source "drivers/coredump/Kconfig"
source "drivers/counter/Kconfig"
Expand Down
5 changes: 5 additions & 0 deletions drivers/charger/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0

add_subdirectory_ifdef(CONFIG_SBS_CHARGER sbs_charger)

zephyr_library_sources_ifdef(CONFIG_USERSPACE charger_syscall_handlers.c)
18 changes: 18 additions & 0 deletions drivers/charger/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 Cirrus Logic, Inc.
#
# SPDX-License-Identifier: Apache-2.0

menuconfig CHARGER
bool "Battery charger drivers"
help
Enable battery charger driver configuration.

if CHARGER

module = CHARGER
module-str = charger
source "subsys/logging/Kconfig.template.log_config"

source "drivers/charger/sbs_charger/Kconfig"

endif # CHARGER
28 changes: 28 additions & 0 deletions drivers/charger/charger_syscall_handlers.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023 Cirrus Logic, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/syscall_handler.h>
#include <zephyr/drivers/charger.h>

static inline int z_vrfy_charger_get_prop(const struct device *dev,
struct charger_get_property *props,
size_t props_len)
{
struct charger_get_property k_props[props_len];

Z_OOPS(Z_SYSCALL_DRIVER_CHARGER(dev, get_property));

Z_OOPS(z_user_from_copy(k_props, props,
props_len * sizeof(struct charger_get_property)));

int ret = z_impl_charger_get_prop(dev, k_props, props_len);

Z_OOPS(z_user_to_copy(props, k_props, props_len * sizeof(struct charger_get_property)));

return ret;
}

#include <syscalls/charger_get_prop_mrsh.c>
6 changes: 6 additions & 0 deletions drivers/charger/sbs_charger/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
zephyr_library()

zephyr_library_sources(sbs_charger.c)

zephyr_include_directories_ifdef(CONFIG_EMUL_SBS_CHARGER .)
zephyr_library_sources_ifdef(CONFIG_EMUL_SBS_CHARGER emul_sbs_charger.c)
17 changes: 17 additions & 0 deletions drivers/charger/sbs_charger/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2023 Cirrus Logic, Inc.
# SPDX-License-Identifier: Apache-2.0

config SBS_CHARGER
bool "Smart Battery Charger"
default y
depends on DT_HAS_SBS_SBS_CHARGER_ENABLED
select I2C
help
Enable I2C-based/SMBus-based driver for a Smart Battery Charger.

config EMUL_SBS_CHARGER
bool "Emulate an SBS 1.1 compliant smart battery charger"
depends on EMUL
help
It provides reading which follow a simple sequence, thus allowing
test code to check that things are working as expected.
149 changes: 149 additions & 0 deletions drivers/charger/sbs_charger/emul_sbs_charger.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright 2023 Cirrus Logic, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Emulator for SBS 1.1 compliant smart battery charger.
*/

#define DT_DRV_COMPAT sbs_sbs_charger

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sbs_sbs_charger);

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>
#include <zephyr/sys/byteorder.h>

#include "sbs_charger.h"

/** Static configuration for the emulator */
struct sbs_charger_emul_cfg {
/** I2C address of emulator */
uint16_t addr;
};

static int emul_sbs_charger_reg_write(const struct emul *target, int reg, int val)
{
LOG_INF("write %x = %x", reg, val);
switch (reg) {
default:
LOG_INF("Unknown write %x", reg);
return -EIO;
}

return 0;
}

static int emul_sbs_charger_reg_read(const struct emul *target, int reg, int *val)
{
switch (reg) {
case SBS_CHARGER_REG_SPEC_INFO:
case SBS_CHARGER_REG_STATUS:
case SBS_CHARGER_REG_ALARM_WARNING:
/* Arbitrary stub value. */
*val = 1;
break;
default:
LOG_ERR("Unknown register 0x%x read", reg);
return -EIO;
}
LOG_INF("read 0x%x = 0x%x", reg, *val);

return 0;
}

static int sbs_charger_emul_transfer_i2c(const struct emul *target, struct i2c_msg *msgs,
int num_msgs, int addr)
{
/* Largely copied from emul_bmi160.c */
struct sbs_charger_emul_data *data;
unsigned int val;
int reg;
int rc;

data = target->data;

__ASSERT_NO_MSG(msgs && num_msgs);

i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
switch (num_msgs) {
case 2:
if (msgs->flags & I2C_MSG_READ) {
LOG_ERR("Unexpected read");
return -EIO;
}
if (msgs->len != 1) {
LOG_ERR("Unexpected msg0 length %d", msgs->len);
return -EIO;
}
reg = msgs->buf[0];

/* Now process the 'read' part of the message */
msgs++;
if (msgs->flags & I2C_MSG_READ) {
switch (msgs->len - 1) {
case 1:
rc = emul_sbs_charger_reg_read(target, reg, &val);
if (rc) {
/* Return before writing bad value to message buffer */
return rc;
}

/* SBS uses SMBus, which sends data in little-endian format. */
sys_put_le16(val, msgs->buf);
break;
default:
LOG_ERR("Unexpected msg1 length %d", msgs->len);
return -EIO;
}
} else {
/* We write a word (2 bytes by the SBS spec) */
if (msgs->len != 2) {
LOG_ERR("Unexpected msg1 length %d", msgs->len);
}
uint16_t value = sys_get_le16(msgs->buf);

rc = emul_sbs_charger_reg_write(target, reg, value);
}
break;
default:
LOG_ERR("Invalid number of messages: %d", num_msgs);
return -EIO;
}

return rc;
}

static const struct i2c_emul_api sbs_charger_emul_api_i2c = {
.transfer = sbs_charger_emul_transfer_i2c,
};

/**
* Set up a new SBS_CHARGER emulator (I2C)
*
* @param emul Emulation information
* @param parent Device to emulate (must use sbs_charger driver)
* @return 0 indicating success (always)
*/
static int emul_sbs_sbs_charger_init(const struct emul *target, const struct device *parent)
{
ARG_UNUSED(target);
ARG_UNUSED(parent);

return 0;
}

/*
* Main instantiation macro. SBS Charger Emulator only implemented for I2C
*/
#define SBS_CHARGER_EMUL(n) \
static const struct sbs_charger_emul_cfg sbs_charger_emul_cfg_##n = { \
.addr = DT_INST_REG_ADDR(n), \
}; \
EMUL_DT_INST_DEFINE(n, emul_sbs_sbs_charger_init, NULL, \
&sbs_charger_emul_cfg_##n, &sbs_charger_emul_api_i2c, NULL)

DT_INST_FOREACH_STATUS_OKAY(SBS_CHARGER_EMUL)
Loading