drivers/regulator/lp3971.c
Source file repositories/reference/linux-study-clean/drivers/regulator/lp3971.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/regulator/lp3971.c- Extension
.c- Size
- 11776 bytes
- Lines
- 461
- Domain
- Driver Families
- Bucket
- drivers/regulator
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bug.hlinux/err.hlinux/i2c.hlinux/kernel.hlinux/module.hlinux/regulator/driver.hlinux/regulator/lp3971.hlinux/slab.h
Detected Declarations
struct lp3971function lp3971_ldo_is_enabledfunction lp3971_ldo_enablefunction lp3971_ldo_disablefunction lp3971_ldo_get_voltage_selfunction lp3971_ldo_set_voltage_selfunction lp3971_dcdc_is_enabledfunction lp3971_dcdc_enablefunction lp3971_dcdc_disablefunction lp3971_dcdc_get_voltage_selfunction lp3971_dcdc_set_voltage_selfunction lp3971_i2c_readfunction lp3971_i2c_writefunction lp3971_reg_readfunction lp3971_set_bitsfunction setup_regulatorsfunction lp3971_i2c_probe
Annotated Snippet
struct lp3971 {
struct device *dev;
struct mutex io_lock;
struct i2c_client *i2c;
};
static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
#define LP3971_SYS_CONTROL1_REG 0x07
/* System control register 1 initial value,
bits 4 and 5 are EPROM programmable */
#define SYS_CONTROL1_INIT_VAL 0x40
#define SYS_CONTROL1_INIT_MASK 0xCF
#define LP3971_BUCK_VOL_ENABLE_REG 0x10
#define LP3971_BUCK_VOL_CHANGE_REG 0x20
/* Voltage control registers shift:
LP3971_BUCK1 -> 0
LP3971_BUCK2 -> 4
LP3971_BUCK3 -> 6
*/
#define BUCK_VOL_CHANGE_SHIFT(x) (((!!x) << 2) | (x & ~0x01))
#define BUCK_VOL_CHANGE_FLAG_GO 0x01
#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
#define LP3971_BUCK1_BASE 0x23
#define LP3971_BUCK2_BASE 0x29
#define LP3971_BUCK3_BASE 0x32
static const int buck_base_addr[] = {
LP3971_BUCK1_BASE,
LP3971_BUCK2_BASE,
LP3971_BUCK3_BASE,
};
#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
static const unsigned int buck_voltage_map[] = {
0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000,
1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000,
3000000, 3300000,
};
#define BUCK_TARGET_VOL_MASK 0x3f
#define LP3971_BUCK_RAMP_REG(x) (buck_base_addr[x]+2)
#define LP3971_LDO_ENABLE_REG 0x12
#define LP3971_LDO_VOL_CONTR_BASE 0x39
/* Voltage control registers:
LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
*/
#define LP3971_LDO_VOL_CONTR_REG(x) (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
/* Voltage control registers shift:
LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
LP3971_LDO5 -> 0
*/
#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
#define LDO_VOL_CONTR_MASK 0x0f
static const unsigned int ldo45_voltage_map[] = {
1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000,
1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000,
};
static const unsigned int ldo123_voltage_map[] = {
1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
};
#define LDO_VOL_MIN_IDX 0x00
#define LDO_VOL_MAX_IDX 0x0f
static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
{
struct lp3971 *lp3971 = rdev_get_drvdata(dev);
int ldo = rdev_get_id(dev) - LP3971_LDO1;
Annotation
- Immediate include surface: `linux/bug.h`, `linux/err.h`, `linux/i2c.h`, `linux/kernel.h`, `linux/module.h`, `linux/regulator/driver.h`, `linux/regulator/lp3971.h`, `linux/slab.h`.
- Detected declarations: `struct lp3971`, `function lp3971_ldo_is_enabled`, `function lp3971_ldo_enable`, `function lp3971_ldo_disable`, `function lp3971_ldo_get_voltage_sel`, `function lp3971_ldo_set_voltage_sel`, `function lp3971_dcdc_is_enabled`, `function lp3971_dcdc_enable`, `function lp3971_dcdc_disable`, `function lp3971_dcdc_get_voltage_sel`.
- Atlas domain: Driver Families / drivers/regulator.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.