Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e776016c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "leds: leds-qpnp-flash: add check for determining enabled flashLED module"

parents f33a43db 5857ed08
Loading
Loading
Loading
Loading
+188 −177
Original line number Diff line number Diff line
@@ -175,6 +175,7 @@ struct flash_node_data {
	u32				boost_voltage_max;
	u16				max_current;
	u16				prgm_current;
	u16				prgm_current2;
	u16				duration;
	u8				id;
	u8				type;
@@ -251,7 +252,7 @@ struct qpnp_flash_led {

static u8 qpnp_flash_led_ctrl_dbg_regs[] = {
	0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
	0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A
	0x4A, 0x4B, 0x4C, 0x4F, 0x51, 0x52, 0x54, 0x55, 0x5A, 0x5C, 0x5D,
};

static int flash_led_dbgfs_file_open(struct qpnp_flash_led *led,
@@ -897,8 +898,22 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
				struct flash_node_data *flash_node)
{
	union power_supply_propval psy_prop;
	int rc, i;
	int rc;
	u8 val, tmp;

	rc = spmi_ext_register_readl(led->spmi_dev->ctrl,
				led->spmi_dev->sid,
				FLASH_LED_STROBE_CTRL(led->base),
				&val, 1);
	if (rc) {
		dev_err(&led->spmi_dev->dev,
				"Unable to read strobe reg\n");
		return -EINVAL;
	}

	tmp = (~flash_node->trigger) & val;
	if (!tmp) {
		if (flash_node->type == TORCH) {
			rc = qpnp_led_masked_write(led->spmi_dev,
				FLASH_LED_UNLOCK_SECURE(led->base),
				FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE);
@@ -916,29 +931,6 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
					"Torch reg write failed\n");
				return -EINVAL;
			}

	if (led->pdata->hdrm_sns_ch0_en) {
		rc = qpnp_led_masked_write(led->spmi_dev,
				FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
				FLASH_LED_HDRM_SNS_ENABLE_MASK,
				FLASH_LED_HDRM_SNS_DISABLE);
		if (rc) {
			dev_err(&led->spmi_dev->dev,
				"Headroom sense disable failed\n");
			return rc;
		}
	}

	if (led->pdata->hdrm_sns_ch1_en) {
		rc = qpnp_led_masked_write(led->spmi_dev,
				FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
				FLASH_LED_HDRM_SNS_ENABLE_MASK,
				FLASH_LED_HDRM_SNS_DISABLE);
		if (rc) {
			dev_err(&led->spmi_dev->dev,
				"Headroom sense disable failed\n");
			return rc;
		}
		}

		rc = qpnp_led_masked_write(led->spmi_dev,
@@ -946,7 +938,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
				FLASH_MODULE_ENABLE_MASK,
				FLASH_LED_MODULE_CTRL_DEFAULT);
		if (rc) {
		dev_err(&led->spmi_dev->dev, "Module disable failed\n");
			dev_err(&led->spmi_dev->dev,
					"Module disable failed\n");
			return -EINVAL;
		}

@@ -972,9 +965,9 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
				return -EINVAL;
			}
		}
	}

	if (!led->flash_node[0].flash_on &&
		!led->flash_node[2].flash_on) {
	if (flash_node->trigger & FLASH_LED0_TRIGGER) {
		rc = qpnp_led_masked_write(led->spmi_dev,
				led->current_addr,
				FLASH_CURRENT_MASK, 0x00);
@@ -983,10 +976,10 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
				"current register write failed\n");
			return -EINVAL;
		}

	}

	if (!led->flash_node[1].flash_on &&
		!led->flash_node[3].flash_on) {
	if (flash_node->trigger & FLASH_LED1_TRIGGER) {
		rc = qpnp_led_masked_write(led->spmi_dev,
				led->current2_addr,
				FLASH_CURRENT_MASK, 0x00);
@@ -997,8 +990,8 @@ static int qpnp_flash_led_module_disable(struct qpnp_flash_led *led,
		}
	}

	for (i = 0; i < led->num_leds; i++)
		led->flash_node[i].flash_on = false;
	if (flash_node->id == FLASH_LED_SWITCH)
		flash_node->trigger = 0;

	return 0;
}
@@ -1018,6 +1011,7 @@ static void qpnp_flash_led_work(struct work_struct *work)
	union power_supply_propval psy_prop;
	int rc, brightness = flash_node->cdev.brightness;
	int max_curr_avail_ma = 0;
	int total_curr_ma = 0;
	int i;
	u8 val;

@@ -1096,11 +1090,7 @@ static void qpnp_flash_led_work(struct work_struct *work)
		}
	}

	if (((led->flash_node[2].flash_on ||
		led->flash_node[3].flash_on) &&
		!led->flash_node[0].flash_on &&
		!led->flash_node[1].flash_on) ||
		flash_node->type == TORCH) {
	if (flash_node->type == TORCH) {
		rc = qpnp_led_masked_write(led->spmi_dev,
			FLASH_LED_UNLOCK_SECURE(led->base),
			FLASH_SECURE_MASK, FLASH_UNLOCK_SECURE);
@@ -1118,15 +1108,11 @@ static void qpnp_flash_led_work(struct work_struct *work)
				"Torch reg write failed\n");
			goto exit_flash_led_work;
		}
		if (led->flash_node[led->num_leds - 1].id ==
							FLASH_LED_SWITCH) {
			flash_node->trigger = 0;
			if (led->flash_node[2].flash_on)
				flash_node->trigger |= FLASH_LED0_TRIGGER;

			val = (u8)(led->flash_node[2].prgm_current *
		if (flash_node->id == FLASH_LED_SWITCH) {
			val = (u8)(flash_node->prgm_current *
						FLASH_TORCH_MAX_LEVEL
					/ led->flash_node[2].max_current);
						/ flash_node->max_current);
			rc = qpnp_led_masked_write(led->spmi_dev,
						led->current_addr,
						FLASH_CURRENT_MASK, val);
@@ -1136,12 +1122,9 @@ static void qpnp_flash_led_work(struct work_struct *work)
				goto exit_flash_led_work;
			}

			if (led->flash_node[3].flash_on)
				flash_node->trigger |= FLASH_LED1_TRIGGER;

			val = (u8)(led->flash_node[3].prgm_current *
			val = (u8)(flash_node->prgm_current2 *
						FLASH_TORCH_MAX_LEVEL
					/ led->flash_node[3].max_current);
						/ flash_node->max_current);
			rc = qpnp_led_masked_write(led->spmi_dev,
					led->current2_addr,
					FLASH_CURRENT_MASK, val);
@@ -1193,46 +1176,49 @@ static void qpnp_flash_led_work(struct work_struct *work)
			goto exit_flash_led_work;
		}

		if (led->pdata->hdrm_sns_ch0_en) {
			if (led->flash_node[2].flash_on) {
		if (led->pdata->hdrm_sns_ch0_en ||
						led->pdata->hdrm_sns_ch1_en) {
			if (flash_node->id == FLASH_LED_SWITCH) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_ENABLE);
					flash_node->trigger &
					FLASH_LED0_TRIGGER ?
					FLASH_LED_HDRM_SNS_ENABLE :
					FLASH_LED_HDRM_SNS_DISABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense enable failed\n");
					goto exit_flash_led_work;
				}
			} else {

				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					flash_node->trigger &
					FLASH_LED1_TRIGGER ?
					FLASH_LED_HDRM_SNS_ENABLE :
					FLASH_LED_HDRM_SNS_DISABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
					"Headroom sense enable failed\n");
					goto exit_flash_led_work;
				}
			}
		}

		if (led->pdata->hdrm_sns_ch1_en) {
			if (led->flash_node[3].flash_on) {
			} else if (flash_node->id == FLASH_LED_0) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_ENABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense enable failed\n");
					"Headroom sense disable failed\n");
					goto exit_flash_led_work;
				}
			} else {
			} else if (flash_node->id == FLASH_LED_1) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_DISABLE);
					FLASH_LED_HDRM_SNS_ENABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
@@ -1243,22 +1229,19 @@ static void qpnp_flash_led_work(struct work_struct *work)

		rc = qpnp_led_masked_write(led->spmi_dev,
			FLASH_LED_STROBE_CTRL(led->base),
			FLASH_STROBE_MASK,
			(flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK
							: flash_node->trigger),
							flash_node->trigger);
		if (rc) {
			dev_err(&led->spmi_dev->dev,
				"Strobe ctrl reg write failed\n");
				"Strobe reg write failed\n");
			goto exit_flash_led_work;
		}
	} else if (((led->flash_node[0].flash_on ||
			led->flash_node[1].flash_on) &&
			!led->flash_node[2].flash_on &&
			!led->flash_node[3].flash_on) ||
			flash_node->type == FLASH) {
		if (led->flash_node[0].flash_on)
			max_curr_avail_ma += led->flash_node[0].max_current;
		if (led->flash_node[1].flash_on)
			max_curr_avail_ma += led->flash_node[1].max_current;
	} else if (flash_node->type == FLASH) {
		if (flash_node->trigger & FLASH_LED0_TRIGGER)
			max_curr_avail_ma += flash_node->max_current;
		if (flash_node->trigger & FLASH_LED1_TRIGGER)
			max_curr_avail_ma += flash_node->max_current;

		psy_prop.intval = true;
		rc = led->battery_psy->set_property(led->battery_psy,
@@ -1301,63 +1284,33 @@ static void qpnp_flash_led_work(struct work_struct *work)
			}
		}

		if (led->flash_node[led->num_leds - 1].id ==
							FLASH_LED_SWITCH) {
			flash_node->trigger = 0;
			if (led->flash_node[0].flash_on &&
					led->flash_node[1].flash_on) {
				if (max_curr_avail_ma <
					flash_node->prgm_current) {
					led->flash_node[0].prgm_current =
						led->flash_node[0].prgm_current
						* max_curr_avail_ma /
						flash_node->prgm_current;
					led->flash_node[1].prgm_current =
						led->flash_node[1].prgm_current
							* max_curr_avail_ma /
						flash_node->prgm_current;
				}
				flash_node->trigger = FLASH_LED0_TRIGGER |
							FLASH_LED1_TRIGGER;
			} else {
				if (led->flash_node[0].flash_on)
					flash_node->trigger |=
							FLASH_LED0_TRIGGER;
		if (flash_node->id == FLASH_LED_SWITCH) {
			if (flash_node->trigger & FLASH_LED0_TRIGGER)
				total_curr_ma += flash_node->prgm_current;
			else if (flash_node->trigger & FLASH_LED1_TRIGGER)
				total_curr_ma += flash_node->prgm_current2;

				led->flash_node[0].prgm_current
					= (max_curr_avail_ma <
					led->flash_node[0].prgm_current)
					? max_curr_avail_ma :
					led->flash_node[0].prgm_current;
			if (max_curr_avail_ma < total_curr_ma) {
				flash_node->prgm_current *=
					max_curr_avail_ma / total_curr_ma;
				flash_node->prgm_current2 *=
					max_curr_avail_ma / total_curr_ma;
			}

				if (led->flash_node[1].flash_on)
					flash_node->trigger |=
							FLASH_LED1_TRIGGER;
				led->flash_node[1].prgm_current
					= (max_curr_avail_ma <
					led->flash_node[1].prgm_current)
					? max_curr_avail_ma :
					led->flash_node[1].prgm_current;
			}

			val = (u8)(led->flash_node[0].prgm_current *
						FLASH_MAX_LEVEL /
					led->flash_node[0].max_current);
			val = (u8)(flash_node->prgm_current *
				FLASH_MAX_LEVEL / flash_node->max_current);
			rc = qpnp_led_masked_write(led->spmi_dev,
						led->current_addr,
						FLASH_CURRENT_MASK, val);
				led->current_addr, FLASH_CURRENT_MASK, val);
			if (rc) {
				dev_err(&led->spmi_dev->dev,
					"Current register write failed\n");
				goto exit_flash_led_work;
			}

			val = (u8)(led->flash_node[1].prgm_current *
						FLASH_MAX_LEVEL /
					led->flash_node[1].max_current);
			val = (u8)(flash_node->prgm_current2 *
				FLASH_MAX_LEVEL / flash_node->max_current);
			rc = qpnp_led_masked_write(led->spmi_dev,
						led->current2_addr,
						FLASH_CURRENT_MASK, val);
				led->current2_addr, FLASH_CURRENT_MASK, val);
			if (rc) {
				dev_err(&led->spmi_dev->dev,
					"Current register write failed\n");
@@ -1433,46 +1386,49 @@ static void qpnp_flash_led_work(struct work_struct *work)
						FLASH_RAMP_UP_DELAY_US_MAX);
		}

		if (led->pdata->hdrm_sns_ch0_en) {
			if (led->flash_node[0].flash_on) {
		if (led->pdata->hdrm_sns_ch0_en ||
					led->pdata->hdrm_sns_ch1_en) {
			if (flash_node->id == FLASH_LED_SWITCH) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_ENABLE);
					(flash_node->trigger &
					FLASH_LED0_TRIGGER ?
					FLASH_LED_HDRM_SNS_ENABLE :
					FLASH_LED_HDRM_SNS_DISABLE));
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense enable failed\n");
					goto exit_flash_led_work;
				}
			} else {

				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_DISABLE);
					(flash_node->trigger &
					FLASH_LED1_TRIGGER ?
					FLASH_LED_HDRM_SNS_ENABLE :
					FLASH_LED_HDRM_SNS_DISABLE));
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
					"Headroom sense enable failed\n");
					goto exit_flash_led_work;
				}
			}
		}

		if (led->pdata->hdrm_sns_ch1_en) {
			if (led->flash_node[1].flash_on) {
			} else if (flash_node->id == FLASH_LED_0) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_ENABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense enable failed\n");
					"Headroom sense disable failed\n");
					goto exit_flash_led_work;
				}
			} else {
			} else if (flash_node->id == FLASH_LED_1) {
				rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_DISABLE);
					FLASH_LED_HDRM_SNS_ENABLE);
				if (rc) {
					dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
@@ -1483,7 +1439,8 @@ static void qpnp_flash_led_work(struct work_struct *work)

		rc = qpnp_led_masked_write(led->spmi_dev,
			FLASH_LED_STROBE_CTRL(led->base),
			FLASH_STROBE_MASK,
			(flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK
							: flash_node->trigger),
							flash_node->trigger);
		if (rc) {
			dev_err(&led->spmi_dev->dev,
@@ -1520,14 +1477,45 @@ static void qpnp_flash_led_work(struct work_struct *work)
turn_off:
	rc = qpnp_led_masked_write(led->spmi_dev,
			FLASH_LED_STROBE_CTRL(led->base),
			flash_node->trigger, FLASH_LED_DISABLE);
			flash_node->id == FLASH_LED_SWITCH ? FLASH_STROBE_MASK
						: flash_node->trigger,
						FLASH_LED_DISABLE);
	if (rc) {
		dev_err(&led->spmi_dev->dev, "Strobe disable failed\n");
		goto exit_flash_led_work;
	}

	usleep_range(FLASH_RAMP_DN_DELAY_US_MIN, FLASH_RAMP_DN_DELAY_US_MAX);
exit_flash_hdrm_sns:
	if (led->pdata->hdrm_sns_ch0_en) {
		if (flash_node->id == FLASH_LED_0 ||
				flash_node->id == FLASH_LED_SWITCH) {
			rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL0(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_DISABLE);
			if (rc) {
				dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
				goto exit_flash_hdrm_sns;
			}
		}
	}

	if (led->pdata->hdrm_sns_ch1_en) {
		if (flash_node->id == FLASH_LED_1 ||
				flash_node->id == FLASH_LED_SWITCH) {
			rc = qpnp_led_masked_write(led->spmi_dev,
					FLASH_HDRM_SNS_ENABLE_CTRL1(led->base),
					FLASH_LED_HDRM_SNS_ENABLE_MASK,
					FLASH_LED_HDRM_SNS_DISABLE);
			if (rc) {
				dev_err(&led->spmi_dev->dev,
					"Headroom sense disable failed\n");
				goto exit_flash_hdrm_sns;
			}
		}
	}
exit_flash_led_work:
	rc = qpnp_flash_led_module_disable(led, flash_node);
	if (rc) {
@@ -1568,19 +1556,42 @@ static void qpnp_flash_led_brightness_set(struct led_classdev *led_cdev,
	flash_node->cdev.brightness = value;
	if (led->flash_node[led->num_leds - 1].id ==
						FLASH_LED_SWITCH) {
		if (flash_node->type == TORCH)
			led->flash_node[led->num_leds - 1].type = TORCH;
		else if (flash_node->type == FLASH)
			led->flash_node[led->num_leds - 1].type = FLASH;

		led->flash_node[led->num_leds - 1].max_current
						= flash_node->max_current;

		if (flash_node->id == FLASH_LED_0 ||
					 flash_node->id == FLASH_LED_1) {
			if (value < FLASH_LED_MIN_CURRENT_MA && value != 0)
				value = FLASH_LED_MIN_CURRENT_MA;

			flash_node->prgm_current = value;
			flash_node->flash_on = value ? true : false;
			if (value)
				led->flash_node[led->num_leds - 1].trigger |=
						(0x80 >> flash_node->id);
			else
				led->flash_node[led->num_leds - 1].trigger &=
						~(0x80 >> flash_node->id);

			if (flash_node->id == FLASH_LED_0)
				led->flash_node[led->num_leds - 1].
				prgm_current = flash_node->prgm_current;
			else if (flash_node->id == FLASH_LED_1)
				led->flash_node[led->num_leds - 1].
				prgm_current2 =
				flash_node->prgm_current;

			return;
		} else if (flash_node->id == FLASH_LED_SWITCH) {
			if (led->flash_node[0].flash_on ||
					led->flash_node[1].flash_on)
				flash_node->prgm_current =
					led->flash_node[0].prgm_current +
					led->flash_node[1].prgm_current;
			if (!value) {
				flash_node->prgm_current = 0;
				flash_node->prgm_current2 = 0;
			}
		}
	} else {
		if (value < FLASH_LED_MIN_CURRENT_MA && value != 0)