Skip to contentSkip to conversation

ARM: tegra: add nvec keyboard support for paz00

PATCH In review Andrey Danin 6 participants 19 messages Apr 27, 2014 – Apr 30, 2014 5 messages not in the archive

Subsystems (5)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [PATCH 0/3] ARM: tegra: add nvec keyboard support for paz00

#1 lore raw

v2 cover ARM: tegra: add nvec keyboard support for paz00

This patch series introduces keyboard support for AC100 (board paz00).

I2C slave mode was implemented for i2c core and tegra-i2c.

NVEC code from linux kernel was reworked to use tegra-i2c driver.

Keytable header file is copied from linux kernel but modified to fix styles and remove unused code.

Based on u-boot-tegra/next.

CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>

---
Changes for v2:
- I2C slave mode for i2c-core and tegra-i2c implemented
- Fixed NVEC dt bindings
- NVEC driver was reworked to use tegra-i2c
- fixed incorrect keys handling in nvec-keyboard driver
- patch is splitted to smaller parts

Andrey Danin (6):
i2c: add slave mode support
ARM: tegra: i2c: add slave mode support
ARM: tegra: i2c: add nvec driver
ARM: tegra: nvec: add keyboard support
ARM: tegra: paz00: add dt bindings for nvec
ARM: tegra: paz00: enable nvec keyboard

 arch/arm/include/asm/arch-tegra/tegra_i2c.h        |    6 +
 arch/arm/include/asm/arch-tegra/tegra_nvec.h       |  130 +++++++++
 .../include/asm/arch-tegra/tegra_nvec_keyboard.h   |  304 ++++++++++++++++++++
 board/compal/dts/tegra20-paz00.dts                 |    8 +-
 board/nvidia/common/board.c                        |   12 +
 drivers/i2c/Makefile                               |    1 +
 drivers/i2c/i2c_core.c                             |   13 +
 drivers/i2c/tegra_i2c.c                            |  199 ++++++++++++-
 drivers/i2c/tegra_nvec.c                           |  294 +++++++++++++++++++
 drivers/input/Makefile                             |    3 +
 drivers/input/tegra-nvec-kbc.c                     |  215 ++++++++++++++
 include/configs/paz00.h                            |    9 +
 include/configs/tegra-common-post.h                |    2 +
 include/fdtdec.h                                   |    1 +
 include/i2c.h                                      |   30 +-
 lib/fdtdec.c                                       |    1 +
 16 files changed, 1223 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h
 create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h
 create mode 100644 drivers/i2c/tegra_nvec.c
 create mode 100644 drivers/input/tegra-nvec-kbc.c
Signature · 6 lines
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#2 lore raw

PATCH v2 1/6 i2c: add slave mode support

CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net
---
 drivers/i2c/i2c_core.c |   13 +++++++++++++
 include/i2c.h          |   30 +++++++++++++++++++++++++++++-
 2 files changed, 42 insertions(+), 1 deletion(-)
drivers/i2c/i2c_core.c +13 -0
index 18d6736..105aa0a 100644
@@ -395,6 +395,19 @@ void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val)
 	i2c_write(addr, reg, 1, &val, 1);
 }
 
+int i2c_slave_io(struct i2c_transaction *trans)
+{
+	struct i2c_adapter *cur = I2C_ADAP;
+
+	if (!cur->slave_io) {
+		printf("Error: slave IO is not supported on adap %d\n",
+		       cur->hwadapnr);
+		return -1;
+	}
+
+	return cur->slave_io(cur, trans);
+}
+
 void __i2c_init(int speed, int slaveaddr)
 {
 	i2c_init_bus(i2c_get_bus_num(), speed, slaveaddr);
include/i2c.h +29 -1
index f93a183..165b919 100644
@@ -55,6 +55,20 @@
 #define CONFIG_SYS_SPD_BUS_NUM		0
 #endif
 
+struct i2c_transaction {
+	char rx_buf[34];
+	int rx_pos;
+
+	char tx_buf[34];
+	int tx_pos;
+	int tx_size;
+
+	unsigned int start_timeout;
+	unsigned int timeout;
+
+	int res;
+};
+
 struct i2c_adapter {
 	void		(*init)(struct i2c_adapter *adap, int speed,
 				int slaveaddr);
@@ -65,6 +79,8 @@ struct i2c_adapter {
 	int		(*write)(struct i2c_adapter *adap, uint8_t chip,
 				uint addr, int alen, uint8_t *buffer,
 				int len);
+	int		(*slave_io)(struct i2c_adapter *adap,
+				struct i2c_transaction *trans);
 	uint		(*set_bus_speed)(struct i2c_adapter *adap,
 				uint speed);
 	int		speed;
@@ -81,12 +97,13 @@ struct i2c_adapter {
 		.probe		=	_probe, \
 		.read		=	_read, \
 		.write		=	_write, \
+		.slave_io	=	0, \
 		.set_bus_speed	=	_set_speed, \
 		.speed		=	_speed, \
 		.slaveaddr	=	_slaveaddr, \
 		.init_done	=	0, \
 		.hwadapnr	=	_hwadapnr, \
-		.name		=	#_name \
+		.name		=	#_name, \
 };
 
 #define U_BOOT_I2C_ADAP_COMPLETE(_name, _init, _probe, _read, _write, \
@@ -450,4 +467,15 @@ int i2c_get_bus_num_fdt(int node);
  * @return 0 if port was reset, -1 if not found
  */
 int i2c_reset_port_fdt(const void *blob, int node);
+
+/**
+ * Perform I2C transaction with master device.
+ *
+ * @param trans  I2C transaction object
+ * @return 0 if succeeded, -1 if not supported,
+ *         1 if not ready, 2 if operation timed out,
+ *         3 if not our packet, other - unknown error.
+ */
+int i2c_slave_io(struct i2c_transaction *trans);
+
 #endif	/* _I2C_H_ */
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH v2 1/6 i2c: add slave mode support

In reply to Andrey Danin

Hello Andrey,

Am 27.04.2014 03:14, schrieb Andrey Danin:

Quoted 89 lines
CC Stephen Warren<[email protected]>
CC Marc Dietrich<[email protected]>
CC Julian Andres Klode<[email protected]>
CC ac100 at lists.launchpad.net
---
  drivers/i2c/i2c_core.c |   13 +++++++++++++
  include/i2c.h          |   30 +++++++++++++++++++++++++++++-
  2 files changed, 42 insertions(+), 1 deletion(-)
drivers/i2c/i2c_core.c +13 -0
index 18d6736..105aa0a 100644
@@ -395,6 +395,19 @@ void i2c_reg_write(uint8_t addr, uint8_t reg, uint8_t val)
  	i2c_write(addr, reg, 1,&val, 1);
  }
 
+int i2c_slave_io(struct i2c_transaction *trans)
+{
+	struct i2c_adapter *cur = I2C_ADAP;
+
+	if (!cur->slave_io) {
+		printf("Error: slave IO is not supported on adap %d\n",
+		       cur->hwadapnr);
+		return -1;
+	}
+
+	return cur->slave_io(cur, trans);
+}
+
  void __i2c_init(int speed, int slaveaddr)
  {
  	i2c_init_bus(i2c_get_bus_num(), speed, slaveaddr);
include/i2c.h +20 -1
index f93a183..165b919 100644
@@ -55,6 +55,20 @@
  #define CONFIG_SYS_SPD_BUS_NUM		0
  #endif
 
+struct i2c_transaction {
+	char rx_buf[34];
+	int rx_pos;
+
+	char tx_buf[34];
+	int tx_pos;
+	int tx_size;
+
+	unsigned int start_timeout;
+	unsigned int timeout;
+
+	int res;
+};
+
  struct i2c_adapter {
  	void		(*init)(struct i2c_adapter *adap, int speed,
  				int slaveaddr);
@@ -65,6 +79,8 @@ struct i2c_adapter {
  	int		(*write)(struct i2c_adapter *adap, uint8_t chip,
  				uint addr, int alen, uint8_t *buffer,
  				int len);
+	int		(*slave_io)(struct i2c_adapter *adap,
+				struct i2c_transaction *trans);
  	uint		(*set_bus_speed)(struct i2c_adapter *adap,
  				uint speed);
  	int		speed;
@@ -81,12 +97,13 @@ struct i2c_adapter {
  		.probe		=	_probe, \
  		.read		=	_read, \
  		.write		=	_write, \
+		.slave_io	=	0, \
  		.set_bus_speed	=	_set_speed, \
  		.speed		=	_speed, \
  		.slaveaddr	=	_slaveaddr, \
  		.init_done	=	0, \
  		.hwadapnr	=	_hwadapnr, \
-		.name		=	#_name \
+		.name		=	#_name, \
  };
 
  #define U_BOOT_I2C_ADAP_COMPLETE(_name, _init, _probe, _read, _write, \
@@ -450,4 +467,15 @@ int i2c_get_bus_num_fdt(int node);
   * @return 0 if port was reset, -1 if not found
   */
  int i2c_reset_port_fdt(const void *blob, int node);
+
+/**

include/i2c.h int i2c_get_bus_num_fdt(int node); · line 481

Quoted 10 lines
include/i2c.h +9 -0
+ * Perform I2C transaction with master device.
+ *
+ * @param trans  I2C transaction object
+ * @return 0 if succeeded, -1 if not supported,
+ *         1 if not ready, 2 if operation timed out,
+ *         3 if not our packet, other - unknown error.
+ */
+int i2c_slave_io(struct i2c_transaction *trans);
+
  #endif	/* _I2C_H_ */

Hmm, why you use positiv error codes? Can we use negativ codes here please? And maybe define somewhere this values as defines? Or can you use:

include/asm-generic/errno.h

Beside of that, it looks Ok to me.

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#6 lore raw

PATCH v2 2/6 ARM: tegra: i2c: add slave mode support

In reply to Andrey Danin
CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net
---
 arch/arm/include/asm/arch-tegra/tegra_i2c.h |    6 +
 drivers/i2c/tegra_i2c.c                     |  199 ++++++++++++++++++++++++++-
 2 files changed, 202 insertions(+), 3 deletions(-)
arch/arm/include/asm/arch-tegra/tegra_i2c.h +6 -0
index 853e59b..f818731 100644
@@ -132,13 +132,19 @@ struct i2c_ctlr {
 				(1 << DVC_CTRL_REG3_I2C_HW_SW_PROG_SHIFT)
 
 /* I2C_CNFG */
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12
+#define I2C_CNFG_DEBOUNCE_CNT_MASK	(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT)
 #define I2C_CNFG_NEW_MASTER_FSM_SHIFT	11
 #define I2C_CNFG_NEW_MASTER_FSM_MASK	(1 << I2C_CNFG_NEW_MASTER_FSM_SHIFT)
 #define I2C_CNFG_PACKET_MODE_SHIFT	10
 #define I2C_CNFG_PACKET_MODE_MASK	(1 << I2C_CNFG_PACKET_MODE_SHIFT)
 
 /* I2C_SL_CNFG */
+#define I2C_SL_CNFG_RESP_SHIFT		0
+#define I2C_SL_CNFG_NACK_SHIFT		1
 #define I2C_SL_CNFG_NEWSL_SHIFT		2
+#define I2C_SL_CNFG_IRQ_SHIFT		3
+#define I2C_SL_CNFG_END_TRANS_SHIFT	4
 #define I2C_SL_CNFG_NEWSL_MASK		(1 << I2C_SL_CNFG_NEWSL_SHIFT)
 
 /* I2C_FIFO_STATUS */
drivers/i2c/tegra_i2c.c +196 -3

261 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#7 lore raw

PATCH v2 2/6 ARM: tegra: i2c: add slave mode support

Hello Andrey,

Am 27.04.2014 03:14, schrieb Andrey Danin:

Quoted 9 lines
CC Stephen Warren<[email protected]>
CC Marc Dietrich<[email protected]>
CC Julian Andres Klode<[email protected]>
CC ac100 at lists.launchpad.net
---
  arch/arm/include/asm/arch-tegra/tegra_i2c.h |    6 +
  drivers/i2c/tegra_i2c.c                     |  199 ++++++++++++++++++++++++++-
  2 files changed, 202 insertions(+), 3 deletions(-)

only some nitpicking comments ...

[...]

Quoted 26 lines
drivers/i2c/tegra_i2c.c +7 -0
index 594e5dd..287a5df 100644
@@ -22,6 +22,7 @@ DECLARE_GLOBAL_DATA_PTR;
  /* Information about i2c controller */
  struct i2c_bus {
  	int			id;
+	int			node;
  	enum periph_id		periph_id;
  	int			speed;
  	int			pinmux_config;
@@ -30,10 +31,31 @@ struct i2c_bus {
  	int			is_dvc;	/* DVC type, rather than I2C */
  	int			is_scs;	/* single clock source (T114+) */
  	int			inited;	/* bus is inited */
+	int			slave_addr;
  };
 
  static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS];
 
+/**
+ * Init i2c controller to operate in slave mode.
+ *
+ * @param bus	i2c bus/controller state struct
+ */

drivers/i2c/tegra_i2c.c struct i2c_bus { · line 53

Quoted 10 lines
drivers/i2c/tegra_i2c.c +10 -0
+static void set_slave_mode(struct i2c_bus *bus)
+{
+	unsigned long val;
+
+	val = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK |
+	    I2C_CNFG_DEBOUNCE_CNT_MASK;
+	writel(val,&bus->regs->cnfg);
+
+	writel(I2C_SL_CNFG_NEWSL_MASK,&bus->regs->sl_cnfg);
+	writel(0x1E,&bus->regs->sl_delay_count);

Space after "," please. Please check globally.

Quoted 24 lines
drivers/i2c/tegra_i2c.c +11 -2
+
+	writel(bus->slave_addr>>  1,&bus->regs->sl_addr1);
+	writel(0,&bus->regs->sl_addr2);
+}
+
  static void set_packet_mode(struct i2c_bus *i2c_bus)
  {
  	u32 config;
@@ -59,8 +81,12 @@ static void i2c_reset_controller(struct i2c_bus *i2c_bus)
  	/* Reset I2C controller. */
  	reset_periph(i2c_bus->periph_id, 1);
 
-	/* re-program config register to packet mode */
-	set_packet_mode(i2c_bus);
+	if (i2c_bus->slave_addr == 0) {
+		/* re-program config register to packet mode */
+		set_packet_mode(i2c_bus);
+	} else {
+		set_slave_mode(i2c_bus);
+	}
  }
 
  static void i2c_init_controller(struct i2c_bus *i2c_bus)

drivers/i2c/tegra_i2c.c static int wait_for_transfer_complete(struct i2c_control *control) · line 228

Quoted 10 lines
drivers/i2c/tegra_i2c.c +7 -0
@@ -193,6 +219,121 @@ static int wait_for_transfer_complete(struct i2c_control *control)
  	return -1;
  }
 
+
+#define I2C_SL_IRQ		(1<<3)
+#define END_TRANS		(1<<4)
+#define RCVD			(1<<2)
+#define RNW			(1<<1)
+
+

only one empty line please. Please check globally.

Quoted 23 lines
drivers/i2c/tegra_i2c.c +23 -0
+static inline int is_ready(unsigned long status)
+{
+	return status&  I2C_SL_IRQ;
+}
+
+static inline int is_read(unsigned long status)
+{
+	return (status&  RNW) == 0;
+}
+
+static inline int is_trans_start(unsigned long status)
+{
+	return status&  RCVD;
+}
+
+static inline int is_trans_end(unsigned long status)
+{
+	return status&  END_TRANS;
+}
+
+
+/**
+ * Send or receive packet in slave mode.

drivers/i2c/tegra_i2c.c static int wait_for_transfer_complete(struct i2c_control *control) · line 261

Quoted 10 lines
drivers/i2c/tegra_i2c.c +10 -0
+ *
+ * @param i2c_bus	pointer to bus structure
+ * @param trans		I2C transaction object
+ *
+ * @return	0 if succeeded,
+ *		1 if not ready,
+ *		2 if operation timed out,
+ *		3 if not our packet,
+ *		other - unknown error.
+ */

See my reply to your patch 1/6. Can we use negativ error codes and defines?

Quoted 10 lines
drivers/i2c/tegra_i2c.c +10 -0
+static int slave_send_recv_packets(struct i2c_bus *i2c_bus,
+				   struct i2c_transaction *trans)
+{
+	unsigned int poll_start_ms = 0;
+	unsigned long status;
+
+	unsigned int received = 0;
+	unsigned int to_send = 0;
+	unsigned int timer_ms = 0;
+	int addr = -1;

drivers/i2c/tegra_i2c.c static int wait_for_transfer_complete(struct i2c_control *control)

Quoted 10 lines
drivers/i2c/tegra_i2c.c +10 -0
+
+	poll_start_ms = get_timer(0);
+
+	while (1) {
+		status = readl(&i2c_bus->regs->sl_status);
+		if (!is_ready(status)) {
+			timer_ms = get_timer(poll_start_ms);
+			if (addr != i2c_bus->slave_addr&&
+			    trans->start_timeout&&
+			    timer_ms>  trans->start_timeout) {

please add a space before "&&" and ">". Please check globally.

Quoted 42 lines
drivers/i2c/tegra_i2c.c +42 -0
+				trans->res = 1;
+				return 1; /*not ready*/
+			}
+
+			if (timer_ms>  trans->timeout) {
+				trans->res = 2;
+				return 2; /*timeout*/
+			}
+
+			udelay(100);
+			continue;
+		}
+
+		if (!is_trans_start(status)&&  addr != i2c_bus->slave_addr) {
+			trans->res = 3;
+			return 3; /* not our packet, retry */
+		}
+
+		if (is_trans_start(status)) {
+			if (!is_read(status)&&  addr != i2c_bus->slave_addr) {
+				trans->res = 3;
+				return 3; /* not our packet, retry */
+			}
+			if (is_read(status)) {
+				addr = readl(&i2c_bus->regs->sl_rcvd);
+				trans->rx_buf[trans->rx_pos++] = addr;
+				continue;
+			}
+		}
+
+		if (is_trans_end(status)) {
+			/* Check for repeated start */
+			if (!is_trans_start(status)) {
+				trans->res = 0;
+				return 0;
+			}
+		}
+
+		if (is_read(status)) {
+			/* TODO Check sizes */
+			received = readl(&i2c_bus->regs->sl_rcvd);
+			trans->rx_buf[trans->rx_pos++] = received;

drivers/i2c/tegra_i2c.c static int wait_for_transfer_complete(struct i2c_control *control) · line 333

Quoted 10 lines
drivers/i2c/tegra_i2c.c +10 -0
+		} else {
+			/* TODO Check sizes */
+			to_send = trans->tx_buf[trans->tx_pos++];
+			writel(to_send,&i2c_bus->regs->sl_rcvd);
+		}
+	}
+
+	/* not reachable */
+	trans->res = 4;
+	return 4;

What is error code 4? Please use defines ...

Quoted 89 lines
drivers/i2c/tegra_i2c.c +49 -1
+}
+
+
  static int send_recv_packets(struct i2c_bus *i2c_bus,
  			     struct i2c_trans_info *trans)
  {
@@ -343,6 +484,7 @@ static unsigned int tegra_i2c_set_bus_speed(struct i2c_adapter *adap,
 
  static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
  {
+	i2c_bus->node = node;
  	i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
 
  	/*
@@ -365,6 +507,8 @@ static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
  	if (i2c_bus->periph_id == -1)
  		return -FDT_ERR_NOTFOUND;
 
+	i2c_bus->slave_addr = fdtdec_get_int(blob, node, "slave-addr", -1);
+
  	return 0;
  }
 
@@ -422,6 +566,28 @@ static int process_nodes(const void *blob, int node_list[], int count,
  	return 0;
  }
 
+static int tegra_i2c_slave_io(struct i2c_adapter *adap,
+			      struct i2c_transaction *trans)
+{
+	struct i2c_bus *bus;
+	debug("tegra_i2c_slave_io: hwadapnr=%d\n", adap->hwadapnr);
+
+	bus = tegra_i2c_get_bus(adap);
+	if (!bus) {
+		error("tegra_i2c_slave_io: no bus for adapter %d\n",
+		      adap->hwadapnr);
+		return -1;
+	}
+
+	if (!bus->slave_addr) {
+		error("tegra_i2c_slave_io: adapter %d isn't in slave mode\n",
+		      adap->hwadapnr);
+		return -2;
+	}
+
+	return slave_send_recv_packets(bus, trans);
+}
+
  /* Sadly there is no error return from this function */
  void i2c_init_board(void)
  {
@@ -453,11 +619,20 @@ void i2c_init_board(void)
 
  static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
  {
+	struct i2c_bus *bus;
+
  	/* No i2c support prior to relocation */
  	if (!(gd->flags&  GD_FLG_RELOC))
  		return;
 
-	/* This will override the speed selected in the fdt for that port */
+	bus = tegra_i2c_get_bus(adap);
+	if (bus) {
+		adap->slave_io = tegra_i2c_slave_io;
+		debug("i2c_init: ignore static init for adapter %d\n",
+		      adap->hwadapnr);
+		return;
+	}
+
  	debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
  	i2c_set_bus_speed(speed);
  }
@@ -614,6 +789,24 @@ int tegra_i2c_get_dvc_bus_num(void)
  	return -1;
  }
 
+/**
+ * Find the I2C bus number by given a FDT I2C node.
+ *
+ * @param blob  Device tree blbo
+ * @param node  FDT I2C node to find
+ * @return the number of I2C bus (zero based), or -1 on error
+ */
+int i2c_get_bus_num_fdt(int node)
+{
+	int i;
+

drivers/i2c/tegra_i2c.c int tegra_i2c_get_dvc_bus_num(void) · line 812

Quoted 10 lines
drivers/i2c/tegra_i2c.c +7 -0
+	for (i = 0; i<  TEGRA_I2C_NUM_CONTROLLERS; ++i)
+		if (i2c_controllers[i].node == node)
+			return i2c_controllers[i].id;
+
+	return -1;
+}
+
  /*
   * Register soft i2c adapters
   */

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#8 lore raw

PATCH v2 3/6 ARM: tegra: i2c: add nvec driver

In reply to Andrey Danin
CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- NVEC driver was reworked to use tegra-i2c

 arch/arm/include/asm/arch-tegra/tegra_nvec.h |  130 ++++++++++++
 board/nvidia/common/board.c                  |   12 ++
 drivers/i2c/Makefile                         |    1 +
 drivers/i2c/tegra_nvec.c                     |  294 ++++++++++++++++++++++++++
 include/fdtdec.h                             |    1 +
 lib/fdtdec.c                                 |    1 +
 6 files changed, 439 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h
 create mode 100644 drivers/i2c/tegra_nvec.c
arch/arm/include/asm/arch-tegra/tegra_nvec.h new file +130 -0
new file mode 100644
index 0000000..f1cec0d
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _TEGRA_NVEC_H_
+#define _TEGRA_NVEC_H_
+
+#define I2C_CNFG			0x00
+#define I2C_CNFG_PACKET_MODE_EN		(1<<10)
+#define I2C_CNFG_NEW_MASTER_SFM		(1<<11)
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12
+
+#define I2C_SL_CNFG		0x20
+#define I2C_SL_NEWSL		(1<<2)
+#define I2C_SL_NACK		(1<<1)
+#define I2C_SL_RESP		(1<<0)
+#define I2C_SL_IRQ		(1<<3)
+#define END_TRANS		(1<<4)
+#define RCVD			(1<<2)
+#define RNW			(1<<1)
+
+#define I2C_SL_RCVD		0x24
+#define I2C_SL_STATUS		0x28
+#define I2C_SL_ADDR1		0x2c
+#define I2C_SL_ADDR2		0x30
+#define I2C_SL_DELAY_COUNT	0x3c
+
+
+enum nvec_msg_type {
+	NVEC_KEYBOARD = 0,
+	NVEC_SYS = 1,
+	NVEC_BAT,
+	NVEC_GPIO,
+	NVEC_SLEEP,
+	NVEC_KBD,
+	NVEC_PS2,
+	NVEC_CNTL,
+	NVEC_OEM0 = 0x0d,
+	NVEC_KB_EVT = 0x80,
+	NVEC_PS2_EVT,
+	NVEC_LAST_MSG,
+};
+
+enum nvec_event_size {
+	NVEC_2BYTES,
+	NVEC_3BYTES,
+	NVEC_VAR_SIZE,
+};
+
+enum sys_subcmds {
+	SYS_GET_STATUS,
+	SYS_CNFG_EVENT_REPORTING,
+	SYS_ACK_STATUS,
+	SYS_CNFG_WAKE = 0xfd,
+};
+
+enum kbd_subcmds {
+	CNFG_WAKE = 3,
+	CNFG_WAKE_KEY_REPORTING,
+	SET_LEDS = 0xed,
+	ENABLE_KBD = 0xf4,
+	DISABLE_KBD,
+};
+
+enum cntl_subcmds {
+	CNTL_RESET_EC = 0x00,
+	CNTL_SELF_TEST = 0x01,
+	CNTL_NOOP = 0x02,
+	CNTL_GET_EC_SPEC_VER = 0x10,
+	CNTL_GET_FIRMWARE_VERSION = 0x15,
+};
+
+enum nvec_sleep_subcmds {
+	GLOBAL_EVENTS,
+	AP_PWR_DOWN,
+	AP_SUSPEND,
+};
+
+enum ps2_subcmds {
+	MOUSE_SEND_CMD = 0x01
+};
+
+#define MOUSE_RESET 0xff
+
+typedef int (*periph_start)(void);
+typedef int (*periph_process_msg)(const unsigned char *);
+
+struct nvec_periph {
+	periph_start		start;
+	periph_process_msg	process_msg;
+};
+
+
+int board_nvec_init(void);
+
+/**
+ * Read all available events.
+ *
+ * @return count of available events if ok, -1 on error
+ */
+int nvec_read_events(void);
+
+int nvec_msg_is_event(const unsigned char *msg);
+int nvec_msg_event_type(const unsigned char *msg);
+
+/**
+ * Register perepherial device driver.
+ *
+ * @param msg_type	type of messages that divece processes.
+ * @param periph	pointer to device description.
+ *
+ * @return 0 if ok, -1 on error
+ */
+int nvec_register_periph(int msg_type, struct nvec_periph *periph);
+
+/**
+ * Send request and read response. If write or read failed
+ * operation will be repeated NVEC_ATTEMPTS_MAX times.
+ *
+ * @param buf		request data
+ * @param size		request data size
+ * @return 0 if ok, -1 on error
+ */
+int nvec_do_request(char *buf, int size);
+
+
+#endif /* _TEGRA_NVEC_H_ */
board/nvidia/common/board.c +12 -0
index 3b18e28..6d3055c 100644
@@ -38,6 +38,9 @@
 #include <asm/arch-tegra/tegra_mmc.h>
 #include <asm/arch-tegra/mmc.h>
 #endif
+#ifdef CONFIG_SYS_I2C_TEGRA_NVEC
+#include <asm/arch-tegra/tegra_nvec.h>
+#endif
 #include <i2c.h>
 #include <spi.h>
 #include "emc.h"
@@ -194,10 +197,19 @@ int board_early_init_f(void)
 
 int board_late_init(void)
 {
+	__maybe_unused int err;
+
 #ifdef CONFIG_LCD
 	/* Make sure we finish initing the LCD */
 	tegra_lcd_check_next_stage(gd->fdt_blob, 1);
 #endif
+
+#ifdef CONFIG_SYS_I2C_TEGRA_NVEC
+	err = board_nvec_init();
+	if (err)
+		debug("NVEC controller init failed: %d\n", err);
+#endif
+
 	return 0;
 }
 
drivers/i2c/Makefile +1 -0
index fa3a875..3041191 100644
@@ -27,4 +27,5 @@ obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
+obj-$(CONFIG_SYS_I2C_TEGRA_NVEC) += tegra_nvec.o
 obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o
drivers/i2c/tegra_nvec.c new file +294 -0

294 lines not on this page · raw message

include/fdtdec.h +1 -0
index 19bab79..7b84335 100644
@@ -64,6 +64,7 @@ enum fdt_compat_id {
 	COMPAT_NVIDIA_TEGRA20_SDMMC,	/* Tegra20 SDMMC controller */
 	COMPAT_NVIDIA_TEGRA20_SFLASH,	/* Tegra 2 SPI flash controller */
 	COMPAT_NVIDIA_TEGRA20_SLINK,	/* Tegra 2 SPI SLINK controller */
+	COMPAT_NVIDIA_TEGRA20_NVEC,	/* Tegra 2 EC controller */
 	COMPAT_NVIDIA_TEGRA114_SPI,	/* Tegra 114 SPI controller */
 	COMPAT_SMSC_LAN9215,		/* SMSC 10/100 Ethernet LAN9215 */
 	COMPAT_SAMSUNG_EXYNOS5_SROMC,	/* Exynos5 SROMC */
lib/fdtdec.c +1 -0
index 1fecab3..82df701 100644
@@ -37,6 +37,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
 	COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
 	COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
+	COMPAT(NVIDIA_TEGRA20_NVEC, "nvidia,tegra20-nvec"),
 	COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
 	COMPAT(SMSC_LAN9215, "smsc,lan9215"),
 	COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
Signature · 1 line
1.7.9.5
#9 lore raw

PATCH v2 3/6 ARM: tegra: i2c: add nvec driver

Hello Andrey,

Am 27.04.2014 03:14, schrieb Andrey Danin:

Quoted 46 lines
CC Stephen Warren<[email protected]>
CC Marc Dietrich<[email protected]>
CC Julian Andres Klode<[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- NVEC driver was reworked to use tegra-i2c

  arch/arm/include/asm/arch-tegra/tegra_nvec.h |  130 ++++++++++++
  board/nvidia/common/board.c                  |   12 ++
  drivers/i2c/Makefile                         |    1 +
  drivers/i2c/tegra_nvec.c                     |  294 ++++++++++++++++++++++++++
  include/fdtdec.h                             |    1 +
  lib/fdtdec.c                                 |    1 +
  6 files changed, 439 insertions(+)

create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h create mode 100644 drivers/i2c/tegra_nvec.c

arch/arm/include/asm/arch-tegra/tegra_nvec.h new file +21 -0
new file mode 100644
index 0000000..f1cec0d
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin<[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _TEGRA_NVEC_H_
+#define _TEGRA_NVEC_H_
+
+#define I2C_CNFG			0x00
+#define I2C_CNFG_PACKET_MODE_EN		(1<<10)
+#define I2C_CNFG_NEW_MASTER_SFM		(1<<11)
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12
+
+#define I2C_SL_CNFG		0x20
+#define I2C_SL_NEWSL		(1<<2)
+#define I2C_SL_NACK		(1<<1)
+#define I2C_SL_RESP		(1<<0)
+#define I2C_SL_IRQ		(1<<3)
+#define END_TRANS		(1<<4)

arch/arm/include/asm/arch-tegra/tegra_nvec.h line 31

Quoted 10 lines
arch/arm/include/asm/arch-tegra/tegra_nvec.h new file +10 -0
+#define RCVD			(1<<2)
+#define RNW			(1<<1)
+
+#define I2C_SL_RCVD		0x24
+#define I2C_SL_STATUS		0x28
+#define I2C_SL_ADDR1		0x2c
+#define I2C_SL_ADDR2		0x30
+#define I2C_SL_DELAY_COUNT	0x3c
+
+

please only one line, check globally.

[...]

Quoted 65 lines
drivers/i2c/tegra_nvec.c new file +59 -0
new file mode 100644
index 0000000..b568988
@@ -0,0 +1,294 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin<[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include<common.h>
+#include<fdtdec.h>
+#include<i2c.h>
+#include<asm/io.h>
+#include<asm/gpio.h>
+#include<asm/arch/clock.h>
+#include<asm/arch/funcmux.h>
+#include<asm/arch-tegra/tegra_nvec.h>
+
+#ifndef CONFIG_SYS_I2C_TEGRA_NVEC
+#error "You should enable CONFIG_SYS_I2C_TEGRA_NVEC"
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct nvec_periph devices[NVEC_LAST_MSG];
+
+
+struct nvec_t {
+	int			i2c_bus;
+	struct fdt_gpio_state	gpio;
+} nvec_data;
+
+
+/* nvec commands */
+char noop[] = { NVEC_CNTL, CNTL_NOOP };
+
+void nvec_signal_request(void)
+{
+	gpio_set_value(nvec_data.gpio.gpio, 0);
+}
+
+
+void nvec_clear_request(void)
+{
+	gpio_set_value(nvec_data.gpio.gpio, 1);
+}
+
+
+int nvec_msg_is_event(const unsigned char *msg)
+{
+	return msg[0]>>  7;
+}
+
+
+int nvec_msg_event_type(const unsigned char *msg)
+{
+	return msg[0]&  0x0f;
+}
+
+
+/**

drivers/i2c/tegra_nvec.c line 69

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+ * Process incoming io message.
+ * If message is keyboard event then key code will
+ * be added to keys buffer.
+ *
+ * @param nvec	nvec state struct
+ */
+void nvec_process_msg(struct nvec_t *nvec, struct i2c_transaction *trans)
+{
+	(void) nvec;
+

no empty line needed.

Quoted 106 lines
drivers/i2c/tegra_nvec.c new file +106 -0
+	const unsigned char *msg = (const unsigned char *)&trans->rx_buf[1];
+	int event_type;
+
+	if (!nvec_msg_is_event(msg))
+		return;
+
+	event_type = nvec_msg_event_type(msg);
+
+	if (event_type<  NVEC_KEYBOARD || event_type>= NVEC_LAST_MSG)
+		return;
+
+	if (devices[event_type].process_msg)
+		devices[event_type].process_msg(msg);
+}
+
+
+/**
+ * Perform complete io operation (read or write).
+ * NOTE: function will wait NVEC_TIMEOUT_MIN (20ms)
+ * before status check to avoid nvec hang.
+ *
+ * @param nvec		nvec state struct
+ * @param wait_for_ec	if 1(NVEC_WAIT_FOR_EC) operation
+ *			timeout is NVEC_TIMEOUT_MAX (600ms),
+ *			otherwise function will return if io
+ *			is not ready.
+ *
+ * @return nvec_io_* code
+ */
+int nvec_do_io(struct nvec_t *nvec)
+{
+	static unsigned int prev_timer;
+	unsigned int poll_start_ms = get_timer(prev_timer);
+	struct i2c_transaction trans;
+	int res;
+
+	if (poll_start_ms>  30000) {
+		if (prev_timer != 0)
+			nvec_do_request(noop, sizeof(noop));
+		prev_timer = get_timer(0);
+	}
+
+	memset(&trans, 0, sizeof(trans));
+	trans.start_timeout = 1;
+	trans.timeout = 6000;
+
+	res = i2c_slave_io(&trans);
+	if (res == 0) {
+		nvec_process_msg(nvec,&trans);
+		return 0;
+	}
+
+	if (res != -1)
+		debug("Error: i2c slave io failed with code %d\n", res);
+
+	return -1;
+}
+
+/**
+ * Send request and read response. If write or read failed
+ * operation will be repeated NVEC_ATTEMPTS_MAX times.
+ *
+ * @param buf	request data
+ * @param size	request data size
+ * @return 0 if ok, -1 on error
+ */
+int nvec_do_request(char *buf, int size)
+{
+	int res;
+	struct i2c_transaction trans;
+	int i;
+
+	nvec_signal_request();
+
+	/* Request */
+	for (i = 0; i<  10; ++i) {
+		memset(&trans, 0, sizeof(trans));
+		trans.start_timeout = 600;
+		trans.timeout = 6000;
+
+		trans.tx_buf[0] = (char)size;
+		memcpy(&trans.tx_buf[1], buf, size);
+		trans.tx_size = size + 1;
+
+		res = i2c_slave_io(&trans);
+		if (res == 0) {
+			if (trans.tx_pos == trans.tx_size)
+				break;
+
+			debug("Request was not sent completely");
+		} else if (res != -1) {
+			debug("Unknown error while slave io");
+		}
+	}
+	nvec_clear_request();
+	if (res != 0) {
+		error("nvec failed to perform request\n");
+		return -1;
+	}
+
+	/* Response */
+	for (i = 0; i<  10; ++i) {
+		memset(&trans, 0, sizeof(trans));
+		trans.start_timeout = 600;
+		trans.timeout = 6000;
+

drivers/i2c/tegra_nvec.c line 185

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+		res = i2c_slave_io(&trans);
+		if (res == 0)
+			break;
+	}
+	if (res != 0) {
+		error("nvec failed to read response\n");
+		return -1;
+	}
+
+	/* TODO Parse response */

?

Is this not a complete driver?

drivers/i2c/tegra_nvec.c line 196

Quoted 11 lines
drivers/i2c/tegra_nvec.c new file +11 -0
+
+	return 0;
+}
+
+
+/**
+ * Decode the nvec information from the fdt.
+ *
+ * @param blob		fdt blob
+ * @param nvec		nvec device sturct
+ * @return 0 if ok, -ve on error

What is "-ve" ?

Quoted 58 lines
drivers/i2c/tegra_nvec.c new file +58 -0
+ */
+static int nvec_decode_config(const void *blob,
+			      struct nvec_t *nvec)
+{
+	int node, parent;
+	int i2c_bus;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_NVEC);
+	if (node<  0) {
+		error("Cannot find NVEC node in fdt\n");
+		return node;
+	}
+
+	parent = fdt_parent_offset(blob, node);
+	if (parent<  0) {
+		debug("%s: Cannot find node parent\n", __func__);
+		return -1;
+	}
+
+	i2c_bus = i2c_get_bus_num_fdt(parent);
+	if (i2c_bus<  0)
+		return -1;
+	nvec->i2c_bus = i2c_bus;
+
+	if (fdtdec_decode_gpio(blob, node, "request-gpios",
+			&nvec->gpio)) {
+		error("No NVEC request gpio\n");
+		return -1;
+	}
+
+	debug("NVEC: i2c:%d, gpio:%s(%u)\n",
+	      nvec->i2c_bus, nvec->gpio.name, nvec->gpio.gpio);
+	return 0;
+}
+
+
+int board_nvec_init(void)
+{
+	int res = 0;
+	int i;
+
+	if (nvec_decode_config(gd->fdt_blob,&nvec_data)) {
+		error("Can't parse NVEC node in device tree\n");
+		return -1;
+	}
+
+	debug("NVEC initialization...\n");
+
+	res = gpio_request(nvec_data.gpio.gpio, NULL);
+	if (res != 0)
+		error("NVEC: err, gpio_request\n");
+	res = gpio_direction_output(nvec_data.gpio.gpio, 1);
+	if (res != 0)
+		error("NVEC: err, gpio_direction\n");
+	res = gpio_set_value(nvec_data.gpio.gpio, 1);
+	if (res != 0)
+		error("NVEC: err, gpio_set_value\n");
+	udelay(100);

drivers/i2c/tegra_nvec.c line 264

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+
+	i2c_set_bus_num(nvec_data.i2c_bus);
+
+	for (i = NVEC_KEYBOARD; i<  NVEC_LAST_MSG; ++i)
+		if (devices[i].start) {
+			debug("Starting device %d(0x%x)\n", i, i);
+			devices[i].start();
+		}
+
+	return 1;

Why "return 1"?

Quoted 4 lines
drivers/i2c/tegra_nvec.c new file +4 -0
+}
+
+
+int nvec_read_events(void)

drivers/i2c/tegra_nvec.c line 278

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+{
+	int res;
+	int cnt = 0;
+
+	while (++cnt<= 8) {
+		res = nvec_do_io(&nvec_data);
+		if (res)
+			break;
+
+		/* TODO Process nvec communication errors */

Again a "TODO" ?

Quoted 33 lines
drivers/i2c/tegra_nvec.c new file +16 -0
+	}
+
+	return cnt;
+}
+
+
+int nvec_register_periph(int msg_type, struct nvec_periph *periph)
+{
+	if (devices[msg_type].start || devices[msg_type].process_msg) {
+		error("Device for msg %d already registered\n", msg_type);
+		return -1;
+	}
+
+	devices[msg_type] = *periph;
+	return 0;
+}
include/fdtdec.h +1 -0
index 19bab79..7b84335 100644
@@ -64,6 +64,7 @@ enum fdt_compat_id {
  	COMPAT_NVIDIA_TEGRA20_SDMMC,	/* Tegra20 SDMMC controller */
  	COMPAT_NVIDIA_TEGRA20_SFLASH,	/* Tegra 2 SPI flash controller */
  	COMPAT_NVIDIA_TEGRA20_SLINK,	/* Tegra 2 SPI SLINK controller */
+	COMPAT_NVIDIA_TEGRA20_NVEC,	/* Tegra 2 EC controller */
  	COMPAT_NVIDIA_TEGRA114_SPI,	/* Tegra 114 SPI controller */
  	COMPAT_SMSC_LAN9215,		/* SMSC 10/100 Ethernet LAN9215 */
  	COMPAT_SAMSUNG_EXYNOS5_SROMC,	/* Exynos5 SROMC */
lib/fdtdec.c +0 -0
index 1fecab3..82df701 100644

lib/fdtdec.c static const char * const compat_names[COMPAT_COUNT] = { · line 43

Quoted 7 lines
lib/fdtdec.c +1 -0
@@ -37,6 +37,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
  	COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
  	COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
  	COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
+	COMPAT(NVIDIA_TEGRA20_NVEC, "nvidia,tegra20-nvec"),
  	COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
  	COMPAT(SMSC_LAN9215, "smsc,lan9215"),
  	COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#10 lore raw

PATCH v2 3/6 ARM: tegra: i2c: add nvec driver

Quoted 2 lines · Heiko Schocher

Hello Andrey,

Hello Heiko.

First of all, thank you for the review!

Quoted 53 lines

Am 27.04.2014 03:14, schrieb Andrey Danin:

Quoted 52 lines
CC Stephen Warren<[email protected]>
CC Marc Dietrich<[email protected]>
CC Julian Andres Klode<[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- NVEC driver was reworked to use tegra-i2c

  arch/arm/include/asm/arch-tegra/tegra_nvec.h |  130 ++++++++++++
  board/nvidia/common/board.c                  |   12 ++
  drivers/i2c/Makefile                         |    1 +
  drivers/i2c/tegra_nvec.c                     |  294
++++++++++++++++++++++++++
  include/fdtdec.h                             |    1 +
  lib/fdtdec.c                                 |    1 +
  6 files changed, 439 insertions(+)

create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h create mode 100644 drivers/i2c/tegra_nvec.c

arch/arm/include/asm/arch-tegra/tegra_nvec.h new file +25 -0
new file mode 100644
index 0000000..f1cec0d
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin<[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _TEGRA_NVEC_H_
+#define _TEGRA_NVEC_H_
+
+#define I2C_CNFG            0x00
+#define I2C_CNFG_PACKET_MODE_EN        (1<<10)
+#define I2C_CNFG_NEW_MASTER_SFM        (1<<11)
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT    12
+
+#define I2C_SL_CNFG        0x20
+#define I2C_SL_NEWSL        (1<<2)
+#define I2C_SL_NACK        (1<<1)
+#define I2C_SL_RESP        (1<<0)
+#define I2C_SL_IRQ        (1<<3)
+#define END_TRANS        (1<<4)
+#define RCVD            (1<<2)
+#define RNW            (1<<1)
+
+#define I2C_SL_RCVD        0x24
Quoted 9 lines

arch/arm/include/asm/arch-tegra/tegra_nvec.h line 31

Quoted 6 lines
arch/arm/include/asm/arch-tegra/tegra_nvec.h new file +6 -0
+#define I2C_SL_STATUS        0x28
+#define I2C_SL_ADDR1        0x2c
+#define I2C_SL_ADDR2        0x30
+#define I2C_SL_DELAY_COUNT    0x3c
+
+

please only one line, check globally.

I will. Thanks for pointing.

Quoted 199 lines

[...]

Quoted 73 lines
drivers/i2c/tegra_nvec.c new file +66 -0
new file mode 100644
index 0000000..b568988
@@ -0,0 +1,294 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin<[email protected]>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include<common.h>
+#include<fdtdec.h>
+#include<i2c.h>
+#include<asm/io.h>
+#include<asm/gpio.h>
+#include<asm/arch/clock.h>
+#include<asm/arch/funcmux.h>
+#include<asm/arch-tegra/tegra_nvec.h>
+
+#ifndef CONFIG_SYS_I2C_TEGRA_NVEC
+#error "You should enable CONFIG_SYS_I2C_TEGRA_NVEC"
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct nvec_periph devices[NVEC_LAST_MSG];
+
+
+struct nvec_t {
+    int            i2c_bus;
+    struct fdt_gpio_state    gpio;
+} nvec_data;
+
+
+/* nvec commands */
+char noop[] = { NVEC_CNTL, CNTL_NOOP };
+
+void nvec_signal_request(void)
+{
+    gpio_set_value(nvec_data.gpio.gpio, 0);
+}
+
+
+void nvec_clear_request(void)
+{
+    gpio_set_value(nvec_data.gpio.gpio, 1);
+}
+
+
+int nvec_msg_is_event(const unsigned char *msg)
+{
+    return msg[0]>>  7;
+}
+
+
+int nvec_msg_event_type(const unsigned char *msg)
+{
+    return msg[0]&  0x0f;
+}
+
+
+/**
+ * Process incoming io message.
+ * If message is keyboard event then key code will
+ * be added to keys buffer.
+ *
+ * @param nvec    nvec state struct
+ */
+void nvec_process_msg(struct nvec_t *nvec, struct i2c_transaction

*trans)

drivers/i2c/tegra_nvec.c line 69

Quoted 3 lines
drivers/i2c/tegra_nvec.c new file +3 -0
+{
+    (void) nvec;
+

no empty line needed.

Quoted 106 lines
drivers/i2c/tegra_nvec.c new file +106 -0
+    const unsigned char *msg = (const unsigned char *)&trans->rx_buf[1];
+    int event_type;
+
+    if (!nvec_msg_is_event(msg))
+        return;
+
+    event_type = nvec_msg_event_type(msg);
+
+    if (event_type<  NVEC_KEYBOARD || event_type>= NVEC_LAST_MSG)
+        return;
+
+    if (devices[event_type].process_msg)
+        devices[event_type].process_msg(msg);
+}
+
+
+/**
+ * Perform complete io operation (read or write).
+ * NOTE: function will wait NVEC_TIMEOUT_MIN (20ms)
+ * before status check to avoid nvec hang.
+ *
+ * @param nvec        nvec state struct
+ * @param wait_for_ec    if 1(NVEC_WAIT_FOR_EC) operation
+ *            timeout is NVEC_TIMEOUT_MAX (600ms),
+ *            otherwise function will return if io
+ *            is not ready.
+ *
+ * @return nvec_io_* code
+ */
+int nvec_do_io(struct nvec_t *nvec)
+{
+    static unsigned int prev_timer;
+    unsigned int poll_start_ms = get_timer(prev_timer);
+    struct i2c_transaction trans;
+    int res;
+
+    if (poll_start_ms>  30000) {
+        if (prev_timer != 0)
+            nvec_do_request(noop, sizeof(noop));
+        prev_timer = get_timer(0);
+    }
+
+    memset(&trans, 0, sizeof(trans));
+    trans.start_timeout = 1;
+    trans.timeout = 6000;
+
+    res = i2c_slave_io(&trans);
+    if (res == 0) {
+        nvec_process_msg(nvec,&trans);
+        return 0;
+    }
+
+    if (res != -1)
+        debug("Error: i2c slave io failed with code %d\n", res);
+
+    return -1;
+}
+
+/**
+ * Send request and read response. If write or read failed
+ * operation will be repeated NVEC_ATTEMPTS_MAX times.
+ *
+ * @param buf    request data
+ * @param size    request data size
+ * @return 0 if ok, -1 on error
+ */
+int nvec_do_request(char *buf, int size)
+{
+    int res;
+    struct i2c_transaction trans;
+    int i;
+
+    nvec_signal_request();
+
+    /* Request */
+    for (i = 0; i<  10; ++i) {
+        memset(&trans, 0, sizeof(trans));
+        trans.start_timeout = 600;
+        trans.timeout = 6000;
+
+        trans.tx_buf[0] = (char)size;
+        memcpy(&trans.tx_buf[1], buf, size);
+        trans.tx_size = size + 1;
+
+        res = i2c_slave_io(&trans);
+        if (res == 0) {
+            if (trans.tx_pos == trans.tx_size)
+                break;
+
+            debug("Request was not sent completely");
+        } else if (res != -1) {
+            debug("Unknown error while slave io");
+        }
+    }
+    nvec_clear_request();
+    if (res != 0) {
+        error("nvec failed to perform request\n");
+        return -1;
+    }
+
+    /* Response */
+    for (i = 0; i<  10; ++i) {
+        memset(&trans, 0, sizeof(trans));
+        trans.start_timeout = 600;
+        trans.timeout = 6000;
+

drivers/i2c/tegra_nvec.c line 185

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+        res = i2c_slave_io(&trans);
+        if (res == 0)
+            break;
+    }
+    if (res != 0) {
+        error("nvec failed to read response\n");
+        return -1;
+    }
+
+    /* TODO Parse response */

?

Quoted 2 lines

Is this not a complete driver?

The driver is complete. This part is not mandatory because request and response are processed synchronously. I will write a proper comment here.

Quoted 5 lines
Quoted 5 lines
drivers/i2c/tegra_nvec.c new file +5 -0
+
+    return 0;
+}
+
+
Quoted 9 lines
Quoted 6 lines

+/**
+ * Decode the nvec information from the fdt.
+ *
+ * @param blob fdt blob
+ * @param nvec nvec device sturct
+ * @return 0 if ok, -ve on error

What is "-ve" ?

It means -error_code.
I will rework return codes, comments, style issues according to all your remarks.

Quoted 71 lines
Quoted 58 lines

+ */

drivers/i2c/tegra_nvec.c new file +57 -0
+static int nvec_decode_config(const void *blob,
+                  struct nvec_t *nvec)
+{
+    int node, parent;
+    int i2c_bus;
+
+    node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA20_NVEC);
+    if (node<  0) {
+        error("Cannot find NVEC node in fdt\n");
+        return node;
+    }
+
+    parent = fdt_parent_offset(blob, node);
+    if (parent<  0) {
+        debug("%s: Cannot find node parent\n", __func__);
+        return -1;
+    }
+
+    i2c_bus = i2c_get_bus_num_fdt(parent);
+    if (i2c_bus<  0)
+        return -1;
+    nvec->i2c_bus = i2c_bus;
+
+    if (fdtdec_decode_gpio(blob, node, "request-gpios",
+            &nvec->gpio)) {
+        error("No NVEC request gpio\n");
+        return -1;
+    }
+
+    debug("NVEC: i2c:%d, gpio:%s(%u)\n",
+          nvec->i2c_bus, nvec->gpio.name, nvec->gpio.gpio);
+    return 0;
+}
+
+
+int board_nvec_init(void)
+{
+    int res = 0;
+    int i;
+
+    if (nvec_decode_config(gd->fdt_blob,&nvec_data)) {
+        error("Can't parse NVEC node in device tree\n");
+        return -1;
+    }
+
+    debug("NVEC initialization...\n");
+
+    res = gpio_request(nvec_data.gpio.gpio, NULL);
+    if (res != 0)
+        error("NVEC: err, gpio_request\n");
+    res = gpio_direction_output(nvec_data.gpio.gpio, 1);
+    if (res != 0)
+        error("NVEC: err, gpio_direction\n");
+    res = gpio_set_value(nvec_data.gpio.gpio, 1);
+    if (res != 0)
+        error("NVEC: err, gpio_set_value\n");
+    udelay(100);

drivers/i2c/tegra_nvec.c line 264

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+
+    i2c_set_bus_num(nvec_data.i2c_bus);
+
+    for (i = NVEC_KEYBOARD; i<  NVEC_LAST_MSG; ++i)
+        if (devices[i].start) {
+            debug("Starting device %d(0x%x)\n", i, i);
+            devices[i].start();
+        }
+
+    return 1;

Why "return 1"?

Quoted 17 lines
Quoted 4 lines
drivers/i2c/tegra_nvec.c new file +4 -0
+}
+
+
+int nvec_read_events(void)

drivers/i2c/tegra_nvec.c line 278

Quoted 10 lines
drivers/i2c/tegra_nvec.c new file +10 -0
+{
+    int res;
+    int cnt = 0;
+
+    while (++cnt<= 8) {
+        res = nvec_do_io(&nvec_data);
+        if (res)
+            break;
+
+        /* TODO Process nvec communication errors */

Again a "TODO" ?

I will implement.

Quoted 36 lines
Quoted 36 lines
drivers/i2c/tegra_nvec.c new file +16 -0
+    }
+
+    return cnt;
+}
+
+
+int nvec_register_periph(int msg_type, struct nvec_periph *periph)
+{
+    if (devices[msg_type].start || devices[msg_type].process_msg) {
+        error("Device for msg %d already registered\n", msg_type);
+        return -1;
+    }
+
+    devices[msg_type] = *periph;
+    return 0;
+}
include/fdtdec.h +1 -0
index 19bab79..7b84335 100644
@@ -64,6 +64,7 @@ enum fdt_compat_id {
      COMPAT_NVIDIA_TEGRA20_SDMMC,    /* Tegra20 SDMMC controller */
      COMPAT_NVIDIA_TEGRA20_SFLASH,    /* Tegra 2 SPI flash controller */
      COMPAT_NVIDIA_TEGRA20_SLINK,    /* Tegra 2 SPI SLINK controller */
+    COMPAT_NVIDIA_TEGRA20_NVEC,    /* Tegra 2 EC controller */
      COMPAT_NVIDIA_TEGRA114_SPI,    /* Tegra 114 SPI controller */
      COMPAT_SMSC_LAN9215,        /* SMSC 10/100 Ethernet LAN9215 */
      COMPAT_SAMSUNG_EXYNOS5_SROMC,    /* Exynos5 SROMC */
lib/fdtdec.c +0 -0
index 1fecab3..82df701 100644
@@ -37,6 +37,7 @@ static const char * const compat_names[COMPAT_COUNT]
 = {
      COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
      COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
Quoted 8 lines
Quoted 5 lines
lib/fdtdec.c +1 -0
      COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
+    COMPAT(NVIDIA_TEGRA20_NVEC, "nvidia,tegra20-nvec"),
      COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
      COMPAT(SMSC_LAN9215, "smsc,lan9215"),

COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),

bye,
Heiko

Thanks.

#11 lore raw

PATCH v2 3/6 ARM: tegra: i2c: add nvec driver

Hello Andrey,

Am 29.04.2014 09:15, schrieb Andrey Danin:

Quoted 6 lines · Heiko Schocher
Quoted 2 lines

Hello Andrey,

Hello Heiko.

First of all, thank you for the review!

You are welcome.

Quoted 20 lines
Quoted 20 lines

Am 27.04.2014 03:14, schrieb Andrey Danin:

Quoted 19 lines
CC Stephen Warren<[email protected]>
CC Marc Dietrich<[email protected]>
CC Julian Andres Klode<[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- NVEC driver was reworked to use tegra-i2c

arch/arm/include/asm/arch-tegra/tegra_nvec.h | 130 ++++++++++++ board/nvidia/common/board.c | 12 ++ drivers/i2c/Makefile | 1 +
drivers/i2c/tegra_nvec.c | 294
++++++++++++++++++++++++++
include/fdtdec.h | 1 +
lib/fdtdec.c | 1 +

6 files changed, 439 insertions(+)

create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h create mode 100644 drivers/i2c/tegra_nvec.c

[...]

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
drivers/i2c/tegra_nvec.c new file +0 -0
new file mode 100644
index 0000000..b568988
@@ -0,0 +1,294 @@

[...]

Quoted 7 lines
Quoted 6 lines
Quoted 1 line

+ /* TODO Parse response */

?

Is this not a complete driver?

The driver is complete. This part is not mandatory because request and response are processed synchronously. I will write a proper comment here.

Ok, thanks!

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
drivers/i2c/tegra_nvec.c new file +5 -0
+
+ return 0;
+}
+
+
Quoted 9 lines
Quoted 6 lines

+/**
+ * Decode the nvec information from the fdt.
+ *
+ * @param blob fdt blob
+ * @param nvec nvec device sturct
+ * @return 0 if ok, -ve on error

What is "-ve" ?

Quoted 2 lines

It means -error_code.
I will rework return codes, comments, style issues according to all your remarks.

Thanks!

[...]

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
drivers/i2c/tegra_nvec.c new file +5 -0
+int nvec_read_events(void)
+{
+ int res;
+ int cnt = 0;
+
Quoted 9 lines
Quoted 6 lines

+ while (++cnt<= 8) {
+ res = nvec_do_io(&nvec_data);
+ if (res)
+ break;
+
+ /* TODO Process nvec communication errors */

Again a "TODO" ?

Quoted 1 line

I will implement.

Sounds great, thanks!

[...]

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#12 lore raw

PATCH v2 4/6 ARM: tegra: nvec: add keyboard support

In reply to Andrey Danin
CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- fixed incorrect keys handling in nvec-keyboard driver

 .../include/asm/arch-tegra/tegra_nvec_keyboard.h   |  304 ++++++++++++++++++++
 drivers/input/Makefile                             |    3 +
 drivers/input/tegra-nvec-kbc.c                     |  215 ++++++++++++++
 include/configs/tegra-common-post.h                |    2 +
 4 files changed, 524 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h
 create mode 100644 drivers/input/tegra-nvec-kbc.c
arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h new file +304 -0
new file mode 100644
index 0000000..5f789f4
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2014
+ * Andrey Danin <[email protected]>
+ * (C) Copyright 2009
+ * NVIDIA Corporation.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#ifndef _TEGRA_NVEC_KEYBOARD_H_
+#define _TEGRA_NVEC_KEYBOARD_H_
+
+#include <linux/input.h>
+
+
+/* Keytables */
+
+static unsigned short code_tab_102us[] = {
+	/* 0x00 */
+	KEY_GRAVE,
+	KEY_ESC,
+	KEY_1,
+	KEY_2,
+	KEY_3,
+	KEY_4,
+	KEY_5,
+	KEY_6,
+	KEY_7,
+	KEY_8,
+	KEY_9,
+	KEY_0,
+	KEY_MINUS,
+	KEY_EQUAL,
+	KEY_BACKSPACE,
+	KEY_TAB,
+	/* 0x10 */
+	KEY_Q,
+	KEY_W,
+	KEY_E,
+	KEY_R,
+	KEY_T,
+	KEY_Y,
+	KEY_U,
+	KEY_I,
+	KEY_O,
+	KEY_P,
+	KEY_LEFTBRACE,
+	KEY_RIGHTBRACE,
+	KEY_ENTER,
+	KEY_LEFTCTRL,
+	KEY_A,
+	KEY_S,
+	/* 0x20 */
+	KEY_D,
+	KEY_F,
+	KEY_G,
+	KEY_H,
+	KEY_J,
+	KEY_K,
+	KEY_L,
+	KEY_SEMICOLON,
+	KEY_APOSTROPHE,
+	KEY_GRAVE,
+	KEY_LEFTSHIFT,
+	KEY_BACKSLASH,
+	KEY_Z,
+	KEY_X,
+	KEY_C,
+	KEY_V,
+	/* 0x30 */
+	KEY_B,
+	KEY_N,
+	KEY_M,
+	KEY_COMMA,
+	KEY_DOT,
+	KEY_SLASH,
+	KEY_RIGHTSHIFT,
+	KEY_KPASTERISK,
+	KEY_LEFTALT,
+	KEY_SPACE,
+	KEY_CAPSLOCK,
+	KEY_F1,
+	KEY_F2,
+	KEY_F3,
+	KEY_F4,
+	KEY_F5,
+	/* 0x40 */
+	KEY_F6,
+	KEY_F7,
+	KEY_F8,
+	KEY_F9,
+	KEY_F10,
+	KEY_FN,
+	/* VK_SCROLL */
+	0,
+	KEY_KP7,
+	KEY_KP8,
+	KEY_KP9,
+	KEY_KPMINUS,
+	KEY_KP4,
+	KEY_KP5,
+	KEY_KP6,
+	KEY_KPPLUS,
+	KEY_KP1,
+	/* 0x50 */
+	KEY_KP2,
+	KEY_KP3,
+	KEY_KP0,
+	KEY_KPDOT,
+	/* VK_SNAPSHOT */
+	0, /* KEY_MENU, */
+	KEY_POWER,
+	/* VK_OEM_102 */
+	KEY_102ND,
+	KEY_F11,
+	KEY_F12,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* 0x60 */
+	0,
+	0,
+	0,
+	0, /* KEY_SEARCH, */
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* 0x70 */
+	0,
+	0,
+	0,
+	KEY_KP5,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	KEY_KP9,
+};
+
+static unsigned short extcode_tab_us102[] = {
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* 0x10 */
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* VK_MEDIA_NEXT_TRACK */
+	0,
+	0,
+	0,
+	/* VK_RETURN */
+	0,
+	KEY_RIGHTCTRL,
+	0,
+	0,
+	/* 0x20 */
+	KEY_MUTE,
+	/* VK_LAUNCH_APP1 */
+	0,
+	/* VK_MEDIA_PLAY_PAUSE */
+	0,
+	0,
+	/* VK_MEDIA_STOP */
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* 0x30 */
+	KEY_VOLUMEUP,
+	0,
+	/* VK_BROWSER_HOME */
+	0,
+	0,
+	0,
+	/* VK_DIVIDE */
+	KEY_KPSLASH,
+	0,
+	/* VK_SNAPSHOT */
+	KEY_SYSRQ,
+	/* VK_RMENU */
+	KEY_RIGHTALT,
+	/* VK_OEM_NV_BACKLIGHT_UP */
+	0,
+	/* VK_OEM_NV_BACKLIGHT_DN */
+	0,
+	/* VK_OEM_NV_BACKLIGHT_AUTOTOGGLE */
+	0,
+	/* VK_OEM_NV_POWER_INFO */
+	0,
+	/* VK_OEM_NV_WIFI_TOGGLE */
+	0,
+	/* VK_OEM_NV_DISPLAY_SELECT */
+	0,
+	/* VK_OEM_NV_AIRPLANE_TOGGLE */
+	0,
+	/* 0x40 */
+	0,
+	KEY_LEFT,
+	0,
+	0,
+	0,
+	0,
+	0, /* KEY_CANCEL, */
+	KEY_HOME,
+	KEY_UP,
+	KEY_PAGEUP,
+	0,
+	KEY_LEFT,
+	0,
+	KEY_RIGHT,
+	0,
+	KEY_END,
+	/* 0x50 */
+	KEY_DOWN,
+	KEY_PAGEDOWN,
+	KEY_INSERT,
+	KEY_DELETE,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	KEY_LEFTMETA,
+	0,
+	KEY_ESC,
+	KEY_KPMINUS,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	/* VK_BROWSER_SEARCH */
+	0,
+	/* VK_BROWSER_FAVORITES */
+	0,
+	/* VK_BROWSER_REFRESH */
+	0,
+	/* VK_BROWSER_STOP */
+	0,
+	/* VK_BROWSER_FORWARD */
+	0,
+	/* VK_BROWSER_BACK */
+	0,
+	/* VK_LAUNCH_APP2 */
+	0,
+	/* VK_LAUNCH_MAIL */
+	0,
+	/* VK_LAUNCH_MEDIA_SELECT */
+	0,
+};
+
+static unsigned short *code_tabs[] = { code_tab_102us, extcode_tab_us102 };
+
+
+#endif /* _TEGRA_NVEC_KEYBOARD_H_ */
drivers/input/Makefile +3 -0
index a8e9be2..38c576f 100644
@@ -7,6 +7,9 @@
 
 obj-$(CONFIG_I8042_KBD) += i8042.o
 obj-$(CONFIG_TEGRA_KEYBOARD) += tegra-kbc.o
+ifdef CONFIG_SYS_I2C_TEGRA_NVEC
+obj-$(CONFIG_TEGRA_NVEC_KEYBOARD) += tegra-nvec-kbc.o
+endif
 obj-$(CONFIG_CROS_EC_KEYB) += cros_ec_keyb.o
 ifdef CONFIG_PS2KBD
 obj-y += keyboard.o pc_keyb.o
drivers/input/tegra-nvec-kbc.c new file +215 -0

215 lines not on this page · raw message

include/configs/tegra-common-post.h +2 -0
index e1a3bbc..efc0ef9 100644
@@ -106,6 +106,8 @@
 
 #ifdef CONFIG_TEGRA_KEYBOARD
 #define STDIN_KBD_KBC ",tegra-kbc"
+#elif defined(CONFIG_TEGRA_NVEC_KEYBOARD)
+#define STDIN_KBD_KBC ",tegra-nvec-kbc"
 #else
 #define STDIN_KBD_KBC ""
 #endif
Signature · 1 line
1.7.9.5
#13 lore raw

PATCH v2 4/6 ARM: tegra: nvec: add keyboard support

Quoted 8 lines · Andrey Danin
CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- fixed incorrect keys handling in nvec-keyboard driver

No patch description?

Something isn't quite right with the device registration here. If U-Boot starts with stdin=serial, and then I "setenv stdin serial,tegra-nvec-kbc", then I can't use the keyboard. However, if I save the environment and reset, then nvec input works. Similarly, it gets confused if I remove and re-add tegra-nvec-kbc to $stdin.

I've also observed quite a stuck keys, hangs, and failed requests:
ERROR: nvec failed to perform request
at .../drivers/i2c/tegra_nvec.c:166/nvec_do_request()

But when it works, it's nice:-)

A message that is not in the archive (sent off-list or not yet received): 1398561270-25091-1-git-send-email-danindrey-JGs/[email protected]

#15 lore raw

PATCH v2 5/6 ARM: tegra: paz00: add dt bindings for nvec

---
Changes for v2:
- Separated from enabling keyboard patch
- Changed NVEC dt bindings

 arch/arm/dts/tegra20-paz00.dts |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/arm/dts/tegra20-paz00.dts +7 -1
index 780203c..9906f3a 100644
@@ -40,7 +40,13 @@
 	};
 
 	i2c@7000c500 {
-		status = "disabled";
+		status = "okay";
+		clock-frequency = <40000>;
+		slave-addr = <138>;
+		nvec {
+			compatible = "nvidia,tegra20-nvec";
+			request-gpios = <&gpio 170 0>; /* gpio PV2 */
+		};
 	};
 
 	i2c@7000d000 {
Signature · 6 lines
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1398561270-25091-6-git-send-email-danindrey-JGs/[email protected]

#17 lore raw

Re: [Ac100] [PATCH v2 5/6] ARM: tegra: paz00: add dt bindings for nvec

On 04/26/2014 07:14 PM, Andrey Danin wrote:

This patch isn't adding DT bindings for NVEC, but rather add DT nodes. The binding is the schema, not the content.

We need a DT binding document that's been reviewed by the DT binding maintainers. Can you please first submit a patch to the Linux kernel that modifies the existing I2C core and Tegra I2C controller binding documentation to add slave mode support. Once that's fully reviewed and ack'd, this patch series can implement support for it in U-Boot.

arch/arm/dts/tegra20-paz00.dts line 48

Quoted 10 lines
arch/arm/dts/tegra20-paz00.dts +6 -1
 
 	i2c@7000c500 {
-		status = "disabled";
+		status = "okay";
+		clock-frequency = <40000>;
+		slave-addr = <138>;
+		nvec {
+			compatible = "nvidia,tegra20-nvec";
+			request-gpios = <&gpio 170 0>; /* gpio PV2 */

The reg property is missing here. Since the i2c node has #address-cells/#size-cells, there must be a reg property in the children.

There's nothing here to indicate that this node is a slave device rather than a master device, and doesn't seem to be any allowance for a single I2C controller to support both master and slave nodes at the same time (which I think Tegra's controller can IIRC).

IIRC, I had previously suggested something like encoding master/slave into the reg property of the I2C child nodes. We could either do:

a) Set some top-bit to indicate a slave device.

b) If #address-cells=<1>, only master devices are present. If #address-cells=<2>, either master or slave devices could be present. Cell 0 could be 0==master, 1==slave, and cell 1 the actual I2C bus address.

Either of those approaches would allow representing an I2C controller that supported multiple slave addresses. Even though I think Tegra's slave controller doesn't support that, I still think we should use a generic binding so that I2C slave mode looks the same everywhere. --
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#19 lore raw

Re: [U-Boot] [Ac100] [PATCH v2 5/6] ARM: tegra: paz00: add dtbindings for nvec

Hi,

Am Montag, 28. April 2014, 17:04:13 schrieb Stephen Warren:

Quoted 10 lines · Andrey Danin

This patch isn't adding DT bindings for NVEC, but rather add DT nodes. The binding is the schema, not the content.

We need a DT binding document that's been reviewed by the DT binding maintainers. Can you please first submit a patch to the Linux kernel that modifies the existing I2C core and Tegra I2C controller binding documentation to add slave mode support. Once that's fully reviewed and ack'd, this patch series can implement support for it in U-Boot.

I'm sorry that I didn't came up with a proper kernel implementation, but while we are discussion the binding I just want to give some coins.

Quoted 20 lines

arch/arm/dts/tegra20-paz00.dts>

Quoted 11 lines
arch/arm/dts/tegra20-paz00.dts> renamed from arch/arm/dts/tegra20-paz00.dts +6 -1
 	i2c@7000c500 {
 
-		status = "disabled";
+		status = "okay";
+		clock-frequency = <40000>;
+		slave-addr = <138>;
+		nvec {
+			compatible = "nvidia,tegra20-nvec";
+			request-gpios = <&gpio 170 0>; /* gpio PV2 */

The reg property is missing here. Since the i2c node has #address-cells/#size-cells, there must be a reg property in the children.

There's nothing here to indicate that this node is a slave device rather than a master device, and doesn't seem to be any allowance for a single I2C controller to support both master and slave nodes at the same time (which I think Tegra's controller can IIRC).

Quoted 8 lines

IIRC, I had previously suggested something like encoding master/slave into the reg property of the I2C child nodes. We could either do:

a) Set some top-bit to indicate a slave device.

b) If #address-cells=<1>, only master devices are present. If #address-cells=<2>, either master or slave devices could be present. Cell 0 could be 0==master, 1==slave, and cell 1 the actual I2C bus address.

I'm not sure if this is really needed. NVEC knows it has to configure the tegra controller as slave. I don't see a reason to double this fact in the device tree. I like the idea of how the downstream kernel does it. The driver calls something like tegra_i2c_init_slave with the slave address as an parameter. This means that the slave address is not a property of the i2c (slave-) controller, but of the master because it has the address hard coded in its firmware. So reg = <138>; would be sufficient here and it also enables multi-slave configs.

i2c-tegra must take care that only one transaction (slave or master) is running at a time. The client (e.g. nvec) is free to drop the excluse usage by calling tegra_i2c_stop_slave so master mode can be used again or another client (master device) can be started where the slave controller gets a different address.

Multi-master would require that only one master can hold the lock enabling slave mode, but that's all software stuff and not related to the binding.

Also the kernel binding would require that nvec node itself has subdevices for e.g. keyboard, mouse, power, ... which are connected to the internal ec bus. We can use the nvec protocol identifiers to assign an address here.

Ok, lets take a look at the binding now:

i2c@7000c500 {
		status = "okay";
		clock-frequency = <40000>;
		nvec@138 {
			compatible = "nvidia,nvec, simple-bus";
			#address-cells = <1>
			#size-cells = <0>;
			reg = <138>;
			request-gpios = <&gpio 170 0>; /* gpio PV2 */

			keyboard@5 {
				compatible = "nvidia,nvec-kbd";						
				reg = <5>;
			};
			mouse@6 {
				compatible = "nvidia,nvec-aux";
				reg = <6>;
				packet-size = <6>;
			};
		};
};

Only thing I'm not sure is where to put the clock-frequency because it really depends on the i2c clients and if we have multiple masters, we could use multiple frequencies. Or maybe the lowest supported must be used instead, in which case the clock-frequency is better placed in the controller node.

Marc

#20 lore raw

Re: [U-Boot] [Ac100] [PATCH v2 5/6] ARM: tegra: paz00: add dtbindings for nvec

Quoted 8 lines · Marc Dietrich

Hi,

Am Montag, 28. April 2014, 17:04:13 schrieb Stephen Warren:

Quoted 5 lines · Andrey Danin

This patch isn't adding DT bindings for NVEC, but rather add DT nodes. The binding is the schema, not the content.

Quoted 8 lines
Quoted 5 lines

We need a DT binding document that's been reviewed by the DT binding maintainers. Can you please first submit a patch to the Linux kernel that modifies the existing I2C core and Tegra I2C controller binding documentation to add slave mode support. Once that's fully reviewed and ack'd, this patch series can implement support for it in U-Boot.

I'm sorry that I didn't came up with a proper kernel implementation, but while we are discussion the binding I just want to give some coins.

I'm not looking for a kernel driver implementation, but we do need to the DT binding fully reviewed and accepted.

Quoted 29 lines
Quoted 20 lines

arch/arm/dts/tegra20-paz00.dts>

Quoted 11 lines
arch/arm/dts/tegra20-paz00.dts> renamed from arch/arm/dts/tegra20-paz00.dts +6 -1
 	i2c@7000c500 {
 
-		status = "disabled";
+		status = "okay";
+		clock-frequency = <40000>;
+		slave-addr = <138>;
+		nvec {
+			compatible = "nvidia,tegra20-nvec";
+			request-gpios = <&gpio 170 0>; /* gpio PV2 */

The reg property is missing here. Since the i2c node has #address-cells/#size-cells, there must be a reg property in the children.

There's nothing here to indicate that this node is a slave device rather than a master device, and doesn't seem to be any allowance for a single I2C controller to support both master and slave nodes at the same time (which I think Tegra's controller can IIRC).

Quoted 8 lines

IIRC, I had previously suggested something like encoding master/slave into the reg property of the I2C child nodes. We could either do:

a) Set some top-bit to indicate a slave device.

b) If #address-cells=<1>, only master devices are present. If #address-cells=<2>, either master or slave devices could be present. Cell 0 could be 0==master, 1==slave, and cell 1 the actual I2C bus address.

Quoted 8 lines

I'm not sure if this is really needed. NVEC knows it has to configure the tegra controller as slave. I don't see a reason to double this fact in the device tree. I like the idea of how the downstream kernel does it. The driver calls something like tegra_i2c_init_slave with the slave address as an parameter. This means that the slave address is not a property of the i2c (slave-) controller, but of the master because it has the address hard coded in its firmware. So reg = <138>; would be sufficient here and it also enables multi-slave configs.

The binding in this patch is very special-cased. Instead, we need to create a generic binding that will work identically across arbitrary I2C controllers, some of which do support multiple slave addresses. The issue that caused Linus to blow up about ARM was because everyone went off and did their own HW-specific stuff without taking a look at the big picture. That's exactly what the binding proposed in this patch does too. --
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#22 lore raw

Re: [U-Boot] [Ac100] [PATCH v2 5/6] ARM: tegra: paz00: add dtbindingsfor nvec

Quoted 13 lines · On Wed, 30 Apr 2014 10:21:07 -0600 Stephen Warren…
Quoted 12 lines · Marc Dietrich

Am Montag, 28. April 2014, 17:04:13 schrieb Stephen Warren:

Quoted 10 lines · Andrey Danin

This patch isn't adding DT bindings for NVEC, but rather add DT nodes. The binding is the schema, not the content.

We need a DT binding document that's been reviewed by the DT binding maintainers. Can you please first submit a patch to the Linux kernel that modifies the existing I2C core and Tegra I2C controller binding documentation to add slave mode support. Once that's fully reviewed and ack'd, this patch series can implement support for it in U-Boot.

Quoted 5 lines
Quoted 2 lines

I'm sorry that I didn't came up with a proper kernel implementation, but while we are discussion the binding I just want to give some coins.

I'm not looking for a kernel driver implementation, but we do need to the DT binding fully reviewed and accepted.

well, a kernel implementation would have included the binding.

Quoted 38 lines
Quoted 29 lines
Quoted 20 lines

arch/arm/dts/tegra20-paz00.dts>

Quoted 11 lines
arch/arm/dts/tegra20-paz00.dts> renamed from arch/arm/dts/tegra20-paz00.dts +6 -1
 	i2c@7000c500 {
 
-		status = "disabled";
+		status = "okay";
+		clock-frequency = <40000>;
+		slave-addr = <138>;
+		nvec {
+			compatible = "nvidia,tegra20-nvec";
+			request-gpios = <&gpio 170 0>; /* gpio PV2 */

The reg property is missing here. Since the i2c node has #address-cells/#size-cells, there must be a reg property in the children.

There's nothing here to indicate that this node is a slave device rather than a master device, and doesn't seem to be any allowance for a single I2C controller to support both master and slave nodes at the same time (which I think Tegra's controller can IIRC).

Quoted 8 lines

IIRC, I had previously suggested something like encoding master/slave into the reg property of the I2C child nodes. We could either do:

a) Set some top-bit to indicate a slave device.

b) If #address-cells=<1>, only master devices are present. If #address-cells=<2>, either master or slave devices could be present. Cell 0 could be 0==master, 1==slave, and cell 1 the actual I2C bus address.

Quoted 8 lines

I'm not sure if this is really needed. NVEC knows it has to configure the tegra controller as slave. I don't see a reason to double this fact in the device tree. I like the idea of how the downstream kernel does it. The driver calls something like tegra_i2c_init_slave with the slave address as an parameter. This means that the slave address is not a property of the i2c (slave-) controller, but of the master because it has the address hard coded in its firmware. So reg = <138>; would be sufficient here and it also enables multi-slave configs.

Quoted 3 lines

The binding in this patch is very special-cased. Instead, we need to create a generic binding that will work identically across arbitrary I2C controllers, some of which do support multiple slave addresses.

I don't see why multi-slave capable controllers won't work. You just increase the number in the controller's address-cells and add the slave addresses to the master's reg property. The point here is that the slave addresses of an i2c controller may be configured at runtime, not at device initialization via devicetree. This also gives a higher flexibility for different slave/master combinations.

Quoted 3 lines

The issue that caused Linus to blow up about ARM was because everyone went off and did their own HW-specific stuff without taking a look at the big picture. That's exactly what the binding proposed in this patch does too.

I can only assume that your are slowly getting tired of this binding discussion. Still there is no reason for harsh words or to delete my proposal from the context. IMHO, I tried to be as generic as possible.

Anyway, we should move this discussion to the devicetree ml.

Marc
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#23 lore raw

PATCH v2 6/6 ARM: tegra: paz00: enable nvec keyboard

In reply to Andrey Danin
CC Stephen Warren <[email protected]>
CC Marc Dietrich <[email protected]>
CC Julian Andres Klode <[email protected]>
CC ac100 at lists.launchpad.net

---
Changes for v2:
- device tree part moved to separate patch
- added I2C specific defines for initialization

 include/configs/paz00.h |    9 +++++++++
 1 file changed, 9 insertions(+)
include/configs/paz00.h +9 -0
index 9e2686a..39dbe1e 100644
@@ -72,6 +72,15 @@
 #define CONFIG_SYS_WHITE_ON_BLACK
 #define CONFIG_CONSOLE_SCROLL_LINES	10
 
+/* Keyboard support */
+#define CONFIG_KEYBOARD
+#define CONFIG_TEGRA_NVEC_KEYBOARD
+/* NVEC support */
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_TEGRA
+#define CONFIG_SYS_I2C_INIT_BOARD
+#define CONFIG_SYS_I2C_TEGRA_NVEC
+
 #include "tegra-common-post.h"
 
 #endif /* __CONFIG_H */
Signature · 1 line
1.7.9.5