Re: [PATCH v2] auxdisplay: ht16k33: Keyscan function is now optional

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Thu, Oct 06, 2016 at 02:41:58PM +0200, Robin van der Gracht wrote:
> Signed-off-by: Robin van der Gracht <robin@xxxxxxxxxxx>
> ---
> Changes in v2:
> 	- Removed the trailing dot in the patch subject
> 
>  .../devicetree/bindings/display/ht16k33.txt        |  15 ++-
>  drivers/auxdisplay/ht16k33.c                       | 126 +++++++++++----------
>  2 files changed, 73 insertions(+), 68 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/ht16k33.txt b/Documentation/devicetree/bindings/display/ht16k33.txt
> index 8e5b30b..e2c9048 100644
> --- a/Documentation/devicetree/bindings/display/ht16k33.txt
> +++ b/Documentation/devicetree/bindings/display/ht16k33.txt
> @@ -4,18 +4,21 @@ Holtek ht16k33 RAM mapping 16*8 LED controller driver with keyscan
>  Required properties:
>  - compatible:		"holtek,ht16k33"
>  - reg:			I2C slave address of the chip.
> -- interrupt-parent:	A phandle pointing to the interrupt controller
> -			serving the interrupt for this chip.
> -- interrupts:		Interrupt specification for the key pressed interrupt.
>  - refresh-rate-hz:	Display update interval in HZ.
> -- debounce-delay-ms:	Debouncing interval time in milliseconds.
> -- linux,keymap: 	The keymap for keys as described in the binding
> -			document (devicetree/bindings/input/matrix-keymap.txt).
>  
>  Optional properties:
>  - linux,no-autorepeat:	Disable keyrepeat.

This too is part of keypad.

>  - default-brightness-level: Initial brightness level [0-15] (default: 15).
>  
> +- Keypad
> + Supply the 'interrupts' property to enable the keyscan feature.
> + - interrupts:		Interrupt specification for the key pressed interrupt.
> + - interrupt-parent:	A phandle pointing to the interrupt controller
> +			serving the interrupt for this chip.
> + - debounce-delay-ms:	Debouncing interval time in milliseconds.
> + - linux,keymap: 	The keymap for keys as described in the binding
> +			document (devicetree/bindings/input/matrix-keymap.txt).
> +
>  Example:
>  
>  &i2c1 {
> diff --git a/drivers/auxdisplay/ht16k33.c b/drivers/auxdisplay/ht16k33.c
> index 9c09bbc..5cf8fb4 100644
> --- a/drivers/auxdisplay/ht16k33.c
> +++ b/drivers/auxdisplay/ht16k33.c
> @@ -334,15 +334,71 @@ static struct fb_ops ht16k33_fb_ops = {
>  	.fb_mmap = ht16k33_mmap,
>  };
>  
> +static int ht16k33_register_keypad(struct ht16k33_priv *priv)
> +{
> +	int rows, cols, err;
> +	struct ht16k33_keypad *keypad = &priv->keypad;
> +	struct device *dev = &priv->client->dev;
> +
> +	keypad->dev = devm_input_allocate_device(dev);
> +	if (!keypad->dev)
> +		return -ENOMEM;
> +
> +	keypad->dev->name = dev_name(dev);
> +	keypad->dev->id.bustype = BUS_I2C;
> +	keypad->dev->open = ht16k33_keypad_start;
> +	keypad->dev->close = ht16k33_keypad_stop;
> +
> +	if (!of_get_property(dev->of_node, "linux,no-autorepeat", NULL))
> +		__set_bit(EV_REP, keypad->dev->evbit);
> +
> +	err = of_property_read_u32(dev->of_node, "debounce-delay-ms",
> +				   &keypad->debounce_ms);
> +	if (err) {
> +		dev_err(dev, "key debounce delay not specified\n");
> +		return err;
> +	}
> +
> +	err = devm_request_threaded_irq(dev, priv->client->irq, NULL,
> +					ht16k33_irq_thread,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					DRIVER_NAME, priv);
> +	if (err) {
> +		dev_err(dev, "Failed to request irq %i\n", priv->client->irq);
> +		return err;
> +	}
> +
> +	disable_irq_nosync(priv->client->irq);
> +	rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
> +	cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
> +	err = matrix_keypad_parse_of_params(dev, &rows, &cols);
> +	if (err)
> +		return err;
> +
> +	err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
> +					 keypad->dev);
> +	if (err) {
> +		dev_err(dev, "failed to build keymap\n");
> +		return err;
> +	}
> +
> +	input_set_drvdata(keypad->dev, priv);
> +	keypad->rows = rows;
> +	keypad->cols = cols;
> +	keypad->row_shift = get_count_order(cols);
> +	INIT_DELAYED_WORK(&keypad->work, ht16k33_keypad_scan);
> +
> +	return input_register_device(keypad->dev);
> +}
> +
>  static int ht16k33_probe(struct i2c_client *client,
>  				  const struct i2c_device_id *id)
>  {
>  	int err;
> -	uint32_t rows, cols, dft_brightness;
> +	uint32_t dft_brightness;
>  	struct backlight_device *bl;
>  	struct backlight_properties bl_props;
>  	struct ht16k33_priv *priv;
> -	struct ht16k33_keypad *keypad;
>  	struct ht16k33_fbdev *fbdev;
>  	struct device_node *node = client->dev.of_node;
>  	const char *dev_id = dev_name(&client->dev);
> @@ -352,11 +408,6 @@ static int ht16k33_probe(struct i2c_client *client,
>  		return -EIO;
>  	}
>  
> -	if (client->irq <= 0) {
> -		dev_err(&client->dev, "No IRQ specified\n");
> -		return -EINVAL;
> -	}
> -
>  	priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
>  	if (!priv)
>  		return -ENOMEM;
> @@ -364,7 +415,6 @@ static int ht16k33_probe(struct i2c_client *client,
>  	priv->client = client;
>  	i2c_set_clientdata(client, priv);
>  	fbdev = &priv->fbdev;
> -	keypad = &priv->keypad;
>  
>  	priv->workqueue = create_singlethread_workqueue(dev_id);
>  	if (priv->workqueue == NULL)
> @@ -417,61 +467,12 @@ static int ht16k33_probe(struct i2c_client *client,
>  		goto err_fbdev_info;
>  
>  	/* Keypad */
> -	keypad->dev = devm_input_allocate_device(&client->dev);
> -	if (!keypad->dev) {
> -		err = -ENOMEM;
> -		goto err_fbdev_unregister;
> -	}
> -
> -	keypad->dev->name = dev_id;
> -	keypad->dev->id.bustype = BUS_I2C;
> -	keypad->dev->open = ht16k33_keypad_start;
> -	keypad->dev->close = ht16k33_keypad_stop;
> -
> -	if (!of_get_property(node, "linux,no-autorepeat", NULL))
> -		__set_bit(EV_REP, keypad->dev->evbit);
> -
> -	err = of_property_read_u32(node, "debounce-delay-ms",
> -				   &keypad->debounce_ms);
> -	if (err) {
> -		dev_err(&client->dev, "key debounce delay not specified\n");
> -		goto err_fbdev_unregister;
> +	if (client->irq > 0) {
> +		err = ht16k33_register_keypad(priv);
> +		if (err)
> +			goto err_fbdev_unregister;
>  	}
>  
> -	err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
> -					ht16k33_irq_thread,
> -					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> -					DRIVER_NAME, priv);
> -	if (err) {
> -		dev_err(&client->dev, "irq request failed %d, error %d\n",
> -			client->irq, err);
> -		goto err_fbdev_unregister;
> -	}
> -
> -	disable_irq_nosync(client->irq);
> -	rows = HT16K33_MATRIX_KEYPAD_MAX_ROWS;
> -	cols = HT16K33_MATRIX_KEYPAD_MAX_COLS;
> -	err = matrix_keypad_parse_of_params(&client->dev, &rows, &cols);
> -	if (err)
> -		goto err_fbdev_unregister;
> -
> -	err = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL,
> -					 keypad->dev);
> -	if (err) {
> -		dev_err(&client->dev, "failed to build keymap\n");
> -		goto err_fbdev_unregister;
> -	}
> -
> -	input_set_drvdata(keypad->dev, priv);
> -	keypad->rows = rows;
> -	keypad->cols = cols;
> -	keypad->row_shift = get_count_order(cols);
> -	INIT_DELAYED_WORK(&keypad->work, ht16k33_keypad_scan);
> -
> -	err = input_register_device(keypad->dev);
> -	if (err)
> -		goto err_fbdev_unregister;
> -
>  	/* Backlight */
>  	memset(&bl_props, 0, sizeof(struct backlight_properties));
>  	bl_props.type = BACKLIGHT_RAW;
> @@ -504,7 +505,8 @@ static int ht16k33_probe(struct i2c_client *client,
>  	return 0;
>  
>  err_keypad_unregister:
> -	input_unregister_device(keypad->dev);
> +	if (priv->keypad.dev)
> +		input_unregister_device(priv->keypad.dev);
>  err_fbdev_unregister:
>  	unregister_framebuffer(fbdev->info);
>  err_fbdev_info:
> -- 
> 2.7.4
> 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux