Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 14/22] Input: atmel_mxt_ts - read and report bootloader version
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 09f8b18..1ed3804 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -202,6 +202,8 @@
 #define MXT_FRAME_CRC_PASS	0x04
 #define MXT_APP_CRC_FAIL	0x40	/* valid 7 8 bit only */
 #define MXT_BOOT_STATUS_MASK	0x3f
+#define MXT_BOOT_EXTENDED_ID	(1 << 5)
+#define MXT_BOOT_ID_MASK	0x1f
 
 /* Touch status */
 #define MXT_UNGRIP		(1 << 0)
@@ -422,6 +424,27 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data)
 	return 0;
 }
 
+static u8 mxt_get_bootloader_version(struct mxt_data *data, u8 val)
+{
+	struct device *dev = &data->client->dev;
+	u8 buf[3];
+
+	if (val & MXT_BOOT_EXTENDED_ID) {
+		if (mxt_bootloader_read(data, &buf[0], 3) != 0) {
+			dev_err(dev, "%s: i2c failure\n", __func__);
+			return -EIO;
+		}
+
+		dev_dbg(dev, "Bootloader ID:%d Version:%d\n", buf[1], buf[2]);
+
+		return buf[0];
+	} else {
+		dev_dbg(dev, "Bootloader ID:%d\n", val & MXT_BOOT_ID_MASK);
+
+		return val;
+	}
+}
+
 static int mxt_check_bootloader(struct mxt_data *data, unsigned int state)
 {
 	struct device *dev = &data->client->dev;
@@ -454,6 +477,9 @@ recheck:
 	if (ret)
 		return ret;
 
+	if (state == MXT_WAITING_BOOTLOAD_CMD)
+		val = mxt_get_bootloader_version(data, val);
+
 	switch (state) {
 	case MXT_WAITING_BOOTLOAD_CMD:
 	case MXT_WAITING_FRAME_DATA:
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 16/22] Input: atmel_mxt_ts - improve bootloader progress output
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

By implementing a frame counter, print out fewer debug messages (the
firmware may contain hundreds of frames).

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 049d48a..b263ec3 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1432,6 +1432,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 	unsigned int frame_size;
 	unsigned int pos = 0;
 	unsigned int retry = 0;
+	unsigned int frame = 0;
 	int ret;
 
 	ret = request_firmware(&fw, fn, dev);
@@ -1491,9 +1492,12 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 		} else {
 			retry = 0;
 			pos += frame_size;
+			frame++;
 		}
 
-		dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
+		if (frame % 50 == 0)
+			dev_dbg(dev, "Sent %d frames, %d/%zd bytes\n",
+				frame, pos, fw->size);
 	}
 
 	/* Wait for flash. */
@@ -1502,6 +1506,8 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 	if (ret)
 		goto disable_irq;
 
+	dev_dbg(dev, "Sent %d frames, %d bytes\n", frame, pos);
+
 	/*
 	 * Wait for device to reset. Some bootloader versions do not assert
 	 * the CHG line after bootloading has finished, so ignore potential
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 17/22] Input: atmel_mxt_ts - add check for incorrect firmware file format
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Atmel supplies firmware files in ASCII HEX format (.enc) which must be
converted before they can be loaded by kernel driver. Try to detect
the error and print a friendly error message rather than feeding junk
to the bootloader.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index b263ec3..b5c3f8e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1425,6 +1425,30 @@ done:
 	return error ?: count;
 }
 
+static int mxt_check_firmware_format(struct device *dev,
+				     const struct firmware *fw)
+{
+	unsigned int pos = 0;
+	char c;
+
+	while (pos < fw->size) {
+		c = *(fw->data + pos);
+
+		if (c < '0' || (c > '9' && c < 'A') || c > 'F')
+			return 0;
+
+		pos++;
+	}
+
+	/*
+	 * To convert file try:
+	 * xxd -r -p mXTXXX__APP_VX-X-XX.enc > maxtouch.fw
+	 */
+	dev_err(dev, "Aborting: firmware file must be in binary format\n");
+
+	return -EINVAL;
+}
+
 static int mxt_load_fw(struct device *dev, const char *fn)
 {
 	struct mxt_data *data = dev_get_drvdata(dev);
@@ -1441,6 +1465,11 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 		return ret;
 	}
 
+	/* Check for incorrect enc file */
+	ret = mxt_check_firmware_format(dev, fw);
+	if (ret)
+		goto release_firmware;
+
 	ret = mxt_lookup_bootloader_address(data);
 	if (ret)
 		goto release_firmware;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 18/22] Input: atmel_mxt_ts - read screen config from chip
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

By reading the touchscreen configuration from the settings that the
maXTouch chip is actually using, we can remove some platform data.

The matrix size is not used for anything, and results in some rather
confusing code to re-read it because it may change when configuration
is downloaded, so don't print it out.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 arch/arm/mach-s5pv210/mach-goni.c         |   3 -
 drivers/input/touchscreen/atmel_mxt_ts.c  | 136 ++++++++++++++----------------
 drivers/platform/chrome/chromeos_laptop.c |   6 --
 include/linux/i2c/atmel_mxt_ts.h          |  14 ---
 4 files changed, 65 insertions(+), 94 deletions(-)

diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 05b1f5c..590a0b1 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -239,9 +239,6 @@ static void __init goni_radio_init(void)
 
 /* TSP */
 static struct mxt_platform_data qt602240_platform_data = {
-	.x_size		= 800,
-	.y_size		= 480,
-	.orient		= MXT_DIAGONAL,
 	.irqflags	= IRQF_TRIGGER_FALLING,
 };
 
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index b5c3f8e..ce88ada 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -104,33 +104,16 @@
 
 /* MXT_TOUCH_MULTI_T9 field */
 #define MXT_TOUCH_CTRL		0
-#define MXT_TOUCH_XORIGIN	1
-#define MXT_TOUCH_YORIGIN	2
-#define MXT_TOUCH_XSIZE		3
-#define MXT_TOUCH_YSIZE		4
-#define MXT_TOUCH_BLEN		6
-#define MXT_TOUCH_TCHTHR	7
-#define MXT_TOUCH_TCHDI		8
-#define MXT_TOUCH_ORIENT	9
-#define MXT_TOUCH_MOVHYSTI	11
-#define MXT_TOUCH_MOVHYSTN	12
-#define MXT_TOUCH_NUMTOUCH	14
-#define MXT_TOUCH_MRGHYST	15
-#define MXT_TOUCH_MRGTHR	16
-#define MXT_TOUCH_AMPHYST	17
-#define MXT_TOUCH_XRANGE_LSB	18
-#define MXT_TOUCH_XRANGE_MSB	19
-#define MXT_TOUCH_YRANGE_LSB	20
-#define MXT_TOUCH_YRANGE_MSB	21
-#define MXT_TOUCH_XLOCLIP	22
-#define MXT_TOUCH_XHICLIP	23
-#define MXT_TOUCH_YLOCLIP	24
-#define MXT_TOUCH_YHICLIP	25
-#define MXT_TOUCH_XEDGECTRL	26
-#define MXT_TOUCH_XEDGEDIST	27
-#define MXT_TOUCH_YEDGECTRL	28
-#define MXT_TOUCH_YEDGEDIST	29
-#define MXT_TOUCH_JUMPLIMIT	30
+#define MXT_T9_ORIENT		9
+#define MXT_T9_RANGE		18
+
+struct t9_range {
+	u16 x;
+	u16 y;
+} __packed;
+
+/* Touch orient bits */
+#define MXT_XY_SWITCH		(1 << 0)
 
 /* MXT_PROCI_GRIPFACE_T20 field */
 #define MXT_GRIPFACE_CTRL	0
@@ -215,11 +198,6 @@
 #define MXT_PRESS		(1 << 6)
 #define MXT_DETECT		(1 << 7)
 
-/* Touch orient bits */
-#define MXT_XY_SWITCH		(1 << 0)
-#define MXT_X_INVERT		(1 << 1)
-#define MXT_Y_INVERT		(1 << 2)
-
 /* Touchscreen absolute values */
 #define MXT_MAX_AREA		0xff
 
@@ -556,11 +534,6 @@ static int __mxt_read_reg(struct i2c_client *client,
 	return ret;
 }
 
-static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
-{
-	return __mxt_read_reg(client, reg, 1, val);
-}
-
 static int __mxt_write_reg(struct i2c_client *client, u16 reg, u16 len,
 			   const void *val)
 {
@@ -1269,12 +1242,59 @@ static void mxt_free_object_table(struct mxt_data *data)
 	data->T19_reportid = 0;
 }
 
+static int mxt_read_t9_resolution(struct mxt_data *data)
+{
+	struct i2c_client *client = data->client;
+	int error;
+	struct t9_range range;
+	unsigned char orient;
+	struct mxt_object *object;
+
+	object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+	if (!object)
+		return -EINVAL;
+
+	error = __mxt_read_reg(client,
+			       object->start_address + MXT_T9_RANGE,
+			       sizeof(range), &range);
+	if (error)
+		return error;
+
+	le16_to_cpus(range.x);
+	le16_to_cpus(range.y);
+
+	error =  __mxt_read_reg(client,
+				object->start_address + MXT_T9_ORIENT,
+				1, &orient);
+	if (error)
+		return error;
+
+	/* Handle default values */
+	if (range.x == 0)
+		range.x = 1023;
+
+	if (range.y == 0)
+		range.y = 1023;
+
+	if (orient & MXT_XY_SWITCH) {
+		data->max_x = range.y;
+		data->max_y = range.x;
+	} else {
+		data->max_x = range.x;
+		data->max_y = range.y;
+	}
+
+	dev_dbg(&client->dev,
+		"Touchscreen size X%uY%u\n", data->max_x, data->max_y);
+
+	return 0;
+}
+
 static int mxt_initialize(struct mxt_data *data)
 {
 	struct i2c_client *client = data->client;
 	struct mxt_info *info = &data->info;
 	int error;
-	u8 val;
 
 	error = mxt_get_info(data);
 	if (error)
@@ -1303,26 +1323,16 @@ static int mxt_initialize(struct mxt_data *data)
 		goto err_free_object_table;
 	}
 
-	/* Update matrix size at info struct */
-	error = mxt_read_reg(client, MXT_MATRIX_X_SIZE, &val);
-	if (error)
-		goto err_free_object_table;
-	info->matrix_xsize = val;
-
-	error = mxt_read_reg(client, MXT_MATRIX_Y_SIZE, &val);
-	if (error)
+	error = mxt_read_t9_resolution(data);
+	if (error) {
+		dev_err(&client->dev, "Failed to initialize T9 resolution\n");
 		goto err_free_object_table;
-	info->matrix_ysize = val;
-
-	dev_info(&client->dev,
-			"Family: %u Variant: %u Firmware V%u.%u.%02X\n",
-			info->family_id, info->variant_id, info->version >> 4,
-			info->version & 0xf, info->build);
+	}
 
 	dev_info(&client->dev,
-			"Matrix X Size: %u Matrix Y Size: %u Objects: %u\n",
-			info->matrix_xsize, info->matrix_ysize,
-			info->object_num);
+		 "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n",
+		 info->family_id, info->variant_id, info->version >> 4,
+		 info->version & 0xf, info->build, info->object_num);
 
 	return 0;
 
@@ -1331,20 +1341,6 @@ err_free_object_table:
 	return error;
 }
 
-static void mxt_calc_resolution(struct mxt_data *data)
-{
-	unsigned int max_x = data->pdata->x_size - 1;
-	unsigned int max_y = data->pdata->y_size - 1;
-
-	if (data->pdata->orient & MXT_XY_SWITCH) {
-		data->max_x = max_y;
-		data->max_y = max_x;
-	} else {
-		data->max_x = max_x;
-		data->max_y = max_y;
-	}
-}
-
 /* Firmware Version is returned as Major.Minor.Build */
 static ssize_t mxt_fw_version_show(struct device *dev,
 				   struct device_attribute *attr, char *buf)
@@ -1670,8 +1666,6 @@ static int mxt_probe(struct i2c_client *client,
 	init_completion(&data->reset_completion);
 	init_completion(&data->crc_completion);
 
-	mxt_calc_resolution(data);
-
 	error = mxt_initialize(data);
 	if (error)
 		goto err_free_mem;
diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c
index 4f6f0b8..545a6d5 100644
--- a/drivers/platform/chrome/chromeos_laptop.c
+++ b/drivers/platform/chrome/chromeos_laptop.c
@@ -80,9 +80,6 @@ static int mxt_t19_keys[] = {
 };
 
 static struct mxt_platform_data atmel_224s_tp_platform_data = {
-	.x_size			= 102*20,
-	.y_size			= 68*20,
-	.orient			= MXT_VERTICAL_FLIP,
 	.irqflags		= IRQF_TRIGGER_FALLING,
 	.t19_num_keys		= ARRAY_SIZE(mxt_t19_keys),
 	.t19_keymap		= mxt_t19_keys,
@@ -95,9 +92,6 @@ static struct i2c_board_info __initdata atmel_224s_tp_device = {
 };
 
 static struct mxt_platform_data atmel_1664s_platform_data = {
-	.x_size			= 1700,
-	.y_size			= 2560,
-	.orient			= MXT_ROTATED_90_COUNTER,
 	.irqflags		= IRQF_TRIGGER_FALLING,
 };
 
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index b569bb8..02bf6ea 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -15,22 +15,8 @@
 
 #include <linux/types.h>
 
-/* Orient */
-#define MXT_NORMAL		0x0
-#define MXT_DIAGONAL		0x1
-#define MXT_HORIZONTAL_FLIP	0x2
-#define MXT_ROTATED_90_COUNTER	0x3
-#define MXT_VERTICAL_FLIP	0x4
-#define MXT_ROTATED_90		0x5
-#define MXT_ROTATED_180		0x6
-#define MXT_DIAGONAL_COUNTER	0x7
-
 /* The platform data for the Atmel maXTouch touchscreen driver */
 struct mxt_platform_data {
-	unsigned int x_size;
-	unsigned int y_size;
-	unsigned char orient;
-
 	unsigned long irqflags;
 	u8 t19_num_keys;
 	const unsigned int *t19_keymap;
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 19/22] Input: atmel_mxt_ts - use deep sleep mode when stopped
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

By writing zero to both the active and idle cycle times the maXTouch device
is put into a deep sleep mode when it consumes minimal power. It is
unnecessary to change the configuration of any other objects (for example
to disable T9 touchscreen).

It is counterproductive to reset the chip on resume, it will result in a
long delay. However it is necessary to issue a calibrate command after the
chip has spent any time in deep sleep.

This patch also deals with the situation where the power configuration is
zero on probe, which would mean that the device never wakes up to execute
commands.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 99 +++++++++++++++++++++++---------
 1 file changed, 73 insertions(+), 26 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index ce88ada..5cd2261 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -89,9 +89,13 @@
 #define MXT_T6_STATUS_RESET	(1 << 7)
 
 /* MXT_GEN_POWER_T7 field */
-#define MXT_POWER_IDLEACQINT	0
-#define MXT_POWER_ACTVACQINT	1
-#define MXT_POWER_ACTV2IDLETO	2
+struct t7_config {
+	u8 idle;
+	u8 active;
+} __packed;
+
+#define MXT_POWER_CFG_RUN		0
+#define MXT_POWER_CFG_DEEPSLEEP		1
 
 /* MXT_GEN_ACQUIRE_T8 field */
 #define MXT_ACQUIRE_CHRGTIME	0
@@ -103,7 +107,6 @@
 #define MXT_ACQUIRE_ATCHCALSTHR	7
 
 /* MXT_TOUCH_MULTI_T9 field */
-#define MXT_TOUCH_CTRL		0
 #define MXT_T9_ORIENT		9
 #define MXT_T9_RANGE		18
 
@@ -242,6 +245,7 @@ struct mxt_data {
 	u32 config_crc;
 	u32 info_crc;
 	u8 bootloader_addr;
+	struct t7_config t7_cfg;
 
 	/* Cached parameters from object table */
 	u8 T6_reportid;
@@ -600,20 +604,6 @@ static int mxt_read_message(struct mxt_data *data,
 			sizeof(struct mxt_message), message);
 }
 
-static int mxt_write_object(struct mxt_data *data,
-				 u8 type, u8 offset, u8 val)
-{
-	struct mxt_object *object;
-	u16 reg;
-
-	object = mxt_get_object(data, type);
-	if (!object || offset >= mxt_obj_size(object))
-		return -EINVAL;
-
-	reg = object->start_address;
-	return mxt_write_reg(data->client, reg + offset, val);
-}
-
 static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
 {
 	struct input_dev *input = data->input_dev;
@@ -1129,6 +1119,60 @@ release:
 	return ret;
 }
 
+static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep)
+{
+	struct device *dev = &data->client->dev;
+	int error;
+	struct t7_config *new_config;
+	struct t7_config deepsleep = { .active = 0, .idle = 0 };
+
+	if (sleep == MXT_POWER_CFG_DEEPSLEEP)
+		new_config = &deepsleep;
+	else
+		new_config = &data->t7_cfg;
+
+	error = __mxt_write_reg(data->client, data->T7_address,
+				sizeof(data->t7_cfg), new_config);
+	if (error)
+		return error;
+
+	dev_dbg(dev, "Set T7 ACTV:%d IDLE:%d\n",
+		new_config->active, new_config->idle);
+
+	return 0;
+}
+
+static int mxt_init_t7_power_cfg(struct mxt_data *data)
+{
+	struct device *dev = &data->client->dev;
+	int error;
+	bool retry = false;
+
+recheck:
+	error = __mxt_read_reg(data->client, data->T7_address,
+				sizeof(data->t7_cfg), &data->t7_cfg);
+	if (error)
+		return error;
+
+	if (data->t7_cfg.active == 0 || data->t7_cfg.idle == 0) {
+		if (!retry) {
+			dev_dbg(dev, "T7 cfg zero, resetting\n");
+			mxt_soft_reset(data);
+			retry = true;
+			goto recheck;
+		} else {
+			dev_dbg(dev, "T7 cfg zero after reset, overriding\n");
+			data->t7_cfg.active = 20;
+			data->t7_cfg.idle = 100;
+			return mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+		}
+	}
+
+	dev_dbg(dev, "Initialized power cfg: ACTV %d, IDLE %d\n",
+		data->t7_cfg.active, data->t7_cfg.idle);
+	return 0;
+}
+
 static int mxt_make_highchg(struct mxt_data *data)
 {
 	struct device *dev = &data->client->dev;
@@ -1323,6 +1367,12 @@ static int mxt_initialize(struct mxt_data *data)
 		goto err_free_object_table;
 	}
 
+	error = mxt_init_t7_power_cfg(data);
+	if (error) {
+		dev_err(&client->dev, "Failed to initialize power cfg\n");
+		goto err_free_object_table;
+	}
+
 	error = mxt_read_t9_resolution(data);
 	if (error) {
 		dev_err(&client->dev, "Failed to initialize T9 resolution\n");
@@ -1596,16 +1646,15 @@ static const struct attribute_group mxt_attr_group = {
 
 static void mxt_start(struct mxt_data *data)
 {
-	/* Touch enable */
-	mxt_write_object(data,
-			MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83);
+	mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
+
+	/* Recalibrate since chip has been in deep sleep */
+	mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
 }
 
 static void mxt_stop(struct mxt_data *data)
 {
-	/* Touch disable */
-	mxt_write_object(data,
-			MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0);
+	mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
 }
 
 static int mxt_input_open(struct input_dev *dev)
@@ -1796,8 +1845,6 @@ static int mxt_resume(struct device *dev)
 	struct mxt_data *data = i2c_get_clientdata(client);
 	struct input_dev *input_dev = data->input_dev;
 
-	mxt_soft_reset(data);
-
 	mutex_lock(&input_dev->mutex);
 
 	if (input_dev->users)
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 21/22] Input: atmel_mxt_ts - rename touchscreen defines to include T9
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

This avoids confusion with the newer T100 touchscreen object.

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 46 ++++++++++++++++----------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index acd524f..bd614a7 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -110,13 +110,23 @@ struct t7_config {
 #define MXT_T9_ORIENT		9
 #define MXT_T9_RANGE		18
 
+/* MXT_TOUCH_MULTI_T9 status */
+#define MXT_T9_UNGRIP		(1 << 0)
+#define MXT_T9_SUPPRESS		(1 << 1)
+#define MXT_T9_AMP		(1 << 2)
+#define MXT_T9_VECTOR		(1 << 3)
+#define MXT_T9_MOVE		(1 << 4)
+#define MXT_T9_RELEASE		(1 << 5)
+#define MXT_T9_PRESS		(1 << 6)
+#define MXT_T9_DETECT		(1 << 7)
+
 struct t9_range {
 	u16 x;
 	u16 y;
 } __packed;
 
-/* Touch orient bits */
-#define MXT_XY_SWITCH		(1 << 0)
+/* MXT_TOUCH_MULTI_T9 orient */
+#define MXT_T9_ORIENT_SWITCH	(1 << 0)
 
 /* MXT_PROCI_GRIPFACE_T20 field */
 #define MXT_GRIPFACE_CTRL	0
@@ -191,16 +201,6 @@ struct t9_range {
 #define MXT_BOOT_EXTENDED_ID	(1 << 5)
 #define MXT_BOOT_ID_MASK	0x1f
 
-/* Touch status */
-#define MXT_UNGRIP		(1 << 0)
-#define MXT_SUPPRESS		(1 << 1)
-#define MXT_AMP			(1 << 2)
-#define MXT_VECTOR		(1 << 3)
-#define MXT_MOVE		(1 << 4)
-#define MXT_RELEASE		(1 << 5)
-#define MXT_PRESS		(1 << 6)
-#define MXT_DETECT		(1 << 7)
-
 /* Touchscreen absolute values */
 #define MXT_MAX_AREA		0xff
 
@@ -644,21 +644,21 @@ static void mxt_input_touchevent(struct mxt_data *data,
 	dev_dbg(dev,
 		"[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
 		id,
-		(status & MXT_DETECT) ? 'D' : '.',
-		(status & MXT_PRESS) ? 'P' : '.',
-		(status & MXT_RELEASE) ? 'R' : '.',
-		(status & MXT_MOVE) ? 'M' : '.',
-		(status & MXT_VECTOR) ? 'V' : '.',
-		(status & MXT_AMP) ? 'A' : '.',
-		(status & MXT_SUPPRESS) ? 'S' : '.',
-		(status & MXT_UNGRIP) ? 'U' : '.',
+		(status & MXT_T9_DETECT) ? 'D' : '.',
+		(status & MXT_T9_PRESS) ? 'P' : '.',
+		(status & MXT_T9_RELEASE) ? 'R' : '.',
+		(status & MXT_T9_MOVE) ? 'M' : '.',
+		(status & MXT_T9_VECTOR) ? 'V' : '.',
+		(status & MXT_T9_AMP) ? 'A' : '.',
+		(status & MXT_T9_SUPPRESS) ? 'S' : '.',
+		(status & MXT_T9_UNGRIP) ? 'U' : '.',
 		x, y, area, amplitude);
 
 	input_mt_slot(input_dev, id);
 	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
-				   status & MXT_DETECT);
+				   status & MXT_T9_DETECT);
 
-	if (status & MXT_DETECT) {
+	if (status & MXT_T9_DETECT) {
 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
 		input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
@@ -1320,7 +1320,7 @@ static int mxt_read_t9_resolution(struct mxt_data *data)
 	if (range.y == 0)
 		range.y = 1023;
 
-	if (orient & MXT_XY_SWITCH) {
+	if (orient & MXT_T9_ORIENT_SWITCH) {
 		data->max_x = range.y;
 		data->max_y = range.x;
 	} else {
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 22/22] Input: atmel_mxt_ts - handle multiple input reports in one message
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 36 +++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index bd614a7..3a83242 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -620,6 +620,12 @@ static void mxt_input_button(struct mxt_data *data, struct mxt_message *message)
 	}
 }
 
+static void mxt_input_sync(struct input_dev *input_dev)
+{
+	input_mt_report_pointer_emulation(input_dev, false);
+	input_sync(input_dev);
+}
+
 static void mxt_input_touchevent(struct mxt_data *data,
 				      struct mxt_message *message, int id)
 {
@@ -633,10 +639,12 @@ static void mxt_input_touchevent(struct mxt_data *data,
 
 	x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
 	y = (message->message[2] << 4) | ((message->message[3] & 0xf));
+
+	/* Handle 10/12 bit switching */
 	if (data->max_x < 1024)
-		x = x >> 2;
+		x >>= 2;
 	if (data->max_y < 1024)
-		y = y >> 2;
+		y >>= 2;
 
 	area = message->message[4];
 	amplitude = message->message[5];
@@ -655,14 +663,28 @@ static void mxt_input_touchevent(struct mxt_data *data,
 		x, y, area, amplitude);
 
 	input_mt_slot(input_dev, id);
-	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
-				   status & MXT_T9_DETECT);
 
 	if (status & MXT_T9_DETECT) {
+		/*
+		 * Multiple bits may be set if the host is slow to read
+		 * the status messages, indicating all the events that
+		 * have happened.
+		 */
+		if (status & MXT_T9_RELEASE) {
+			input_mt_report_slot_state(input_dev,
+						   MT_TOOL_FINGER, 0);
+			mxt_input_sync(input_dev);
+		}
+
+		/* Touch active */
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
 		input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
 		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
+	} else {
+		/* Touch no longer active, close out slot */
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
 	}
 }
 
@@ -720,10 +742,8 @@ static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
 		}
 	} while (reportid != 0xff);
 
-	if (update_input) {
-		input_mt_report_pointer_emulation(data->input_dev, false);
-		input_sync(data->input_dev);
-	}
+	if (update_input)
+		mxt_input_sync(data->input_dev);
 
 	return IRQ_HANDLED;
 }
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH v2 5/8] regulator: AXP20x: Add support for regulators subsystem
From: Mark Brown @ 2014-03-17 17:33 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <1394898225-28452-6-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 597 bytes --]

On Sat, Mar 15, 2014 at 04:43:42PM +0100, Carlo Caione wrote:
> AXP202 and AXP209 come with two synchronous step-down DC-DCs and five
> LDOs. This patch introduces basic support for those regulators.

This is mostly fine apart from the things Krzysztof mentioned and...

> +static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
> +{
> +	struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
> +
> +	if (dcdcfreq < 750)
> +		dcdcfreq = 750;
> +
> +	if (dcdcfreq > 1875)
> +		dcdcfreq = 1875;

I'd expect at least a warning on out of spec values being specified
here.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH 00/22] atmel_mxt_ts patches, already signed-off
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson

Hi Dimitry-

Here is a set of patches for atmel_mxt_ts that you've already signed-off. I've
rebased them against the most recent mainline and made some very minor changes
such as INIT_COMPLETION->reinit_completion.

thanks

Nick Dyer


^ permalink raw reply

* [PATCH 03/22] Input: atmel_mxt_ts - return IRQ_NONE when interrupt handler fails
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 65df362..0cff8bb 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -590,7 +590,7 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 	do {
 		if (mxt_read_message(data, &message)) {
 			dev_err(dev, "Failed to read message\n");
-			goto end;
+			return IRQ_NONE;
 		}
 
 		reportid = message.reportid;
@@ -617,7 +617,6 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 		input_sync(data->input_dev);
 	}
 
-end:
 	return IRQ_HANDLED;
 }
 
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 07/22] Input: atmel_mxt_ts - wait for CHG after bootloader resets
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

From: Benson Leung <bleung@chromium.org>

Rather than msleep for MXT_RESET_TIME and MXT_FWRESET_TIME during the
transition to bootloader mode and the transition back from app, wait for the
CHG assert to indicate that the transition is done.

This change replaces the msleep with a wait for completion that the
mxt_interrupt handler signals.

Also add CHG poll after last firmware frame - some bootloader versions will
assert the interrupt line after the final frame, in testing this meant that
the driver attempts to read the info block too early whilst the chip is still
resetting.

This improves firmware update time as we no longer wait longer than necessary
for each reset.

Signed-off-by: Benson Leung <bleung@chromium.org>
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7f51d39..d5b3043 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -181,8 +181,8 @@
 #define MXT_BACKUP_VALUE	0x55
 #define MXT_BACKUP_TIME		50	/* msec */
 #define MXT_RESET_TIME		200	/* msec */
-
-#define MXT_FWRESET_TIME	175	/* msec */
+#define MXT_FW_RESET_TIME	3000	/* msec */
+#define MXT_FW_CHG_TIMEOUT	300	/* msec */
 
 /* Command to unlock bootloader */
 #define MXT_UNLOCK_CMD_MSB	0xaa
@@ -375,7 +375,7 @@ recheck:
 		 * CHG assertion before reading the status byte.
 		 * Once the status byte has been read, the line is deasserted.
 		 */
-		ret = mxt_wait_for_chg(data, 300);
+		ret = mxt_wait_for_chg(data, MXT_FW_CHG_TIMEOUT);
 		if (ret) {
 			/*
 			 * TODO: handle -ERESTARTSYS better by terminating
@@ -1047,6 +1047,18 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 		dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
 	}
 
+	/* Wait for flash. */
+	ret = mxt_wait_for_chg(data, MXT_FW_RESET_TIME);
+	if (ret)
+		goto disable_irq;
+
+	/*
+	 * Wait for device to reset. Some bootloader versions do not assert
+	 * the CHG line after bootloading has finished, so ignore potential
+	 * errors.
+	 */
+	mxt_wait_for_chg(data, MXT_FW_RESET_TIME);
+
 	data->in_bootloader = false;
 
 disable_irq:
@@ -1075,10 +1087,6 @@ static ssize_t mxt_update_fw_store(struct device *dev,
 		count = error;
 	} else {
 		dev_dbg(dev, "The firmware update succeeded\n");
-
-		/* Wait for reset */
-		msleep(MXT_FWRESET_TIME);
-
 		mxt_free_object_table(data);
 
 		mxt_initialize(data);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 15/22] Input: atmel_mxt_ts - implement bootloader frame retries
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 1ed3804..049d48a 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -486,8 +486,12 @@ recheck:
 		val &= ~MXT_BOOT_STATUS_MASK;
 		break;
 	case MXT_FRAME_CRC_PASS:
-		if (val == MXT_FRAME_CRC_CHECK)
+		if (val == MXT_FRAME_CRC_CHECK) {
 			goto recheck;
+		} else if (val == MXT_FRAME_CRC_FAIL) {
+			dev_err(dev, "Bootloader CRC fail\n");
+			return -EINVAL;
+		}
 		break;
 	default:
 		return -EINVAL;
@@ -1427,6 +1431,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 	const struct firmware *fw = NULL;
 	unsigned int frame_size;
 	unsigned int pos = 0;
+	unsigned int retry = 0;
 	int ret;
 
 	ret = request_firmware(&fw, fn, dev);
@@ -1464,9 +1469,7 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 
 		frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));
 
-		/* We should add 2 at frame size as the the firmware data is not
-		 * included the CRC bytes.
-		 */
+		/* Take account of CRC bytes */
 		frame_size += 2;
 
 		/* Write one frame to device */
@@ -1475,10 +1478,20 @@ static int mxt_load_fw(struct device *dev, const char *fn)
 			goto disable_irq;
 
 		ret = mxt_check_bootloader(data, MXT_FRAME_CRC_PASS);
-		if (ret)
-			goto disable_irq;
+		if (ret) {
+			retry++;
 
-		pos += frame_size;
+			/* Back off by 20ms per retry */
+			msleep(retry * 20);
+
+			if (retry > 20) {
+				dev_err(dev, "Retry count exceeded\n");
+				goto disable_irq;
+			}
+		} else {
+			retry = 0;
+			pos += frame_size;
+		}
 
 		dev_dbg(dev, "Updated %d bytes / %zd bytes\n", pos, fw->size);
 	}
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 20/22] Input: atmel_mxt_ts - rename pressure to amplitude to match spec
From: Nick Dyer @ 2014-03-17 17:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Yufeng Shen, Daniel Kurtz, Henrik Rydberg, Joonyoung Shim,
	Alan Bowens, linux-input, linux-kernel, Peter Meerwald,
	Benson Leung, Olof Johansson, Nick Dyer
In-Reply-To: <1395077215-10922-1-git-send-email-nick.dyer@itdev.co.uk>

Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Benson Leung <bleung@chromium.org>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 5cd2261..acd524f 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -629,7 +629,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
 	int x;
 	int y;
 	int area;
-	int pressure;
+	int amplitude;
 
 	x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
 	y = (message->message[2] << 4) | ((message->message[3] & 0xf));
@@ -639,7 +639,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
 		y = y >> 2;
 
 	area = message->message[4];
-	pressure = message->message[5];
+	amplitude = message->message[5];
 
 	dev_dbg(dev,
 		"[%u] %c%c%c%c%c%c%c%c x: %5u y: %5u area: %3u amp: %3u\n",
@@ -652,7 +652,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
 		(status & MXT_AMP) ? 'A' : '.',
 		(status & MXT_SUPPRESS) ? 'S' : '.',
 		(status & MXT_UNGRIP) ? 'U' : '.',
-		x, y, area, pressure);
+		x, y, area, amplitude);
 
 	input_mt_slot(input_dev, id);
 	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
@@ -661,7 +661,7 @@ static void mxt_input_touchevent(struct mxt_data *data,
 	if (status & MXT_DETECT) {
 		input_report_abs(input_dev, ABS_MT_POSITION_X, x);
 		input_report_abs(input_dev, ABS_MT_POSITION_Y, y);
-		input_report_abs(input_dev, ABS_MT_PRESSURE, pressure);
+		input_report_abs(input_dev, ABS_MT_PRESSURE, amplitude);
 		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
 	}
 }
-- 
1.8.3.2


^ permalink raw reply related

* Yet another ALPS dualpoint TP protocol in preparation
From: Václav Krpec @ 2014-03-17 17:53 UTC (permalink / raw)
  To: linux-input

Hello everybody,

yes, I'm another poor soul who ended up with an ALPS touchpad.

More specifically (although not much helpfully), it's a device
ALPS manufactured for my Toshiba Portege Z30-A-12N.
I've written to both ALPS and Toshiba with pleads for tech.
documentation, but (not surprisingly) Toshiba didn't respond
at all, ALPS just told me they can't help me...
The same old song (although it never hurts to try).

Well, being Linux user for quite some time and SW developer
myself, I decided to do a reverse analysis of the device,
hoping to get proper support of its capabilities in psmouse
kernel module.

Here's a short list of what I've done (hope I didn't bore
you off up to this point, it'll turn worse ;-):

1/
I've contacted Sebastian Kapfer, the current maintainer
of the ALPS sub-driver; with his advice and support,
I was able to find out that the device responds to
"AlpsPS/2 v3 Rushmore" flavour of HW initialisation routine.
I should note here that the device works in plain PS/2 mouse
compatibility mode unless the HW init. sequence above is executed.

2/
I've created a simple tool for reverse analysis of the device PS/2
protocol; it's here (just in case someone else would find it helpful):
https://github.com/vencik/alsp-ra
I was able to successfully unravel the device protocol packet structure
and have drafted a new version (codename "v7").

3/
I'm now in process of implementing the driver; so far, the trackstick
works fine, the TP sends abs. coords OK, I got tap and tap-and-drag
working too (although fine tuning shall be nice).
I can distinguish 2 fingers, either, and get secondary coords.
I've however hit a few issues:

4/
I'm using the (apparently) old BTN_TOOL_FINGER / BTN_TOOL_DOUBLETAP
input_report_* interface.
Accordingly to the documentation and what I saw in the code,
the new input_mt_slot & input_mt_report_slot_state should be more
suitable for multitouch (the touchpad can apparently detect at least
3, maybe even more, fingers).
Although I don't really need that, it seems better to use the more
general approach.
However, I don't seem to be able to get any events reported using
that new iface.
Do I need to do any special initialisation or something?
Note that I do use alps_set_abs_params_mt for the set_abs_params
callback.
Or perhaps do I need to set something on the synaptics X11 driver?

5/
I've also noticed that the TP seems to get out-of-sync or something
if I re-load the driver and touch it too soon before the X server
loads the synaptics driver.
If I wait for about 3 seconds, it works fine.
If I touch it sooner, I get no cursor (although the other trackstick
device still works nicely and so do the TP buttons).
Is there any reset required/possible?

6/
I also have a bit of trouble reporting switch from 2 to one touch.
When that happens, I try to
input_report_key(dev, BTN_TOOL_DOUBLETAP, 0)
and then
input_report_key(dev, BTN_TOOL_FINGER, 1)
(with sync) to avoid cursor skip if the primary touch is the lost
one, but that doesn't seem to do the trick.
What should I do?

7/
Well, there'll be much more to do, but so far, the above are the most
interesting/bugging issues.

Any help/advice/moral support highly appreciated. :-)

Also, don't hesitate to point me to any existing info resources
(and at this point, I'd like to apologise if asking an already responded
question).

Of course, if anyone else have similar device, I'd very much like to
share findings or (at some point) perhaps get the opportunity to
test the code on another machine.

Thanks,

Best regards

vencik




^ permalink raw reply

* Re: [PATCH v5 0/9] Use regmap+devm+DT in pm8xxx input drivers
From: Stephen Boyd @ 2014-03-17 21:17 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Josh Cartwright,
	linux-input, devicetree@vger.kernel.org
In-Reply-To: <531F4CC8.5010202@codeaurora.org>

ping?

On 03/11/14 10:50, Stephen Boyd wrote:
> ping?
>
> On 03/04/14 10:34, Stephen Boyd wrote:
>> These patches move the pm8xxx input drivers over to use devm_* APIs
>> and regmap. This breaks the dependency of these drivers on the pm8xxx
>> specific read/write calls and also simplifies the probe code a bit.
>> Finally we add devicetree support to these drivers so they can be probed
>> on the platforms that are supported upstream.
>>
>> Changes since v4:
>>  * Added reg property to bindings
>>  * Added linux,* properties to keypad binding
>>
>> Changes since v3:
>>  * Dropped devm conversion patch for pwrkey
>>  * Fixed compilation of keypad
>>
>> Changes since v2:
>>  * Rebased to v3.14-rc3
>>
>> Changes since v1:
>>  * Picked up Dmitry's version of devm for pwrkey
>>  * Added DT bindings and parsing patches
>>  * Dropped patches picked up by Dmitry
>>
>> Stephen Boyd (9):
>>   Input: pmic8xxx-keypad - Fix build by removing gpio configuration
>>   Input: pmic8xxx-keypad - Migrate to devm_* APIs
>>   Input: pmic8xxx-keypad - Migrate to regmap APIs
>>   Input: pmic8xxx-keypad - Migrate to DT
>>   Input: pmic8xxx-pwrkey - Migrate to DT
>>   Input: pm8xxx-vibrator - Add DT match table
>>   devicetree: bindings: Document PM8921/8058 keypads
>>   devicetree: bindings: Document PM8921/8058 power keys
>>   devicetree: bindings: Document PM8921/8058 vibrators
>>
>>  .../bindings/input/qcom,pm8xxx-keypad.txt          |  89 ++++++
>>  .../bindings/input/qcom,pm8xxx-pwrkey.txt          |  46 +++
>>  .../devicetree/bindings/input/qcom,pm8xxx-vib.txt  |  22 ++
>>  drivers/input/keyboard/pmic8xxx-keypad.c           | 348 ++++++++-------------
>>  drivers/input/misc/pm8xxx-vibrator.c               |   8 +
>>  drivers/input/misc/pmic8xxx-pwrkey.c               |  33 +-
>>  include/linux/input/pmic8xxx-keypad.h              |  52 ---
>>  include/linux/input/pmic8xxx-pwrkey.h              |  31 --
>>  8 files changed, 316 insertions(+), 313 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-keypad.txt
>>  create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-pwrkey.txt
>>  create mode 100644 Documentation/devicetree/bindings/input/qcom,pm8xxx-vib.txt
>>  delete mode 100644 include/linux/input/pmic8xxx-keypad.h
>>  delete mode 100644 include/linux/input/pmic8xxx-pwrkey.h
>>
>


-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply

* Re: [PATCH] hid: fix bug destroying hidraw device files after parent
From: Jiri Kosina @ 2014-03-17 23:42 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: linux-input, linux-usb, Nestor Lopez Casado, Greg Kroah-Hartman,
	Tejun Heo
In-Reply-To: <53266890.1040504@lab.ntt.co.jp>

On Mon, 17 Mar 2014, Fernando Luis Vázquez Cao wrote:

> > I have slightly modified the patch title to make sure that it's obvious
> > that what it fixes is actually a WARN_ON() splat.
> 
> Thank you.
> 
> Any chance we can get this to Linus before 3.14 comes out?
> According to Linus, rc7 may be the last rc.

It will be in Linus' 3.14 final -- it went in post-rc7.

Thanks for taking care,

-- 
Jiri Kosina
SUSE Labs
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] hid: fix bug destroying hidraw device files after parent
From: Fernando Luis Vázquez Cao @ 2014-03-18  1:24 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: linux-input, linux-usb, Nestor Lopez Casado, Greg Kroah-Hartman,
	Tejun Heo
In-Reply-To: <alpine.LNX.2.00.1403180041100.3690@pobox.suse.cz>

(2014年03月18日 08:42), Jiri Kosina wrote:
> On Mon, 17 Mar 2014, Fernando Luis Vázquez Cao wrote:
>
>>> I have slightly modified the patch title to make sure that it's obvious
>>> that what it fixes is actually a WARN_ON() splat.
>> Thank you.
>>
>> Any chance we can get this to Linus before 3.14 comes out?
>> According to Linus, rc7 may be the last rc.
> It will be in Linus' 3.14 final -- it went in post-rc7.
>
> Thanks for taking care,

Thanks!

- Fernando
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/8] mfd: AXP20x: Add bindings documentation
From: Maxime Ripard @ 2014-03-18  8:45 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <1394898225-28452-3-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 3254 bytes --]

On Sat, Mar 15, 2014 at 04:43:39PM +0100, Carlo Caione wrote:
> Bindings documentation for the AXP20x driver. In this file also two
> sub-nodes (PEK and regulators) are documented.

PEK doesn't look to be documented, either in this patch, or any other.

> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/mfd/axp20x.txt   | 83 ++++++++++++++++++++++
>  .../devicetree/bindings/vendor-prefixes.txt        |  1 +

I don't really know what the DT maintainers are expecting here, but I
would have done two patches.

>  2 files changed, 84 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/axp20x.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
> new file mode 100644
> index 0000000..982aefe
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
> @@ -0,0 +1,83 @@
> +* axp20x device tree bindings
> +
> +The axp20x family current members :-
> +axp202 (X-Powers)
> +axp209 (X-Powers)
> +
> +Required properties:
> +- compatible 			: Should be "x-powers,axp202" or "x-powers,axp209"
> +- interrupt-controller 		: axp20x has its own internal IRQs
> +- #interrupt-cells 		: Should be set to 1
> +- interrupt-parent 		: The parent interrupt controller
> +- interrupts 			: Interrupt specifiers for interrupt sources
> +- reg 				: The I2C slave address for the AXP chip
> +
> +Sub-nodes:
> +* regulators : Contain the regulator nodes. The regulators are bound using
> +	       their name as listed here: dcdc2, dcdc3, ldo1, ldo2, ldo3,
> +	       ldo4, ldo5.
> +	       The bindings details of individual regulator device can be found in:
> +	       Documentation/devicetree/bindings/regulator/regulator.txt with the
> +	       exception of:
> +
> +	- dcdc-freq		: defines the work frequency of DC-DC in KHz
> +				  (range: 750-1875). Default: 1.5MHz
> +	- dcdc-workmode		: Optional. 1 for PWM mode, 0 for AUTO mode
> +				  Default: AUTO mode

Those two are x-powers specific, or would it make sense to have them
in other drivers too?

If the former, please add the x-powers prefix.

> +
> +Example:
> +
> +axp: axp20x@34 {
> +	reg = <0x34>;
> +	interrupt-parent = <&nmi_intc>;
> +	interrupts = <0 8>;
> +
> +	compatible = "x-powers,axp209";
> +	interrupt-controller;
> +	#interrupt-cells = <1>;
> +
> +	regulators {

Do we really need that subnode ? it looks useless, and we already know
that we are defining regulators here.

> +		dcdc-freq = "1500";

That frequency is defined at the same level than the dcdc-workmode
property, yet they both seem to be placed at different levels.

> +
> +		axp_dcdc2: dcdc2 {
> +			regulator-min-microvolt = <700000>;
> +			regulator-max-microvolt = <2275000>;
> +			dcdc-workmode = <0>;
> +			regulator-always-on;
> +		};
> +
> +		axp_dcdc3: dcdc3 {
> +			regulator-min-microvolt = <700000>;
> +			regulator-max-microvolt = <3500000>;
> +			dcdc-workmode = <0>;

It looks like those are at their default values?

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v3 4/4] mfd: max8997: move regmap handling to function drivers
From: Lee Jones @ 2014-03-18  8:50 UTC (permalink / raw)
  To: Robert Baldyga
  Cc: Mark Brown, Chanwoo Choi, sameo, myungjoo.ham, dmitry.torokhov,
	cooloney, rpurdie, dbaryshkov, dwmw2, lgirdwood, a.zummo,
	paul.gortmaker, linux-kernel, linux-input, linux-leds, rtc-linux,
	m.szyprowski, k.kozlowski
In-Reply-To: <5322E653.90107@samsung.com>

> >>> Is it necessary? If previous mfd driver has various i2c line, previous mfd driver
> >>> initialize regmap/i2c setting on mfd driver.
> >>> I'm not sure that regmap/i2c setting code move from mfd driver to each driver.
> >>>
> >>> Dear Lee Jones,
> >>> I need your opinion about moving regmap/i2c code from mfd driver to each driver.
> > 
> >> I'd rather take advice from Mark on this one.
> > 
> > I don't really case that much; I'm having a hard time seeing it as
> > particularly useful to do the refactoring but if it makes people
> > happy...  Keeping things in the core would help promote reusability I
> > guess but I'm not sure that's likely to actually happen with this sort
> > of driver/device.
> 
> If you think it's not needed, you can ignore this patch. I prepared it
> due to Dmitry Torokhov suggestion. If you think it's useless it doesn't
> make me unhappy :)

Ignored, thanks. ;)

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* Re: [PATCH v2 3/8] input: misc: Add driver for AXP20x Power Enable Key
From: Maxime Ripard @ 2014-03-18  9:00 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <1394898225-28452-4-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 10545 bytes --]

On Sat, Mar 15, 2014 at 04:43:40PM +0100, Carlo Caione wrote:
> This patch add support for the Power Enable Key found on MFD AXP202 and
> AXP209. Besides the basic support for the button, the driver adds two
> entries in sysfs to configure the time delay for power on/off.
> 
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  drivers/input/misc/Kconfig      |  11 ++
>  drivers/input/misc/Makefile     |   1 +
>  drivers/input/misc/axp20x-pek.c | 267 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 279 insertions(+)
>  create mode 100644 drivers/input/misc/axp20x-pek.c

From what I understood of the MFD framework, you usually have a MFD
core driver that gets loaded from the DT and instantiate its various
functions through sub-devices, that are registered through
mfd_add_devices, and the drivers for these sub-devices are supported
in sub-drivers that are located in the driver/mfd, alongside the core
driver.

I believe that such a pattern allows for two interesting things:
  - You don't have to search around the whole kernel tree to find
    where a given sub-feature is supported.
  - You don't have to cripple your DT with instantiation of all the
    subcomponents, while you only really have one device.

Do you have a reason for not following this pattern?

> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 7904ab0..87244fb 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -393,6 +393,17 @@ config INPUT_RETU_PWRBUTTON
>  	  To compile this driver as a module, choose M here. The module will
>  	  be called retu-pwrbutton.
>  
> +config INPUT_AXP20X_PEK
> +	tristate "X-Powers AXP20X power button driver"
> +	depends on MFD_AXP20X
> +	help
> +	  Say Y here if you want to enable power key reporting via the
> +	  AXP20X PMIC.
> +
> +	  To compile this driver as a module, choose M here. The module will
> +	  be called axp20x-pek.
> +
> +
>  config INPUT_TWL4030_PWRBUTTON
>  	tristate "TWL4030 Power button Driver"
>  	depends on TWL4030_CORE
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index cda71fc..624abf5 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
>  obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
>  obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
>  obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
> +obj-$(CONFIG_INPUT_AXP20X_PEK)		+= axp20x-pek.o
>  obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
>  obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
>  obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
> diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
> new file mode 100644
> index 0000000..060212f
> --- /dev/null
> +++ b/drivers/input/misc/axp20x-pek.c
> @@ -0,0 +1,267 @@
> +/*
> + * axp20x power button driver.
> + *
> + * Copyright (C) 2013 Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> + *
> + * This file is subject to the terms and conditions of the GNU General
> + * Public License. See the file "COPYING" in the main directory of this
> + * archive for more details.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/errno.h>
> +#include <linux/irq.h>
> +#include <linux/init.h>
> +#include <linux/input.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/axp20x.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +
> +#define AXP20X_PEK_STARTUP_MASK		(0xc0)
> +#define AXP20X_PEK_SHUTDOWN_MASK	(0x03)
> +
> +static const char const *startup_time[] = { "128ms", "3s" , "1s", "2s" };
> +static const char const *shutdown_time[] = { "4s", "6s" , "8s", "10s" };
> +
> +struct axp20x_pek {
> +	struct axp20x_dev *axp20x;
> +	struct input_dev *input;
> +	int irq_dbr;
> +	int irq_dbf;
> +};
> +
> +struct axp20x_pek_ext_attr {
> +	const char const **str;
> +	unsigned int mask;
> +};
> +
> +static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
> +	.str	= startup_time,
> +	.mask	= AXP20X_PEK_STARTUP_MASK,
> +};
> +
> +static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
> +	.str	= shutdown_time,
> +	.mask	= AXP20X_PEK_SHUTDOWN_MASK,
> +};
> +
> +static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
> +{
> +	return container_of(attr, struct dev_ext_attribute, attr)->var;
> +}
> +
> +static ssize_t axp20x_show_ext_attr(struct device *dev, struct device_attribute *attr,
> +			     char *buf)
> +{
> +	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
> +	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
> +	unsigned int val;
> +	int ret, i;
> +	int cnt = 0;
> +
> +	ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val);
> +	if (ret != 0)
> +		return ret;
> +
> +	val &= axp20x_ea->mask;
> +	val >>= ffs(axp20x_ea->mask) - 1;
> +
> +	for (i = 0; i < 4; i++) {
> +		if (val == i)
> +			cnt += sprintf(buf + cnt, "[%s] ", axp20x_ea->str[i]);
> +		else
> +			cnt += sprintf(buf + cnt, "%s ", axp20x_ea->str[i]);
> +	}
> +
> +	cnt += sprintf(buf + cnt, "\n");
> +
> +	return cnt;
> +}
> +
> +static ssize_t axp20x_store_ext_attr(struct device *dev, struct device_attribute *attr,
> +			      const char *buf, size_t count)
> +{
> +	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
> +	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
> +	char val_str[20];
> +	int ret, i;
> +	size_t len;
> +
> +	val_str[sizeof(val_str) - 1] = '\0';
> +	strncpy(val_str, buf, sizeof(val_str) - 1);
> +	len = strlen(val_str);
> +
> +	if (len && val_str[len - 1] == '\n')
> +		val_str[len - 1] = '\0';
> +
> +	for (i = 0; i < 4; i++) {
> +		if (!strcmp(val_str, axp20x_ea->str[i])) {
> +
> +			i <<= ffs(axp20x_ea->mask) - 1;
> +			ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
> +						 AXP20X_PEK_KEY,
> +						 axp20x_ea->mask, i);
> +			if (ret != 0)
> +				return -EINVAL;
> +			return count;
> +		}
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static struct dev_ext_attribute axp20x_dev_attr_startup = {
> +	.attr	= __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
> +	.var	= &axp20x_pek_startup_ext_attr
> +};
> +
> +static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
> +	__ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
> +	&axp20x_pek_shutdown_ext_attr
> +};
> +
> +static struct attribute *dev_attrs[] = {
> +	&axp20x_dev_attr_startup.attr.attr,
> +	&axp20x_dev_attr_shutdown.attr.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group dev_attr_group = {
> +	.attrs	= dev_attrs,
> +};
> +
> +static const struct attribute_group *dev_attr_groups[] = {
> +	&dev_attr_group,
> +	NULL,
> +};
> +
> +static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
> +{
> +	struct input_dev *idev = pwr;
> +	struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
> +
> +	if (irq == axp20x_pek->irq_dbr)
> +		input_report_key(idev, KEY_POWER, true);
> +	else if (irq == axp20x_pek->irq_dbf)
> +		input_report_key(idev, KEY_POWER, false);
> +
> +	input_sync(idev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int axp20x_pek_probe(struct platform_device *pdev)
> +{
> +	struct axp20x_pek *axp20x_pek;
> +	struct axp20x_dev *axp20x;
> +	struct input_dev *idev;
> +	int error;
> +
> +	axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
> +				  GFP_KERNEL);
> +	if (!axp20x_pek)
> +		return -ENOMEM;
> +
> +	axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
> +	axp20x = axp20x_pek->axp20x;
> +
> +	axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
> +	if (axp20x_pek->irq_dbr < 0) {
> +		dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
> +				axp20x_pek->irq_dbr);
> +		return axp20x_pek->irq_dbr;
> +	}
> +	axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
> +						  axp20x_pek->irq_dbr);
> +
> +	axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
> +	if (axp20x_pek->irq_dbf < 0) {
> +		dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
> +				axp20x_pek->irq_dbf);
> +		return axp20x_pek->irq_dbf;
> +	}
> +	axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
> +						  axp20x_pek->irq_dbf);
> +
> +	axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
> +	if (!axp20x_pek->input)
> +		return -ENOMEM;
> +
> +	idev = axp20x_pek->input;
> +
> +	idev->name = "axp20x-pek";
> +	idev->phys = "m1kbd/input2";
> +	idev->dev.parent = &pdev->dev;
> +
> +	input_set_capability(idev, EV_KEY, KEY_POWER);
> +
> +	input_set_drvdata(idev, axp20x_pek);
> +
> +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr,
> +					  NULL, axp20x_pek_irq, 0,
> +					  "axp20x-pek-dbr", idev);
> +	if (error) {
> +		dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
> +			axp20x_pek->irq_dbr, error);
> +
> +		return error;
> +	}
> +
> +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbf,
> +					  NULL, axp20x_pek_irq, 0,
> +					  "axp20x-pek-dbf", idev);
> +	if (error) {
> +		dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
> +			axp20x_pek->irq_dbf, error);
> +		return error;
> +	}
> +
> +	idev->dev.groups = dev_attr_groups;
> +	error = input_register_device(idev);
> +	if (error) {
> +		dev_err(axp20x->dev, "Can't register input device: %d\n", error);
> +		return error;
> +	}
> +
> +	platform_set_drvdata(pdev, axp20x_pek);
> +
> +	return 0;
> +}
> +
> +static int axp20x_pek_remove(struct platform_device *pdev)
> +{
> +	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
> +
> +	input_unregister_device(axp20x_pek->input);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id axp20x_pek_match[] = {
> +	{ .compatible = "x-powers,axp20x-pek", },

No pattern-matching compatible strings please.

Thanks!
Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v2 6/8] ARM: sunxi: dt: Add x-powers-axp209.dtsi file
From: Maxime Ripard @ 2014-03-18  9:04 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <1394898225-28452-7-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1789 bytes --]

On Sat, Mar 15, 2014 at 04:43:43PM +0100, Carlo Caione wrote:
> This dtsi describes the axp209 PMIC, and is to be included from inside
> the i2c controller node to which the axp209 is connected.
> 
> Signed-off-by: Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/boot/dts/x-powers-axp209.dtsi | 60 ++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
>  create mode 100644 arch/arm/boot/dts/x-powers-axp209.dtsi
> 
> diff --git a/arch/arm/boot/dts/x-powers-axp209.dtsi b/arch/arm/boot/dts/x-powers-axp209.dtsi
> new file mode 100644
> index 0000000..d272e67
> --- /dev/null
> +++ b/arch/arm/boot/dts/x-powers-axp209.dtsi
> @@ -0,0 +1,60 @@
> +/*
> + * x-powers,axp209 common code to be include from inside the axp209 node
> + *
> + * Copyright 2014 - Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +

I didn't even know such a thing was possible :)
Nice hack.

> +	compatible = "x-powers,axp209";
> +	interrupt-controller;
> +	#interrupt-cells = <1>;

However, I'd move this out of it, and in the board file, so that we
actually get an idea by looking at the board DTS of what device we are
actually registering at this given address, and what it's capable of.

Maxime

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v2 8/8] ARM: sunxi: Add AXP20x support in defconfig
From: Maxime Ripard @ 2014-03-18  9:05 UTC (permalink / raw)
  To: Carlo Caione
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	lee.jones-QSEj5FYQhm4dnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <1394898225-28452-9-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 417 bytes --]

On Sat, Mar 15, 2014 at 04:43:45PM +0100, Carlo Caione wrote:
> Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> ---
>  arch/arm/configs/sunxi_defconfig | 4 ++++
>  1 file changed, 4 insertions(+)

Could you add another patch doing the same with multi_v7 ?

Thanks!

-- 
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* Re: [PATCH v2 3/8] input: misc: Add driver for AXP20x Power Enable Key
From: Lee Jones @ 2014-03-18  9:50 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Carlo Caione, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
	hdegoede-H+wXaHxf7aLQT0dZR+AlfA, emilio-0Z03zUJReD5OxF6Tv1QG9Q,
	wens-jdAy2FN1RRM, sameo-VuQAYsv1563Yd54FQh9/CA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	linux-doc-u79uwXL29TY76Z2rM5mHXA,
	lgirdwood-Re5JQEeQqe8AvxtiuMwx3w, broonie-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <20140318090013.GU27873@lukather>

> > This patch add support for the Power Enable Key found on MFD AXP202 and
> > AXP209. Besides the basic support for the button, the driver adds two
> > entries in sysfs to configure the time delay for power on/off.
> > 
> > Signed-off-by: Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> > ---
> >  drivers/input/misc/Kconfig      |  11 ++
> >  drivers/input/misc/Makefile     |   1 +
> >  drivers/input/misc/axp20x-pek.c | 267 ++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 279 insertions(+)
> >  create mode 100644 drivers/input/misc/axp20x-pek.c
> 
> From what I understood of the MFD framework, you usually have a MFD
> core driver that gets loaded from the DT and instantiate its various
> functions through sub-devices, that are registered through
> mfd_add_devices, and the drivers for these sub-devices are supported
> in sub-drivers that are located in the driver/mfd, alongside the core
> driver.
> 
> I believe that such a pattern allows for two interesting things:
>   - You don't have to search around the whole kernel tree to find
>     where a given sub-feature is supported.
>   - You don't have to cripple your DT with instantiation of all the
>     subcomponents, while you only really have one device.
> 
> Do you have a reason for not following this pattern?

Sorry Maxime, this is not the case.

If an MFD contains Regulators and USB & GPIO Controllers, I'd expect
to see the device represented in the following way:

  drivers/mfd/<id>.c
  drivers/{gpio,pinctrl}/{gpio,pinctrl}-<id>.c
  drivers/regulator/<id>-regulator.c
  drivers/usb/host/<id>.c

> > diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> > index 7904ab0..87244fb 100644
> > --- a/drivers/input/misc/Kconfig
> > +++ b/drivers/input/misc/Kconfig
> > @@ -393,6 +393,17 @@ config INPUT_RETU_PWRBUTTON
> >  	  To compile this driver as a module, choose M here. The module will
> >  	  be called retu-pwrbutton.
> >  
> > +config INPUT_AXP20X_PEK
> > +	tristate "X-Powers AXP20X power button driver"
> > +	depends on MFD_AXP20X
> > +	help
> > +	  Say Y here if you want to enable power key reporting via the
> > +	  AXP20X PMIC.
> > +
> > +	  To compile this driver as a module, choose M here. The module will
> > +	  be called axp20x-pek.
> > +
> > +
> >  config INPUT_TWL4030_PWRBUTTON
> >  	tristate "TWL4030 Power button Driver"
> >  	depends on TWL4030_CORE
> > diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> > index cda71fc..624abf5 100644
> > --- a/drivers/input/misc/Makefile
> > +++ b/drivers/input/misc/Makefile
> > @@ -50,6 +50,7 @@ obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
> >  obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
> >  obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
> >  obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
> > +obj-$(CONFIG_INPUT_AXP20X_PEK)		+= axp20x-pek.o
> >  obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
> >  obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
> >  obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
> > diff --git a/drivers/input/misc/axp20x-pek.c b/drivers/input/misc/axp20x-pek.c
> > new file mode 100644
> > index 0000000..060212f
> > --- /dev/null
> > +++ b/drivers/input/misc/axp20x-pek.c
> > @@ -0,0 +1,267 @@
> > +/*
> > + * axp20x power button driver.
> > + *
> > + * Copyright (C) 2013 Carlo Caione <carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org>
> > + *
> > + * This file is subject to the terms and conditions of the GNU General
> > + * Public License. See the file "COPYING" in the main directory of this
> > + * archive for more details.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/errno.h>
> > +#include <linux/irq.h>
> > +#include <linux/init.h>
> > +#include <linux/input.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/kernel.h>
> > +#include <linux/mfd/axp20x.h>
> > +#include <linux/module.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/regmap.h>
> > +#include <linux/slab.h>
> > +
> > +#define AXP20X_PEK_STARTUP_MASK		(0xc0)
> > +#define AXP20X_PEK_SHUTDOWN_MASK	(0x03)
> > +
> > +static const char const *startup_time[] = { "128ms", "3s" , "1s", "2s" };
> > +static const char const *shutdown_time[] = { "4s", "6s" , "8s", "10s" };
> > +
> > +struct axp20x_pek {
> > +	struct axp20x_dev *axp20x;
> > +	struct input_dev *input;
> > +	int irq_dbr;
> > +	int irq_dbf;
> > +};
> > +
> > +struct axp20x_pek_ext_attr {
> > +	const char const **str;
> > +	unsigned int mask;
> > +};
> > +
> > +static struct axp20x_pek_ext_attr axp20x_pek_startup_ext_attr = {
> > +	.str	= startup_time,
> > +	.mask	= AXP20X_PEK_STARTUP_MASK,
> > +};
> > +
> > +static struct axp20x_pek_ext_attr axp20x_pek_shutdown_ext_attr = {
> > +	.str	= shutdown_time,
> > +	.mask	= AXP20X_PEK_SHUTDOWN_MASK,
> > +};
> > +
> > +static struct axp20x_pek_ext_attr *get_axp_ext_attr(struct device_attribute *attr)
> > +{
> > +	return container_of(attr, struct dev_ext_attribute, attr)->var;
> > +}
> > +
> > +static ssize_t axp20x_show_ext_attr(struct device *dev, struct device_attribute *attr,
> > +			     char *buf)
> > +{
> > +	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
> > +	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
> > +	unsigned int val;
> > +	int ret, i;
> > +	int cnt = 0;
> > +
> > +	ret = regmap_read(axp20x_pek->axp20x->regmap, AXP20X_PEK_KEY, &val);
> > +	if (ret != 0)
> > +		return ret;
> > +
> > +	val &= axp20x_ea->mask;
> > +	val >>= ffs(axp20x_ea->mask) - 1;
> > +
> > +	for (i = 0; i < 4; i++) {
> > +		if (val == i)
> > +			cnt += sprintf(buf + cnt, "[%s] ", axp20x_ea->str[i]);
> > +		else
> > +			cnt += sprintf(buf + cnt, "%s ", axp20x_ea->str[i]);
> > +	}
> > +
> > +	cnt += sprintf(buf + cnt, "\n");
> > +
> > +	return cnt;
> > +}
> > +
> > +static ssize_t axp20x_store_ext_attr(struct device *dev, struct device_attribute *attr,
> > +			      const char *buf, size_t count)
> > +{
> > +	struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
> > +	struct axp20x_pek_ext_attr *axp20x_ea = get_axp_ext_attr(attr);
> > +	char val_str[20];
> > +	int ret, i;
> > +	size_t len;
> > +
> > +	val_str[sizeof(val_str) - 1] = '\0';
> > +	strncpy(val_str, buf, sizeof(val_str) - 1);
> > +	len = strlen(val_str);
> > +
> > +	if (len && val_str[len - 1] == '\n')
> > +		val_str[len - 1] = '\0';
> > +
> > +	for (i = 0; i < 4; i++) {
> > +		if (!strcmp(val_str, axp20x_ea->str[i])) {
> > +
> > +			i <<= ffs(axp20x_ea->mask) - 1;
> > +			ret = regmap_update_bits(axp20x_pek->axp20x->regmap,
> > +						 AXP20X_PEK_KEY,
> > +						 axp20x_ea->mask, i);
> > +			if (ret != 0)
> > +				return -EINVAL;
> > +			return count;
> > +		}
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static struct dev_ext_attribute axp20x_dev_attr_startup = {
> > +	.attr	= __ATTR(startup, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
> > +	.var	= &axp20x_pek_startup_ext_attr
> > +};
> > +
> > +static struct dev_ext_attribute axp20x_dev_attr_shutdown = {
> > +	__ATTR(shutdown, 0644, axp20x_show_ext_attr, axp20x_store_ext_attr),
> > +	&axp20x_pek_shutdown_ext_attr
> > +};
> > +
> > +static struct attribute *dev_attrs[] = {
> > +	&axp20x_dev_attr_startup.attr.attr,
> > +	&axp20x_dev_attr_shutdown.attr.attr,
> > +	NULL,
> > +};
> > +
> > +static struct attribute_group dev_attr_group = {
> > +	.attrs	= dev_attrs,
> > +};
> > +
> > +static const struct attribute_group *dev_attr_groups[] = {
> > +	&dev_attr_group,
> > +	NULL,
> > +};
> > +
> > +static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
> > +{
> > +	struct input_dev *idev = pwr;
> > +	struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);
> > +
> > +	if (irq == axp20x_pek->irq_dbr)
> > +		input_report_key(idev, KEY_POWER, true);
> > +	else if (irq == axp20x_pek->irq_dbf)
> > +		input_report_key(idev, KEY_POWER, false);
> > +
> > +	input_sync(idev);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int axp20x_pek_probe(struct platform_device *pdev)
> > +{
> > +	struct axp20x_pek *axp20x_pek;
> > +	struct axp20x_dev *axp20x;
> > +	struct input_dev *idev;
> > +	int error;
> > +
> > +	axp20x_pek = devm_kzalloc(&pdev->dev, sizeof(struct axp20x_pek),
> > +				  GFP_KERNEL);
> > +	if (!axp20x_pek)
> > +		return -ENOMEM;
> > +
> > +	axp20x_pek->axp20x = dev_get_drvdata(pdev->dev.parent);
> > +	axp20x = axp20x_pek->axp20x;
> > +
> > +	axp20x_pek->irq_dbr = platform_get_irq_byname(pdev, "PEK_DBR");
> > +	if (axp20x_pek->irq_dbr < 0) {
> > +		dev_err(&pdev->dev, "No IRQ for PEK_DBR, error=%d\n",
> > +				axp20x_pek->irq_dbr);
> > +		return axp20x_pek->irq_dbr;
> > +	}
> > +	axp20x_pek->irq_dbr = regmap_irq_get_virq(axp20x->regmap_irqc,
> > +						  axp20x_pek->irq_dbr);
> > +
> > +	axp20x_pek->irq_dbf = platform_get_irq_byname(pdev, "PEK_DBF");
> > +	if (axp20x_pek->irq_dbf < 0) {
> > +		dev_err(&pdev->dev, "No IRQ for PEK_DBF, error=%d\n",
> > +				axp20x_pek->irq_dbf);
> > +		return axp20x_pek->irq_dbf;
> > +	}
> > +	axp20x_pek->irq_dbf = regmap_irq_get_virq(axp20x->regmap_irqc,
> > +						  axp20x_pek->irq_dbf);
> > +
> > +	axp20x_pek->input = devm_input_allocate_device(&pdev->dev);
> > +	if (!axp20x_pek->input)
> > +		return -ENOMEM;
> > +
> > +	idev = axp20x_pek->input;
> > +
> > +	idev->name = "axp20x-pek";
> > +	idev->phys = "m1kbd/input2";
> > +	idev->dev.parent = &pdev->dev;
> > +
> > +	input_set_capability(idev, EV_KEY, KEY_POWER);
> > +
> > +	input_set_drvdata(idev, axp20x_pek);
> > +
> > +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbr,
> > +					  NULL, axp20x_pek_irq, 0,
> > +					  "axp20x-pek-dbr", idev);
> > +	if (error) {
> > +		dev_err(axp20x->dev, "Failed to request dbr IRQ#%d: %d\n",
> > +			axp20x_pek->irq_dbr, error);
> > +
> > +		return error;
> > +	}
> > +
> > +	error = devm_request_threaded_irq(&pdev->dev, axp20x_pek->irq_dbf,
> > +					  NULL, axp20x_pek_irq, 0,
> > +					  "axp20x-pek-dbf", idev);
> > +	if (error) {
> > +		dev_err(axp20x->dev, "Failed to request dbf IRQ#%d: %d\n",
> > +			axp20x_pek->irq_dbf, error);
> > +		return error;
> > +	}
> > +
> > +	idev->dev.groups = dev_attr_groups;
> > +	error = input_register_device(idev);
> > +	if (error) {
> > +		dev_err(axp20x->dev, "Can't register input device: %d\n", error);
> > +		return error;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, axp20x_pek);
> > +
> > +	return 0;
> > +}
> > +
> > +static int axp20x_pek_remove(struct platform_device *pdev)
> > +{
> > +	struct axp20x_pek *axp20x_pek = platform_get_drvdata(pdev);
> > +
> > +	input_unregister_device(axp20x_pek->input);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id axp20x_pek_match[] = {
> > +	{ .compatible = "x-powers,axp20x-pek", },
> 
> No pattern-matching compatible strings please.
> 
> Thanks!
> Maxime
> 



-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

-- 
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.

^ permalink raw reply

* Re: [PATCH v3 1/4] mfd: max8997: use regmap to access registers
From: Chanwoo Choi @ 2014-03-18  9:51 UTC (permalink / raw)
  To: Robert Baldyga
  Cc: sameo, lee.jones, myungjoo.ham, dmitry.torokhov, cooloney,
	rpurdie, dbaryshkov, dwmw2, lgirdwood, broonie, a.zummo,
	paul.gortmaker, linux-kernel, linux-input, linux-leds, rtc-linux,
	m.szyprowski, k.kozlowski
In-Reply-To: <1394703532-494-2-git-send-email-r.baldyga@samsung.com>

On 03/13/2014 06:38 PM, Robert Baldyga wrote:
> This patch modifies max8997 driver and each associated function driver,
> to use regmap instead of operating directly on i2c bus. It will allow to
> simplify IRQ handling using regmap-irq.
> 
> Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
>  drivers/extcon/extcon-max8997.c     |   31 ++++----
>  drivers/input/misc/max8997_haptic.c |   34 +++++----
>  drivers/leds/leds-max8997.c         |   13 ++--
>  drivers/mfd/Kconfig                 |    1 +
>  drivers/mfd/max8997-irq.c           |   64 +++++++---------
>  drivers/mfd/max8997.c               |  141 ++++++++++++++++-------------------
>  drivers/power/max8997_charger.c     |   33 ++++----
>  drivers/regulator/max8997.c         |   87 +++++++++++----------
>  drivers/rtc/rtc-max8997.c           |   56 +++++++-------
>  include/linux/mfd/max8997-private.h |   17 ++---
>  10 files changed, 228 insertions(+), 249 deletions(-)
> 

For extcon part,
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>

Thanks,
Chanwoo Choi


^ permalink raw reply

* Re: [PATCH v3 2/4] mfd: max8997: handle IRQs using regmap
From: Chanwoo Choi @ 2014-03-18  9:52 UTC (permalink / raw)
  To: Robert Baldyga
  Cc: sameo, lee.jones, myungjoo.ham, dmitry.torokhov, cooloney,
	rpurdie, dbaryshkov, dwmw2, lgirdwood, broonie, a.zummo,
	paul.gortmaker, linux-kernel, linux-input, linux-leds, rtc-linux,
	m.szyprowski, k.kozlowski
In-Reply-To: <5322BEDF.4080408@samsung.com>

On 03/14/2014 05:33 PM, Robert Baldyga wrote:
> On 03/13/2014 11:45 AM, Chanwoo Choi wrote:
>> Hi Robert,
>>
>> On 03/13/2014 06:38 PM, Robert Baldyga wrote:
>>> This patch modifies mfd driver to use regmap for handling interrupts.
>>> It allows to simplify irq handling process. This modifications needed
>>> to make small changes in function drivers, which use interrupts.
>>>
>>> Signed-off-by: Robert Baldyga <r.baldyga@samsung.com>
> 
> (...)
> 
>>> @@ -468,8 +560,11 @@ static int max8997_suspend(struct device *dev)
>>>  	struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
>>>  	struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
>>>  
>>> -	if (device_may_wakeup(dev))
>>> -		irq_set_irq_wake(max8997->irq, 1);
>>> +	if (device_may_wakeup(dev)) {
>>> +		enable_irq_wake(max8997->irq);
>>> +		disable_irq(max8997->irq);
>>
>> irq_set_irq_wake() is same as enable_irq_wake().
> 
> It's more intuitive name and makes code reading easier.
> 
>> Why is it necessary for disable_irq(max8997->irq)?
> 
> It's because we don't want to get interrupts before i2c controller will
> be ready. So we disable irq in drivers suspend, and enable in resume.
> 
> If some iqr will come before enable_irq() call, it will be noticed, and
> IRQ_PENDING flag will be set. In this case irq will be handled
> immediately after enable_irq() call.
> 
> In previous version there was call of max8997_irq_resume() in resume
> function, which caused forced interrupt handling, which has similar effect.
> 

OK,

For extcon part,
Acked-by: Chanwoo Choi <cw00.choi@samsung.com>

Thanks,
Chanwoo Choi

^ permalink raw reply


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