drivers/firmware/samsung/exynos-acpm-pmic.c

Source file repositories/reference/linux-study-clean/drivers/firmware/samsung/exynos-acpm-pmic.c

File Facts

System
Linux kernel
Corpus path
drivers/firmware/samsung/exynos-acpm-pmic.c
Extension
.c
Size
6074 bytes
Lines
230
Domain
Driver Families
Bucket
drivers/firmware
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2020 Samsung Electronics Co., Ltd.
 * Copyright 2020 Google LLC.
 * Copyright 2024 Linaro Ltd.
 */
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/errno.h>
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
#include <linux/ktime.h>
#include <linux/types.h>

#include "exynos-acpm.h"
#include "exynos-acpm-pmic.h"

#define ACPM_PMIC_CHANNEL		GENMASK(15, 12)
#define ACPM_PMIC_TYPE			GENMASK(11, 8)
#define ACPM_PMIC_REG			GENMASK(7, 0)

#define ACPM_PMIC_RETURN		GENMASK(31, 24)
#define ACPM_PMIC_MASK			GENMASK(23, 16)
#define ACPM_PMIC_VALUE			GENMASK(15, 8)
#define ACPM_PMIC_FUNC			GENMASK(7, 0)

#define ACPM_PMIC_BULK_SHIFT		8
#define ACPM_PMIC_BULK_MASK		GENMASK(7, 0)
#define ACPM_PMIC_BULK_MAX_COUNT	8

enum exynos_acpm_pmic_func {
	ACPM_PMIC_READ,
	ACPM_PMIC_WRITE,
	ACPM_PMIC_UPDATE,
	ACPM_PMIC_BULK_READ,
	ACPM_PMIC_BULK_WRITE,
};

static const int acpm_pmic_linux_errmap[] = {
	[0] = 0, /* ACPM_PMIC_SUCCESS */
	[1] = -EACCES, /* Read register can't be accessed or issues to access it. */
	[2] = -EACCES, /* Write register can't be accessed or issues to access it. */
};

static int acpm_pmic_to_linux_err(unsigned int err)
{
	if (err >= 0 && err < ARRAY_SIZE(acpm_pmic_linux_errmap))
		return acpm_pmic_linux_errmap[err];
	return -EIO;
}

static inline u32 acpm_pmic_set_bulk(u32 data, unsigned int i)
{
	return (data & ACPM_PMIC_BULK_MASK) << (ACPM_PMIC_BULK_SHIFT * i);
}

static inline u32 acpm_pmic_get_bulk(u32 data, unsigned int i)
{
	return (data >> (ACPM_PMIC_BULK_SHIFT * i)) & ACPM_PMIC_BULK_MASK;
}

static void acpm_pmic_init_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan)
{
	cmd[0] = FIELD_PREP(ACPM_PMIC_TYPE, type) |
		 FIELD_PREP(ACPM_PMIC_REG, reg) |
		 FIELD_PREP(ACPM_PMIC_CHANNEL, chan);
	cmd[1] = FIELD_PREP(ACPM_PMIC_FUNC, ACPM_PMIC_READ);
	cmd[3] = ktime_to_ms(ktime_get());
}

int acpm_pmic_read_reg(struct acpm_handle *handle,
		       unsigned int acpm_chan_id, u8 type, u8 reg, u8 chan,
		       u8 *buf)
{
	struct acpm_xfer xfer;
	u32 cmd[4] = {0};
	int ret;

	acpm_pmic_init_read_cmd(cmd, type, reg, chan);
	acpm_set_xfer(&xfer, cmd, ARRAY_SIZE(cmd), acpm_chan_id, true);

	ret = acpm_do_xfer(handle, &xfer);
	if (ret)
		return ret;

	*buf = FIELD_GET(ACPM_PMIC_VALUE, xfer.rxd[1]);

	return acpm_pmic_to_linux_err(FIELD_GET(ACPM_PMIC_RETURN, xfer.rxd[1]));
}

static void acpm_pmic_init_bulk_read_cmd(u32 cmd[4], u8 type, u8 reg, u8 chan,

Annotation

Implementation Notes