drivers/leds/leds-lp8501.c

Source file repositories/reference/linux-study-clean/drivers/leds/leds-lp8501.c

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-lp8501.c
Extension
.c
Size
3759 bytes
Lines
160
Domain
Driver Families
Bucket
drivers/leds
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
/*
 * TI LP8501 9 channel LED Driver
 *
 * Copyright (C) 2013 Texas Instruments
 *
 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
 */

#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/leds.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_data/leds-lp55xx.h>
#include <linux/slab.h>

#include "leds-lp55xx-common.h"

#define LP8501_PAGES_PER_ENGINE		1
#define LP8501_MAX_LEDS			9

/* Registers */
#define LP8501_REG_ENABLE		0x00
#define LP8501_ENABLE			BIT(6)

#define LP8501_REG_OP_MODE		0x01

#define LP8501_REG_PWR_CONFIG		0x05
#define LP8501_PWR_CONFIG_M		0x03

#define LP8501_REG_LED_PWM_BASE		0x16

#define LP8501_REG_LED_CURRENT_BASE	0x26

#define LP8501_REG_CONFIG		0x36
#define LP8501_PWM_PSAVE		BIT(7)
#define LP8501_AUTO_INC			BIT(6)
#define LP8501_PWR_SAVE			BIT(5)
#define LP8501_CP_MODE_MASK		0x18
#define LP8501_CP_MODE_SHIFT		3
#define LP8501_INT_CLK			BIT(0)
#define LP8501_DEFAULT_CFG (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE)

#define LP8501_REG_STATUS		0x3A
#define LP8501_ENGINE_BUSY		BIT(4)

#define LP8501_REG_RESET		0x3D
#define LP8501_RESET			0xFF

#define LP8501_REG_PROG_MEM		0x50

static int lp8501_post_init_device(struct lp55xx_chip *chip)
{
	int ret;
	u8 val = LP8501_DEFAULT_CFG;

	ret = lp55xx_write(chip, LP8501_REG_ENABLE, LP8501_ENABLE);
	if (ret)
		return ret;

	/* Chip startup time is 500 us, 1 - 2 ms gives some margin */
	usleep_range(1000, 2000);

	if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT)
		val |= LP8501_INT_CLK;

	val |= (chip->pdata->charge_pump_mode << LP8501_CP_MODE_SHIFT) & LP8501_CP_MODE_MASK;

	ret = lp55xx_write(chip, LP8501_REG_CONFIG, val);
	if (ret)
		return ret;

	/* Power selection for each output */
	return lp55xx_update_bits(chip, LP8501_REG_PWR_CONFIG,
				LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel);
}

static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
{
	/* stop engine */
	if (!start) {
		lp55xx_stop_all_engine(chip);
		lp55xx_turn_off_channels(chip);
		return;
	}

Annotation

Implementation Notes