drivers/video/backlight/mp3309c.c

Source file repositories/reference/linux-study-clean/drivers/video/backlight/mp3309c.c

File Facts

System
Linux kernel
Corpus path
drivers/video/backlight/mp3309c.c
Extension
.c
Size
10888 bytes
Lines
423
Domain
Driver Families
Bucket
drivers/video
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 mp3309c_platform_data {
	unsigned int max_brightness;
	unsigned int default_brightness;
	unsigned int *levels;
	u8  dimming_mode;
	u8  over_voltage_protection;
	bool sync_mode;
	u8 status;
};

struct mp3309c_chip {
	struct device *dev;
	struct mp3309c_platform_data *pdata;
	struct backlight_device *bl;
	struct gpio_desc *enable_gpio;
	struct regmap *regmap;
	struct pwm_device *pwmd;
};

static const struct regmap_config mp3309c_regmap = {
	.name = "mp3309c_regmap",
	.reg_bits = 8,
	.reg_stride = 1,
	.val_bits = 8,
	.max_register = REG_I2C_1,
};

static int mp3309c_enable_device(struct mp3309c_chip *chip)
{
	u8 reg_val;
	int ret;

	/* I2C register #0 - Device enable */
	ret = regmap_update_bits(chip->regmap, REG_I2C_0, REG_I2C_0_EN,
				 REG_I2C_0_EN);
	if (ret)
		return ret;

	/*
	 * I2C register #1 - Set working mode:
	 *  - enable/disable synchronous mode
	 *  - set overvoltage protection (OVP)
	 */
	reg_val = 0x00;
	if (chip->pdata->sync_mode)
		reg_val |= REG_I2C_1_SYNC;
	reg_val |= chip->pdata->over_voltage_protection;
	ret = regmap_write(chip->regmap, REG_I2C_1, reg_val);
	if (ret)
		return ret;

	return 0;
}

static int mp3309c_bl_update_status(struct backlight_device *bl)
{
	struct mp3309c_chip *chip = bl_get_data(bl);
	int brightness = backlight_get_brightness(bl);
	struct pwm_state pwmstate;
	unsigned int analog_val, bits_val;
	int i, ret;

	if (chip->pdata->dimming_mode == DIMMING_PWM) {
		/*
		 * PWM control mode
		 */
		pwm_get_state(chip->pwmd, &pwmstate);
		pwm_set_relative_duty_cycle(&pwmstate,
					    chip->pdata->levels[brightness],
					    chip->pdata->levels[chip->pdata->max_brightness]);
		pwmstate.enabled = true;
		ret = pwm_apply_might_sleep(chip->pwmd, &pwmstate);
		if (ret)
			return ret;

		switch (chip->pdata->status) {
		case FIRST_POWER_ON:
		case BACKLIGHT_OFF:
			/*
			 * After 20ms of low pwm signal level, the chip turns
			 * off automatically. In this case, before enabling the
			 * chip again, we must wait about 10ms for pwm signal to
			 * stabilize.
			 */
			if (brightness > 0) {
				msleep(10);
				mp3309c_enable_device(chip);
				chip->pdata->status = BACKLIGHT_ON;
			} else {
				chip->pdata->status = BACKLIGHT_OFF;

Annotation

Implementation Notes