drivers/leds/leds-cht-wcove.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/leds-cht-wcove.c
Extension
.c
Size
12974 bytes
Lines
473
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

struct cht_wc_led_regs {
	/* Register addresses */
	u16 ctrl;
	u16 fsm;
	u16 pwm;
	/* Mask + values for turning the LED on/off */
	u8 on_off_mask;
	u8 on_val;
	u8 off_val;
};

struct cht_wc_led_saved_regs {
	unsigned int ctrl;
	unsigned int fsm;
	unsigned int pwm;
};

struct cht_wc_led {
	struct led_classdev cdev;
	const struct cht_wc_led_regs *regs;
	struct regmap *regmap;
	struct mutex mutex;
	struct cht_wc_led_saved_regs saved_regs;
};

struct cht_wc_leds {
	struct cht_wc_led leds[CHT_WC_LED_COUNT];
	/* Saved LED1 initial register values */
	struct cht_wc_led_saved_regs led1_initial_regs;
};

static const struct cht_wc_led_regs cht_wc_led_regs[CHT_WC_LED_COUNT] = {
	{
		.ctrl		= CHT_WC_LED1_CTRL,
		.fsm		= CHT_WC_LED1_FSM,
		.pwm		= CHT_WC_LED1_PWM,
		.on_off_mask	= CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON,
		.on_val		= CHT_WC_LED1_SWCTL | CHT_WC_LED1_ON,
		.off_val	= CHT_WC_LED1_SWCTL,
	},
	{
		.ctrl		= CHT_WC_LED2_CTRL,
		.fsm		= CHT_WC_LED2_FSM,
		.pwm		= CHT_WC_LED2_PWM,
		.on_off_mask	= CHT_WC_LED2_ON,
		.on_val		= CHT_WC_LED2_ON,
		.off_val	= 0,
	},
};

static const char * const cht_wc_leds_names[CHT_WC_LED_COUNT] = {
	"platform::" LED_FUNCTION_CHARGING,
	"platform::" LED_FUNCTION_INDICATOR,
};

static int cht_wc_leds_brightness_set(struct led_classdev *cdev,
				      enum led_brightness value)
{
	struct cht_wc_led *led = container_of(cdev, struct cht_wc_led, cdev);
	int ret;

	mutex_lock(&led->mutex);

	if (!value) {
		ret = regmap_update_bits(led->regmap, led->regs->ctrl,
					 led->regs->on_off_mask, led->regs->off_val);
		if (ret < 0) {
			dev_err(cdev->dev, "Failed to turn off: %d\n", ret);
			goto out;
		}

		/* Disable HW blinking */
		ret = regmap_update_bits(led->regmap, led->regs->fsm,
					 CHT_WC_LED_EFF_MASK, CHT_WC_LED_EFF_ON);
		if (ret < 0)
			dev_err(cdev->dev, "Failed to update LED FSM reg: %d\n", ret);
	} else {
		ret = regmap_write(led->regmap, led->regs->pwm, value);
		if (ret < 0) {
			dev_err(cdev->dev, "Failed to set brightness: %d\n", ret);
			goto out;
		}

		ret = regmap_update_bits(led->regmap, led->regs->ctrl,
					 led->regs->on_off_mask, led->regs->on_val);
		if (ret < 0)
			dev_err(cdev->dev, "Failed to turn on: %d\n", ret);
	}
out:
	mutex_unlock(&led->mutex);

Annotation

Implementation Notes