linux-pwm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff LaBundy <jeff@labundy.com>
To: Marek Vasut <marex@denx.de>
Cc: linux-input@vger.kernel.org,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
	"Frieder Schrempf" <frieder.schrempf@kontron.de>,
	"Manuel Traut" <manuel.traut@mt.com>,
	"Thierry Reding" <thierry.reding@gmail.com>,
	linux-pwm@vger.kernel.org
Subject: Re: [PATCH] Input: pwm-beeper - Support volume setting via sysfs
Date: Fri, 12 May 2023 20:12:42 -0500	[thread overview]
Message-ID: <ZF7kCjKGVjsxK8ec@nixie71> (raw)
In-Reply-To: <20230512185551.183049-1-marex@denx.de>

Hi Marek,

On Fri, May 12, 2023 at 08:55:51PM +0200, Marek Vasut wrote:
> The PWM beeper volume can be controlled by adjusting the PWM duty cycle,
> expose volume setting via sysfs, so users can make the beeper quieter.
> This patch adds sysfs attribute 'volume' in range 0..50000, i.e. from 0
> to 50% in 1/1000th of percent steps, this resolution should be sufficient.
> 
> The reason for 50000 cap on volume or PWM duty cycle is because duty cycle
> above 50% again reduces the loudness, the PWM wave form is inverted wave
> form of the one for duty cycle below 50% and the beeper gets quieter the
> closer the setting is to 100% . Hence, 50% cap where the wave form yields
> the loudest result.
> 
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> An alternative option would be to extend the userspace input ABI, e.g. by
> using SND_TONE top 16bits to encode the duty cycle in 0..50000 range, and
> bottom 16bit to encode the existing frequency in Hz . Since frequency in
> Hz is likely to be below some 25 kHz for audible bell, this fits in 16bits
> just fine. Thoughts ?
> ---

Thanks for the patch; this seems like a useful feature.

My first thought is that 50000 seems like an oddly specific limit to impose
upon user space. Ideally, user space need not even care that the beeper is
implemented via PWM and why 50000 is significant.

Instead, what about accepting 0..255 as the LED subsystem does for brightness,
then map these values to 0..50000 internally? In fact, the leds-pwm driver
does something similar.

I'm also curious as to whether this function should be a rogue sysfs control
limited to this driver, or a generic operation in input. For example, input
already allows user space to specify the magnitude of an FF effect; perhaps
something similar is warranted here?

> NOTE: This uses approach similar to [1], except it is much simpler.
>       [1] https://patchwork.kernel.org/project/linux-input/cover/20230201152128.614439-1-manuel.traut@mt.com/
> ---
> Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Frieder Schrempf <frieder.schrempf@kontron.de>
> Cc: Manuel Traut <manuel.traut@mt.com>
> Cc: Marek Vasut <marex@denx.de>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: linux-input@vger.kernel.org
> Cc: linux-pwm@vger.kernel.org
> ---
>  drivers/input/misc/pwm-beeper.c | 58 ++++++++++++++++++++++++++++++++-
>  1 file changed, 57 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
> index 3cf1812384e6a..f63d0ebbaf573 100644
> --- a/drivers/input/misc/pwm-beeper.c
> +++ b/drivers/input/misc/pwm-beeper.c
> @@ -21,6 +21,7 @@ struct pwm_beeper {
>  	struct regulator *amplifier;
>  	struct work_struct work;
>  	unsigned long period;
> +	unsigned long duty_cycle;
>  	unsigned int bell_frequency;
>  	bool suspended;
>  	bool amplifier_on;
> @@ -37,7 +38,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, 50, 100);
> +	pwm_set_relative_duty_cycle(&state, beeper->duty_cycle, 100000);
>  
>  	error = pwm_apply_state(beeper->pwm, &state);
>  	if (error)
> @@ -119,6 +120,53 @@ static void pwm_beeper_close(struct input_dev *input)
>  	pwm_beeper_stop(beeper);
>  }
>  
> +static ssize_t volume_show(struct device *dev,
> +			   struct device_attribute *attr,
> +			   char *buf)
> +{
> +	struct pwm_beeper *beeper = dev_get_drvdata(dev);
> +
> +	return sysfs_emit(buf, "%ld\n", beeper->duty_cycle);
> +}
> +
> +static ssize_t volume_store(struct device *dev,
> +			    struct device_attribute *attr,
> +			    const char *buf, size_t count)
> +{
> +	struct pwm_beeper *beeper = dev_get_drvdata(dev);
> +	unsigned long val;
> +
> +	if (kstrtoul(buf, 0, &val) < 0)
> +		return -EINVAL;
> +
> +	/*
> +	 * Volume is really PWM duty cycle in pcm (per cent mille, 1/1000th
> +	 * of percent). This value therefore ranges from 0 to 50000 . Duty
> +	 * cycle of 50% = 50000pcm is the maximum volume .
> +	 */
> +	val = clamp(val, 0UL, 50000UL);
> +	/* No change in current settings, do nothing. */
> +	if (val == beeper->duty_cycle)
> +		return count;
> +
> +	/* Update current settings and apply to PWM chip. */
> +	beeper->duty_cycle = val;
> +	if (!beeper->suspended)
> +		schedule_work(&beeper->work);
> +
> +	return count;
> +}
> +static DEVICE_ATTR_RW(volume);
> +
> +static struct attribute *pwm_beeper_dev_attrs[] = {
> +	&dev_attr_volume.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group pwm_beeper_attr_group = {
> +	.attrs = pwm_beeper_dev_attrs,
> +};
> +
>  static int pwm_beeper_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -192,6 +240,14 @@ static int pwm_beeper_probe(struct platform_device *pdev)
>  
>  	input_set_drvdata(beeper->input, beeper);
>  
> +	beeper->duty_cycle = 50000;
> +	error = devm_device_add_group(dev, &pwm_beeper_attr_group);
> +	if (error) {
> +		dev_err(dev, "Unable to create sysfs attributes: %d\n",
> +			error);
> +		return error;
> +	}
> +
>  	error = input_register_device(beeper->input);
>  	if (error) {
>  		dev_err(dev, "Failed to register input device: %d\n", error);
> -- 
> 2.39.2
> 

Kind regards,
Jeff LaBundy

  reply	other threads:[~2023-05-13  1:12 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-12 18:55 [PATCH] Input: pwm-beeper - Support volume setting via sysfs Marek Vasut
2023-05-13  1:12 ` Jeff LaBundy [this message]
2023-05-13  1:51   ` Marek Vasut
2023-05-13 21:02     ` Marek Vasut
2023-07-31  5:36       ` Dmitry Torokhov
2023-07-31  6:21         ` Takashi Iwai
2023-07-31 11:49           ` Marek Vasut
2023-07-31 12:15             ` Takashi Iwai
2023-07-31 14:05               ` Marek Vasut
2023-07-31 14:20                 ` Takashi Iwai
2023-07-31 14:36                   ` Marek Vasut
2023-07-31 16:24                     ` Dmitry Torokhov
2023-07-31 17:49                       ` Marek Vasut
2023-08-01  2:56                         ` Jeff LaBundy
2023-08-01  6:11                           ` Takashi Iwai
2023-08-01 11:38                             ` Marek Vasut
2023-08-01 12:25                               ` Takashi Iwai
2023-08-01  7:28                           ` Dmitry Torokhov
2023-08-01 11:51                             ` Marek Vasut
2023-08-11  4:19                               ` Jeff LaBundy
2023-08-11  7:52                                 ` Takashi Iwai
2023-08-11 10:47                                   ` Traut Manuel LCPF-CH
2023-08-15 21:33                                     ` Dmitry Torokhov
2023-08-17 10:50                                       ` Marek Vasut
2023-08-11 12:39                             ` John Watts
2023-08-14  2:26                               ` Marek Vasut
2023-05-15  6:50 ` AW: EXTERNAL - " Traut Manuel LCPF-CH
2023-05-15 13:36   ` Marek Vasut
2023-05-15 14:25     ` Jeff LaBundy
2023-05-15 17:27       ` Marek Vasut
2023-05-15 15:24     ` AW: AW: " Traut Manuel LCPF-CH
2023-05-15 17:28       ` Marek Vasut
2023-06-14  6:45 ` Uwe Kleine-König
2023-06-14  9:30   ` Marek Vasut

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZF7kCjKGVjsxK8ec@nixie71 \
    --to=jeff@labundy.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=frieder.schrempf@kontron.de \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=manuel.traut@mt.com \
    --cc=marex@denx.de \
    --cc=thierry.reding@gmail.com \
    --cc=u.kleine-koenig@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).