mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
Merge "pwm: pwm-qti-lpg: Add property for LPG channel synchronization"
This commit is contained in:
commit
e137b4a2f9
@ -40,6 +40,17 @@ device module in Qualcomm Technologies, Inc. PMIC chips.
|
||||
channels. This property is required if any LPG channels
|
||||
support LUT mode.
|
||||
|
||||
- qcom,sync-channel-ids:
|
||||
Usage: optional
|
||||
Value type: <prop-encoded-array>
|
||||
Definition: The hardware IDs of the LPG channel that required be
|
||||
grouped together. These channels will share the same LUT
|
||||
ramping configuration so that they will be enabled with a
|
||||
synchronized pattern. If the LUT ramping configuration
|
||||
differs for the channels grouped for synchronization,
|
||||
configuration of the first channel will be applied for
|
||||
all others.
|
||||
|
||||
Subnode is optional if LUT mode is not required, it's required if any LPG
|
||||
channels expected to be supported in LUT mode.
|
||||
|
||||
@ -114,6 +125,7 @@ Example:
|
||||
#pwm-cells = <2>;
|
||||
qcom,lut-patterns = <0 14 28 42 56 70 84 100
|
||||
100 84 70 56 42 28 14 0>;
|
||||
qcom,sync-channel-ids = <3 4 5>;
|
||||
lpg@3 {
|
||||
qcom,lpg-chan-id = <3>;
|
||||
qcom,ramp-step-ms = <200>;
|
||||
|
@ -165,6 +165,7 @@ struct qpnp_lpg_chip {
|
||||
struct qpnp_lpg_channel *lpgs;
|
||||
struct qpnp_lpg_lut *lut;
|
||||
struct mutex bus_lock;
|
||||
u32 *lpg_group;
|
||||
u32 num_lpgs;
|
||||
};
|
||||
|
||||
@ -659,8 +660,9 @@ static int qpnp_lpg_pwm_src_enable(struct qpnp_lpg_channel *lpg, bool en)
|
||||
{
|
||||
struct qpnp_lpg_chip *chip = lpg->chip;
|
||||
struct qpnp_lpg_lut *lut = chip->lut;
|
||||
struct pwm_device *pwm;
|
||||
u8 mask, val;
|
||||
int rc;
|
||||
int i, lpg_idx, rc;
|
||||
|
||||
mask = LPG_PWM_SRC_SELECT_MASK | LPG_EN_LPG_OUT_BIT |
|
||||
LPG_EN_RAMP_GEN_MASK;
|
||||
@ -680,8 +682,31 @@ static int qpnp_lpg_pwm_src_enable(struct qpnp_lpg_channel *lpg, bool en)
|
||||
}
|
||||
|
||||
if (lpg->src_sel == LUT_PATTERN && en) {
|
||||
mutex_lock(&lut->lock);
|
||||
val = 1 << lpg->lpg_idx;
|
||||
for (i = 0; i < chip->num_lpgs; i++) {
|
||||
if (chip->lpg_group == NULL)
|
||||
break;
|
||||
if (chip->lpg_group[i] == 0)
|
||||
break;
|
||||
lpg_idx = chip->lpg_group[i] - 1;
|
||||
pwm = &chip->pwm_chip.pwms[lpg_idx];
|
||||
if ((pwm_get_output_type(pwm) == PWM_OUTPUT_MODULATED)
|
||||
&& pwm_is_enabled(pwm)) {
|
||||
rc = qpnp_lpg_masked_write(&chip->lpgs[lpg_idx],
|
||||
REG_LPG_ENABLE_CONTROL,
|
||||
LPG_EN_LPG_OUT_BIT, 0);
|
||||
if (rc < 0)
|
||||
break;
|
||||
rc = qpnp_lpg_masked_write(&chip->lpgs[lpg_idx],
|
||||
REG_LPG_ENABLE_CONTROL,
|
||||
LPG_EN_LPG_OUT_BIT,
|
||||
LPG_EN_LPG_OUT_BIT);
|
||||
if (rc < 0)
|
||||
break;
|
||||
val |= 1 << lpg_idx;
|
||||
}
|
||||
}
|
||||
mutex_lock(&lut->lock);
|
||||
rc = qpnp_lut_write(lut, REG_LPG_LUT_RAMP_CONTROL, val);
|
||||
if (rc < 0)
|
||||
dev_err(chip->dev, "Write LPG_LUT_RAMP_CONTROL failed, rc=%d\n",
|
||||
@ -1146,6 +1171,53 @@ static int qpnp_lpg_parse_dt(struct qpnp_lpg_chip *chip)
|
||||
"qcom,ramp-toggle");
|
||||
}
|
||||
|
||||
rc = of_property_count_elems_of_size(chip->dev->of_node,
|
||||
"qcom,sync-channel-ids", sizeof(u32));
|
||||
if (rc < 0)
|
||||
return 0;
|
||||
|
||||
length = rc;
|
||||
if (length > chip->num_lpgs) {
|
||||
dev_err(chip->dev, "qcom,sync-channel-ids has too many channels: %d\n",
|
||||
length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip->lpg_group = devm_kcalloc(chip->dev, chip->num_lpgs,
|
||||
sizeof(u32), GFP_KERNEL);
|
||||
if (!chip->lpg_group)
|
||||
return -ENOMEM;
|
||||
|
||||
rc = of_property_read_u32_array(chip->dev->of_node,
|
||||
"qcom,sync-channel-ids", chip->lpg_group, length);
|
||||
if (rc < 0) {
|
||||
dev_err(chip->dev, "Get qcom,sync-channel-ids failed, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (chip->lpg_group[i] <= 0 ||
|
||||
chip->lpg_group[i] > chip->num_lpgs) {
|
||||
dev_err(chip->dev, "lpg_group[%d]: %d is not a valid channel\n",
|
||||
i, chip->lpg_group[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The LPG channel in the same group should have the same ramping
|
||||
* configuration, so force to use the ramping configuration of the
|
||||
* 1st LPG channel in the group for sychronization.
|
||||
*/
|
||||
lpg = &chip->lpgs[chip->lpg_group[0] - 1];
|
||||
ramp = &lpg->ramp_config;
|
||||
|
||||
for (i = 1; i < length; i++) {
|
||||
lpg = &chip->lpgs[chip->lpg_group[i] - 1];
|
||||
memcpy(&lpg->ramp_config, ramp, sizeof(struct lpg_ramp_config));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user