All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] input: cap11xx: plasma globe proof
@ 2019-12-29 19:21 Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 1/6] cap11xx: set device driver_data Kurt Van Dijck
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can

Hey,

I built a raspberry-pi wakeup for my kids. Recently, one of them bought
a plasma globe. That globe leaves an electrostatic field that disturbes
the cap11xx when it operates with default settings.
So I grabbed the datasheet and started modifying the configuration.
This is the result that should apply to other scenarios as well.

The patch series improves the cap11xx in 2 ways.
It adds support for a cap1208 as on the explorer hat of Pimoroni,
and allows to run in polling mode (the explorer hat omitted the irq,
or I didn't find it).
It then exposes the major configuration parts of the chip so one can
tune it to her/his needs.

Please feel free to comment

Kind regards,
Kurt


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] cap11xx: set device driver_data
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 2/6] cap11xx: support cap1208 Kurt Van Dijck
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 688e2be..16287ab 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -346,6 +346,8 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	if (!priv)
 		return -ENOMEM;
 
+	i2c_set_clientdata(i2c_client, priv);
+
 	priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config);
 	if (IS_ERR(priv->regmap))
 		return PTR_ERR(priv->regmap);
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/6] cap11xx: support cap1208
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 1/6] cap11xx: set device driver_data Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 3/6] cap11xx: polling mode without irq Kurt Van Dijck
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 16287ab..092dcd2 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -97,12 +97,14 @@ enum {
 	CAP1106,
 	CAP1126,
 	CAP1188,
+	CAP1208,
 };
 
 static const struct cap11xx_hw_model cap11xx_devices[] = {
 	[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 },
+	[CAP1208] = { .product_id = 0x6b, .num_channels = 8, .num_leds = 0 },
 };
 
 static const struct reg_default cap11xx_reg_defaults[] = {
@@ -472,6 +474,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	{ .compatible = "microchip,cap1106", },
 	{ .compatible = "microchip,cap1126", },
 	{ .compatible = "microchip,cap1188", },
+	{ .compatible = "microchip,cap1208", },
 	{}
 };
 MODULE_DEVICE_TABLE(of, cap11xx_dt_ids);
@@ -480,6 +483,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	{ "cap1106", CAP1106 },
 	{ "cap1126", CAP1126 },
 	{ "cap1188", CAP1188 },
+	{ "cap1208", CAP1208 },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, cap11xx_i2c_ids);
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/6] cap11xx: polling mode without irq
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 1/6] cap11xx: set device driver_data Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 2/6] cap11xx: support cap1208 Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 4/6] cap11xx: add register definition for LED_LINK Kurt Van Dijck
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 49 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 45 insertions(+), 4 deletions(-)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 092dcd2..5a7eaed 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/input.h>
+#include <linux/kthread.h>
 #include <linux/leds.h>
 #include <linux/of_irq.h>
 #include <linux/regmap.h>
@@ -78,6 +79,7 @@ struct cap11xx_led {
 
 struct cap11xx_priv {
 	struct regmap *regmap;
+	struct task_struct *poll_thread;
 	struct input_dev *idev;
 
 	struct cap11xx_led *leds;
@@ -202,6 +204,24 @@ static irqreturn_t cap11xx_thread_func(int irq_num, void *data)
 	return IRQ_HANDLED;
 }
 
+static int poll_irq(void *data) {
+
+	struct cap11xx_priv *priv = data;
+	int ret;
+	unsigned int status;
+
+	/* until module unload */
+	while (!kthread_should_stop()) {
+		ret = regmap_read(priv->regmap, CAP11XX_REG_MAIN_CONTROL, &status);
+		if (ret >= 0 && (status & 1))
+			cap11xx_thread_func(-1, priv);
+		usleep_range(15000, 25000);
+	}
+
+	return 0;
+}
+
+
 static int cap11xx_set_sleep(struct cap11xx_priv *priv, bool sleep)
 {
 	/*
@@ -320,6 +340,17 @@ static int cap11xx_init_leds(struct device *dev,
 }
 #endif
 
+static int cap11xx_i2c_remove(struct i2c_client *i2c_client)
+{
+	struct cap11xx_priv *priv = i2c_get_clientdata(i2c_client);
+
+	if (priv->poll_thread) {
+		kthread_stop(priv->poll_thread);
+		mdelay(10);
+	}
+	return 0;
+}
+
 static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 			     const struct i2c_device_id *id)
 {
@@ -348,8 +379,6 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	if (!priv)
 		return -ENOMEM;
 
-	i2c_set_clientdata(i2c_client, priv);
-
 	priv->regmap = devm_regmap_init_i2c(i2c_client, &cap11xx_regmap_config);
 	if (IS_ERR(priv->regmap))
 		return PTR_ERR(priv->regmap);
@@ -458,8 +487,19 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 
 	irq = irq_of_parse_and_map(node, 0);
 	if (!irq) {
-		dev_err(dev, "Unable to parse or map IRQ\n");
-		return -ENXIO;
+		if (!of_property_read_bool(node, "linux,irq-poll")) {
+			dev_err(dev, "Unable to parse or map IRQ\n");
+			return -ENXIO;
+		}
+		dev_info(dev, "IRQ failed or undefined, using poll_thread\n");
+		priv->poll_thread = kthread_create(poll_irq, priv, "%s-%s-poll",
+				id->name, dev_name(dev));
+		if (!priv->poll_thread) {
+			dev_err(dev, "Unable to start poll_thread\n");
+			return -ENXIO;
+		}
+		wake_up_process(priv->poll_thread);
+		return 0;
 	}
 
 	error = devm_request_threaded_irq(dev, irq, NULL, cap11xx_thread_func,
@@ -495,6 +535,7 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	},
 	.id_table	= cap11xx_i2c_ids,
 	.probe		= cap11xx_i2c_probe,
+	.remove		= cap11xx_i2c_remove,
 };
 
 module_i2c_driver(cap11xx_i2c_driver);
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/6] cap11xx: add register definition for LED_LINK
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
                   ` (2 preceding siblings ...)
  2019-12-29 19:21 ` [PATCH 3/6] cap11xx: polling mode without irq Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 5/6] cap11xx: enable all 8 inputs Kurt Van Dijck
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index 5a7eaed..b666e9e 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -46,6 +46,7 @@
 #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_SENSOR_LED_LINK	0x72
 #define CAP11XX_REG_LED_POLARITY	0x73
 #define CAP11XX_REG_LED_OUTPUT_CONTROL	0x74
 
@@ -139,6 +140,7 @@ enum {
 	{ CAP11XX_REG_STANDBY_SENSITIVITY,	0x02 },
 	{ CAP11XX_REG_STANDBY_THRESH,		0x40 },
 	{ CAP11XX_REG_CONFIG2,			0x40 },
+	{ CAP11XX_REG_SENSOR_LED_LINK,		0x00 },
 	{ CAP11XX_REG_LED_POLARITY,		0x00 },
 	{ CAP11XX_REG_SENSOR_CALIB_LSB1,	0x00 },
 	{ CAP11XX_REG_SENSOR_CALIB_LSB2,	0x00 },
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/6] cap11xx: enable all 8 inputs
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
                   ` (3 preceding siblings ...)
  2019-12-29 19:21 ` [PATCH 4/6] cap11xx: add register definition for LED_LINK Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2019-12-29 19:21 ` [PATCH 6/6] cap11xx: export major chip settings to sysfs Kurt Van Dijck
  2020-01-09 20:03 ` [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index b666e9e..cdcc89b9 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -117,13 +117,13 @@ enum {
 	{ CAP11XX_REG_NOISE_FLAG_STATUS,	0x00 },
 	{ CAP11XX_REG_SENSITIVITY_CONTROL,	0x2f },
 	{ CAP11XX_REG_CONFIG,			0x20 },
-	{ CAP11XX_REG_SENSOR_ENABLE,		0x3f },
+	{ CAP11XX_REG_SENSOR_ENABLE,		0xff },
 	{ CAP11XX_REG_SENSOR_CONFIG,		0xa4 },
 	{ CAP11XX_REG_SENSOR_CONFIG2,		0x07 },
 	{ CAP11XX_REG_SAMPLING_CONFIG,		0x39 },
 	{ CAP11XX_REG_CALIBRATION,		0x00 },
-	{ CAP11XX_REG_INT_ENABLE,		0x3f },
-	{ CAP11XX_REG_REPEAT_RATE,		0x3f },
+	{ CAP11XX_REG_INT_ENABLE,		0xff },
+	{ CAP11XX_REG_REPEAT_RATE,		0xff },
 	{ CAP11XX_REG_MT_CONFIG,		0x80 },
 	{ CAP11XX_REG_MT_PATTERN_CONFIG,	0x00 },
 	{ CAP11XX_REG_MT_PATTERN,		0x3f },
@@ -134,6 +134,8 @@ enum {
 	{ CAP11XX_REG_SENSOR_THRESH(3),		0x40 },
 	{ CAP11XX_REG_SENSOR_THRESH(4),		0x40 },
 	{ CAP11XX_REG_SENSOR_THRESH(5),		0x40 },
+	{ CAP11XX_REG_SENSOR_THRESH(6),		0x40 },
+	{ CAP11XX_REG_SENSOR_THRESH(7),		0x40 },
 	{ CAP11XX_REG_SENSOR_NOISE_THRESH,	0x01 },
 	{ CAP11XX_REG_STANDBY_CHANNEL,		0x00 },
 	{ CAP11XX_REG_STANDBY_CONFIG,		0x39 },
@@ -157,6 +159,8 @@ static bool cap11xx_volatile_reg(struct device *dev, unsigned int reg)
 	case CAP11XX_REG_SENOR_DELTA(3):
 	case CAP11XX_REG_SENOR_DELTA(4):
 	case CAP11XX_REG_SENOR_DELTA(5):
+	case CAP11XX_REG_SENOR_DELTA(6):
+	case CAP11XX_REG_SENOR_DELTA(7):
 	case CAP11XX_REG_PRODUCT_ID:
 	case CAP11XX_REG_MANUFACTURER_ID:
 	case CAP11XX_REG_REVISION:
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/6] cap11xx: export major chip settings to sysfs
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
                   ` (4 preceding siblings ...)
  2019-12-29 19:21 ` [PATCH 5/6] cap11xx: enable all 8 inputs Kurt Van Dijck
@ 2019-12-29 19:21 ` Kurt Van Dijck
  2020-01-09 20:03 ` [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2019-12-29 19:21 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can, Kurt Van Dijck

Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be>
---
 drivers/input/keyboard/cap11xx.c | 161 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 161 insertions(+)

diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c
index cdcc89b9..eb68efc 100644
--- a/drivers/input/keyboard/cap11xx.c
+++ b/drivers/input/keyboard/cap11xx.c
@@ -346,6 +346,159 @@ static int cap11xx_init_leds(struct device *dev,
 }
 #endif
 
+/* register attribute:
+ * create a simple way to export properties in the register map
+ */
+struct register_attribute {
+	struct device_attribute dev_attr;
+	int reg;
+	int mask;
+	int shift;
+};
+#define to_reg_attr(_dev_attr) container_of((dev_attr), \
+		struct register_attribute, dev_attr)
+#define to_dev_attr(_attr) container_of(attr, struct device_attribute, attr)
+
+static ssize_t show_reg_attr(struct device *dev, struct device_attribute *attr,
+		char *buf)
+{
+	struct cap11xx_priv *priv = dev_get_drvdata(dev);
+	struct register_attribute *rattr = to_reg_attr(attr);
+	int ret, value;
+
+	ret = regmap_read(priv->regmap, rattr->reg, &value);
+	if (ret < 0)
+		return ret;
+	return sprintf(buf, "0x%02x\n", (value >> rattr->shift) & rattr->mask);
+}
+
+static ssize_t store_reg_attr(struct device *dev, struct device_attribute * attr,
+		const char *buf, size_t len)
+{
+	struct cap11xx_priv *priv = dev_get_drvdata(dev);
+	struct register_attribute *rattr = to_reg_attr(attr);
+	int ret;
+	long value;
+
+	ret = kstrtoul(buf, 0, &value);
+	if (ret)
+		return ret;
+
+	if (value & ~rattr->mask)
+		return -ERANGE;
+
+	ret = regmap_update_bits(priv->regmap, rattr->reg,
+			rattr->mask << rattr->shift, value << rattr->shift);
+	if (ret)
+		return ret;
+	return len;
+}
+
+#define REG_ATTR(_name, _mode, _reg, _nbits, _shift) \
+	struct register_attribute reg_dev_attr_##_name = { \
+		__ATTR(_name, _mode, show_reg_attr, store_reg_attr), \
+		.reg = _reg, \
+		.mask = (1 << (_nbits)) -1, \
+		.shift = _shift, \
+	}
+#define TO_ATTR(_name) (&(reg_dev_attr_##_name).dev_attr.attr)
+
+static REG_ATTR(gain, 0644, CAP11XX_REG_MAIN_CONTROL, 2, 6);
+static REG_ATTR(delta_sense, 0644, CAP11XX_REG_SENSITIVITY_CONTROL, 3, 4);
+static REG_ATTR(base_shift, 0644, CAP11XX_REG_SENSITIVITY_CONTROL, 4, 0);
+static REG_ATTR(dis_dig_noise, 0644, CAP11XX_REG_CONFIG, 1, 5);
+static REG_ATTR(dis_ana_noise, 0644, CAP11XX_REG_CONFIG, 1, 4);
+static REG_ATTR(max_dur_enable, 0644, CAP11XX_REG_CONFIG, 1, 3);
+static REG_ATTR(cs_en, 0644, CAP11XX_REG_SENSOR_ENABLE, 8, 0);
+static REG_ATTR(max_dur, 0644, CAP11XX_REG_SENSOR_CONFIG, 4, 4);
+static REG_ATTR(avg, 0644, CAP11XX_REG_SAMPLING_CONFIG, 3, 4);
+static REG_ATTR(samp_time, 0644, CAP11XX_REG_SAMPLING_CONFIG, 2, 2);
+static REG_ATTR(cycle_time, 0644, CAP11XX_REG_SAMPLING_CONFIG, 2, 0);
+static REG_ATTR(mulkt_blk_en, 0644, CAP11XX_REG_MT_CONFIG, 1, 7);
+static REG_ATTR(b_mult_t, 0644, CAP11XX_REG_MT_CONFIG, 2, 2);
+static REG_ATTR(mtp_en, 0644, CAP11XX_REG_MT_PATTERN_CONFIG, 1, 7);
+static REG_ATTR(mtp_th, 0644, CAP11XX_REG_MT_PATTERN_CONFIG, 2, 2);
+static REG_ATTR(comp_ptrn, 0644, CAP11XX_REG_MT_PATTERN_CONFIG, 1, 1);
+static REG_ATTR(cs_ptrn, 0644, CAP11XX_REG_MT_PATTERN, 8, 0);
+static REG_ATTR(cs_th1, 0644, CAP11XX_REG_SENSOR_THRESH(0), 8, 0);
+static REG_ATTR(cs_th2, 0644, CAP11XX_REG_SENSOR_THRESH(1), 8, 0);
+static REG_ATTR(cs_th3, 0644, CAP11XX_REG_SENSOR_THRESH(2), 8, 0);
+static REG_ATTR(cs_th4, 0644, CAP11XX_REG_SENSOR_THRESH(3), 8, 0);
+static REG_ATTR(cs_th5, 0644, CAP11XX_REG_SENSOR_THRESH(4), 8, 0);
+static REG_ATTR(cs_th6, 0644, CAP11XX_REG_SENSOR_THRESH(5), 8, 0);
+static REG_ATTR(cs_th7, 0644, CAP11XX_REG_SENSOR_THRESH(6), 8, 0);
+static REG_ATTR(cs_th8, 0644, CAP11XX_REG_SENSOR_THRESH(7), 8, 0);
+static REG_ATTR(cs_bn_th, 0644, CAP11XX_REG_SENSOR_NOISE_THRESH, 2, 0);
+static REG_ATTR(cs_led, 0644, CAP11XX_REG_SENSOR_LED_LINK, 8, 0);
+
+static struct attribute *reg_attrs[] = {
+	TO_ATTR(gain),
+	TO_ATTR(delta_sense),
+	TO_ATTR(base_shift),
+	TO_ATTR(dis_dig_noise),
+	TO_ATTR(dis_ana_noise),
+	TO_ATTR(max_dur_enable),
+	TO_ATTR(cs_en),
+	TO_ATTR(max_dur),
+	TO_ATTR(avg),
+	TO_ATTR(samp_time),
+	TO_ATTR(cycle_time),
+	TO_ATTR(mulkt_blk_en),
+	TO_ATTR(b_mult_t),
+	TO_ATTR(mtp_en),
+	TO_ATTR(mtp_th),
+	TO_ATTR(comp_ptrn),
+	TO_ATTR(cs_ptrn),
+	TO_ATTR(cs_th1),
+	TO_ATTR(cs_th2),
+	TO_ATTR(cs_th3),
+	TO_ATTR(cs_th4),
+	TO_ATTR(cs_th5),
+	TO_ATTR(cs_th6),
+	TO_ATTR(cs_th7),
+	TO_ATTR(cs_th8),
+	TO_ATTR(cs_bn_th),
+	TO_ATTR(cs_led),
+	NULL,
+};
+
+static const struct attribute_group reg_attr_group = {
+	.name = "reg",
+	.attrs = reg_attrs,
+};
+
+/* load register properties from OF */
+static int cap11xx_load_regs_from_of(struct device *dev)
+{
+	struct cap11xx_priv *priv = dev_get_drvdata(dev);
+	struct attribute **attr;
+	struct register_attribute *rattr;
+	char name[32];
+	int ret, value;
+
+	for (attr = reg_attrs; *attr; ++attr) {
+		rattr = to_reg_attr(to_dev_attr(*attr));
+
+		sprintf(name, "reg,%s", rattr->dev_attr.attr.name);
+		ret = of_property_read_u32(dev->of_node, name, &value);
+		if (ret)
+			continue;
+		if (value & ~rattr->mask) {
+			dev_warn(dev, "of %s: value %u, max %u\n",
+					name, value, rattr->mask);
+			continue;
+		}
+		ret = regmap_update_bits(priv->regmap, rattr->reg,
+				rattr->mask << rattr->shift,
+				value << rattr->shift);
+		if (ret) {
+			dev_err(dev, "of %s, regmap returned %i\n", name, ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
 static int cap11xx_i2c_remove(struct i2c_client *i2c_client)
 {
 	struct cap11xx_priv *priv = i2c_get_clientdata(i2c_client);
@@ -430,6 +583,10 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 			return error;
 	}
 
+	error = cap11xx_load_regs_from_of(dev);
+	if (error)
+		return error;
+
 	/* Provide some useful defaults */
 	for (i = 0; i < cap->num_channels; i++)
 		priv->keycodes[i] = KEY_A + i;
@@ -491,6 +648,10 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
 	if (error)
 		return error;
 
+	error = devm_device_add_group(dev, &reg_attr_group);
+	if (error)
+		return error;
+
 	irq = irq_of_parse_and_map(node, 0);
 	if (!irq) {
 		if (!of_property_read_bool(node, "linux,irq-poll")) {
-- 
1.8.5.rc3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC] input: cap11xx: plasma globe proof
  2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
                   ` (5 preceding siblings ...)
  2019-12-29 19:21 ` [PATCH 6/6] cap11xx: export major chip settings to sysfs Kurt Van Dijck
@ 2020-01-09 20:03 ` Kurt Van Dijck
  6 siblings, 0 replies; 8+ messages in thread
From: Kurt Van Dijck @ 2020-01-09 20:03 UTC (permalink / raw)
  To: linux-input; +Cc: linux-can

Ping?

On zo, 29 dec 2019 20:21:11 +0100, Kurt Van Dijck wrote:
> Hey,
> 
> I built a raspberry-pi wakeup for my kids. Recently, one of them bought
> a plasma globe. That globe leaves an electrostatic field that disturbes
> the cap11xx when it operates with default settings.
> So I grabbed the datasheet and started modifying the configuration.
> This is the result that should apply to other scenarios as well.
> 
> The patch series improves the cap11xx in 2 ways.
> It adds support for a cap1208 as on the explorer hat of Pimoroni,
> and allows to run in polling mode (the explorer hat omitted the irq,
> or I didn't find it).
> It then exposes the major configuration parts of the chip so one can
> tune it to her/his needs.
> 
> Please feel free to comment
> 
> Kind regards,
> Kurt
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-01-09 20:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-29 19:21 [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 1/6] cap11xx: set device driver_data Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 2/6] cap11xx: support cap1208 Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 3/6] cap11xx: polling mode without irq Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 4/6] cap11xx: add register definition for LED_LINK Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 5/6] cap11xx: enable all 8 inputs Kurt Van Dijck
2019-12-29 19:21 ` [PATCH 6/6] cap11xx: export major chip settings to sysfs Kurt Van Dijck
2020-01-09 20:03 ` [RFC] input: cap11xx: plasma globe proof Kurt Van Dijck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.