drivers/leds/flash/leds-sy7802.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/flash/leds-sy7802.c
Extension
.c
Size
14281 bytes
Lines
540
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 sy7802_led {
	struct led_classdev_flash flash;
	struct sy7802 *chip;
	u8 led_id;
};

struct sy7802 {
	struct device *dev;
	struct regmap *regmap;
	struct mutex mutex;

	struct gpio_desc *enable_gpio;
	struct regulator *vin_regulator;

	unsigned int fled_strobe_used;
	unsigned int fled_torch_used;
	unsigned int leds_active;
	int num_leds;
	struct sy7802_led leds[] __counted_by(num_leds);
};

static int sy7802_torch_brightness_set(struct led_classdev *lcdev, enum led_brightness brightness)
{
	struct sy7802_led *led = container_of(lcdev, struct sy7802_led, flash.led_cdev);
	struct sy7802 *chip = led->chip;
	u32 fled_torch_used_tmp;
	u32 led_enable_mask;
	u32 enable_mask;
	u32 torch_mask;
	u32 val;
	int ret;

	mutex_lock(&chip->mutex);

	if (chip->fled_strobe_used) {
		dev_warn(chip->dev, "Cannot set torch brightness whilst strobe is enabled\n");
		ret = -EBUSY;
		goto unlock;
	}

	if (brightness)
		fled_torch_used_tmp = chip->fled_torch_used | BIT(led->led_id);
	else
		fled_torch_used_tmp = chip->fled_torch_used & ~BIT(led->led_id);

	led_enable_mask = led->led_id == SY7802_LED_JOINT ?
			  SY7802_LEDS_MASK_ALL :
			  SY7802_LEDS_MASK(led->led_id);

	val = brightness ? led_enable_mask : SY7802_MODE_OFF;
	if (fled_torch_used_tmp)
		val |= SY7802_MODE_TORCH;

	/* Disable torch to apply brightness */
	ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, SY7802_MODE_MASK,
				 SY7802_MODE_OFF);
	if (ret)
		goto unlock;

	torch_mask = led->led_id == SY7802_LED_JOINT ?
		     SY7802_TORCH_CURRENT_MASK_ALL :
		     SY7802_TORCH_CURRENT_MASK(led->led_id);

	/* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */
	if (brightness)
		brightness -= 1;

	brightness |= (brightness << SY7802_TORCH_CURRENT_SHIFT);

	ret = regmap_update_bits(chip->regmap, SY7802_REG_TORCH_BRIGHTNESS, torch_mask, brightness);
	if (ret)
		goto unlock;

	enable_mask = SY7802_MODE_MASK | led_enable_mask;
	ret = regmap_update_bits(chip->regmap, SY7802_REG_ENABLE, enable_mask, val);
	if (ret)
		goto unlock;

	chip->fled_torch_used = fled_torch_used_tmp;

unlock:
	mutex_unlock(&chip->mutex);
	return ret;
}

static int sy7802_flash_brightness_set(struct led_classdev_flash *fl_cdev, u32 brightness)
{
	struct sy7802_led *led = container_of(fl_cdev, struct sy7802_led, flash);
	struct led_flash_setting *s = &fl_cdev->brightness;
	u32 val = (brightness - s->min) / s->step;

Annotation

Implementation Notes