drivers/leds/flash/leds-aat1290.c

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

File Facts

System
Linux kernel
Corpus path
drivers/leds/flash/leds-aat1290.c
Extension
.c
Size
14611 bytes
Lines
551
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 aat1290_led_config_data {
	/* maximum LED current in movie mode */
	u32 max_mm_current;
	/* maximum LED current in flash mode */
	u32 max_flash_current;
	/* maximum flash timeout */
	u32 max_flash_tm;
	/* external strobe capability */
	bool has_external_strobe;
	/* max LED brightness level */
	enum led_brightness max_brightness;
};

struct aat1290_led {
	/* platform device data */
	struct platform_device *pdev;
	/* secures access to the device */
	struct mutex lock;

	/* corresponding LED Flash class device */
	struct led_classdev_flash fled_cdev;
	/* V4L2 Flash device */
	struct v4l2_flash *v4l2_flash;

	/* FLEN pin */
	struct gpio_desc *gpio_fl_en;
	/* EN|SET pin  */
	struct gpio_desc *gpio_en_set;
	/* movie mode current scale */
	int *mm_current_scale;
	/* device mode */
	bool movie_mode;
};

static struct aat1290_led *fled_cdev_to_led(
				struct led_classdev_flash *fled_cdev)
{
	return container_of(fled_cdev, struct aat1290_led, fled_cdev);
}

static struct led_classdev_flash *led_cdev_to_fled_cdev(
				struct led_classdev *led_cdev)
{
	return container_of(led_cdev, struct led_classdev_flash, led_cdev);
}

static void aat1290_as2cwire_write(struct aat1290_led *led, int addr, int value)
{
	int i;

	gpiod_direction_output(led->gpio_fl_en, 0);
	gpiod_direction_output(led->gpio_en_set, 0);

	udelay(AAT1290_FLEN_OFF_DELAY_TIME_US);

	/* write address */
	for (i = 0; i < addr; ++i) {
		udelay(AAT1290_EN_SET_TICK_TIME_US);
		gpiod_direction_output(led->gpio_en_set, 0);
		udelay(AAT1290_EN_SET_TICK_TIME_US);
		gpiod_direction_output(led->gpio_en_set, 1);
	}

	usleep_range(AAT1290_LATCH_TIME_MIN_US, AAT1290_LATCH_TIME_MAX_US);

	/* write data */
	for (i = 0; i < value; ++i) {
		udelay(AAT1290_EN_SET_TICK_TIME_US);
		gpiod_direction_output(led->gpio_en_set, 0);
		udelay(AAT1290_EN_SET_TICK_TIME_US);
		gpiod_direction_output(led->gpio_en_set, 1);
	}

	usleep_range(AAT1290_LATCH_TIME_MIN_US, AAT1290_LATCH_TIME_MAX_US);
}

static void aat1290_set_flash_safety_timer(struct aat1290_led *led,
					unsigned int micro_sec)
{
	struct led_classdev_flash *fled_cdev = &led->fled_cdev;
	struct led_flash_setting *flash_tm = &fled_cdev->timeout;
	int flash_tm_reg = AAT1290_FLASH_TM_NUM_LEVELS -
				(micro_sec / flash_tm->step) + 1;

	aat1290_as2cwire_write(led, AAT1290_FLASH_SAFETY_TIMER_ADDR,
							flash_tm_reg);
}

/* LED subsystem callbacks */

Annotation

Implementation Notes