drivers: i2c: Add DTS support for i2c_sam_twihs driver

Signed-off-by: Piotr Mienkowski <piotr.mienkowski@gmail.com>
diff --git a/boards/arm/sam_e70_xplained/Kconfig.defconfig b/boards/arm/sam_e70_xplained/Kconfig.defconfig
index b0b105d..9477323 100644
--- a/boards/arm/sam_e70_xplained/Kconfig.defconfig
+++ b/boards/arm/sam_e70_xplained/Kconfig.defconfig
@@ -34,22 +34,20 @@
 	string
 	default "I2C_0"
 
-# Configure I2C bus driver
-
 config ETH_SAM_GMAC_MAC_I2C_EEPROM
 	bool
 	select I2C
-	select I2C_SAM_TWIHS
-	select I2C_0
-
-config I2C_0_DEFAULT_CFG
-	hex
-	default 0x12
-
-config I2C_0_IRQ_PRI
-	int
-	default 0
 
 endif # ETH_SAM_GMAC
 
+if I2C
+
+config I2C_SAM_TWIHS
+	default y
+
+config I2C_0
+	default y
+
+endif # I2C
+
 endif # BOARD_SAM_E70_XPLAINED
diff --git a/boards/arm/sam_e70_xplained/dts.fixup b/boards/arm/sam_e70_xplained/dts.fixup
index cf58cdd..c9785f3 100644
--- a/boards/arm/sam_e70_xplained/dts.fixup
+++ b/boards/arm/sam_e70_xplained/dts.fixup
@@ -6,6 +6,27 @@
 
 #define CONFIG_NUM_IRQ_PRIO_BITS	ARM_V7M_NVIC_E000E100_ARM_NUM_IRQ_PRIORITY_BITS
 
+#define CONFIG_I2C_0_BASE_ADDRESS	ATMEL_SAM_I2C_TWIHS_40018000_BASE_ADDRESS
+#define CONFIG_I2C_0_NAME		ATMEL_SAM_I2C_TWIHS_40018000_LABEL
+#define CONFIG_I2C_0_BITRATE		ATMEL_SAM_I2C_TWIHS_40018000_CLOCK_FREQUENCY
+#define CONFIG_I2C_0_IRQ		ATMEL_SAM_I2C_TWIHS_40018000_IRQ_0
+#define CONFIG_I2C_0_IRQ_PRI		ATMEL_SAM_I2C_TWIHS_40018000_IRQ_0_PRIORITY
+#define CONFIG_I2C_0_PERIPHERAL_ID	ATMEL_SAM_I2C_TWIHS_40018000_PERIPHERAL_ID
+
+#define CONFIG_I2C_1_BASE_ADDRESS	ATMEL_SAM_I2C_TWIHS_4001C000_BASE_ADDRESS
+#define CONFIG_I2C_1_NAME		ATMEL_SAM_I2C_TWIHS_4001C000_LABEL
+#define CONFIG_I2C_1_BITRATE		ATMEL_SAM_I2C_TWIHS_4001C000_CLOCK_FREQUENCY
+#define CONFIG_I2C_1_IRQ		ATMEL_SAM_I2C_TWIHS_4001C000_IRQ_0
+#define CONFIG_I2C_1_IRQ_PRI		ATMEL_SAM_I2C_TWIHS_4001C000_IRQ_0_PRIORITY
+#define CONFIG_I2C_1_PERIPHERAL_ID	ATMEL_SAM_I2C_TWIHS_4001C000_PERIPHERAL_ID
+
+#define CONFIG_I2C_2_BASE_ADDRESS	ATMEL_SAM_I2C_TWIHS_40060000_BASE_ADDRESS
+#define CONFIG_I2C_2_NAME		ATMEL_SAM_I2C_TWIHS_40060000_LABEL
+#define CONFIG_I2C_2_BITRATE		ATMEL_SAM_I2C_TWIHS_40060000_CLOCK_FREQUENCY
+#define CONFIG_I2C_2_IRQ		ATMEL_SAM_I2C_TWIHS_40060000_IRQ_0
+#define CONFIG_I2C_2_IRQ_PRI		ATMEL_SAM_I2C_TWIHS_40060000_IRQ_0_PRIORITY
+#define CONFIG_I2C_2_PERIPHERAL_ID	ATMEL_SAM_I2C_TWIHS_40060000_PERIPHERAL_ID
+
 #define CONFIG_UART_SAM_PORT_0_NAME	ATMEL_SAM_UART_400E0800_LABEL
 #define CONFIG_UART_SAM_PORT_0_BAUD_RATE	ATMEL_SAM_UART_400E0800_CURRENT_SPEED
 #define CONFIG_UART_SAM_PORT_1_NAME	ATMEL_SAM_UART_400E0A00_LABEL
diff --git a/boards/arm/sam_e70_xplained/sam_e70_xplained.dts b/boards/arm/sam_e70_xplained/sam_e70_xplained.dts
index 64af610..8ce35c5 100644
--- a/boards/arm/sam_e70_xplained/sam_e70_xplained.dts
+++ b/boards/arm/sam_e70_xplained/sam_e70_xplained.dts
@@ -13,6 +13,12 @@
 	model = "Atmel SAM E70 Xplained board";
 	compatible = "atmel,sam_e70_xplained", "atmel,same70q21", "atmel,same70";
 
+	aliases {
+		i2c_0 = &i2c0;
+		i2c_1 = &i2c1;
+		i2c_2 = &i2c2;
+	};
+
 	chosen {
 		zephyr,console = &usart1;
 		zephyr,sram = &sram0;
@@ -28,6 +34,14 @@
 	status = "ok";
 };
 
+&i2c0 {
+	status = "ok";
+};
+
+&i2c2 {
+	status = "ok";
+};
+
 &usart1 {
 	current-speed = <115200>;
 	status = "ok";
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 1c96cca..79bbb33 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -59,6 +59,7 @@
 config I2C_SAM_TWIHS
 	bool "Atmel SAM (TWIHS) I2C driver"
 	depends on SOC_FAMILY_SAM
+	select HAS_DTS_I2C
 	default n
 	help
 	  Enable Atmel SAM MCU Family (TWIHS) I2C bus driver.
diff --git a/drivers/i2c/i2c_sam_twihs.c b/drivers/i2c/i2c_sam_twihs.c
index b3c2dd8..49d0a26 100644
--- a/drivers/i2c/i2c_sam_twihs.c
+++ b/drivers/i2c/i2c_sam_twihs.c
@@ -10,6 +10,10 @@
  * Only I2C Master Mode with 7 bit addressing is currently supported.
  */
 
+#define SYS_LOG_DOMAIN "dev/i2c_sam_twihs"
+#define SYS_LOG_LEVEL CONFIG_SYS_LOG_I2C_LEVEL
+#include <logging/sys_log.h>
+
 #include <errno.h>
 #include <misc/__assert.h>
 #include <kernel.h>
@@ -17,10 +21,7 @@
 #include <init.h>
 #include <soc.h>
 #include <i2c.h>
-
-#define SYS_LOG_DOMAIN "dev/i2c_sam_twihs"
-#define SYS_LOG_LEVEL CONFIG_SYS_LOG_I2C_LEVEL
-#include <logging/sys_log.h>
+#include "i2c-priv.h"
 
 /** I2C bus speed [Hz] in Standard Mode */
 #define BUS_SPEED_STANDARD_HZ         100000U
@@ -35,7 +36,7 @@
 struct i2c_sam_twihs_dev_cfg {
 	Twihs *regs;
 	void (*irq_config)(void);
-	u32_t mode_config;
+	u32_t bitrate;
 	const struct soc_gpio_pin *pin_list;
 	u8_t pin_list_size;
 	u8_t periph_id;
@@ -148,7 +149,7 @@
 static void write_msg_start(Twihs *const twihs, struct twihs_msg *msg,
 			    u8_t daddr)
 {
-	/* Set slave address and number of internal address bytes. */
+	/* Set slave address. */
 	twihs->TWIHS_MMR = TWIHS_MMR_DADR(daddr);
 
 	/* Write first data byte on I2C bus */
@@ -281,6 +282,7 @@
 	const struct i2c_sam_twihs_dev_cfg *const dev_cfg = DEV_CFG(dev);
 	struct i2c_sam_twihs_dev_data *const dev_data = DEV_DATA(dev);
 	Twihs *const twihs = dev_cfg->regs;
+	u32_t bitrate_cfg;
 	int ret;
 
 	/* Configure interrupts */
@@ -298,7 +300,9 @@
 	/* Reset the module */
 	twihs->TWIHS_CR = TWIHS_CR_SWRST;
 
-	ret = i2c_sam_twihs_configure(dev, dev_cfg->mode_config);
+	bitrate_cfg = _i2c_map_dt_bitrate(dev_cfg->bitrate);
+
+	ret = i2c_sam_twihs_configure(dev, I2C_MODE_MASTER | bitrate_cfg);
 	if (ret < 0) {
 		SYS_LOG_ERR("Failed to initialize %s device", DEV_NAME(dev));
 		return ret;
@@ -324,20 +328,20 @@
 
 static void i2c0_sam_irq_config(void)
 {
-	IRQ_CONNECT(TWIHS0_IRQn, CONFIG_I2C_0_IRQ_PRI, i2c_sam_twihs_isr,
+	IRQ_CONNECT(CONFIG_I2C_0_IRQ, CONFIG_I2C_0_IRQ_PRI, i2c_sam_twihs_isr,
 		    DEVICE_GET(i2c0_sam), 0);
 }
 
 static const struct soc_gpio_pin pins_twihs0[] = PINS_TWIHS0;
 
 static const struct i2c_sam_twihs_dev_cfg i2c0_sam_config = {
-	.regs = TWIHS0,
+	.regs = (Twihs *)CONFIG_I2C_0_BASE_ADDRESS,
 	.irq_config = i2c0_sam_irq_config,
-	.periph_id = ID_TWIHS0,
-	.irq_id = TWIHS0_IRQn,
+	.periph_id = CONFIG_I2C_0_PERIPHERAL_ID,
+	.irq_id = CONFIG_I2C_0_IRQ,
 	.pin_list = pins_twihs0,
 	.pin_list_size = ARRAY_SIZE(pins_twihs0),
-	.mode_config = CONFIG_I2C_0_DEFAULT_CFG,
+	.bitrate = CONFIG_I2C_0_BITRATE,
 };
 
 static struct i2c_sam_twihs_dev_data i2c0_sam_data;
@@ -354,20 +358,20 @@
 
 static void i2c1_sam_irq_config(void)
 {
-	IRQ_CONNECT(TWIHS1_IRQn, CONFIG_I2C_1_IRQ_PRI, i2c_sam_twihs_isr,
+	IRQ_CONNECT(CONFIG_I2C_1_IRQ, CONFIG_I2C_1_IRQ_PRI, i2c_sam_twihs_isr,
 		    DEVICE_GET(i2c1_sam), 0);
 }
 
 static const struct soc_gpio_pin pins_twihs1[] = PINS_TWIHS1;
 
 static const struct i2c_sam_twihs_dev_cfg i2c1_sam_config = {
-	.regs = TWIHS1,
+	.regs = (Twihs *)CONFIG_I2C_1_BASE_ADDRESS,
 	.irq_config = i2c1_sam_irq_config,
-	.periph_id = ID_TWIHS1,
-	.irq_id = TWIHS1_IRQn,
+	.periph_id = CONFIG_I2C_1_PERIPHERAL_ID,
+	.irq_id = CONFIG_I2C_1_IRQ,
 	.pin_list = pins_twihs1,
 	.pin_list_size = ARRAY_SIZE(pins_twihs1),
-	.mode_config = CONFIG_I2C_1_DEFAULT_CFG,
+	.bitrate = CONFIG_I2C_1_BITRATE,
 };
 
 static struct i2c_sam_twihs_dev_data i2c1_sam_data;
@@ -384,20 +388,20 @@
 
 static void i2c2_sam_irq_config(void)
 {
-	IRQ_CONNECT(TWIHS2_IRQn, CONFIG_I2C_2_IRQ_PRI, i2c_sam_twihs_isr,
+	IRQ_CONNECT(CONFIG_I2C_2_IRQ, CONFIG_I2C_2_IRQ_PRI, i2c_sam_twihs_isr,
 		    DEVICE_GET(i2c2_sam), 0);
 }
 
 static const struct soc_gpio_pin pins_twihs2[] = PINS_TWIHS2;
 
 static const struct i2c_sam_twihs_dev_cfg i2c2_sam_config = {
-	.regs = TWIHS2,
+	.regs = (Twihs *)CONFIG_I2C_2_BASE_ADDRESS,
 	.irq_config = i2c2_sam_irq_config,
-	.periph_id = ID_TWIHS2,
-	.irq_id = TWIHS2_IRQn,
+	.periph_id = CONFIG_I2C_2_PERIPHERAL_ID,
+	.irq_id = CONFIG_I2C_2_IRQ,
 	.pin_list = pins_twihs2,
 	.pin_list_size = ARRAY_SIZE(pins_twihs2),
-	.mode_config = CONFIG_I2C_2_DEFAULT_CFG,
+	.bitrate = CONFIG_I2C_2_BITRATE,
 };
 
 static struct i2c_sam_twihs_dev_data i2c2_sam_data;
diff --git a/dts/arm/atmel/same70.dtsi b/dts/arm/atmel/same70.dtsi
index 6d6b0c4..62b6971 100644
--- a/dts/arm/atmel/same70.dtsi
+++ b/dts/arm/atmel/same70.dtsi
@@ -7,6 +7,7 @@
 
 #include <arm/armv7-m.dtsi>
 #include <atmel/same70_mem.h>
+#include <dt-bindings/i2c/i2c.h>
 
 / {
 	cpus {
@@ -31,6 +32,42 @@
 	};
 
 	soc {
+		i2c0: i2c@40018000 {
+			compatible = "atmel,sam-i2c-twihs";
+			clock-frequency = <I2C_BITRATE_STANDARD>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x40018000 0x12B>;
+			interrupts = <19 0>;
+			peripheral-id = <19>;
+			label = "I2C_0";
+			status = "disabled";
+		};
+
+		i2c1: i2c@4001C000 {
+			compatible = "atmel,sam-i2c-twihs";
+			clock-frequency = <I2C_BITRATE_STANDARD>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x4001C000 0x12B>;
+			interrupts = <20 0>;
+			peripheral-id = <20>;
+			label = "I2C_1";
+			status = "disabled";
+		};
+
+		i2c2: i2c@40060000 {
+			compatible = "atmel,sam-i2c-twihs";
+			clock-frequency = <I2C_BITRATE_STANDARD>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x40060000 0x12B>;
+			interrupts = <41 0>;
+			peripheral-id = <41>;
+			label = "I2C_2";
+			status = "disabled";
+		};
+
 		uart0: uart@400E0800 {
 			compatible = "atmel,sam-uart";
 			reg = <0x400E0800 0x100>;
diff --git a/dts/bindings/i2c/atmel,sam-i2c-twihs.yaml b/dts/bindings/i2c/atmel,sam-i2c-twihs.yaml
new file mode 100644
index 0000000..df98bb0
--- /dev/null
+++ b/dts/bindings/i2c/atmel,sam-i2c-twihs.yaml
@@ -0,0 +1,41 @@
+#
+# Copyright (c) 2017 Piotr Mienkowski
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+---
+title: Atmel SAM Family I2C (TWIHS) node
+id: atmel,sam-i2c-twihs
+version: 0.1
+
+description: >
+    This is a representation of the Atmel SAM Family I2C (TWIHS) node
+
+inherits:
+  - !include i2c.yaml
+
+properties:
+  - compatible:
+      type: string
+      category: required
+      description: compatible strings
+      constraint: "atmel,sam-i2c-twihs"
+
+  - reg:
+      type: array
+      description: mmio register space
+      generation: define
+      category: required
+
+  - interrupts:
+      type: array
+      category: required
+      description: required interrupts
+      generation: define
+
+  - peripheral-id:
+      type: int
+      description: peripheral ID
+      generation: define
+      category: required
+...