cap11xx: add LED support
Subsystems (3)
PATCH v2 1/1 cap11xx: add LED support
Several cap11xx variants have LEDs that be can be controlled, this patchset implements this functionality.
--- drivers/input/keyboard/cap11xx.c | 90 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)
drivers/input/keyboard/cap11xx.c +87 -3
@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/of_irq.h> #include <linux/regmap.h> #include <linux/i2c.h>
@@ -47,6 +48,8 @@#define CAP11XX_REG_CONFIG2 0x44#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6)#define CAP11XX_REG_SENSOR_BASE_CNT (X ) (0x50 + (X)) +#define CAP11XX_REG_LED_POLARITY 0x73 +#define CAP11XX_REG_LED_OUTPUT_CONTROL 0x74#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X))#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba
@@ -56,10 +59,25 @@#define CAP11XX_MANUFACTURER_ID 0x5d +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led { +struct cap11xx_priv *priv; +struct led_classdev cdev; +struct work_struct work; +char name[32 ]; +int id; +enum led_brightness new_brightness; +}; +#endif +struct cap11xx_priv {struct regmap *regmap;struct input_dev *idev; +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led *leds; +int num_leds; +#endif /* config */ u32 keycodes[]; };
@@ -67,6 +85,7 @@ struct cap11xx_priv {struct cap11xx_hw_model {u8 product_id;unsigned int num_channels; +unsigned int num_leds; };enum {
@@ -76,9 +95,9 @@ enum { };static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106 ] = { .product_id =0x55 , .num_channels =6 }, - [CAP1126 ] = { .product_id =0x53 , .num_channels =6 }, - [CAP1188 ] = { .product_id =0x50 , .num_channels =8 }, + [CAP1106 ] = { .product_id =0x55 , .num_channels =6 , .num_leds =0 }, + [CAP1126 ] = { .product_id =0x53 , .num_channels =6 , .num_leds =2 }, + [CAP1188 ] = { .product_id =0x50 , .num_channels =8 , .num_leds =8 }, };static const struct reg_default cap11xx_reg_defaults[] = {
@@ -111,6 +130,7 @@ static const struct reg_default cap11xx_reg_defaults[] = { { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, { CAP11XX_REG_STANDBY_THRESH, 0x40 }, { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_LED_POLARITY, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, };
@@ -196,6 +216,58 @@ static void cap11xx_input_close(struct input_dev *idev)cap11xx_set_sleep (priv, true); } +#ifdef CONFIG_LEDS_CLASS +static void cap11xx_led_work (struct work_struct *work) +{ + struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); +struct cap11xx_priv *priv = led->priv; +int value = led->new_brightness; + +regmap_update_bits (priv->regmap,CAP11XX_REG_LED_OUTPUT_CONTROL , +BIT (led->id), !!value ?BIT (led->id) :0 ); +} + +static void cap11xx_led_set (struct led_classdev *cdev, +enum led_brightness value) +{ + struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); + + led->new_brightness = value; +schedule_work (&led->work); +} + +static int cap11xx_register_leds (struct device *dev,struct cap11xx_priv *priv) +{ +int ret; +int i; + +/* +* Be sure all LEDS are in off-state +*/ +regmap_update_bits (priv->regmap, +CAP11XX_REG_LED_OUTPUT_CONTROL ,0xff ,0 ); + +for (i =0 ; i < priv->num_leds; i++) { +struct cap11xx_led *led = &priv->leds[i]; + +snprintf (led->name,sizeof (led->name),"cap11xx:led%d" , i +1 ); + led->cdev.name = led->name; + led->cdev.brightness_set = cap11xx_led_set; + led->cdev.brightness =LED_OFF ; + led->cdev.max_brightness =1 ; + led->id = i; + led->priv = priv; + + ret =devm_led_classdev_register (dev, &led->cdev); +if (ret <0 ) +return ret; + +INIT_WORK (&led->work, cap11xx_led_work); + }; +return 0 ; +} +#endif +static int cap11xx_i2c_probe (struct i2c_client *i2c_client,const struct i2c_device_id *id) {
@@ -316,6 +388,18 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, priv->idev->open = cap11xx_input_open; priv->idev->close = cap11xx_input_close; +#ifdef CONFIG_LEDS_CLASS +if (cap->num_leds >0 ) { + priv->leds =devm_kcalloc (dev, cap->num_leds, +sizeof (struct cap11xx_led ),GFP_KERNEL ); +if (!priv->leds) +return -ENOMEM ; + priv->num_leds = cap->num_leds; + error =cap11xx_register_leds (dev, priv); +if (error) +return error; + } +#endif input_set_drvdata (priv->idev, priv);/*
Signature · 1 line
1.9.1
Hi Matt,
Quoted 13 lines · Matt Ranostay
Several cap11xx variants have LEDs that be can be controlled, this patchset implements this functionality.
Signed-off-by Matt Ranostay <[email protected]>--- drivers/input/keyboard/cap11xx.c | 90 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)drivers/input/keyboard/cap11xx.c +0
-0
drivers/input/keyboard/cap11xx.c line 18
Quoted 7 lines
drivers/input/keyboard/cap11xx.c +1
-0@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/of_irq.h> #include <linux/regmap.h> #include <linux/i2c.h>
These include directives aren't arranged in an alphabetical order. You could fix that as you are modifying this file.
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +2
-0@@ -47,6 +48,8 @@#define CAP11XX_REG_CONFIG2 0x44#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6)#define CAP11XX_REG_SENSOR_BASE_CNT (X ) (0x50 + (X)) +#define CAP11XX_REG_LED_POLARITY 0x73 +#define CAP11XX_REG_LED_OUTPUT_CONTROL 0x74#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X))#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba
drivers/input/keyboard/cap11xx.c line 67
Quoted 9 lines
drivers/input/keyboard/cap11xx.c +6
-0@@ -56,10 +59,25 @@#define CAP11XX_MANUFACTURER_ID 0x5d +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led { + struct cap11xx_priv *priv; + struct led_classdev cdev; + struct work_struct work; + char name[32];
This 'name' field is not needed. Instead the 'name' field of struct led_classdev should be initialized with the address of either a 'label' property from DT child node representing a LED, or the DT child node name if the label is absent. Please refer to Documentation/devicetree/bindings/leds/common.txt.
This is usually accomplished in the LED subsystem with following instruction:
led_cdev->name = of_get_property(child_node, "label", NULL) ? :
child_node->name;
Quoted 25 lines
drivers/input/keyboard/cap11xx.c +10
-0+int id; + enum led_brightness new_brightness; +}; +#endif +struct cap11xx_priv {struct regmap *regmap;struct input_dev *idev; +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led *leds; +int num_leds; +#endif /* config */ u32 keycodes[]; };@@ -67,6 +85,7 @@ struct cap11xx_priv {struct cap11xx_hw_model {u8 product_id;unsigned int num_channels; +unsigned int num_leds; };enum {
drivers/input/keyboard/cap11xx.c enum { · line 101
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +3
-3@@ -76,9 +95,9 @@ enum { };static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106 ] = { .product_id =0x55 , .num_channels =6 }, - [CAP1126 ] = { .product_id =0x53 , .num_channels =6 }, - [CAP1188 ] = { .product_id =0x50 , .num_channels =8 }, + [CAP1106 ] = { .product_id =0x55 , .num_channels =6 , .num_leds =0 }, + [CAP1126 ] = { .product_id =0x53 , .num_channels =6 , .num_leds =2 }, + [CAP1188 ] = { .product_id =0x50 , .num_channels =8 , .num_leds =8 }, };
The number of LEDs should be determined by the number of DT child nodes representing each LED. Please refer to Documentation/devicetree/bindings/leds/common.txt and other LED subsystem drivers to find out how it should be implemented.
Quoted 88 lines
drivers/input/keyboard/cap11xx.c +65
-0static const struct reg_default cap11xx_reg_defaults[] = {@@ -111,6 +130,7 @@ static const struct reg_default cap11xx_reg_defaults[] = { { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, { CAP11XX_REG_STANDBY_THRESH, 0x40 }, { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_LED_POLARITY, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, };@@ -196,6 +216,58 @@ static void cap11xx_input_close(struct input_dev *idev)cap11xx_set_sleep (priv, true); } +#ifdef CONFIG_LEDS_CLASS +static void cap11xx_led_work (struct work_struct *work) +{ + struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); +struct cap11xx_priv *priv = led->priv; +int value = led->new_brightness; + +regmap_update_bits (priv->regmap,CAP11XX_REG_LED_OUTPUT_CONTROL , +BIT (led->id), !!value ?BIT (led->id) :0 ); +} + +static void cap11xx_led_set (struct led_classdev *cdev, +enum led_brightness value) +{ + struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); + + led->new_brightness = value; +schedule_work (&led->work); +} + +static int cap11xx_register_leds (struct device *dev,struct cap11xx_priv *priv) +{ +int ret; +int i; + +/* +* Be sure all LEDS are in off-state +*/ +regmap_update_bits (priv->regmap, +CAP11XX_REG_LED_OUTPUT_CONTROL ,0xff ,0 ); + +for (i =0 ; i < priv->num_leds; i++) { +struct cap11xx_led *led = &priv->leds[i]; + +snprintf (led->name,sizeof (led->name),"cap11xx:led%d" , i +1 ); + led->cdev.name = led->name; + led->cdev.brightness_set = cap11xx_led_set; + led->cdev.brightness =LED_OFF ; + led->cdev.max_brightness =1 ; + led->id = i; + led->priv = priv; + + ret =devm_led_classdev_register (dev, &led->cdev); +if (ret <0 ) +return ret; + +INIT_WORK (&led->work, cap11xx_led_work); + }; +return 0 ; +} +#endif +static int cap11xx_i2c_probe (struct i2c_client *i2c_client,const struct i2c_device_id *id) {@@ -316,6 +388,18 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, priv->idev->open = cap11xx_input_open; priv->idev->close = cap11xx_input_close; +#ifdef CONFIG_LEDS_CLASS +if (cap->num_leds >0 ) { + priv->leds =devm_kcalloc (dev, cap->num_leds, +sizeof (struct cap11xx_led ),GFP_KERNEL ); +if (!priv->leds) +return -ENOMEM ; + priv->num_leds = cap->num_leds; + error =cap11xx_register_leds (dev, priv); +if (error) +return error; + } +#endif input_set_drvdata (priv->idev, priv);/*
Signature · 2 lines
Best Regards, Jacek Anaszewski
Quoted 102 lines · Jacek Anaszewski
Hi Matt,
Quoted 16 lines · Matt Ranostay
Several cap11xx variants have LEDs that be can be controlled, this patchset implements this functionality.
Signed-off-by Matt Ranostay <[email protected]>--- drivers/input/keyboard/cap11xx.c | 90 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)drivers/input/keyboard/cap11xx.c +0
-0drivers/input/keyboard/cap11xx.c line 18
Quoted 7 lines
drivers/input/keyboard/cap11xx.c +1
-0@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/of_irq.h> #include <linux/regmap.h> #include <linux/i2c.h> These include directives aren't arranged in an alphabetical order. You could fix that as you are modifying this file.
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +2
-0@@ -47,6 +48,8 @@#define CAP11XX_REG_CONFIG2 0x44#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6)#define CAP11XX_REG_SENSOR_BASE_CNT (X ) (0x50 + (X)) +#define CAP11XX_REG_LED_POLARITY 0x73 +#define CAP11XX_REG_LED_OUTPUT_CONTROL 0x74#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X))#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xbadrivers/input/keyboard/cap11xx.c line 67
Quoted 9 lines
drivers/input/keyboard/cap11xx.c +6
-0@@ -56,10 +59,25 @@#define CAP11XX_MANUFACTURER_ID 0x5d +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led { + struct cap11xx_priv *priv; + struct led_classdev cdev; + struct work_struct work; + char name[32];This 'name' field is not needed. Instead the 'name' field of struct
led_classdevshould be initialized with the address of either a 'label' property from DT child node representing a LED, or the DT child node name if the label is absent. Please refer toDocumentation/devicetree/bindings/leds/common.txt.This is usually accomplished in the LED subsystem with following instruction:
led_cdev->name=of_get_property(child_node, "label", NULL)? :child_node->name;Quoted 36 lines
drivers/input/keyboard/cap11xx.c +13
-3+int id; + enum led_brightness new_brightness; +}; +#endif +struct cap11xx_priv {struct regmap *regmap;struct input_dev *idev; +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led *leds; +int num_leds; +#endif /* config */ u32 keycodes[]; };@@ -67,6 +85,7 @@ struct cap11xx_priv {struct cap11xx_hw_model {u8 product_id;unsigned int num_channels; +unsigned int num_leds; };enum {@@ -76,9 +95,9 @@ enum { };static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106 ] = { .product_id =0x55 , .num_channels =6 }, - [CAP1126 ] = { .product_id =0x53 , .num_channels =6 }, - [CAP1188 ] = { .product_id =0x50 , .num_channels =8 }, + [CAP1106 ] = { .product_id =0x55 , .num_channels =6 , .num_leds =0 }, + [CAP1126 ] = { .product_id =0x53 , .num_channels =6 , .num_leds =2 }, + [CAP1188 ] = { .product_id =0x50 , .num_channels =8 , .num_leds =8
Quoted 9 lines
Quoted 2 lines
drivers/input/keyboard/cap11xx.c +0
-0},};The number of LEDs should be determined by the number of DT child nodes representing each LED. Please refer to
Documentation/devicetree/bindings/leds/common.txtand other LED subsystem drivers to find out how it should be implemented.
Ok but this is still needed as a check so you don't "overflow" the number the chipset supports, correct?
Quoted 102 lines
Quoted 95 lines
static const struct reg_default cap11xx_reg_defaults[] = {drivers/input/keyboard/cap11xx.c +1
-0@@ -111,6 +130,7 @@ static const struct reg_default cap11xx_reg_defaults[] = { { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, { CAP11XX_REG_STANDBY_THRESH, 0x40 }, { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_LED_POLARITY, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 },};drivers/input/keyboard/cap11xx.c +21
-0@@ -196,6 +216,58 @@ static void cap11xx_input_close(struct input_dev *idev)cap11xx_set_sleep (priv, true); } +#ifdef CONFIG_LEDS_CLASS +static void cap11xx_led_work (struct work_struct *work) +{ + struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); +struct cap11xx_priv *priv = led->priv; +int value = led->new_brightness; + +regmap_update_bits (priv->regmap,CAP11XX_REG_LED_OUTPUT_CONTROL , +BIT (led->id), !!value ?BIT (led->id) :0 ); +} + +static void cap11xx_led_set (struct led_classdev *cdev, +enum led_brightness value) +{ + struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); + + led->new_brightness = value; +schedule_work (&led->work); +} + +static int cap11xx_register_leds(struct device *dev, struct cap11xx_priv*priv)
drivers/input/keyboard/cap11xx.c +44
-0+{ +int ret; +int i; + +/* +* Be sure all LEDS are in off-state +*/ +regmap_update_bits (priv->regmap, +CAP11XX_REG_LED_OUTPUT_CONTROL ,0xff ,0 ); + +for (i =0 ; i < priv->num_leds; i++) { +struct cap11xx_led *led = &priv->leds[i]; + +snprintf (led->name,sizeof (led->name),"cap11xx:led%d" , i + 1); + led->cdev.name = led->name; + led->cdev.brightness_set = cap11xx_led_set; + led->cdev.brightness =LED_OFF ; + led->cdev.max_brightness =1 ; + led->id = i; + led->priv = priv; + + ret =devm_led_classdev_register (dev, &led->cdev); +if (ret <0 ) +return ret; + +INIT_WORK (&led->work, cap11xx_led_work); + }; +return 0 ; +} +#endif +static int cap11xx_i2c_probe (struct i2c_client *i2c_client,const struct i2c_device_id *id) {@@ -316,6 +388,18 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, priv->idev->open = cap11xx_input_open; priv->idev->close = cap11xx_input_close; +#ifdef CONFIG_LEDS_CLASS +if (cap->num_leds >0 ) { + priv->leds =devm_kcalloc (dev, cap->num_leds, +sizeof (struct cap11xx_led ),GFP_KERNEL ); +if (!priv->leds) +return -ENOMEM ; + priv->num_leds = cap->num_leds; + error =cap11xx_register_leds (dev, priv); +if (error) +return error; + } +#endif input_set_drvdata (priv->idev, priv);Quoted 2 lines
/*--
Best Regards,
Jacek Anaszewski
On 06/11/2015 12:07 AM, Matt Ranostay wrote:
[...]
Quoted 13 lines
Quoted 13 lines
Quoted 11 lines
static const struct cap11xx_hw_model cap11xx_devices[] = {drivers/input/keyboard/cap11xx.c +1
-3- [CAP1106] = { .product_id = 0x55, .num_channels = 6 }, - [CAP1126] = { .product_id = 0x53, .num_channels = 6 }, - [CAP1188] = { .product_id = 0x50, .num_channels = 8 }, + [CAP1106] = { .product_id = 0x55, .num_channels = 6, .num_leds = 0},
+ [CAP1126] = { .product_id =0x53, .num_channels = 6, .num_leds = 2
},
+ [CAP1188] = { .product_id =0x50, .num_channels = 8, .num_leds = 8
},
};
Quoted 7 lines
Quoted 5 lines
The number of LEDs should be determined by the number of DT child nodes representing each LED. Please refer to
Documentation/devicetree/bindings/leds/common.txtand other LED subsystem drivers to find out how it should be implemented.Ok but this is still needed as a check so you don't "overflow" the number the chipset supports, correct?
Right, the above modification is correct then.
Signature · 2 lines
Best Regards, Jacek Anaszewski
Dmitry Torokhov
maintainerHi Matt,
Quoted 87 lines · Matt Ranostay
Several cap11xx variants have LEDs that be can be controlled, this patchset implements this functionality.
Signed-off-by Matt Ranostay <[email protected]>--- drivers/input/keyboard/cap11xx.c | 90 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)drivers/input/keyboard/cap11xx.c +23
-3@@ -12,6 +12,7 @@#include <linux/module.h> #include <linux/interrupt.h> #include <linux/input.h> +#include <linux/leds.h> #include <linux/of_irq.h> #include <linux/regmap.h> #include <linux/i2c.h> @@ -47,6 +48,8 @@#define CAP11XX_REG_CONFIG2 0x44#define CAP11XX_REG_CONFIG2_ALT_POL BIT(6)#define CAP11XX_REG_SENSOR_BASE_CNT (X ) (0x50 + (X)) +#define CAP11XX_REG_LED_POLARITY 0x73 +#define CAP11XX_REG_LED_OUTPUT_CONTROL 0x74#define CAP11XX_REG_SENSOR_CALIB (0xb1 + (X))#define CAP11XX_REG_SENSOR_CALIB_LSB1 0xb9#define CAP11XX_REG_SENSOR_CALIB_LSB2 0xba@@ -56,10 +59,25 @@#define CAP11XX_MANUFACTURER_ID 0x5d +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led { +struct cap11xx_priv *priv; +struct led_classdev cdev; +struct work_struct work; +char name[32 ]; +int id; +enum led_brightness new_brightness; +}; +#endif +struct cap11xx_priv {struct regmap *regmap;struct input_dev *idev; +#ifdef CONFIG_LEDS_CLASS +struct cap11xx_led *leds; +int num_leds; +#endif /* config */ u32 keycodes[]; };@@ -67,6 +85,7 @@ struct cap11xx_priv {struct cap11xx_hw_model {u8 product_id;unsigned int num_channels; +unsigned int num_leds; };enum {@@ -76,9 +95,9 @@ enum { };static const struct cap11xx_hw_model cap11xx_devices[] = { - [CAP1106 ] = { .product_id =0x55 , .num_channels =6 }, - [CAP1126 ] = { .product_id =0x53 , .num_channels =6 }, - [CAP1188 ] = { .product_id =0x50 , .num_channels =8 }, + [CAP1106 ] = { .product_id =0x55 , .num_channels =6 , .num_leds =0 }, + [CAP1126 ] = { .product_id =0x53 , .num_channels =6 , .num_leds =2 }, + [CAP1188 ] = { .product_id =0x50 , .num_channels =8 , .num_leds =8 }, };static const struct reg_default cap11xx_reg_defaults[] = {@@ -111,6 +130,7 @@ static const struct reg_default cap11xx_reg_defaults[] = { { CAP11XX_REG_STANDBY_SENSITIVITY, 0x02 }, { CAP11XX_REG_STANDBY_THRESH, 0x40 }, { CAP11XX_REG_CONFIG2, 0x40 }, + { CAP11XX_REG_LED_POLARITY, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB1, 0x00 }, { CAP11XX_REG_SENSOR_CALIB_LSB2, 0x00 }, };@@ -196,6 +216,58 @@ static void cap11xx_input_close(struct input_dev *idev)cap11xx_set_sleep (priv, true); }
drivers/input/keyboard/cap11xx.c static void cap11xx_input_close(struct input_dev *idev) · line 227
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +9
-0+#ifdef CONFIG_LEDS_CLASS +static void cap11xx_led_work (struct work_struct *work) +{ + struct cap11xx_led *led = container_of(work, struct cap11xx_led, work); +struct cap11xx_priv *priv = led->priv; +int value = led->new_brightness; + +regmap_update_bits (priv->regmap,CAP11XX_REG_LED_OUTPUT_CONTROL , +BIT (led->id), !!value ?BIT (led->id) :0 );
Why do we need to convert value to bool before doing the tertiary operation?
Quoted 4 lines
drivers/input/keyboard/cap11xx.c +4
-0+} + +static void cap11xx_led_set (struct led_classdev *cdev, +enum led_brightness value)
drivers/input/keyboard/cap11xx.c static void cap11xx_input_close(struct input_dev *idev) · line 241
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +10
-0+{ + struct cap11xx_led *led = container_of(cdev, struct cap11xx_led, cdev); + + led->new_brightness = value; +schedule_work (&led->work); +} + +static int cap11xx_register_leds (struct device *dev,struct cap11xx_priv *priv) +{ +int ret;
Let's call it "error" please.
Quoted 14 lines
drivers/input/keyboard/cap11xx.c +14
-0+int i; + +/* +* Be sure all LEDS are in off-state +*/ +regmap_update_bits (priv->regmap, +CAP11XX_REG_LED_OUTPUT_CONTROL ,0xff ,0 ); + +for (i =0 ; i < priv->num_leds; i++) { +struct cap11xx_led *led = &priv->leds[i]; + +snprintf (led->name,sizeof (led->name),"cap11xx:led%d" , i +1 ); + led->cdev.name = led->name; + led->cdev.brightness_set = cap11xx_led_set;
drivers/input/keyboard/cap11xx.c static void cap11xx_input_close(struct input_dev *idev) · line 265
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +10
-0+ led->cdev.brightness =LED_OFF ; + led->cdev.max_brightness =1 ; + led->id = i; + led->priv = priv; + + ret =devm_led_classdev_register (dev, &led->cdev); +if (ret <0 ) +return ret; + +INIT_WORK (&led->work, cap11xx_led_work);
This is too late, request may come even before you return from devm_led_classdev_register. Please move to a spot above.
drivers/input/keyboard/cap11xx.c static void cap11xx_input_close(struct input_dev *idev) · line 266
Quoted 1 line
drivers/input/keyboard/cap11xx.c +1
-0+ };
A stray semicolon.
Quoted 13 lines
drivers/input/keyboard/cap11xx.c +6
-0+ return 0; +} +#endif +static int cap11xx_i2c_probe (struct i2c_client *i2c_client,const struct i2c_device_id *id) {@@ -316,6 +388,18 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client, priv->idev->open = cap11xx_input_open; priv->idev->close = cap11xx_input_close; +#ifdef CONFIG_LEDS_CLASS +if (cap->num_leds >0 ) {
drivers/input/keyboard/cap11xx.c static int cap11xx_i2c_probe(struct i2c_client *i2c_client, · line 402
Quoted 10 lines
drivers/input/keyboard/cap11xx.c +10
-0+ priv->leds =devm_kcalloc (dev, cap->num_leds, +sizeof (struct cap11xx_led ),GFP_KERNEL ); +if (!priv->leds) +return -ENOMEM ; + priv->num_leds = cap->num_leds; + error =cap11xx_register_leds (dev, priv); +if (error) + return error; + } +#endif
Instead of inline #ifdef would prefer you moved memory allocation into cap11xx_register_leds() and stub it out of leds are disabled.
Quoted 6 lines
drivers/input/keyboard/cap11xx.c +0
-0input_set_drvdata (priv->idev, priv);/* Signature · 1 line
1.9.1
Thanks.
Signature · 1 line
Dmitry