Commit 02d0a752 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c updates from Wolfram Sang:
 "For 3.14, the I2C subsystem has the following to offer:

   - new drivers for Renesas RIIC and RobotFuzz OSIF
   - driver cleanups & improvements & bugfixes

  Pretty standard stuff this time, I'd say.  There is more complex stuff
  coming up, but I didn't have the bandwidth between the years to pull
  it in for this release.  Sadly"

* 'i2c/for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (26 commits)
  i2c: s3c2410: fix quirk usage for 64-bit
  i2c: pnx: Use devm_*() functions
  i2c: at91: add a new compatibility string for the at91sam9261
  i2c-ismt: support I2C_SMBUS_I2C_BLOCK_DATA transaction type
  i2c: Add bus driver for for OSIF USB i2c device.
  i2c: i2c-tiny-usb: Remove RobotFuzz USB vendor:product ID
  i2c: designware: remove HAVE_CLK build dependecy
  Documentation: i2c: Remove obsolete example
  i2c: nomadik: remove platform data header
  i2c: nomadik: auto-calculate slave setup time
  i2c: viperboard: remove superfluous assignment
  i2c: xilinx: Use devm_* functions
  i2c: xilinx: Do not enable irq before irq handler
  i2c: xilinx: Fix i2c checkpatch warnings
  i2c: at91: document clock properties
  i2c: isch: Use devm_request_region()
  i2c: viperboard: Use devm_kzalloc() functions
  i2c: imx: propagate irq error code in probe
  i2c: s3c2410: dont need CPU_FREQ transitions for exynos series
  i2c: s3c2410: Add polling mode support
  ...
parents fb2e2c85 5f1b1155
......@@ -9,6 +9,7 @@ Required properties :
- interrupts: interrupt number to the cpu.
- #address-cells = <1>;
- #size-cells = <0>;
- clocks: phandles to input clocks.
Optional properties:
- Child nodes conforming to i2c bus binding
......@@ -21,6 +22,7 @@ i2c0: i2c@fff84000 {
interrupts = <12 4 6>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&twi0_clk>;
24c512@50 {
compatible = "24c512";
......
* NXP PCA954x I2C bus switch
Required Properties:
- compatible: Must contain one of the following.
"nxp,pca9540", "nxp,pca9542", "nxp,pca9543", "nxp,pca9544",
"nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548"
- reg: The I2C address of the device.
The following required properties are defined externally:
- Standard I2C mux properties. See i2c-mux.txt in this directory.
- I2C child bus nodes. See i2c-mux.txt in this directory.
Optional Properties:
- reset-gpios: Reference to the GPIO connected to the reset input.
Example:
i2c-switch@74 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x74>;
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
eeprom@54 {
compatible = "at,24c08";
reg = <0x54>;
};
};
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
rtc@51 {
compatible = "nxp,pcf8563";
reg = <0x51>;
};
};
};
Device tree configuration for Renesas RIIC driver
Required properties:
- compatible : "renesas,riic-<soctype>". "renesas,riic-rz" as fallback
- reg : address start and address range size of device
- interrupts : 8 interrupts (TEI, RI, TI, SPI, STI, NAKI, ALI, TMOI)
- clock-frequency : frequency of bus clock in Hz
- #address-cells : should be <1>
- #size-cells : should be <0>
Pinctrl properties might be needed, too. See there.
Example:
i2c0: i2c@fcfee000 {
compatible = "renesas,riic-r7s72100", "renesas,riic-rz";
reg = <0xfcfee000 0x44>;
interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>,
<0 158 IRQ_TYPE_EDGE_RISING>,
<0 159 IRQ_TYPE_EDGE_RISING>,
<0 160 IRQ_TYPE_LEVEL_HIGH>,
<0 161 IRQ_TYPE_LEVEL_HIGH>,
<0 162 IRQ_TYPE_LEVEL_HIGH>,
<0 163 IRQ_TYPE_LEVEL_HIGH>,
<0 164 IRQ_TYPE_LEVEL_HIGH>;
clock-frequency = <100000>;
#address-cells = <1>;
#size-cells = <0>;
};
......@@ -10,6 +10,8 @@ Required properties:
inside HDMIPHY block found on several samsung SoCs
(d) "samsung, exynos5440-i2c", for s3c2440-like i2c used
on EXYNOS5440 which does not need GPIO configuration.
(e) "samsung, exynos5-sata-phy-i2c", for s3c2440-like i2c used as
a host to SATA PHY controller on an internal bus.
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: interrupt number to the cpu.
......
......@@ -64,9 +64,6 @@ EINVAL
detected before any I/O operation was started. Use a more
specific fault code when you can.
One example would be a driver trying an SMBus Block Write
with block size outside the range of 1-32 bytes.
EIO
This rather vague error means something went wrong when
performing an I/O operation. Use a more specific fault
......
......@@ -412,7 +412,6 @@ config I2C_DESIGNWARE_CORE
config I2C_DESIGNWARE_PLATFORM
tristate "Synopsys DesignWare Platform"
depends on HAVE_CLK
select I2C_DESIGNWARE_CORE
help
If you say yes to this option, support will be included for the
......@@ -648,6 +647,16 @@ config I2C_PXA_SLAVE
is necessary for systems where the PXA may be a target on the
I2C bus.
config I2C_RIIC
tristate "Renesas RIIC adapter"
depends on ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
Renesas RIIC I2C interface.
This driver can also be built as a module. If so, the module
will be called i2c-riic.
config HAVE_S3C2410_I2C
bool
help
......@@ -683,7 +692,7 @@ config I2C_SH7760
config I2C_SH_MOBILE
tristate "SuperH Mobile I2C Controller"
depends on SUPERH || ARM || COMPILE_TEST
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Renesas SH-Mobile processor.
......@@ -796,7 +805,7 @@ config I2C_XLR
config I2C_RCAR
tristate "Renesas R-Car I2C Controller"
depends on ARM || COMPILE_TEST
depends on ARCH_SHMOBILE || COMPILE_TEST
help
If you say yes to this option, support will be included for the
R-Car I2C controller.
......@@ -865,6 +874,16 @@ config I2C_PARPORT_LIGHT
This support is also available as a module. If so, the module
will be called i2c-parport-light.
config I2C_ROBOTFUZZ_OSIF
tristate "RobotFuzz Open Source InterFace USB adapter"
depends on USB
help
If you say yes to this option, support will be included for the
RobotFuzz Open Source InterFace USB to I2C interface.
This driver can also be built as a module. If so, the module
will be called i2c-osif.
config I2C_TAOS_EVM
tristate "TAOS evaluation module"
depends on TTY
......
......@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
......@@ -83,6 +84,7 @@ obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
obj-$(CONFIG_I2C_DIOLAN_U2C) += i2c-diolan-u2c.o
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF) += i2c-robotfuzz-osif.o
obj-$(CONFIG_I2C_TAOS_EVM) += i2c-taos-evm.o
obj-$(CONFIG_I2C_TINY_USB) += i2c-tiny-usb.o
obj-$(CONFIG_I2C_VIPERBOARD) += i2c-viperboard.o
......
......@@ -588,6 +588,9 @@ static const struct of_device_id atmel_twi_dt_ids[] = {
} , {
.compatible = "atmel,at91sam9260-i2c",
.data = &at91sam9260_config,
} , {
.compatible = "atmel,at91sam9261-i2c",
.data = &at91sam9261_config,
} , {
.compatible = "atmel,at91sam9g20-i2c",
.data = &at91sam9g20_config,
......
......@@ -26,7 +26,6 @@
*
*/
#include <linux/export.h>
#include <linux/clk.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/i2c.h>
......
......@@ -607,7 +607,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "can't get irq number\n");
return -ENOENT;
return irq;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
......@@ -275,7 +275,8 @@ static int smbus_sch_probe(struct platform_device *dev)
if (!res)
return -EBUSY;
if (!request_region(res->start, resource_size(res), dev->name)) {
if (!devm_request_region(&dev->dev, res->start, resource_size(res),
dev->name)) {
dev_err(&dev->dev, "SMBus region 0x%x already in use!\n",
sch_smba);
return -EBUSY;
......@@ -294,7 +295,6 @@ static int smbus_sch_probe(struct platform_device *dev)
retval = i2c_add_adapter(&sch_adapter);
if (retval) {
dev_err(&dev->dev, "Couldn't register adapter!\n");
release_region(res->start, resource_size(res));
sch_smba = 0;
}
......@@ -303,11 +303,8 @@ static int smbus_sch_probe(struct platform_device *dev)
static int smbus_sch_remove(struct platform_device *pdev)
{
struct resource *res;
if (sch_smba) {
i2c_del_adapter(&sch_adapter);
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
release_region(res->start, resource_size(res));
sch_smba = 0;
}
......
......@@ -344,6 +344,7 @@ static int ismt_process_desc(const struct ismt_desc *desc,
data->word = dma_buffer[0] | (dma_buffer[1] << 8);
break;
case I2C_SMBUS_BLOCK_DATA:
case I2C_SMBUS_I2C_BLOCK_DATA:
memcpy(&data->block[1], dma_buffer, desc->rxbytes);
data->block[0] = desc->rxbytes;
break;
......@@ -509,6 +510,41 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
}
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
/* Make sure the length is valid */
if (data->block[0] < 1)
data->block[0] = 1;
if (data->block[0] > I2C_SMBUS_BLOCK_MAX)
data->block[0] = I2C_SMBUS_BLOCK_MAX;
if (read_write == I2C_SMBUS_WRITE) {
/* i2c Block Write */
dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: WRITE\n");
dma_size = data->block[0] + 1;
dma_direction = DMA_TO_DEVICE;
desc->wr_len_cmd = dma_size;
desc->control |= ISMT_DESC_I2C;
priv->dma_buffer[0] = command;
memcpy(&priv->dma_buffer[1], &data->block[1], dma_size);
} else {
/* i2c Block Read */
dev_dbg(dev, "I2C_SMBUS_I2C_BLOCK_DATA: READ\n");
dma_size = data->block[0];
dma_direction = DMA_FROM_DEVICE;
desc->rd_len = dma_size;
desc->wr_len_cmd = command;
desc->control |= (ISMT_DESC_I2C | ISMT_DESC_CWRL);
/*
* Per the "Table 15-15. I2C Commands",
* in the External Design Specification (EDS),
* (Document Number: 508084, Revision: 2.0),
* the _rw bit must be 0
*/
desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, 0);
}
break;
default:
dev_err(dev, "Unsupported transaction %d\n",
size);
......@@ -582,6 +618,7 @@ static u32 ismt_func(struct i2c_adapter *adap)
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_PROC_CALL |
I2C_FUNC_SMBUS_BLOCK_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_PEC;
}
......
......@@ -22,7 +22,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/i2c-nomadik.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
......@@ -104,6 +103,29 @@
/* maximum threshold value */
#define MAX_I2C_FIFO_THRESHOLD 15
enum i2c_freq_mode {
I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
};
/**
* struct nmk_i2c_controller - client specific controller configuration
* @clk_freq: clock frequency for the operation mode
* @tft: Tx FIFO Threshold in bytes
* @rft: Rx FIFO Threshold in bytes
* @timeout Slave response timeout(ms)
* @sm: speed mode
*/
struct nmk_i2c_controller {
u32 clk_freq;
unsigned char tft;
unsigned char rft;
int timeout;
enum i2c_freq_mode sm;
};
/**
* struct i2c_vendor_data - per-vendor variations
* @has_mtdws: variant has the MTDWS bit
......@@ -340,6 +362,8 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
{
u32 brcr1, brcr2;
u32 i2c_clk, div;
u32 ns;
u16 slsu;
writel(0x0, dev->virtbase + I2C_CR);
writel(0x0, dev->virtbase + I2C_HSMCR);
......@@ -347,18 +371,38 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
writel(0x0, dev->virtbase + I2C_RFTR);
writel(0x0, dev->virtbase + I2C_DMAR);
i2c_clk = clk_get_rate(dev->clk);
/*
* set the slsu:
*
* slsu defines the data setup time after SCL clock
* stretching in terms of i2c clk cycles. The
* needed setup time for the three modes are 250ns,
* 100ns, 10ns respectively thus leading to the values
* of 14, 6, 2 for a 48 MHz i2c clk.
* stretching in terms of i2c clk cycles + 1 (zero means
* "wait one cycle"), the needed setup time for the three
* modes are 250ns, 100ns, 10ns respectively.
*
* As the time for one cycle T in nanoseconds is
* T = (1/f) * 1000000000 =>
* slsu = cycles / (1000000000 / f) + 1
*/
writel(dev->cfg.slsu << 16, dev->virtbase + I2C_SCR);
ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk);
switch (dev->cfg.sm) {
case I2C_FREQ_MODE_FAST:
case I2C_FREQ_MODE_FAST_PLUS:
slsu = DIV_ROUND_UP(100, ns); /* Fast */
break;
case I2C_FREQ_MODE_HIGH_SPEED:
slsu = DIV_ROUND_UP(10, ns); /* High */
break;
case I2C_FREQ_MODE_STANDARD:
default:
slsu = DIV_ROUND_UP(250, ns); /* Standard */
break;
}
slsu += 1;
i2c_clk = clk_get_rate(dev->clk);
dev_dbg(&dev->adev->dev, "calculated SLSU = %04x\n", slsu);
writel(slsu << 16, dev->virtbase + I2C_SCR);
/*
* The spec says, in case of std. mode the divider is
......@@ -915,11 +959,6 @@ static const struct i2c_algorithm nmk_i2c_algo = {
};
static struct nmk_i2c_controller u8500_i2c = {
/*
* Slave data setup time; 250ns, 100ns, and 10ns, which
* is 14, 6 and 2 respectively for a 48Mhz i2c clock.
*/
.slsu = 0xe,
.tft = 1, /* Tx FIFO threshold */
.rft = 8, /* Rx FIFO threshold */
.clk_freq = 400000, /* fast mode operation */
......@@ -1027,7 +1066,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
/* fetch the controller configuration from machine */
dev->cfg.clk_freq = pdata->clk_freq;
dev->cfg.slsu = pdata->slsu;
dev->cfg.tft = pdata->tft;
dev->cfg.rft = pdata->rft;
dev->cfg.sm = pdata->sm;
......
......@@ -628,11 +628,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)
struct resource *res;
u32 speed = I2C_PNX_SPEED_KHZ_DEFAULT * 1000;
alg_data = kzalloc(sizeof(*alg_data), GFP_KERNEL);
if (!alg_data) {
ret = -ENOMEM;
goto err_kzalloc;
}
alg_data = devm_kzalloc(&pdev->dev, sizeof(*alg_data), GFP_KERNEL);
if (!alg_data)
return -ENOMEM;
platform_set_drvdata(pdev, alg_data);
......@@ -657,11 +655,9 @@ static int i2c_pnx_probe(struct platform_device *pdev)
*/
}
#endif
alg_data->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(alg_data->clk)) {
ret = PTR_ERR(alg_data->clk);
goto out_drvdata;
}
alg_data->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(alg_data->clk))
return PTR_ERR(alg_data->clk);
init_timer(&alg_data->mif.timer);
alg_data->mif.timer.function = i2c_pnx_timeout;
......@@ -672,31 +668,13 @@ static int i2c_pnx_probe(struct platform_device *pdev)
/* Register I/O resource */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Unable to get mem resource.\n");
ret = -EBUSY;
goto out_clkget;
}
if (!request_mem_region(res->start, I2C_PNX_REGION_SIZE,
pdev->name)) {
dev_err(&pdev->dev,
"I/O region 0x%08x for I2C already in use.\n",
res->start);
ret = -ENOMEM;
goto out_clkget;
}
alg_data->base = res->start;
alg_data->ioaddr = ioremap(res->start, I2C_PNX_REGION_SIZE);
if (!alg_data->ioaddr) {
dev_err(&pdev->dev, "Couldn't ioremap I2C I/O region\n");
ret = -ENOMEM;
goto out_release;
}
alg_data->ioaddr = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(alg_data->ioaddr))
return PTR_ERR(alg_data->ioaddr);
ret = clk_enable(alg_data->clk);
if (ret)
goto out_unmap;
return ret;
freq = clk_get_rate(alg_data->clk);
......@@ -730,8 +708,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
ret = alg_data->irq;
goto out_clock;
}
ret = request_irq(alg_data->irq, i2c_pnx_interrupt,
0, pdev->name, alg_data);
ret = devm_request_irq(&pdev->dev, alg_data->irq, i2c_pnx_interrupt,
0, pdev->name, alg_data);
if (ret)
goto out_clock;
......@@ -739,7 +717,7 @@ static int i2c_pnx_probe(struct platform_device *pdev)
ret = i2c_add_numbered_adapter(&alg_data->adapter);
if (ret < 0) {
dev_err(&pdev->dev, "I2C: Failed to add bus\n");
goto out_irq;
goto out_clock;
}
dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
......@@ -747,19 +725,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
return 0;
out_irq:
free_irq(alg_data->irq, alg_data);
out_clock:
clk_disable(alg_data->clk);
out_unmap:
iounmap(alg_data->ioaddr);
out_release:
release_mem_region(res->start, I2C_PNX_REGION_SIZE);
out_clkget:
clk_put(alg_data->clk);
out_drvdata:
kfree(alg_data);
err_kzalloc:
return ret;
}
......@@ -767,13 +734,8 @@ static int i2c_pnx_remove(struct platform_device *pdev)
{
struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev);
free_irq(alg_data->irq, alg_data);
i2c_del_adapter(&alg_data->adapter);
clk_disable(alg_data->clk);
iounmap(alg_data->ioaddr);
release_mem_region(alg_data->base, I2C_PNX_REGION_SIZE);
clk_put(alg_data->clk);
kfree(alg_data);
return 0;
}
......
/*
* Renesas RIIC driver
*
* Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
* Copyright (C) 2013 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
/*
* This i2c core has a lot of interrupts, namely 8. We use their chaining as
* some kind of state machine.
*
* 1) The main xfer routine kicks off a transmission by putting the start bit
* (or repeated start) on the bus and enabling the transmit interrupt (TIE)
* since we need to send the slave address + RW bit in every case.
*
* 2) TIE sends slave address + RW bit and selects how to continue.
*
* 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
* are done, we switch over to the transmission done interrupt (TEIE) and mark
* the message as completed (includes sending STOP) there.
*
* 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is
* needed to start clocking, then we keep receiving until we are done. Note
* that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by
* writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a
* message to create the final NACK as sketched in the datasheet. This caused
* some subtle races (when byte n was processed and byte n+1 was already
* waiting), though, and I started with the safe approach.
*
* 4) If we got a NACK somewhere, we flag the error and stop the transmission
* via NAKIE.
*
* Also check the comments in the interrupt routines for some gory details.
*/
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#define RIIC_ICCR1 0x00
#define RIIC_ICCR2 0x04
#define RIIC_ICMR1 0x08
#define RIIC_ICMR3 0x10
#define RIIC_ICSER 0x18
#define RIIC_ICIER 0x1c
#define RIIC_ICSR2 0x24
#define RIIC_ICBRL 0x34
#define RIIC_ICBRH 0x38
#define RIIC_ICDRT 0x3c
#define RIIC_ICDRR 0x40
#define ICCR1_ICE 0x80
#define ICCR1_IICRST 0x40
#define ICCR1_SOWP 0x10
#define ICCR2_BBSY 0x80
#define ICCR2_SP 0x08
#define ICCR2_RS 0x04
#define ICCR2_ST 0x02
#define ICMR1_CKS_MASK 0x70
#define ICMR1_BCWP 0x08
#define ICMR1_CKS(_x) ((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP)
#define ICMR3_RDRFS 0x20
#define ICMR3_ACKWP 0x10
#define ICMR3_ACKBT 0x08
#define ICIER_TIE 0x80
#define ICIER_TEIE 0x40
#define ICIER_RIE 0x20
#define ICIER_NAKIE 0x10
#define ICSR2_NACKF 0x10