Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 7/8] Input: qt2160 - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:19 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-7-frank.li@vivo.com>

Hi Yangtao,

On Fri, Jul 14, 2023 at 04:06:10PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.
> 
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  drivers/input/keyboard/qt2160.c | 30 +++++++++++-------------------
>  1 file changed, 11 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/input/keyboard/qt2160.c b/drivers/input/keyboard/qt2160.c
> index 599ea85cfd30..218ef92b8c2b 100644
> --- a/drivers/input/keyboard/qt2160.c
> +++ b/drivers/input/keyboard/qt2160.c
> @@ -340,6 +340,7 @@ static bool qt2160_identify(struct i2c_client *client)
>  
>  static int qt2160_probe(struct i2c_client *client)
>  {
> +	struct device *dev = &client->dev;

You create a temporary, but half of the code does not use it. Please if
you introduce a temporary make sure everything is using it.

>  	struct qt2160_data *qt2160;
>  	struct input_dev *input;
>  	int i;
> @@ -358,12 +359,11 @@ static int qt2160_probe(struct i2c_client *client)
>  		return -ENODEV;
>  
>  	/* Chip is valid and active. Allocate structure */
> -	qt2160 = kzalloc(sizeof(struct qt2160_data), GFP_KERNEL);
> -	input = input_allocate_device();
> +	qt2160 = devm_kzalloc(dev, sizeof(struct qt2160_data), GFP_KERNEL);
> +	input = devm_input_allocate_device(dev);
>  	if (!qt2160 || !input) {

This double check was a cheat when resources did not free automatically,
it makes no sense to carry with devm.

>  		dev_err(&client->dev, "insufficient memory\n");
> -		error = -ENOMEM;
> -		goto err_free_mem;
> +		return -ENOMEM;
>  	}
>  
>  	qt2160->client = client;
> @@ -389,23 +389,23 @@ static int qt2160_probe(struct i2c_client *client)
>  	error = qt2160_write(client, QT2160_CMD_CALIBRATE, 1);
>  	if (error) {
>  		dev_err(&client->dev, "failed to calibrate device\n");
> -		goto err_free_mem;
> +		return error;
>  	}
>  
>  	if (client->irq) {
> -		error = request_irq(client->irq, qt2160_irq,
> -				    IRQF_TRIGGER_FALLING, "qt2160", qt2160);
> +		error = devm_request_irq(dev, client->irq, qt2160_irq,
> +					 IRQF_TRIGGER_FALLING, "qt2160", qt2160);
>  		if (error) {
>  			dev_err(&client->dev,
>  				"failed to allocate irq %d\n", client->irq);
> -			goto err_free_mem;
> +			return error;
>  		}
>  	}
>  
>  	error = qt2160_register_leds(qt2160);
>  	if (error) {
>  		dev_err(&client->dev, "Failed to register leds\n");
> -		goto err_free_irq;
> +		return error;
>  	}
>  
>  	error = input_register_device(qt2160->input);
> @@ -422,29 +422,21 @@ static int qt2160_probe(struct i2c_client *client)
>  
>  err_unregister_leds:
>  	qt2160_unregister_leds(qt2160);

LEDs can also be registered with devm.

> -err_free_irq:
> -	if (client->irq)
> -		free_irq(client->irq, qt2160);
> -err_free_mem:
> -	input_free_device(input);
> -	kfree(qt2160);
>  	return error;
>  }
>  
>  static void qt2160_remove(struct i2c_client *client)
>  {
>  	struct qt2160_data *qt2160 = i2c_get_clientdata(client);
> +	struct device *dev = &client->dev;
>  
>  	qt2160_unregister_leds(qt2160);
>  
>  	/* Release IRQ so no queue will be scheduled */
>  	if (client->irq)
> -		free_irq(client->irq, qt2160);
> +		devm_free_irq(dev, client->irq, qt2160);
>  
>  	cancel_delayed_work_sync(&qt2160->dwork);

It is not great that we are left with non-empty qt2160_remove(). The
driver should be converted away from using work item, and then entirety
of qt2160_remove() can be deleted.

I posted a series that cleans up the driver and incorporates an updated
version of your patch.

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH 1/2] Input: lm8323 - rely on device core to create kp_disable attribute
From: Dmitry Torokhov @ 2023-07-24  5:28 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel

Device core now has facilities to create driver-specific device attributes
as part of driver probing, use them.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/lm8323.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index 3964f6e0f6af..d5195415533a 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -615,6 +615,12 @@ static ssize_t lm8323_set_disable(struct device *dev,
 }
 static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable);
 
+static struct attribute *lm8323_attrs[] = {
+	&dev_attr_disable_kp.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(lm8323);
+
 static int lm8323_probe(struct i2c_client *client)
 {
 	struct lm8323_platform_data *pdata = dev_get_platdata(&client->dev);
@@ -696,9 +702,6 @@ static int lm8323_probe(struct i2c_client *client)
 	}
 
 	lm->kp_enabled = true;
-	err = device_create_file(&client->dev, &dev_attr_disable_kp);
-	if (err < 0)
-		goto fail2;
 
 	idev->name = pdata->name ? : "LM8323 keypad";
 	snprintf(lm->phys, sizeof(lm->phys),
@@ -719,14 +722,14 @@ static int lm8323_probe(struct i2c_client *client)
 	err = input_register_device(idev);
 	if (err) {
 		dev_dbg(&client->dev, "error registering input device\n");
-		goto fail3;
+		goto fail2;
 	}
 
 	err = request_threaded_irq(client->irq, NULL, lm8323_irq,
 			  IRQF_TRIGGER_LOW|IRQF_ONESHOT, "lm8323", lm);
 	if (err) {
 		dev_err(&client->dev, "could not get IRQ %d\n", client->irq);
-		goto fail4;
+		goto fail3;
 	}
 
 	i2c_set_clientdata(client, lm);
@@ -736,11 +739,9 @@ static int lm8323_probe(struct i2c_client *client)
 
 	return 0;
 
-fail4:
+fail3:
 	input_unregister_device(idev);
 	idev = NULL;
-fail3:
-	device_remove_file(&client->dev, &dev_attr_disable_kp);
 fail2:
 	while (--pwm >= 0)
 		if (lm->pwm[pwm].enabled)
@@ -761,8 +762,6 @@ static void lm8323_remove(struct i2c_client *client)
 
 	input_unregister_device(lm->idev);
 
-	device_remove_file(&lm->client->dev, &dev_attr_disable_kp);
-
 	for (i = 0; i < 3; i++)
 		if (lm->pwm[i].enabled)
 			led_classdev_unregister(&lm->pwm[i].cdev);
@@ -823,8 +822,9 @@ static const struct i2c_device_id lm8323_id[] = {
 
 static struct i2c_driver lm8323_i2c_driver = {
 	.driver = {
-		.name	= "lm8323",
-		.pm	= pm_sleep_ptr(&lm8323_pm_ops),
+		.name		= "lm8323",
+		.pm		= pm_sleep_ptr(&lm8323_pm_ops),
+		.dev_groups	= lm8323_groups,
 	},
 	.probe		= lm8323_probe,
 	.remove		= lm8323_remove,
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 2/2] Input: lm8323 - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:29 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel
In-Reply-To: <20230724052901.350240-1-dmitry.torokhov@gmail.com>

From: Yangtao Li <frank.li@vivo.com>

Use devm_* api to simplify code, this makes it unnecessary to explicitly
release resources.

Signed-off-by: Yangtao Li <frank.li@vivo.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/lm8323.c | 77 +++++++++++----------------------
 1 file changed, 26 insertions(+), 51 deletions(-)

diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index d5195415533a..7bee93e9b0f5 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -556,6 +556,7 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
 		    const char *name)
 {
 	struct lm8323_pwm *pwm;
+	int err;
 
 	BUG_ON(id > 3);
 
@@ -575,9 +576,11 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
 		pwm->cdev.name = name;
 		pwm->cdev.brightness_set = lm8323_pwm_set_brightness;
 		pwm->cdev.groups = lm8323_pwm_groups;
-		if (led_classdev_register(dev, &pwm->cdev) < 0) {
-			dev_err(dev, "couldn't register PWM %d\n", id);
-			return -1;
+
+		err = devm_led_classdev_register(dev, &pwm->cdev);
+		if (err) {
+			dev_err(dev, "couldn't register PWM %d: %d\n", id, err);
+			return err;
 		}
 		pwm->enabled = true;
 	}
@@ -585,8 +588,6 @@ static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev,
 	return 0;
 }
 
-static struct i2c_driver lm8323_i2c_driver;
-
 static ssize_t lm8323_show_disable(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
@@ -648,12 +649,13 @@ static int lm8323_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	lm = kzalloc(sizeof *lm, GFP_KERNEL);
-	idev = input_allocate_device();
-	if (!lm || !idev) {
-		err = -ENOMEM;
-		goto fail1;
-	}
+	lm = devm_kzalloc(&client->dev, sizeof(*lm), GFP_KERNEL);
+	if (!lm)
+		return -ENOMEM;
+
+	idev = devm_input_allocate_device(&client->dev);
+	if (!idev)
+		return -ENOMEM;
 
 	lm->client = client;
 	lm->idev = idev;
@@ -669,8 +671,10 @@ static int lm8323_probe(struct i2c_client *client)
 
 	lm8323_reset(lm);
 
-	/* Nothing's set up to service the IRQ yet, so just spin for max.
-	 * 100ms until we can configure. */
+	/*
+	 * Nothing's set up to service the IRQ yet, so just spin for max.
+	 * 100ms until we can configure.
+	 */
 	tmo = jiffies + msecs_to_jiffies(100);
 	while (lm8323_read(lm, LM8323_CMD_READ_INT, data, 1) == 1) {
 		if (data[0] & INT_NOINIT)
@@ -690,15 +694,14 @@ static int lm8323_probe(struct i2c_client *client)
 	/* If a true probe check the device */
 	if (lm8323_read_id(lm, data) != 0) {
 		dev_err(&client->dev, "device not found\n");
-		err = -ENODEV;
-		goto fail1;
+		return -ENODEV;
 	}
 
 	for (pwm = 0; pwm < LM8323_NUM_PWMS; pwm++) {
 		err = init_pwm(lm, pwm + 1, &client->dev,
 			       pdata->pwm_names[pwm]);
-		if (err < 0)
-			goto fail2;
+		if (err)
+			return err;
 	}
 
 	lm->kp_enabled = true;
@@ -722,14 +725,16 @@ static int lm8323_probe(struct i2c_client *client)
 	err = input_register_device(idev);
 	if (err) {
 		dev_dbg(&client->dev, "error registering input device\n");
-		goto fail2;
+		return err;
 	}
 
-	err = request_threaded_irq(client->irq, NULL, lm8323_irq,
-			  IRQF_TRIGGER_LOW|IRQF_ONESHOT, "lm8323", lm);
+	err = devm_request_threaded_irq(&client->dev, client->irq,
+					NULL, lm8323_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					"lm8323", lm);
 	if (err) {
 		dev_err(&client->dev, "could not get IRQ %d\n", client->irq);
-		goto fail3;
+		return err;
 	}
 
 	i2c_set_clientdata(client, lm);
@@ -738,35 +743,6 @@ static int lm8323_probe(struct i2c_client *client)
 	enable_irq_wake(client->irq);
 
 	return 0;
-
-fail3:
-	input_unregister_device(idev);
-	idev = NULL;
-fail2:
-	while (--pwm >= 0)
-		if (lm->pwm[pwm].enabled)
-			led_classdev_unregister(&lm->pwm[pwm].cdev);
-fail1:
-	input_free_device(idev);
-	kfree(lm);
-	return err;
-}
-
-static void lm8323_remove(struct i2c_client *client)
-{
-	struct lm8323_chip *lm = i2c_get_clientdata(client);
-	int i;
-
-	disable_irq_wake(client->irq);
-	free_irq(client->irq, lm);
-
-	input_unregister_device(lm->idev);
-
-	for (i = 0; i < 3; i++)
-		if (lm->pwm[i].enabled)
-			led_classdev_unregister(&lm->pwm[i].cdev);
-
-	kfree(lm);
 }
 
 /*
@@ -827,7 +803,6 @@ static struct i2c_driver lm8323_i2c_driver = {
 		.dev_groups	= lm8323_groups,
 	},
 	.probe		= lm8323_probe,
-	.remove		= lm8323_remove,
 	.id_table	= lm8323_id,
 };
 MODULE_DEVICE_TABLE(i2c, lm8323_id);
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 4/5] Input: tca6416-keypad - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:30 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel
In-Reply-To: <20230724053024.352054-1-dmitry.torokhov@gmail.com>

From: Yangtao Li <frank.li@vivo.com>

Use devm_* api to simplify code, this makes it unnecessary to explicitly
release resources.

Signed-off-by: Yangtao Li <frank.li@vivo.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/tca6416-keypad.c | 53 +++++++++----------------
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 21a2f2de4345..ff665319791e 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -216,12 +216,15 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 		return -EINVAL;
 	}
 
-	chip = kzalloc(struct_size(chip, buttons, pdata->nbuttons), GFP_KERNEL);
-	input = input_allocate_device();
-	if (!chip || !input) {
-		error = -ENOMEM;
-		goto fail1;
-	}
+	chip = devm_kzalloc(&client->dev,
+			    struct_size(chip, buttons, pdata->nbuttons),
+			    GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	input = devm_input_allocate_device(&client->dev);
+	if (!input)
+		return -ENOMEM;
 
 	chip->client = client;
 	chip->input = input;
@@ -233,7 +236,6 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 
 	input->phys = "tca6416-keys/input0";
 	input->name = client->name;
-	input->dev.parent = &client->dev;
 
 	input->open = tca6416_keys_open;
 	input->close = tca6416_keys_close;
@@ -263,19 +265,20 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 	 */
 	error = tca6416_setup_registers(chip);
 	if (error)
-		goto fail1;
+		return error;
 
 	if (!chip->use_polling) {
-		error = request_threaded_irq(client->irq, NULL,
-					     tca6416_keys_isr,
-					     IRQF_TRIGGER_FALLING |
-					     IRQF_ONESHOT | IRQF_NO_AUTOEN,
-					     "tca6416-keypad", chip);
+		error = devm_request_threaded_irq(&client->dev, client->irq,
+						  NULL, tca6416_keys_isr,
+						  IRQF_TRIGGER_FALLING |
+							IRQF_ONESHOT |
+							IRQF_NO_AUTOEN,
+						  "tca6416-keypad", chip);
 		if (error) {
 			dev_dbg(&client->dev,
 				"Unable to claim irq %d; error %d\n",
 				client->irq, error);
-			goto fail1;
+			return error;
 		}
 	}
 
@@ -283,31 +286,12 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 	if (error) {
 		dev_dbg(&client->dev,
 			"Unable to register input device, error: %d\n", error);
-		goto fail2;
+		return error;
 	}
 
 	i2c_set_clientdata(client, chip);
 
 	return 0;
-
-fail2:
-	if (!chip->use_polling)
-		free_irq(client->irq, chip);
-fail1:
-	input_free_device(input);
-	kfree(chip);
-	return error;
-}
-
-static void tca6416_keypad_remove(struct i2c_client *client)
-{
-	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
-
-	if (!chip->use_polling)
-		free_irq(client->irq, chip);
-
-	input_unregister_device(chip->input);
-	kfree(chip);
 }
 
 static struct i2c_driver tca6416_keypad_driver = {
@@ -315,7 +299,6 @@ static struct i2c_driver tca6416_keypad_driver = {
 		.name	= "tca6416-keypad",
 	},
 	.probe		= tca6416_keypad_probe,
-	.remove		= tca6416_keypad_remove,
 	.id_table	= tca6416_id,
 };
 
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 2/5] Input: tca6416-keypad - rely on I2C core to set up suspend/resume
From: Dmitry Torokhov @ 2023-07-24  5:30 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel
In-Reply-To: <20230724053024.352054-1-dmitry.torokhov@gmail.com>

tca6416_keypad_suspend() and tca6416_keypad_resume() only configure device
IRQ for wakeup. I2C core already does this by registering interrupt as a
wakeup IRQ in case when device is marked as wakeup-enabled, so we can
simply remove this code from the driver.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/tca6416-keypad.c | 25 -------------------------
 1 file changed, 25 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 01bc0b881188..906dffbf171c 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -287,7 +287,6 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 	}
 
 	i2c_set_clientdata(client, chip);
-	device_init_wakeup(&client->dev, 1);
 
 	return 0;
 
@@ -315,33 +314,9 @@ static void tca6416_keypad_remove(struct i2c_client *client)
 	kfree(chip);
 }
 
-static int tca6416_keypad_suspend(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-
-	if (device_may_wakeup(dev))
-		enable_irq_wake(client->irq);
-
-	return 0;
-}
-
-static int tca6416_keypad_resume(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-
-	if (device_may_wakeup(dev))
-		disable_irq_wake(client->irq);
-
-	return 0;
-}
-
-static DEFINE_SIMPLE_DEV_PM_OPS(tca6416_keypad_dev_pm_ops,
-				tca6416_keypad_suspend, tca6416_keypad_resume);
-
 static struct i2c_driver tca6416_keypad_driver = {
 	.driver = {
 		.name	= "tca6416-keypad",
-		.pm	= pm_sleep_ptr(&tca6416_keypad_dev_pm_ops),
 	},
 	.probe		= tca6416_keypad_probe,
 	.remove		= tca6416_keypad_remove,
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 1/5] Input: tca6416-keypad - always expect proper IRQ number in i2c client
From: Dmitry Torokhov @ 2023-07-24  5:30 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel

Remove option having i2c client contain raw gpio number instead of proper
IRQ number. There are no users of this facility in mainline and it will
allow cleaning up the driver code with regard to wakeup handling, etc.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/tca6416-keypad.c | 27 +++++++++----------------
 include/linux/tca6416_keypad.h          |  1 -
 2 files changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 2f745cabf4f2..01bc0b881188 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -148,7 +148,7 @@ static int tca6416_keys_open(struct input_dev *dev)
 	if (chip->use_polling)
 		schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
 	else
-		enable_irq(chip->irqnum);
+		enable_irq(chip->client->irq);
 
 	return 0;
 }
@@ -160,7 +160,7 @@ static void tca6416_keys_close(struct input_dev *dev)
 	if (chip->use_polling)
 		cancel_delayed_work_sync(&chip->dwork);
 	else
-		disable_irq(chip->irqnum);
+		disable_irq(chip->client->irq);
 }
 
 static int tca6416_setup_registers(struct tca6416_keypad_chip *chip)
@@ -266,12 +266,7 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 		goto fail1;
 
 	if (!chip->use_polling) {
-		if (pdata->irq_is_gpio)
-			chip->irqnum = gpio_to_irq(client->irq);
-		else
-			chip->irqnum = client->irq;
-
-		error = request_threaded_irq(chip->irqnum, NULL,
+		error = request_threaded_irq(client->irq, NULL,
 					     tca6416_keys_isr,
 					     IRQF_TRIGGER_FALLING |
 					     IRQF_ONESHOT | IRQF_NO_AUTOEN,
@@ -279,7 +274,7 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 		if (error) {
 			dev_dbg(&client->dev,
 				"Unable to claim irq %d; error %d\n",
-				chip->irqnum, error);
+				client->irq, error);
 			goto fail1;
 		}
 	}
@@ -298,8 +293,8 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 
 fail2:
 	if (!chip->use_polling) {
-		free_irq(chip->irqnum, chip);
-		enable_irq(chip->irqnum);
+		free_irq(client->irq, chip);
+		enable_irq(client->irq);
 	}
 fail1:
 	input_free_device(input);
@@ -312,8 +307,8 @@ static void tca6416_keypad_remove(struct i2c_client *client)
 	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
 
 	if (!chip->use_polling) {
-		free_irq(chip->irqnum, chip);
-		enable_irq(chip->irqnum);
+		free_irq(client->irq, chip);
+		enable_irq(client->irq);
 	}
 
 	input_unregister_device(chip->input);
@@ -323,10 +318,9 @@ static void tca6416_keypad_remove(struct i2c_client *client)
 static int tca6416_keypad_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
-	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
 
 	if (device_may_wakeup(dev))
-		enable_irq_wake(chip->irqnum);
+		enable_irq_wake(client->irq);
 
 	return 0;
 }
@@ -334,10 +328,9 @@ static int tca6416_keypad_suspend(struct device *dev)
 static int tca6416_keypad_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
-	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
 
 	if (device_may_wakeup(dev))
-		disable_irq_wake(chip->irqnum);
+		disable_irq_wake(client->irq);
 
 	return 0;
 }
diff --git a/include/linux/tca6416_keypad.h b/include/linux/tca6416_keypad.h
index b0d36a9934cc..5cf6f6f82aa7 100644
--- a/include/linux/tca6416_keypad.h
+++ b/include/linux/tca6416_keypad.h
@@ -25,7 +25,6 @@ struct tca6416_keys_platform_data {
 	unsigned int rep:1;	/* enable input subsystem auto repeat */
 	uint16_t pinmask;
 	uint16_t invert;
-	int irq_is_gpio;
 	int use_polling;	/* use polling if Interrupt is not connected*/
 };
 #endif
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 3/5] Input: tca6416-keypad - fix interrupt enable disbalance
From: Dmitry Torokhov @ 2023-07-24  5:30 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel
In-Reply-To: <20230724053024.352054-1-dmitry.torokhov@gmail.com>

The driver has been switched to use IRQF_NO_AUTOEN, but in the error
unwinding and remove paths calls to enable_irq() were left in place, which
will lead to an incorrect enable counter value.

Fixes: bcd9730a04a1 ("Input: move to use request_irq by IRQF_NO_AUTOEN flag")
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/tca6416-keypad.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index 906dffbf171c..21a2f2de4345 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -291,10 +291,8 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 	return 0;
 
 fail2:
-	if (!chip->use_polling) {
+	if (!chip->use_polling)
 		free_irq(client->irq, chip);
-		enable_irq(client->irq);
-	}
 fail1:
 	input_free_device(input);
 	kfree(chip);
@@ -305,10 +303,8 @@ static void tca6416_keypad_remove(struct i2c_client *client)
 {
 	struct tca6416_keypad_chip *chip = i2c_get_clientdata(client);
 
-	if (!chip->use_polling) {
+	if (!chip->use_polling)
 		free_irq(client->irq, chip);
-		enable_irq(client->irq);
-	}
 
 	input_unregister_device(chip->input);
 	kfree(chip);
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* [PATCH 5/5] Input: tca6416-keypad - switch to using input core's polling features
From: Dmitry Torokhov @ 2023-07-24  5:30 UTC (permalink / raw)
  To: linux-input; +Cc: Yangtao Li, linux-kernel
In-Reply-To: <20230724053024.352054-1-dmitry.torokhov@gmail.com>

Instead of rolling custom polling implementation use input core
facilities.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/keyboard/tca6416-keypad.c | 46 ++++++++++---------------
 1 file changed, 19 insertions(+), 27 deletions(-)

diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c
index ff665319791e..ebc8b9561266 100644
--- a/drivers/input/keyboard/tca6416-keypad.c
+++ b/drivers/input/keyboard/tca6416-keypad.c
@@ -24,6 +24,8 @@
 #define TCA6416_INVERT         2
 #define TCA6416_DIRECTION      3
 
+#define TCA6416_POLL_INTERVAL	100 /* msec */
+
 static const struct i2c_device_id tca6416_id[] = {
 	{ "tca6416-keys", 16, },
 	{ "tca6408-keys", 8, },
@@ -43,7 +45,6 @@ struct tca6416_keypad_chip {
 
 	struct i2c_client *client;
 	struct input_dev *input;
-	struct delayed_work dwork;
 	int io_size;
 	int irqnum;
 	u16 pinmask;
@@ -85,9 +86,9 @@ static int tca6416_read_reg(struct tca6416_keypad_chip *chip, int reg, u16 *val)
 	return 0;
 }
 
-static void tca6416_keys_scan(struct tca6416_keypad_chip *chip)
+static void tca6416_keys_scan(struct input_dev *input)
 {
-	struct input_dev *input = chip->input;
+	struct tca6416_keypad_chip *chip = input_get_drvdata(input);
 	u16 reg_val, val;
 	int error, i, pin_index;
 
@@ -122,33 +123,20 @@ static void tca6416_keys_scan(struct tca6416_keypad_chip *chip)
  */
 static irqreturn_t tca6416_keys_isr(int irq, void *dev_id)
 {
-	struct tca6416_keypad_chip *chip = dev_id;
-
-	tca6416_keys_scan(chip);
+	tca6416_keys_scan(dev_id);
 
 	return IRQ_HANDLED;
 }
 
-static void tca6416_keys_work_func(struct work_struct *work)
-{
-	struct tca6416_keypad_chip *chip =
-		container_of(work, struct tca6416_keypad_chip, dwork.work);
-
-	tca6416_keys_scan(chip);
-	schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
-}
-
 static int tca6416_keys_open(struct input_dev *dev)
 {
 	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
 
-	/* Get initial device state in case it has switches */
-	tca6416_keys_scan(chip);
-
-	if (chip->use_polling)
-		schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100));
-	else
+	if (!chip->use_polling) {
+		/* Get initial device state in case it has switches */
+		tca6416_keys_scan(dev);
 		enable_irq(chip->client->irq);
+	}
 
 	return 0;
 }
@@ -157,9 +145,7 @@ static void tca6416_keys_close(struct input_dev *dev)
 {
 	struct tca6416_keypad_chip *chip = input_get_drvdata(dev);
 
-	if (chip->use_polling)
-		cancel_delayed_work_sync(&chip->dwork);
-	else
+	if (!chip->use_polling)
 		disable_irq(chip->client->irq);
 }
 
@@ -232,8 +218,6 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 	chip->pinmask = pdata->pinmask;
 	chip->use_polling = pdata->use_polling;
 
-	INIT_DELAYED_WORK(&chip->dwork, tca6416_keys_work_func);
-
 	input->phys = "tca6416-keys/input0";
 	input->name = client->name;
 
@@ -268,12 +252,20 @@ static int tca6416_keypad_probe(struct i2c_client *client)
 		return error;
 
 	if (!chip->use_polling) {
+		error = input_setup_polling(input, tca6416_keys_scan);
+		if (error) {
+			dev_err(&client->dev, "Failed to setup polling\n");
+			return error;
+		}
+
+		input_set_poll_interval(input, TCA6416_POLL_INTERVAL);
+	} else {
 		error = devm_request_threaded_irq(&client->dev, client->irq,
 						  NULL, tca6416_keys_isr,
 						  IRQF_TRIGGER_FALLING |
 							IRQF_ONESHOT |
 							IRQF_NO_AUTOEN,
-						  "tca6416-keypad", chip);
+						  "tca6416-keypad", input);
 		if (error) {
 			dev_dbg(&client->dev,
 				"Unable to claim irq %d; error %d\n",
-- 
2.41.0.487.g6d72f3e995-goog


^ permalink raw reply related

* Re: [PATCH 1/8] Input: lm8333 - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:32 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-1-frank.li@vivo.com>

Hi Yangtao,

On Fri, Jul 14, 2023 at 04:06:04PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.
> 
> Signed-off-by: Yangtao Li <frank.li@vivo.com>
> ---
>  drivers/input/keyboard/lm8333.c | 40 +++++++++------------------------
>  1 file changed, 11 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/input/keyboard/lm8333.c b/drivers/input/keyboard/lm8333.c
> index c9f05764e36d..41d088933e01 100644
> --- a/drivers/input/keyboard/lm8333.c
> +++ b/drivers/input/keyboard/lm8333.c
> @@ -129,6 +129,7 @@ static int lm8333_probe(struct i2c_client *client)
>  {
>  	const struct lm8333_platform_data *pdata =
>  			dev_get_platdata(&client->dev);
> +	struct device *dev = &client->dev;

This temporary is used only in few places, while the rest are still
using &client->dev. I removed it, made a couple more changes and
applied, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/8] Input: amikbd - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:33 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-2-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:05PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

Applied with minor changes, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 3/8] Input: mcs-touchkey - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:34 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-3-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:06PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

Applied with minor edits, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 5/8] Input: qt1070 - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:35 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-5-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:08PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

Applied with minor edits, thank you.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 8/8] Input: lm8323 - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:37 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-8-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:11PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

LEDs can be managed with devm, as well as we now have better way of
managing custom driver attribute; I posted a series of 2 patches
addressing this.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 4/8] Input: tca6416-keypad - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:38 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-4-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:07PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

The driver needs bigger facelift; I posted a series addressing this
that incorporates your patch.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 6/8] Input: sh-keysc - convert to use devm_* api
From: Dmitry Torokhov @ 2023-07-24  5:39 UTC (permalink / raw)
  To: Yangtao Li; +Cc: linux-input, linux-kernel
In-Reply-To: <20230714080611.81302-6-frank.li@vivo.com>

On Fri, Jul 14, 2023 at 04:06:09PM +0800, Yangtao Li wrote:
> Use devm_* api to simplify code, this makes it unnecessary to explicitly
> release resources.

I'd like to see a more complete conversion that results in
sh_keysc_remove() being completely removed.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: 6.5-rc2: keys autorepeating when they should not
From: Dmitry Torokhov @ 2023-07-24  5:42 UTC (permalink / raw)
  To: Pavel Machek; +Cc: kernel list, linux-input
In-Reply-To: <ZL0b/odKy/GlEzJV@duo.ucw.cz>

Hi Pavel,

On Sun, Jul 23, 2023 at 02:24:30PM +0200, Pavel Machek wrote:
> Hi!
> 
> I updated to 6.5-rc2, and now I see keyboard problems (in X). ~ once
> in two days I get keyboard "stuck", autorepeating. It is USB keyboard,
> hitting another key cancels the autorepeat.

Sounds like keys are not released because autorepeat handled by X and
not the kernel. I am not sure what would cause this, there were no
changes to the input core recently... Maybe HID?

From which kernel did you update to 6.5-rc2? Any chance you could try
bisecting?

Thanks.


-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3 24/42] mtd: nand: add support for ts72xx
From: Miquel Raynal @ 2023-07-24  7:09 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: nikita.shubin, Hartley Sweeten, Lennert Buytenhek,
	Alexander Sverdlin, Russell King, Lukasz Majewski, Linus Walleij,
	Bartosz Golaszewski, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Michael Turquette, Stephen Boyd, Daniel Lezcano,
	Thomas Gleixner, Alessandro Zummo, Alexandre Belloni,
	Wim Van Sebroeck, Guenter Roeck, Sebastian Reichel,
	Thierry Reding, Uwe Kleine-König, Mark Brown,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Vinod Koul, Richard Weinberger, Vignesh Raghavendra,
	Damien Le Moal, Sergey Shtylyov, Dmitry Torokhov, Arnd Bergmann,
	Olof Johansson, soc, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Michael Peters, Kris Bahnsen, linux-arm-kernel, linux-kernel,
	linux-gpio, devicetree, linux-clk, linux-rtc, linux-watchdog,
	linux-pm, linux-pwm, linux-spi, netdev, dmaengine, linux-mtd,
	linux-ide, linux-input, alsa-devel
In-Reply-To: <ZLqx+Osn3gcHjUph@smile.fi.intel.com>

Hi Andy,

> > +static int ts72xx_nand_attach_chip(struct nand_chip *chip)
> > +{
> > +	switch (chip->ecc.engine_type) {
> > +	case NAND_ECC_ENGINE_TYPE_SOFT:
> > +		if (chip->ecc.algo == NAND_ECC_ALGO_UNKNOWN)
> > +			chip->ecc.algo = NAND_ECC_ALGO_HAMMING;
> > +		break;
> > +	case NAND_ECC_ENGINE_TYPE_ON_HOST:
> > +		return -EINVAL;
> > +	default:  
> 
> > +		break;  
> 
> Here it will return 0, is it a problem?

Seems ok, there are two other situations: on-die ECC engine and no ECC
engine, both do not require any specific handling on the controller
side.

> 
> > +	}
> > +
> > +	return 0;
> > +}  
> 
> ...
> 
> > +static void ts72xx_nand_remove(struct platform_device *pdev)
> > +{
> > +	struct ts72xx_nand_data *data = platform_get_drvdata(pdev);
> > +	struct nand_chip *chip = &data->chip;
> > +	int ret;
> > +
> > +	ret = mtd_device_unregister(nand_to_mtd(chip));  
> 
> > +	WARN_ON(ret);  
> 
> Why?!  Is it like this in other MTD drivers?

Yes, we did not yet change the internal machinery to return void, and
we don't want people to think getting errors there is normal.

> > +	nand_cleanup(chip);
> > +}  
> 

Thanks,
Miquèl

^ permalink raw reply

* [HID Patchsets v1 0/2] HID Patchsets for Samsung driver
From: sandeep.cs @ 2023-07-24  8:47 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: junwan.cho, jitender.s21, suhyun_.kim, ih0923.kim, gaudium.lee,
	sandeep.cs, linux-input, linux-kernel
In-Reply-To: <CGME20230724084829epcas5p1686507367b11db0ff5d17c3e6cb1ff7c@epcas5p1.samsung.com>

Dear All,

I hope this email finds you well. I am writing to submit a series of two patches for review and consideration.

As of today, Opensource kernel Samsung driver only supports USB HID devices and do not have support for Bluetooth HID devices. 
Samsung would like to improve the samsung driver and extend it's support for bluetooth devices as well.


Patch Series Overview:

--------------------------------------

[Patch 1/2]

Added Support for Samsung Bluetooth devices like

Samsung wireless Keyboard
Samsung wireless GamePad
Samsung Wireless Action Mouse
Samsung Wireless Book Cover
Samsung Wireless Universal Keyboard
Samsung Wireless HOGP Keyboard

And also added Special key processing on each of the devices in Samsung driver.

[Patch 2/2]

Earlier Samsung driver only handles USB HID devices and returns an error if it encounters a different type of HID device.
By removing this USB validation check, we allow the driver to handle other types of HID devices, including Bluetooth HID devices, which were previously excluded.
This change improves driver compatibility and extends its support for a wide range of devices.


All these changes have been verified and tested thoroughly in android devices.

Please accept our changes.


Thanks for your time and consideration

Best regards
Sandeep C S



sandeep.cs (2):
  HID: Add support for Samsung Bluetooth hid devices
  HID: Removed USB Validation check

 drivers/hid/hid-ids.h     |   8 +
 drivers/hid/hid-samsung.c | 415 +++++++++++++++++++++++++++++++++++---
 2 files changed, 399 insertions(+), 24 deletions(-)

-- 
2.25.1


^ permalink raw reply

* [HID Patchsets v1 1/2] HID: Add support for Samsung Bluetooth hid devices
From: sandeep.cs @ 2023-07-24  8:47 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: junwan.cho, jitender.s21, suhyun_.kim, ih0923.kim, gaudium.lee,
	sandeep.cs, linux-input, linux-kernel
In-Reply-To: <20230724084752.371245-1-sandeep.cs@samsung.com>

This patch add support for the Samsung hid devices like keyboard, action mouse and gamepad over the Bluetooth connection.

Bluetooth devices

Vendor 04e8 (Samsung)
Device 7021 (Samsung Wireless Keyboard)
Device a000 (Samsung Wireless GamePad)
Device a004 (Samsung Wireless Action Mouse)
Device a005 (Samsung Wireless BookCover)
Device a006 (Samsung Wireless Universal Keyboard)
Device a064 (Samsung Wireless HOGP Keyboard)

And also, special key processing on each Samsung Bluetooth devices.

The changes in this commit adhere to the kernel coding guidelines.

Signed-off-by: Sandeep C S <sandeep.cs@samsung.com>
Signed-off-by: Junwan Cho <junwan.cho@samsung.com>
Signed-off-by: Jitender Sajwan <jitender.s21@samsung.com>
---
 drivers/hid/hid-ids.h     |   8 +
 drivers/hid/hid-samsung.c | 412 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 399 insertions(+), 21 deletions(-)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 8a310f8ff20f..35b2f50ba3c6 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1139,6 +1139,14 @@
 #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE	0x0001
 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE	0x0600
 
+#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS	0x04e8
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD	0x7021
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD	0xa000
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE	0xa004
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER	0xa005
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD	0xa006
+#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD	0xa064
+
 #define USB_VENDOR_ID_SEMICO			0x1a2c
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD	0x0023
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2	0x0027
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index cf5992e97094..33e963303d11 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -67,20 +67,17 @@ static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 		rdesc[178] = 0x08;
 		rdesc[180] = 0x06;
 		rdesc[182] = 0x42;
-	} else
-	if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
+	} else if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
 			rdesc[194] == 0x25 && rdesc[195] == 0x12) {
 		samsung_irda_dev_trace(hdev, 203);
 		rdesc[193] = 0x1;
 		rdesc[195] = 0xf;
-	} else
-	if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
+	} else if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
 			rdesc[126] == 0x25 && rdesc[127] == 0x11) {
 		samsung_irda_dev_trace(hdev, 135);
 		rdesc[125] = 0x1;
 		rdesc[127] = 0xe;
-	} else
-	if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
+	} else if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
 			rdesc[162] == 0x25 && rdesc[163] == 0x01) {
 		samsung_irda_dev_trace(hdev, 171);
 		rdesc[161] = 0x1;
@@ -107,17 +104,39 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
 
 	switch (usage->hid & HID_USAGE) {
 	/* report 2 */
-	case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
-	case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL);	break;
-	case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
-	case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
-	case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
-	case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
-	case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
-	case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
-	case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
-	case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
-	case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
+	case 0x183:
+		samsung_kbd_mouse_map_key_clear(KEY_MEDIA);
+		break;
+	case 0x195:
+		samsung_kbd_mouse_map_key_clear(KEY_EMAIL);
+		break;
+	case 0x196:
+		samsung_kbd_mouse_map_key_clear(KEY_CALC);
+		break;
+	case 0x197:
+		samsung_kbd_mouse_map_key_clear(KEY_COMPUTER);
+		break;
+	case 0x22b:
+		samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
+		break;
+	case 0x22c:
+		samsung_kbd_mouse_map_key_clear(KEY_WWW);
+		break;
+	case 0x22d:
+		samsung_kbd_mouse_map_key_clear(KEY_BACK);
+		break;
+	case 0x22e:
+		samsung_kbd_mouse_map_key_clear(KEY_FORWARD);
+		break;
+	case 0x22f:
+		samsung_kbd_mouse_map_key_clear(KEY_FAVORITES);
+		break;
+	case 0x230:
+		samsung_kbd_mouse_map_key_clear(KEY_REFRESH);
+		break;
+	case 0x231:
+		samsung_kbd_mouse_map_key_clear(KEY_STOP);
+		break;
 	default:
 		return 0;
 	}
@@ -125,10 +144,342 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
 	return 1;
 }
 
+static int samsung_kbd_input_mapping(struct hid_device *hdev,
+	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
+	unsigned long **bit, int *max)
+{
+	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
+			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
+		return 0;
+	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
+		usage->hid & HID_USAGE);
+	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
+		set_bit(EV_REP, hi->input->evbit);
+		switch (usage->hid & HID_USAGE) {
+		/* Only for UK keyboard */
+		/* key found */
+#ifdef CONFIG_HID_KK_UPGRADE
+		case 0x32:
+			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
+			break;
+		case 0x64:
+			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
+			break;
+#else
+		case 0x32:
+			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
+			break;
+		case 0x64:
+			samsung_kbd_mouse_map_key_clear(KEY_102ND);
+			break;
+#endif
+		/* Only for BR keyboard */
+		case 0x87:
+			samsung_kbd_mouse_map_key_clear(KEY_RO);
+			break;
+		default:
+			return 0;
+		}
+	}
+	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
+		switch (usage->hid & HID_USAGE) {
+		/* report 2 */
+		/* MENU */
+		case 0x040:
+			samsung_kbd_mouse_map_key_clear(KEY_MENU);
+			break;
+		case 0x18a:
+			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
+			break;
+		case 0x196:
+			samsung_kbd_mouse_map_key_clear(KEY_WWW);
+			break;
+		case 0x19e:
+			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
+			break;
+		case 0x221:
+			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
+			break;
+		case 0x223:
+			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
+			break;
+		/* Smtart Voice Key */
+		case 0x300:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY13);
+			break;
+		/* RECENTAPPS */
+		case 0x301:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
+			break;
+		/* APPLICATION */
+		case 0x302:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
+			break;
+		/* Voice search */
+		case 0x305:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
+			break;
+		/* QPANEL on/off */
+		case 0x306:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
+			break;
+		/* SIP on/off */
+		case 0x307:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
+			break;
+		/* LANG */
+		case 0x308:
+			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
+			break;
+		case 0x30a:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
+			break;
+		case 0x30b:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
+			break;
+		default:
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static int samsung_gamepad_input_mapping(struct hid_device *hdev,
+	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
+	unsigned long **bit, int *max)
+{
+	if (!(HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE) ||
+			HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)))
+		return 0;
+	dbg_hid("samsung wireless gamepad input mapping event [0x%x], %ld, %ld, [0x%x]\n",
+		usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0], usage->hid & HID_USAGE_PAGE);
+	if (HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE)) {
+		switch (usage->hid & HID_USAGE) {
+		case 0x01:
+			samsung_kbd_mouse_map_key_clear(BTN_A);
+			break;
+		case 0x02:
+			samsung_kbd_mouse_map_key_clear(BTN_B);
+			break;
+		case 0x03:
+			samsung_kbd_mouse_map_key_clear(BTN_C);
+			break;
+		case 0x04:
+			samsung_kbd_mouse_map_key_clear(BTN_X);
+			break;
+		case 0x05:
+			samsung_kbd_mouse_map_key_clear(BTN_Y);
+			break;
+		case 0x06:
+			samsung_kbd_mouse_map_key_clear(BTN_Z);
+			break;
+		case 0x07:
+			samsung_kbd_mouse_map_key_clear(BTN_TL);
+			break;
+		case 0x08:
+			samsung_kbd_mouse_map_key_clear(BTN_TR);
+			break;
+		case 0x09:
+			samsung_kbd_mouse_map_key_clear(BTN_TL2);
+			break;
+		case 0x0a:
+			samsung_kbd_mouse_map_key_clear(BTN_TR2);
+			break;
+		case 0x0b:
+			samsung_kbd_mouse_map_key_clear(BTN_SELECT);
+			break;
+		case 0x0c:
+			samsung_kbd_mouse_map_key_clear(BTN_START);
+			break;
+		case 0x0d:
+			samsung_kbd_mouse_map_key_clear(BTN_MODE);
+			break;
+		case 0x0e:
+			samsung_kbd_mouse_map_key_clear(BTN_THUMBL);
+			break;
+		case 0x0f:
+			samsung_kbd_mouse_map_key_clear(BTN_THUMBR);
+			break;
+		case 0x10:
+			samsung_kbd_mouse_map_key_clear(0x13f);
+			break;
+		default:
+			return 0;
+		}
+	}
+	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
+		switch (usage->hid & HID_USAGE) {
+		case 0x040:
+			samsung_kbd_mouse_map_key_clear(KEY_MENU);
+			break;
+		case 0x223:
+			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
+			break;
+		case 0x224:
+			samsung_kbd_mouse_map_key_clear(KEY_BACK);
+			break;
+		/* Screen Capture */
+		case 0x303:
+			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
+			break;
+		default:
+			return 0;
+		}
+	}
+	return 1;
+}
+static int samsung_actionmouse_input_mapping(struct hid_device *hdev,
+	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
+	unsigned long **bit, int *max)
+{
+	dbg_hid("samsung wireless actionmouse input mapping event [0x%x], [0x%x], %ld, %ld, [0x%x]\n",
+			usage->hid, usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0],
+			usage->hid & HID_USAGE_PAGE);
+	if (((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) && ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON))
+		return 0;
+	switch (usage->hid & HID_USAGE) {
+	case 0x301:
+		samsung_kbd_mouse_map_key_clear(254);
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+static int samsung_universal_kbd_input_mapping(struct hid_device *hdev,
+	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
+	unsigned long **bit, int *max)
+{
+	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
+			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
+		return 0;
+	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
+		usage->hid & HID_USAGE);
+	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
+		set_bit(EV_REP, hi->input->evbit);
+		switch (usage->hid & HID_USAGE) {
+		/* Only for UK keyboard */
+		/* key found */
+#ifdef CONFIG_HID_KK_UPGRADE
+		case 0x32:
+			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
+			break;
+		case 0x64:
+			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
+			break;
+#else
+		case 0x32:
+			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
+			break;
+		case 0x64:
+			samsung_kbd_mouse_map_key_clear(KEY_102ND);
+			break;
+#endif
+		/* Only for BR keyboard */
+		case 0x87:
+			samsung_kbd_mouse_map_key_clear(KEY_RO);
+			break;
+		default:
+			return 0;
+		}
+	}
+	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
+		switch (usage->hid & HID_USAGE) {
+		/* report 2 */
+		/* MENU */
+		case 0x040:
+			samsung_kbd_mouse_map_key_clear(KEY_MENU);
+			break;
+		case 0x18a:
+			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
+			break;
+		case 0x196:
+			samsung_kbd_mouse_map_key_clear(KEY_WWW);
+			break;
+		case 0x19e:
+			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
+			break;
+		case 0x221:
+			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
+			break;
+		case 0x223:
+			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
+			break;
+		/* RECENTAPPS */
+		case 0x301:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
+			break;
+		/* APPLICATION */
+		case 0x302:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
+			break;
+		/* Voice search */
+		case 0x305:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
+			break;
+		/* QPANEL on/off */
+		case 0x306:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
+			break;
+		/* SIP on/off */
+		case 0x307:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
+			break;
+		/* LANG */
+		case 0x308:
+			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
+			break;
+		case 0x30a:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
+			break;
+		case 0x070:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
+			break;
+		case 0x30b:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
+			break;
+		case 0x06f:
+			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
+			break;
+		/* S-Finder */
+		case 0x304:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY7);
+			break;
+		/* Screen Capture */
+		case 0x303:
+			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
+			break;
+		/* Multi Window */
+		case 0x309:
+			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY9);
+			break;
+		/* HotKey App 1 */
+		case 0x071:
+			samsung_kbd_mouse_map_key_clear(0x2f5);
+			break;
+		/* HotKey App 2 */
+		case 0x072:
+			samsung_kbd_mouse_map_key_clear(0x2f6);
+			break;
+		/* HotKey App 3 */
+		case 0x073:
+			samsung_kbd_mouse_map_key_clear(0x2f7);
+			break;
+		/* Dex */
+		case 0x06e:
+			samsung_kbd_mouse_map_key_clear(0x2bd);
+			break;
+		default:
+			return 0;
+		}
+	}
+	return 1;
+}
+
 static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 	unsigned int *rsize)
 {
-	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
+	if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE)
 		rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
 	return rdesc;
 }
@@ -139,10 +490,24 @@ static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
 {
 	int ret = 0;
 
-	if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
+	if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE)
 		ret = samsung_kbd_mouse_input_mapping(hdev,
 			hi, field, usage, bit, max);
-
+	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD)
+		ret = samsung_kbd_input_mapping(hdev,
+			hi, field, usage, bit, max);
+	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD)
+		ret = samsung_gamepad_input_mapping(hdev,
+			hi, field, usage, bit, max);
+	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE)
+		ret = samsung_actionmouse_input_mapping(hdev,
+			hi, field, usage, bit, max);
+	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD)
+		ret = samsung_universal_kbd_input_mapping(hdev,
+			hi, field, usage, bit, max);
+	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD)
+		ret = samsung_universal_kbd_input_mapping(hdev,
+			hi, field, usage, bit, max);
 	return ret;
 }
 
@@ -161,7 +526,7 @@ static int samsung_probe(struct hid_device *hdev,
 		goto err_free;
 	}
 
-	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
+	if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) {
 		if (hdev->rsize == 184) {
 			/* disable hidinput, force hiddev */
 			cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
@@ -183,6 +548,11 @@ static int samsung_probe(struct hid_device *hdev,
 static const struct hid_device_id samsung_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD) },
+	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD) },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, samsung_devices);
-- 
2.25.1


^ permalink raw reply related

* [HID Patchsets v1 2/2] HID: Removed USB Validation check
From: sandeep.cs @ 2023-07-24  8:47 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: junwan.cho, jitender.s21, suhyun_.kim, ih0923.kim, gaudium.lee,
	sandeep.cs, linux-input, linux-kernel
In-Reply-To: <20230724084752.371245-1-sandeep.cs@samsung.com>

Earlier Samsung driver only handles USB HID devices and returns an error if it encounters a Bluetooth type of HID device.
By removing this USB validation check, we allow the driver to handle other types of HID devices including Bluetooth HID devices, which were previously excluded.

This change improves driver compatibility and extends its support for a wide range of devices.

Signed-off-by: Sandeep C S<sandeep.cs@samsung.com>
Signed-off-by: Junwan Cho <junwan.cho@samsung.com>
Signed-off-by: Jitender Sajwan <jitender.s21@samsung.com>
---
 drivers/hid/hid-samsung.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 33e963303d11..3cafbf4d9dc6 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -517,9 +517,6 @@ static int samsung_probe(struct hid_device *hdev,
 	int ret;
 	unsigned int cmask = HID_CONNECT_DEFAULT;
 
-	if (!hid_is_usb(hdev))
-		return -EINVAL;
-
 	ret = hid_parse(hdev);
 	if (ret) {
 		hid_err(hdev, "parse failed\n");
-- 
2.25.1


^ permalink raw reply related

* Don't miss out on our low Interest loan opportunity
From: Coinloan Support Center @ 2023-07-24  8:46 UTC (permalink / raw)
  To: linux-input

Are you looking for a loan to either increase your activity or to 
carry out a project. 
We offer Crypto Loans at 2-7% interest rate with or without a 
credit check.
Please get back to us if you are interested in more details.

^ permalink raw reply

* Re: [HID Patchsets v1 2/2] HID: Removed USB Validation check
From: Benjamin Tissoires @ 2023-07-24 10:10 UTC (permalink / raw)
  To: sandeep.cs
  Cc: Jiri Kosina, Benjamin Tissoires, junwan.cho, jitender.s21,
	suhyun_.kim, ih0923.kim, gaudium.lee, linux-input, linux-kernel
In-Reply-To: <20230724084752.371245-3-sandeep.cs@samsung.com>

Hi Sandeep,

On Jul 24 2023, sandeep.cs wrote:
> Earlier Samsung driver only handles USB HID devices and returns an error if it encounters a Bluetooth type of HID device.
> By removing this USB validation check, we allow the driver to handle other types of HID devices including Bluetooth HID devices, which were previously excluded.

Please no, not with that patch at least.

hid_is_usb() protects the kernel from making an oops if the actual
transport layer is not USB, let's say an emulated uhid device. So by
removing that check you are just allowing anybody with root access to
access random memory in the kernel.

The correct fix is to move the check where it's needed, in
samsung_kbd_mouse_input_mapping().
I'll let you decide what need should be done if it's not a USB device
there: consider the interface to be 0 or just abort the function.

Cheers,
Benjamin

> 
> This change improves driver compatibility and extends its support for a wide range of devices.
> 
> Signed-off-by: Sandeep C S<sandeep.cs@samsung.com>
> Signed-off-by: Junwan Cho <junwan.cho@samsung.com>
> Signed-off-by: Jitender Sajwan <jitender.s21@samsung.com>
> ---
>  drivers/hid/hid-samsung.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
> index 33e963303d11..3cafbf4d9dc6 100644
> --- a/drivers/hid/hid-samsung.c
> +++ b/drivers/hid/hid-samsung.c
> @@ -517,9 +517,6 @@ static int samsung_probe(struct hid_device *hdev,
>  	int ret;
>  	unsigned int cmask = HID_CONNECT_DEFAULT;
>  
> -	if (!hid_is_usb(hdev))
> -		return -EINVAL;
> -
>  	ret = hid_parse(hdev);
>  	if (ret) {
>  		hid_err(hdev, "parse failed\n");
> -- 
> 2.25.1
> 

^ permalink raw reply

* Re: [HID Patchsets v1 1/2] HID: Add support for Samsung Bluetooth hid devices
From: Benjamin Tissoires @ 2023-07-24 10:13 UTC (permalink / raw)
  To: sandeep.cs
  Cc: Jiri Kosina, Benjamin Tissoires, junwan.cho, jitender.s21,
	suhyun_.kim, ih0923.kim, gaudium.lee, linux-input, linux-kernel
In-Reply-To: <20230724084752.371245-2-sandeep.cs@samsung.com>

Hi Sandeep,

On Jul 24 2023, sandeep.cs wrote:
> This patch add support for the Samsung hid devices like keyboard, action mouse and gamepad over the Bluetooth connection.
> 
> Bluetooth devices
> 
> Vendor 04e8 (Samsung)
> Device 7021 (Samsung Wireless Keyboard)
> Device a000 (Samsung Wireless GamePad)
> Device a004 (Samsung Wireless Action Mouse)
> Device a005 (Samsung Wireless BookCover)
> Device a006 (Samsung Wireless Universal Keyboard)
> Device a064 (Samsung Wireless HOGP Keyboard)
> 
> And also, special key processing on each Samsung Bluetooth devices.
> 
> The changes in this commit adhere to the kernel coding guidelines.
> 
> Signed-off-by: Sandeep C S <sandeep.cs@samsung.com>
> Signed-off-by: Junwan Cho <junwan.cho@samsung.com>
> Signed-off-by: Jitender Sajwan <jitender.s21@samsung.com>
> ---
>  drivers/hid/hid-ids.h     |   8 +
>  drivers/hid/hid-samsung.c | 412 ++++++++++++++++++++++++++++++++++++--

That's a huge patch. Way too big for me IMO.

Please refactor the series with:
1. hid_is_usb() check being moved
2. fix the checkpatch complains without adding new devices
3+ split the remaining changes, one per device so we can track which
   device needs what.

(1. and 2. can be done in any order)

Cheers,
Benjamin

>  2 files changed, 399 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 8a310f8ff20f..35b2f50ba3c6 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -1139,6 +1139,14 @@
>  #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE	0x0001
>  #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE	0x0600
>  
> +#define USB_VENDOR_ID_SAMSUNG_ELECTRONICS	0x04e8
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD	0x7021
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD	0xa000
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE	0xa004
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_BOOKCOVER	0xa005
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD	0xa006
> +#define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD	0xa064
> +
>  #define USB_VENDOR_ID_SEMICO			0x1a2c
>  #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD	0x0023
>  #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2	0x0027
> diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
> index cf5992e97094..33e963303d11 100644
> --- a/drivers/hid/hid-samsung.c
> +++ b/drivers/hid/hid-samsung.c
> @@ -67,20 +67,17 @@ static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>  		rdesc[178] = 0x08;
>  		rdesc[180] = 0x06;
>  		rdesc[182] = 0x42;
> -	} else
> -	if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
> +	} else if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
>  			rdesc[194] == 0x25 && rdesc[195] == 0x12) {
>  		samsung_irda_dev_trace(hdev, 203);
>  		rdesc[193] = 0x1;
>  		rdesc[195] = 0xf;
> -	} else
> -	if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
> +	} else if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
>  			rdesc[126] == 0x25 && rdesc[127] == 0x11) {
>  		samsung_irda_dev_trace(hdev, 135);
>  		rdesc[125] = 0x1;
>  		rdesc[127] = 0xe;
> -	} else
> -	if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
> +	} else if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
>  			rdesc[162] == 0x25 && rdesc[163] == 0x01) {
>  		samsung_irda_dev_trace(hdev, 171);
>  		rdesc[161] = 0x1;
> @@ -107,17 +104,39 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
>  
>  	switch (usage->hid & HID_USAGE) {
>  	/* report 2 */
> -	case 0x183: samsung_kbd_mouse_map_key_clear(KEY_MEDIA); break;
> -	case 0x195: samsung_kbd_mouse_map_key_clear(KEY_EMAIL);	break;
> -	case 0x196: samsung_kbd_mouse_map_key_clear(KEY_CALC); break;
> -	case 0x197: samsung_kbd_mouse_map_key_clear(KEY_COMPUTER); break;
> -	case 0x22b: samsung_kbd_mouse_map_key_clear(KEY_SEARCH); break;
> -	case 0x22c: samsung_kbd_mouse_map_key_clear(KEY_WWW); break;
> -	case 0x22d: samsung_kbd_mouse_map_key_clear(KEY_BACK); break;
> -	case 0x22e: samsung_kbd_mouse_map_key_clear(KEY_FORWARD); break;
> -	case 0x22f: samsung_kbd_mouse_map_key_clear(KEY_FAVORITES); break;
> -	case 0x230: samsung_kbd_mouse_map_key_clear(KEY_REFRESH); break;
> -	case 0x231: samsung_kbd_mouse_map_key_clear(KEY_STOP); break;
> +	case 0x183:
> +		samsung_kbd_mouse_map_key_clear(KEY_MEDIA);
> +		break;
> +	case 0x195:
> +		samsung_kbd_mouse_map_key_clear(KEY_EMAIL);
> +		break;
> +	case 0x196:
> +		samsung_kbd_mouse_map_key_clear(KEY_CALC);
> +		break;
> +	case 0x197:
> +		samsung_kbd_mouse_map_key_clear(KEY_COMPUTER);
> +		break;
> +	case 0x22b:
> +		samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
> +		break;
> +	case 0x22c:
> +		samsung_kbd_mouse_map_key_clear(KEY_WWW);
> +		break;
> +	case 0x22d:
> +		samsung_kbd_mouse_map_key_clear(KEY_BACK);
> +		break;
> +	case 0x22e:
> +		samsung_kbd_mouse_map_key_clear(KEY_FORWARD);
> +		break;
> +	case 0x22f:
> +		samsung_kbd_mouse_map_key_clear(KEY_FAVORITES);
> +		break;
> +	case 0x230:
> +		samsung_kbd_mouse_map_key_clear(KEY_REFRESH);
> +		break;
> +	case 0x231:
> +		samsung_kbd_mouse_map_key_clear(KEY_STOP);
> +		break;
>  	default:
>  		return 0;
>  	}
> @@ -125,10 +144,342 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
>  	return 1;
>  }
>  
> +static int samsung_kbd_input_mapping(struct hid_device *hdev,
> +	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
> +	unsigned long **bit, int *max)
> +{
> +	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
> +			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
> +		return 0;
> +	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
> +		usage->hid & HID_USAGE);
> +	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
> +		set_bit(EV_REP, hi->input->evbit);
> +		switch (usage->hid & HID_USAGE) {
> +		/* Only for UK keyboard */
> +		/* key found */
> +#ifdef CONFIG_HID_KK_UPGRADE
> +		case 0x32:
> +			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
> +			break;
> +		case 0x64:
> +			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
> +			break;
> +#else
> +		case 0x32:
> +			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
> +			break;
> +		case 0x64:
> +			samsung_kbd_mouse_map_key_clear(KEY_102ND);
> +			break;
> +#endif
> +		/* Only for BR keyboard */
> +		case 0x87:
> +			samsung_kbd_mouse_map_key_clear(KEY_RO);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
> +		switch (usage->hid & HID_USAGE) {
> +		/* report 2 */
> +		/* MENU */
> +		case 0x040:
> +			samsung_kbd_mouse_map_key_clear(KEY_MENU);
> +			break;
> +		case 0x18a:
> +			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
> +			break;
> +		case 0x196:
> +			samsung_kbd_mouse_map_key_clear(KEY_WWW);
> +			break;
> +		case 0x19e:
> +			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
> +			break;
> +		case 0x221:
> +			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
> +			break;
> +		case 0x223:
> +			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
> +			break;
> +		/* Smtart Voice Key */
> +		case 0x300:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY13);
> +			break;
> +		/* RECENTAPPS */
> +		case 0x301:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
> +			break;
> +		/* APPLICATION */
> +		case 0x302:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
> +			break;
> +		/* Voice search */
> +		case 0x305:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
> +			break;
> +		/* QPANEL on/off */
> +		case 0x306:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
> +			break;
> +		/* SIP on/off */
> +		case 0x307:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
> +			break;
> +		/* LANG */
> +		case 0x308:
> +			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
> +			break;
> +		case 0x30a:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
> +			break;
> +		case 0x30b:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	return 1;
> +}
> +
> +static int samsung_gamepad_input_mapping(struct hid_device *hdev,
> +	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
> +	unsigned long **bit, int *max)
> +{
> +	if (!(HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE) ||
> +			HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)))
> +		return 0;
> +	dbg_hid("samsung wireless gamepad input mapping event [0x%x], %ld, %ld, [0x%x]\n",
> +		usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0], usage->hid & HID_USAGE_PAGE);
> +	if (HID_UP_BUTTON == (usage->hid & HID_USAGE_PAGE)) {
> +		switch (usage->hid & HID_USAGE) {
> +		case 0x01:
> +			samsung_kbd_mouse_map_key_clear(BTN_A);
> +			break;
> +		case 0x02:
> +			samsung_kbd_mouse_map_key_clear(BTN_B);
> +			break;
> +		case 0x03:
> +			samsung_kbd_mouse_map_key_clear(BTN_C);
> +			break;
> +		case 0x04:
> +			samsung_kbd_mouse_map_key_clear(BTN_X);
> +			break;
> +		case 0x05:
> +			samsung_kbd_mouse_map_key_clear(BTN_Y);
> +			break;
> +		case 0x06:
> +			samsung_kbd_mouse_map_key_clear(BTN_Z);
> +			break;
> +		case 0x07:
> +			samsung_kbd_mouse_map_key_clear(BTN_TL);
> +			break;
> +		case 0x08:
> +			samsung_kbd_mouse_map_key_clear(BTN_TR);
> +			break;
> +		case 0x09:
> +			samsung_kbd_mouse_map_key_clear(BTN_TL2);
> +			break;
> +		case 0x0a:
> +			samsung_kbd_mouse_map_key_clear(BTN_TR2);
> +			break;
> +		case 0x0b:
> +			samsung_kbd_mouse_map_key_clear(BTN_SELECT);
> +			break;
> +		case 0x0c:
> +			samsung_kbd_mouse_map_key_clear(BTN_START);
> +			break;
> +		case 0x0d:
> +			samsung_kbd_mouse_map_key_clear(BTN_MODE);
> +			break;
> +		case 0x0e:
> +			samsung_kbd_mouse_map_key_clear(BTN_THUMBL);
> +			break;
> +		case 0x0f:
> +			samsung_kbd_mouse_map_key_clear(BTN_THUMBR);
> +			break;
> +		case 0x10:
> +			samsung_kbd_mouse_map_key_clear(0x13f);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
> +		switch (usage->hid & HID_USAGE) {
> +		case 0x040:
> +			samsung_kbd_mouse_map_key_clear(KEY_MENU);
> +			break;
> +		case 0x223:
> +			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
> +			break;
> +		case 0x224:
> +			samsung_kbd_mouse_map_key_clear(KEY_BACK);
> +			break;
> +		/* Screen Capture */
> +		case 0x303:
> +			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	return 1;
> +}
> +static int samsung_actionmouse_input_mapping(struct hid_device *hdev,
> +	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
> +	unsigned long **bit, int *max)
> +{
> +	dbg_hid("samsung wireless actionmouse input mapping event [0x%x], [0x%x], %ld, %ld, [0x%x]\n",
> +			usage->hid, usage->hid & HID_USAGE, hi->input->evbit[0], hi->input->absbit[0],
> +			usage->hid & HID_USAGE_PAGE);
> +	if (((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) && ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON))
> +		return 0;
> +	switch (usage->hid & HID_USAGE) {
> +	case 0x301:
> +		samsung_kbd_mouse_map_key_clear(254);
> +		break;
> +	default:
> +		return 0;
> +	}
> +	return 1;
> +}
> +static int samsung_universal_kbd_input_mapping(struct hid_device *hdev,
> +	struct hid_input *hi, struct hid_field *field, struct hid_usage *usage,
> +	unsigned long **bit, int *max)
> +{
> +	if (!(HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE) ||
> +			HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)))
> +		return 0;
> +	dbg_hid("samsung wireless keyboard input mapping event [0x%x]\n",
> +		usage->hid & HID_USAGE);
> +	if (HID_UP_KEYBOARD == (usage->hid & HID_USAGE_PAGE)) {
> +		set_bit(EV_REP, hi->input->evbit);
> +		switch (usage->hid & HID_USAGE) {
> +		/* Only for UK keyboard */
> +		/* key found */
> +#ifdef CONFIG_HID_KK_UPGRADE
> +		case 0x32:
> +			samsung_kbd_mouse_map_key_clear(KEY_KBDILLUMTOGGLE);
> +			break;
> +		case 0x64:
> +			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
> +			break;
> +#else
> +		case 0x32:
> +			samsung_kbd_mouse_map_key_clear(KEY_BACKSLASH);
> +			break;
> +		case 0x64:
> +			samsung_kbd_mouse_map_key_clear(KEY_102ND);
> +			break;
> +#endif
> +		/* Only for BR keyboard */
> +		case 0x87:
> +			samsung_kbd_mouse_map_key_clear(KEY_RO);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	if (HID_UP_CONSUMER == (usage->hid & HID_USAGE_PAGE)) {
> +		switch (usage->hid & HID_USAGE) {
> +		/* report 2 */
> +		/* MENU */
> +		case 0x040:
> +			samsung_kbd_mouse_map_key_clear(KEY_MENU);
> +			break;
> +		case 0x18a:
> +			samsung_kbd_mouse_map_key_clear(KEY_MAIL);
> +			break;
> +		case 0x196:
> +			samsung_kbd_mouse_map_key_clear(KEY_WWW);
> +			break;
> +		case 0x19e:
> +			samsung_kbd_mouse_map_key_clear(KEY_SCREENLOCK);
> +			break;
> +		case 0x221:
> +			samsung_kbd_mouse_map_key_clear(KEY_SEARCH);
> +			break;
> +		case 0x223:
> +			samsung_kbd_mouse_map_key_clear(KEY_HOMEPAGE);
> +			break;
> +		/* RECENTAPPS */
> +		case 0x301:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY1);
> +			break;
> +		/* APPLICATION */
> +		case 0x302:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY2);
> +			break;
> +		/* Voice search */
> +		case 0x305:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY4);
> +			break;
> +		/* QPANEL on/off */
> +		case 0x306:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY5);
> +			break;
> +		/* SIP on/off */
> +		case 0x307:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY3);
> +			break;
> +		/* LANG */
> +		case 0x308:
> +			samsung_kbd_mouse_map_key_clear(KEY_LANGUAGE);
> +			break;
> +		case 0x30a:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
> +			break;
> +		case 0x070:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSDOWN);
> +			break;
> +		case 0x30b:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
> +			break;
> +		case 0x06f:
> +			samsung_kbd_mouse_map_key_clear(KEY_BRIGHTNESSUP);
> +			break;
> +		/* S-Finder */
> +		case 0x304:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY7);
> +			break;
> +		/* Screen Capture */
> +		case 0x303:
> +			samsung_kbd_mouse_map_key_clear(KEY_SYSRQ);
> +			break;
> +		/* Multi Window */
> +		case 0x309:
> +			samsung_kbd_mouse_map_key_clear(BTN_TRIGGER_HAPPY9);
> +			break;
> +		/* HotKey App 1 */
> +		case 0x071:
> +			samsung_kbd_mouse_map_key_clear(0x2f5);
> +			break;
> +		/* HotKey App 2 */
> +		case 0x072:
> +			samsung_kbd_mouse_map_key_clear(0x2f6);
> +			break;
> +		/* HotKey App 3 */
> +		case 0x073:
> +			samsung_kbd_mouse_map_key_clear(0x2f7);
> +			break;
> +		/* Dex */
> +		case 0x06e:
> +			samsung_kbd_mouse_map_key_clear(0x2bd);
> +			break;
> +		default:
> +			return 0;
> +		}
> +	}
> +	return 1;
> +}
> +
>  static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
>  	unsigned int *rsize)
>  {
> -	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
> +	if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE)
>  		rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
>  	return rdesc;
>  }
> @@ -139,10 +490,24 @@ static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
>  {
>  	int ret = 0;
>  
> -	if (USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE == hdev->product)
> +	if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE)
>  		ret = samsung_kbd_mouse_input_mapping(hdev,
>  			hi, field, usage, bit, max);
> -
> +	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD)
> +		ret = samsung_kbd_input_mapping(hdev,
> +			hi, field, usage, bit, max);
> +	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD)
> +		ret = samsung_gamepad_input_mapping(hdev,
> +			hi, field, usage, bit, max);
> +	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE)
> +		ret = samsung_actionmouse_input_mapping(hdev,
> +			hi, field, usage, bit, max);
> +	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD)
> +		ret = samsung_universal_kbd_input_mapping(hdev,
> +			hi, field, usage, bit, max);
> +	else if (hdev->product == USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD)
> +		ret = samsung_universal_kbd_input_mapping(hdev,
> +			hi, field, usage, bit, max);
>  	return ret;
>  }
>  
> @@ -161,7 +526,7 @@ static int samsung_probe(struct hid_device *hdev,
>  		goto err_free;
>  	}
>  
> -	if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) {
> +	if (hdev->product == USB_DEVICE_ID_SAMSUNG_IR_REMOTE) {
>  		if (hdev->rsize == 184) {
>  			/* disable hidinput, force hiddev */
>  			cmask = (cmask & ~HID_CONNECT_HIDINPUT) |
> @@ -183,6 +548,11 @@ static int samsung_probe(struct hid_device *hdev,
>  static const struct hid_device_id samsung_devices[] = {
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
>  	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
> +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD) },
> +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_GAMEPAD) },
> +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_ACTIONMOUSE) },
> +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD) },
> +	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SAMSUNG_ELECTRONICS, USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD) },
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(hid, samsung_devices);
> -- 
> 2.25.1
> 

^ permalink raw reply

* Re: [PATCH] dt-bindings: input: convert syna,rmi4 to DT schema
From: Rob Herring @ 2023-07-24 15:58 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Dmitry Torokhov, Krzysztof Kozlowski, Conor Dooley,
	Jason A. Donenfeld, Matthias Schiffer, Vincent Huang, linux-input,
	devicetree, linux-kernel
In-Reply-To: <20230720110008.133359-1-krzysztof.kozlowski@linaro.org>

On Thu, Jul 20, 2023 at 01:00:08PM +0200, Krzysztof Kozlowski wrote:
> Convert the bindings for Synaptics RMI4 bus and devices to DT schema.
> Changes during conversion:
> 1. Add reset-gpios already used in DTS and mentioned by RMI4
>    specification.
> 2. Do not require address/size cells, because without functions
>    (children) they aren't really needed.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> 
> ---
> 
> Jason, Matthias, Vincent,
> I put your names as maintainers, because moderately recently you were
> changing the driver. Let me know if this is okay or you prefer not to
> maintain the hardware.
> ---
>  .../bindings/input/rmi4/rmi_2d_sensor.txt     |  56 ----
>  .../bindings/input/rmi4/rmi_f01.txt           |  39 ---
>  .../bindings/input/rmi4/rmi_i2c.txt           |  61 ----
>  .../bindings/input/rmi4/rmi_spi.txt           |  56 ----
>  .../devicetree/bindings/input/syna,rmi4.yaml  | 271 ++++++++++++++++++
>  5 files changed, 271 insertions(+), 212 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_2d_sensor.txt
>  delete mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_f01.txt
>  delete mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_i2c.txt
>  delete mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt
>  create mode 100644 Documentation/devicetree/bindings/input/syna,rmi4.yaml


> diff --git a/Documentation/devicetree/bindings/input/syna,rmi4.yaml b/Documentation/devicetree/bindings/input/syna,rmi4.yaml
> new file mode 100644
> index 000000000000..286b4d52cea9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/syna,rmi4.yaml
> @@ -0,0 +1,271 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/syna,rmi4.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Synaptics RMI4 compliant devices
> +
> +maintainers:
> +  - Jason A. Donenfeld <Jason@zx2c4.com>
> +  - Matthias Schiffer <matthias.schiffer@ew.tq-group.com
> +  - Vincent Huang <vincent.huang@tw.synaptics.com>
> +
> +description: |
> +  The Synaptics RMI4 (Register Mapped Interface 4) core is able to support RMI4
> +  devices using different transports (I2C, SPI) and different functions (e.g.
> +  Function 1, 2D sensors using Function 11 or 12).
> +
> +properties:
> +  compatible:
> +    enum:
> +      - syna,rmi4-i2c
> +      - syna,rmi4-spi
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  reset-gpios:
> +    maxItems: 1
> +    description: Active low signal
> +
> +  spi-cpha: true
> +  spi-cpol: true
> +
> +  syna,reset-delay-ms:
> +    description:
> +      Delay to wait after resetting the device.
> +
> +  syna,startup-delay-ms:
> +    description:
> +      Delay to wait after powering on the device.
> +
> +  vdd-supply: true
> +  vio-supply: true
> +
> +  rmi4-f01@1:
> +    type: object
> +    additionalProperties: false
> +    description:
> +      Function 1
> +
> +    properties:
> +      reg:
> +        maxItems: 1
> +
> +      syna,nosleep-mode:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [0, 1, 2]
> +        description:
> +          If set the device will run at full power without sleeping.  nosleep
> +          has 3 modes, 0 will not change the default setting, 1 will disable
> +          nosleep (allow sleeping), and 2 will enable nosleep (disabling
> +          sleep).
> +
> +      syna,wakeup-threshold:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Defines the amplitude of the disturbance to the background
> +          capacitance that will cause the device to wake from dozing.
> +
> +      syna,doze-holdoff-ms:
> +        description:
> +          The delay to wait after the last finger lift and the first doze
> +          cycle.
> +
> +      syna,doze-interval-ms:
> +        description:
> +          The time period that the device sleeps between finger activity.
> +
> +    required:
> +      - reg
> +
> +patternProperties:
> +  "^rmi4-f1[12]@1[12]$":
> +    type: object
> +    unevaluatedProperties: false
> +    $ref: /schemas/input/touchscreen/touchscreen.yaml#
> +    description:
> +      RMI4 Function 11 and Function 12 are for 2D touch position sensing.
> +
> +    properties:
> +      reg:
> +        maxItems: 1
> +
> +      syna,clip-x-low:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Minimum value for X.
> +
> +      syna,clip-y-low:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Minimum value for Y.
> +
> +      syna,clip-x-high:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Maximum value for X.
> +
> +      syna,clip-y-high:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Maximum value for Y.
> +
> +      syna,offset-x:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Add an offset to X.
> +
> +      syna,offset-y:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Add an offset to Y.
> +
> +      syna,delta-x-threshold:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Minimum distance on the X axis required to generate an interrupt in
> +          reduced reporting mode.
> +
> +      syna,delta-y-threshold:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Minimum distance on the Y axis required to generate an interrupt in
> +          reduced reporting mode.
> +
> +      syna,sensor-type:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [1, 2]
> +        description: |
> +          Sensor type: 1 for touchscreen 2 for touchpad.
> +
> +      syna,disable-report-mask:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description:
> +          Mask for disabling posiiton reporting. Used to disable reporing
> +          absolute position data.
> +
> +      syna,rezero-wait-ms:
> +        description:
> +          Time to wait after issuing a rezero command.
> +
> +    required:
> +      - reg
> +
> +  "^rmi4-f[0-9a-z]+@[0-9a-z]+$":

a-f in both places.

> +    type: object
> +    description:
> +      Other functions, not documented yet.
> +
> +    properties:
> +      reg:
> +        maxItems: 1
> +
> +    required:
> +      - reg
> +
> +required:
> +  - compatible
> +  - reg
> +
> +unevaluatedProperties: false
> +
> +allOf:
> +  - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: syna,rmi4-i2c
> +    then:
> +      properties:
> +        spi-rx-delay-us: false
> +        spi-tx-delay-us: false
> +    else:
> +      properties:
> +        syna,reset-delay-ms: false
> +        syna,startup-delay-ms: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        touchscreen@20 {
> +            compatible = "syna,rmi4-i2c";
> +            reg = <0x20>;
> +            interrupt-parent = <&gpx1>;
> +            interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
> +
> +            syna,startup-delay-ms = <100>;
> +            vdd-supply = <&tsp_vdd>;
> +            vio-supply = <&ldo32_reg>;
> +
> +            pinctrl-0 = <&touch_irq>;
> +            pinctrl-names = "default";
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            rmi4-f01@1 {
> +                reg = <0x1>;
> +                syna,nosleep-mode = <1>;
> +            };
> +
> +            rmi4-f12@12 {
> +                reg = <0x12>;
> +                syna,sensor-type = <1>;
> +            };
> +
> +            rmi4-f1a@1a {
> +                reg = <0x1a>;
> +            };
> +        };
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    spi {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        touchscreen@0 {
> +            compatible = "syna,rmi4-spi";
> +            reg = <0x0>;
> +            interrupt-parent = <&gpx1>;
> +            interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
> +
> +            spi-max-frequency = <4000000>;
> +            spi-rx-delay-us = <30>;
> +            spi-cpha;
> +            spi-cpol;
> +
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +
> +            rmi4-f01@1 {
> +                reg = <0x1>;
> +                syna,nosleep-mode = <1>;
> +            };
> +
> +            rmi4-f11@11 {
> +                reg = <0x11>;
> +                touchscreen-inverted-y;
> +                syna,sensor-type = <2>;
> +            };
> +        };
> +    };
> -- 
> 2.34.1
> 

^ permalink raw reply

* [PATCH] HID: logitech-hidpp: add support for the Logitech G Pro X mouse
From: Hamza Mahfooz @ 2023-07-24 16:30 UTC (permalink / raw)
  To: linux-kernel
  Cc: Hamza Mahfooz, Filipe Laíns, Bastien Nocera, Jiri Kosina,
	Benjamin Tissoires, linux-input

The Logitech G Pro X mouse uses the HID++ protocol and supports battery
reporting. So, add it to the list of supported devices.

Signed-off-by: Hamza Mahfooz <someguy@effective-light.com>
---
 drivers/hid/hid-logitech-hidpp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 129b01be488d..34fc4f7b254a 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -4620,6 +4620,8 @@ static const struct hid_device_id hidpp_devices[] = {
 		.driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS },
 	{ /* Logitech G Pro Gaming Mouse over USB */
 	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
+	{ /* Logitech G Pro X Superlight Gaming Mouse over USB */
+	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
 
 	{ /* G935 Gaming Headset */
 	  HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
-- 
2.41.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox