From: Frieder Schrempf <frieder.schrempf@xxxxxxxxxx> Add devicetree bindings to define supported volume levels and the default volume level. Signed-off-by: Frieder Schrempf <frieder.schrempf@xxxxxxxxxx> Signed-off-by: Manuel Traut <manuel.traut@xxxxxx> Tested-by: Manuel Traut <manuel.traut@xxxxxx> --- drivers/input/misc/pwm-beeper.c | 73 +++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 214d3fa0a06d..fc367a249490 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -93,7 +93,7 @@ static int pwm_beeper_on(struct pwm_beeper *beeper, unsigned long period) state.enabled = true; state.period = period; - pwm_set_relative_duty_cycle(&state, beeper->volume_levels[beeper->volume], 1000); + pwm_set_relative_duty_cycle(&state, beeper->volume_levels[beeper->volume], 10000); error = pwm_apply_state(beeper->pwm, &state); if (error) @@ -181,8 +181,9 @@ static int pwm_beeper_probe(struct platform_device *pdev) struct pwm_beeper *beeper; struct pwm_state state; u32 bell_frequency; - int error; + int error, i, length; size_t size; + u32 value; beeper = devm_kzalloc(dev, sizeof(*beeper), GFP_KERNEL); if (!beeper) @@ -228,23 +229,59 @@ static int pwm_beeper_probe(struct platform_device *pdev) beeper->bell_frequency = bell_frequency; - beeper->max_volume = 4; - - size = sizeof(*beeper->volume_levels) * - (beeper->max_volume + 1); - - beeper->volume_levels = devm_kzalloc(&(pdev->dev), size, - GFP_KERNEL); - if (!beeper->volume_levels) - return -ENOMEM; - - beeper->volume_levels[0] = 0; - beeper->volume_levels[1] = 80; - beeper->volume_levels[2] = 200; - beeper->volume_levels[3] = 400; - beeper->volume_levels[4] = 5000; + /* determine the number of volume levels */ + length = device_property_read_u32_array(&pdev->dev, "volume-levels-bp", NULL, 0); + if (length <= 0) { + dev_dbg(&pdev->dev, "no volume levels specified, using max volume\n"); + beeper->max_volume = 1; + } else + beeper->max_volume = length; + + /* read volume levels from DT property */ + if (beeper->max_volume > 0) { + size = sizeof(*beeper->volume_levels) * beeper->max_volume; + + beeper->volume_levels = devm_kzalloc(&(pdev->dev), size, + GFP_KERNEL); + if (!beeper->volume_levels) + return -ENOMEM; + + if (length > 0) { + error = device_property_read_u32_array(&pdev->dev, "volume-levels-bp", + beeper->volume_levels, + beeper->max_volume); + + if (error < 0) + return error; + + error = device_property_read_u32(&pdev->dev, "default-volume-level-bp", + &value); + + if (error < 0) { + dev_dbg(&pdev->dev, "no default volume specified, using max volume\n"); + value = beeper->max_volume - 1; + } else { + for (i = 0; i < length; i++) { + if (beeper->volume_levels[i] == value) { + value = i; + break; + } + } + if (value != i) { + dev_dbg(&pdev->dev, + "default-volume-level-bp %d invalid, using %d\n", + value, beeper->max_volume - 1); + value = beeper->max_volume - 1; + } + } + } else { + beeper->volume_levels[0] = 5000; + value = 0; + } - beeper->volume = beeper->max_volume; + beeper->volume = value; + beeper->max_volume--; + } beeper->input = devm_input_allocate_device(dev); if (!beeper->input) { -- 2.39.0