18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for the Renesas R-Car I2C unit
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2014-19 Wolfram Sang <wsa@sang-engineering.com>
68c2ecf20Sopenharmony_ci * Copyright (C) 2011-2019 Renesas Electronics Corporation
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Copyright (C) 2012-14 Renesas Solutions Corp.
98c2ecf20Sopenharmony_ci * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * This file is based on the drivers/i2c/busses/i2c-sh7760.c
128c2ecf20Sopenharmony_ci * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci#include <linux/bitops.h>
158c2ecf20Sopenharmony_ci#include <linux/clk.h>
168c2ecf20Sopenharmony_ci#include <linux/delay.h>
178c2ecf20Sopenharmony_ci#include <linux/dmaengine.h>
188c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
198c2ecf20Sopenharmony_ci#include <linux/err.h>
208c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
218c2ecf20Sopenharmony_ci#include <linux/io.h>
228c2ecf20Sopenharmony_ci#include <linux/iopoll.h>
238c2ecf20Sopenharmony_ci#include <linux/i2c.h>
248c2ecf20Sopenharmony_ci#include <linux/i2c-smbus.h>
258c2ecf20Sopenharmony_ci#include <linux/kernel.h>
268c2ecf20Sopenharmony_ci#include <linux/module.h>
278c2ecf20Sopenharmony_ci#include <linux/of_device.h>
288c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
298c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h>
308c2ecf20Sopenharmony_ci#include <linux/reset.h>
318c2ecf20Sopenharmony_ci#include <linux/slab.h>
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/* register offsets */
348c2ecf20Sopenharmony_ci#define ICSCR	0x00	/* slave ctrl */
358c2ecf20Sopenharmony_ci#define ICMCR	0x04	/* master ctrl */
368c2ecf20Sopenharmony_ci#define ICSSR	0x08	/* slave status */
378c2ecf20Sopenharmony_ci#define ICMSR	0x0C	/* master status */
388c2ecf20Sopenharmony_ci#define ICSIER	0x10	/* slave irq enable */
398c2ecf20Sopenharmony_ci#define ICMIER	0x14	/* master irq enable */
408c2ecf20Sopenharmony_ci#define ICCCR	0x18	/* clock dividers */
418c2ecf20Sopenharmony_ci#define ICSAR	0x1C	/* slave address */
428c2ecf20Sopenharmony_ci#define ICMAR	0x20	/* master address */
438c2ecf20Sopenharmony_ci#define ICRXTX	0x24	/* data port */
448c2ecf20Sopenharmony_ci#define ICFBSCR	0x38	/* first bit setup cycle (Gen3) */
458c2ecf20Sopenharmony_ci#define ICDMAER	0x3c	/* DMA enable (Gen3) */
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* ICSCR */
488c2ecf20Sopenharmony_ci#define SDBS	(1 << 3)	/* slave data buffer select */
498c2ecf20Sopenharmony_ci#define SIE	(1 << 2)	/* slave interface enable */
508c2ecf20Sopenharmony_ci#define GCAE	(1 << 1)	/* general call address enable */
518c2ecf20Sopenharmony_ci#define FNA	(1 << 0)	/* forced non acknowledgment */
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/* ICMCR */
548c2ecf20Sopenharmony_ci#define MDBS	(1 << 7)	/* non-fifo mode switch */
558c2ecf20Sopenharmony_ci#define FSCL	(1 << 6)	/* override SCL pin */
568c2ecf20Sopenharmony_ci#define FSDA	(1 << 5)	/* override SDA pin */
578c2ecf20Sopenharmony_ci#define OBPC	(1 << 4)	/* override pins */
588c2ecf20Sopenharmony_ci#define MIE	(1 << 3)	/* master if enable */
598c2ecf20Sopenharmony_ci#define TSBE	(1 << 2)
608c2ecf20Sopenharmony_ci#define FSB	(1 << 1)	/* force stop bit */
618c2ecf20Sopenharmony_ci#define ESG	(1 << 0)	/* enable start bit gen */
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/* ICSSR (also for ICSIER) */
648c2ecf20Sopenharmony_ci#define GCAR	(1 << 6)	/* general call received */
658c2ecf20Sopenharmony_ci#define STM	(1 << 5)	/* slave transmit mode */
668c2ecf20Sopenharmony_ci#define SSR	(1 << 4)	/* stop received */
678c2ecf20Sopenharmony_ci#define SDE	(1 << 3)	/* slave data empty */
688c2ecf20Sopenharmony_ci#define SDT	(1 << 2)	/* slave data transmitted */
698c2ecf20Sopenharmony_ci#define SDR	(1 << 1)	/* slave data received */
708c2ecf20Sopenharmony_ci#define SAR	(1 << 0)	/* slave addr received */
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/* ICMSR (also for ICMIE) */
738c2ecf20Sopenharmony_ci#define MNR	(1 << 6)	/* nack received */
748c2ecf20Sopenharmony_ci#define MAL	(1 << 5)	/* arbitration lost */
758c2ecf20Sopenharmony_ci#define MST	(1 << 4)	/* sent a stop */
768c2ecf20Sopenharmony_ci#define MDE	(1 << 3)
778c2ecf20Sopenharmony_ci#define MDT	(1 << 2)
788c2ecf20Sopenharmony_ci#define MDR	(1 << 1)
798c2ecf20Sopenharmony_ci#define MAT	(1 << 0)	/* slave addr xfer done */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/* ICDMAER */
828c2ecf20Sopenharmony_ci#define RSDMAE	(1 << 3)	/* DMA Slave Received Enable */
838c2ecf20Sopenharmony_ci#define TSDMAE	(1 << 2)	/* DMA Slave Transmitted Enable */
848c2ecf20Sopenharmony_ci#define RMDMAE	(1 << 1)	/* DMA Master Received Enable */
858c2ecf20Sopenharmony_ci#define TMDMAE	(1 << 0)	/* DMA Master Transmitted Enable */
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci/* ICFBSCR */
888c2ecf20Sopenharmony_ci#define TCYC17	0x0f		/* 17*Tcyc delay 1st bit between SDA and SCL */
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#define RCAR_MIN_DMA_LEN	8
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#define RCAR_BUS_PHASE_START	(MDBS | MIE | ESG)
938c2ecf20Sopenharmony_ci#define RCAR_BUS_PHASE_DATA	(MDBS | MIE)
948c2ecf20Sopenharmony_ci#define RCAR_BUS_PHASE_STOP	(MDBS | MIE | FSB)
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci#define RCAR_IRQ_SEND	(MNR | MAL | MST | MAT | MDE)
978c2ecf20Sopenharmony_ci#define RCAR_IRQ_RECV	(MNR | MAL | MST | MAT | MDR)
988c2ecf20Sopenharmony_ci#define RCAR_IRQ_STOP	(MST)
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci#define RCAR_IRQ_ACK_SEND	(~(MAT | MDE) & 0x7F)
1018c2ecf20Sopenharmony_ci#define RCAR_IRQ_ACK_RECV	(~(MAT | MDR) & 0x7F)
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#define ID_LAST_MSG	(1 << 0)
1048c2ecf20Sopenharmony_ci#define ID_FIRST_MSG	(1 << 1)
1058c2ecf20Sopenharmony_ci#define ID_DONE		(1 << 2)
1068c2ecf20Sopenharmony_ci#define ID_ARBLOST	(1 << 3)
1078c2ecf20Sopenharmony_ci#define ID_NACK		(1 << 4)
1088c2ecf20Sopenharmony_ci/* persistent flags */
1098c2ecf20Sopenharmony_ci#define ID_P_HOST_NOTIFY	BIT(28)
1108c2ecf20Sopenharmony_ci#define ID_P_REP_AFTER_RD	BIT(29)
1118c2ecf20Sopenharmony_ci#define ID_P_NO_RXDMA		BIT(30) /* HW forbids RXDMA sometimes */
1128c2ecf20Sopenharmony_ci#define ID_P_PM_BLOCKED		BIT(31)
1138c2ecf20Sopenharmony_ci#define ID_P_MASK		GENMASK(31, 28)
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_cienum rcar_i2c_type {
1168c2ecf20Sopenharmony_ci	I2C_RCAR_GEN1,
1178c2ecf20Sopenharmony_ci	I2C_RCAR_GEN2,
1188c2ecf20Sopenharmony_ci	I2C_RCAR_GEN3,
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistruct rcar_i2c_priv {
1228c2ecf20Sopenharmony_ci	u32 flags;
1238c2ecf20Sopenharmony_ci	void __iomem *io;
1248c2ecf20Sopenharmony_ci	struct i2c_adapter adap;
1258c2ecf20Sopenharmony_ci	struct i2c_msg *msg;
1268c2ecf20Sopenharmony_ci	int msgs_left;
1278c2ecf20Sopenharmony_ci	struct clk *clk;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	wait_queue_head_t wait;
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	int pos;
1328c2ecf20Sopenharmony_ci	u32 icccr;
1338c2ecf20Sopenharmony_ci	u8 recovery_icmcr;	/* protected by adapter lock */
1348c2ecf20Sopenharmony_ci	enum rcar_i2c_type devtype;
1358c2ecf20Sopenharmony_ci	struct i2c_client *slave;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	struct resource *res;
1388c2ecf20Sopenharmony_ci	struct dma_chan *dma_tx;
1398c2ecf20Sopenharmony_ci	struct dma_chan *dma_rx;
1408c2ecf20Sopenharmony_ci	struct scatterlist sg;
1418c2ecf20Sopenharmony_ci	enum dma_data_direction dma_direction;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	struct reset_control *rstc;
1448c2ecf20Sopenharmony_ci	int irq;
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	struct i2c_client *host_notify_client;
1478c2ecf20Sopenharmony_ci};
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci#define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
1508c2ecf20Sopenharmony_ci#define rcar_i2c_is_recv(p)		((p)->msg->flags & I2C_M_RD)
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_cistatic void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)
1538c2ecf20Sopenharmony_ci{
1548c2ecf20Sopenharmony_ci	writel(val, priv->io + reg);
1558c2ecf20Sopenharmony_ci}
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	return readl(priv->io + reg);
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic int rcar_i2c_get_scl(struct i2c_adapter *adap)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	return !!(rcar_i2c_read(priv, ICMCR) & FSCL);
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci};
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic void rcar_i2c_set_scl(struct i2c_adapter *adap, int val)
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci	if (val)
1758c2ecf20Sopenharmony_ci		priv->recovery_icmcr |= FSCL;
1768c2ecf20Sopenharmony_ci	else
1778c2ecf20Sopenharmony_ci		priv->recovery_icmcr &= ~FSCL;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
1808c2ecf20Sopenharmony_ci};
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic void rcar_i2c_set_sda(struct i2c_adapter *adap, int val)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	if (val)
1878c2ecf20Sopenharmony_ci		priv->recovery_icmcr |= FSDA;
1888c2ecf20Sopenharmony_ci	else
1898c2ecf20Sopenharmony_ci		priv->recovery_icmcr &= ~FSDA;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMCR, priv->recovery_icmcr);
1928c2ecf20Sopenharmony_ci};
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic int rcar_i2c_get_bus_free(struct i2c_adapter *adap)
1958c2ecf20Sopenharmony_ci{
1968c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	return !(rcar_i2c_read(priv, ICMCR) & FSDA);
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci};
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_cistatic struct i2c_bus_recovery_info rcar_i2c_bri = {
2038c2ecf20Sopenharmony_ci	.get_scl = rcar_i2c_get_scl,
2048c2ecf20Sopenharmony_ci	.set_scl = rcar_i2c_set_scl,
2058c2ecf20Sopenharmony_ci	.set_sda = rcar_i2c_set_sda,
2068c2ecf20Sopenharmony_ci	.get_bus_free = rcar_i2c_get_bus_free,
2078c2ecf20Sopenharmony_ci	.recover_bus = i2c_generic_scl_recovery,
2088c2ecf20Sopenharmony_ci};
2098c2ecf20Sopenharmony_cistatic void rcar_i2c_init(struct rcar_i2c_priv *priv)
2108c2ecf20Sopenharmony_ci{
2118c2ecf20Sopenharmony_ci	/* reset master mode */
2128c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMIER, 0);
2138c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMCR, MDBS);
2148c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMSR, 0);
2158c2ecf20Sopenharmony_ci	/* start clock */
2168c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICCCR, priv->icccr);
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	if (priv->devtype == I2C_RCAR_GEN3)
2198c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICFBSCR, TCYC17);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci}
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	int ret;
2268c2ecf20Sopenharmony_ci	u32 val;
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	ret = readl_poll_timeout(priv->io + ICMCR, val, !(val & FSDA), 10,
2298c2ecf20Sopenharmony_ci				 priv->adap.timeout);
2308c2ecf20Sopenharmony_ci	if (ret) {
2318c2ecf20Sopenharmony_ci		/* Waiting did not help, try to recover */
2328c2ecf20Sopenharmony_ci		priv->recovery_icmcr = MDBS | OBPC | FSDA | FSCL;
2338c2ecf20Sopenharmony_ci		ret = i2c_recover_bus(&priv->adap);
2348c2ecf20Sopenharmony_ci	}
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	return ret;
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_cistatic int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
2408c2ecf20Sopenharmony_ci{
2418c2ecf20Sopenharmony_ci	u32 scgd, cdf, round, ick, sum, scl, cdf_width;
2428c2ecf20Sopenharmony_ci	unsigned long rate;
2438c2ecf20Sopenharmony_ci	struct device *dev = rcar_i2c_priv_to_dev(priv);
2448c2ecf20Sopenharmony_ci	struct i2c_timings t = {
2458c2ecf20Sopenharmony_ci		.bus_freq_hz		= I2C_MAX_STANDARD_MODE_FREQ,
2468c2ecf20Sopenharmony_ci		.scl_fall_ns		= 35,
2478c2ecf20Sopenharmony_ci		.scl_rise_ns		= 200,
2488c2ecf20Sopenharmony_ci		.scl_int_delay_ns	= 50,
2498c2ecf20Sopenharmony_ci	};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	/* Fall back to previously used values if not supplied */
2528c2ecf20Sopenharmony_ci	i2c_parse_fw_timings(dev, &t, false);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	switch (priv->devtype) {
2558c2ecf20Sopenharmony_ci	case I2C_RCAR_GEN1:
2568c2ecf20Sopenharmony_ci		cdf_width = 2;
2578c2ecf20Sopenharmony_ci		break;
2588c2ecf20Sopenharmony_ci	case I2C_RCAR_GEN2:
2598c2ecf20Sopenharmony_ci	case I2C_RCAR_GEN3:
2608c2ecf20Sopenharmony_ci		cdf_width = 3;
2618c2ecf20Sopenharmony_ci		break;
2628c2ecf20Sopenharmony_ci	default:
2638c2ecf20Sopenharmony_ci		dev_err(dev, "device type error\n");
2648c2ecf20Sopenharmony_ci		return -EIO;
2658c2ecf20Sopenharmony_ci	}
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	/*
2688c2ecf20Sopenharmony_ci	 * calculate SCL clock
2698c2ecf20Sopenharmony_ci	 * see
2708c2ecf20Sopenharmony_ci	 *	ICCCR
2718c2ecf20Sopenharmony_ci	 *
2728c2ecf20Sopenharmony_ci	 * ick	= clkp / (1 + CDF)
2738c2ecf20Sopenharmony_ci	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
2748c2ecf20Sopenharmony_ci	 *
2758c2ecf20Sopenharmony_ci	 * ick  : I2C internal clock < 20 MHz
2768c2ecf20Sopenharmony_ci	 * ticf : I2C SCL falling time
2778c2ecf20Sopenharmony_ci	 * tr   : I2C SCL rising  time
2788c2ecf20Sopenharmony_ci	 * intd : LSI internal delay
2798c2ecf20Sopenharmony_ci	 * clkp : peripheral_clk
2808c2ecf20Sopenharmony_ci	 * F[]  : integer up-valuation
2818c2ecf20Sopenharmony_ci	 */
2828c2ecf20Sopenharmony_ci	rate = clk_get_rate(priv->clk);
2838c2ecf20Sopenharmony_ci	cdf = rate / 20000000;
2848c2ecf20Sopenharmony_ci	if (cdf >= 1U << cdf_width) {
2858c2ecf20Sopenharmony_ci		dev_err(dev, "Input clock %lu too high\n", rate);
2868c2ecf20Sopenharmony_ci		return -EIO;
2878c2ecf20Sopenharmony_ci	}
2888c2ecf20Sopenharmony_ci	ick = rate / (cdf + 1);
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	/*
2918c2ecf20Sopenharmony_ci	 * it is impossible to calculate large scale
2928c2ecf20Sopenharmony_ci	 * number on u32. separate it
2938c2ecf20Sopenharmony_ci	 *
2948c2ecf20Sopenharmony_ci	 * F[(ticf + tr + intd) * ick] with sum = (ticf + tr + intd)
2958c2ecf20Sopenharmony_ci	 *  = F[sum * ick / 1000000000]
2968c2ecf20Sopenharmony_ci	 *  = F[(ick / 1000000) * sum / 1000]
2978c2ecf20Sopenharmony_ci	 */
2988c2ecf20Sopenharmony_ci	sum = t.scl_fall_ns + t.scl_rise_ns + t.scl_int_delay_ns;
2998c2ecf20Sopenharmony_ci	round = (ick + 500000) / 1000000 * sum;
3008c2ecf20Sopenharmony_ci	round = (round + 500) / 1000;
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci	/*
3038c2ecf20Sopenharmony_ci	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
3048c2ecf20Sopenharmony_ci	 *
3058c2ecf20Sopenharmony_ci	 * Calculation result (= SCL) should be less than
3068c2ecf20Sopenharmony_ci	 * bus_speed for hardware safety
3078c2ecf20Sopenharmony_ci	 *
3088c2ecf20Sopenharmony_ci	 * We could use something along the lines of
3098c2ecf20Sopenharmony_ci	 *	div = ick / (bus_speed + 1) + 1;
3108c2ecf20Sopenharmony_ci	 *	scgd = (div - 20 - round + 7) / 8;
3118c2ecf20Sopenharmony_ci	 *	scl = ick / (20 + (scgd * 8) + round);
3128c2ecf20Sopenharmony_ci	 * (not fully verified) but that would get pretty involved
3138c2ecf20Sopenharmony_ci	 */
3148c2ecf20Sopenharmony_ci	for (scgd = 0; scgd < 0x40; scgd++) {
3158c2ecf20Sopenharmony_ci		scl = ick / (20 + (scgd * 8) + round);
3168c2ecf20Sopenharmony_ci		if (scl <= t.bus_freq_hz)
3178c2ecf20Sopenharmony_ci			goto scgd_find;
3188c2ecf20Sopenharmony_ci	}
3198c2ecf20Sopenharmony_ci	dev_err(dev, "it is impossible to calculate best SCL\n");
3208c2ecf20Sopenharmony_ci	return -EIO;
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ciscgd_find:
3238c2ecf20Sopenharmony_ci	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
3248c2ecf20Sopenharmony_ci		scl, t.bus_freq_hz, rate, round, cdf, scgd);
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	/* keep icccr value */
3278c2ecf20Sopenharmony_ci	priv->icccr = scgd << cdf_width | cdf;
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ci	return 0;
3308c2ecf20Sopenharmony_ci}
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_cistatic void rcar_i2c_prepare_msg(struct rcar_i2c_priv *priv)
3338c2ecf20Sopenharmony_ci{
3348c2ecf20Sopenharmony_ci	int read = !!rcar_i2c_is_recv(priv);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	priv->pos = 0;
3378c2ecf20Sopenharmony_ci	if (priv->msgs_left == 1)
3388c2ecf20Sopenharmony_ci		priv->flags |= ID_LAST_MSG;
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMAR, i2c_8bit_addr_from_msg(priv->msg));
3418c2ecf20Sopenharmony_ci	/*
3428c2ecf20Sopenharmony_ci	 * We don't have a test case but the HW engineers say that the write order
3438c2ecf20Sopenharmony_ci	 * of ICMSR and ICMCR depends on whether we issue START or REP_START. Since
3448c2ecf20Sopenharmony_ci	 * it didn't cause a drawback for me, let's rather be safe than sorry.
3458c2ecf20Sopenharmony_ci	 */
3468c2ecf20Sopenharmony_ci	if (priv->flags & ID_FIRST_MSG) {
3478c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMSR, 0);
3488c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
3498c2ecf20Sopenharmony_ci	} else {
3508c2ecf20Sopenharmony_ci		if (priv->flags & ID_P_REP_AFTER_RD)
3518c2ecf20Sopenharmony_ci			priv->flags &= ~ID_P_REP_AFTER_RD;
3528c2ecf20Sopenharmony_ci		else
3538c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
3548c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMSR, 0);
3558c2ecf20Sopenharmony_ci	}
3568c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMIER, read ? RCAR_IRQ_RECV : RCAR_IRQ_SEND);
3578c2ecf20Sopenharmony_ci}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_cistatic void rcar_i2c_next_msg(struct rcar_i2c_priv *priv)
3608c2ecf20Sopenharmony_ci{
3618c2ecf20Sopenharmony_ci	priv->msg++;
3628c2ecf20Sopenharmony_ci	priv->msgs_left--;
3638c2ecf20Sopenharmony_ci	priv->flags &= ID_P_MASK;
3648c2ecf20Sopenharmony_ci	rcar_i2c_prepare_msg(priv);
3658c2ecf20Sopenharmony_ci}
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_cistatic void rcar_i2c_dma_unmap(struct rcar_i2c_priv *priv)
3688c2ecf20Sopenharmony_ci{
3698c2ecf20Sopenharmony_ci	struct dma_chan *chan = priv->dma_direction == DMA_FROM_DEVICE
3708c2ecf20Sopenharmony_ci		? priv->dma_rx : priv->dma_tx;
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_ci	dma_unmap_single(chan->device->dev, sg_dma_address(&priv->sg),
3738c2ecf20Sopenharmony_ci			 sg_dma_len(&priv->sg), priv->dma_direction);
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci	/* Gen3 can only do one RXDMA per transfer and we just completed it */
3768c2ecf20Sopenharmony_ci	if (priv->devtype == I2C_RCAR_GEN3 &&
3778c2ecf20Sopenharmony_ci	    priv->dma_direction == DMA_FROM_DEVICE)
3788c2ecf20Sopenharmony_ci		priv->flags |= ID_P_NO_RXDMA;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	priv->dma_direction = DMA_NONE;
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	/* Disable DMA Master Received/Transmitted, must be last! */
3838c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICDMAER, 0);
3848c2ecf20Sopenharmony_ci}
3858c2ecf20Sopenharmony_ci
3868c2ecf20Sopenharmony_cistatic void rcar_i2c_cleanup_dma(struct rcar_i2c_priv *priv)
3878c2ecf20Sopenharmony_ci{
3888c2ecf20Sopenharmony_ci	if (priv->dma_direction == DMA_NONE)
3898c2ecf20Sopenharmony_ci		return;
3908c2ecf20Sopenharmony_ci	else if (priv->dma_direction == DMA_FROM_DEVICE)
3918c2ecf20Sopenharmony_ci		dmaengine_terminate_all(priv->dma_rx);
3928c2ecf20Sopenharmony_ci	else if (priv->dma_direction == DMA_TO_DEVICE)
3938c2ecf20Sopenharmony_ci		dmaengine_terminate_all(priv->dma_tx);
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci	rcar_i2c_dma_unmap(priv);
3968c2ecf20Sopenharmony_ci}
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic void rcar_i2c_dma_callback(void *data)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = data;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	priv->pos += sg_dma_len(&priv->sg);
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	rcar_i2c_dma_unmap(priv);
4058c2ecf20Sopenharmony_ci}
4068c2ecf20Sopenharmony_ci
4078c2ecf20Sopenharmony_cistatic bool rcar_i2c_dma(struct rcar_i2c_priv *priv)
4088c2ecf20Sopenharmony_ci{
4098c2ecf20Sopenharmony_ci	struct device *dev = rcar_i2c_priv_to_dev(priv);
4108c2ecf20Sopenharmony_ci	struct i2c_msg *msg = priv->msg;
4118c2ecf20Sopenharmony_ci	bool read = msg->flags & I2C_M_RD;
4128c2ecf20Sopenharmony_ci	enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
4138c2ecf20Sopenharmony_ci	struct dma_chan *chan = read ? priv->dma_rx : priv->dma_tx;
4148c2ecf20Sopenharmony_ci	struct dma_async_tx_descriptor *txdesc;
4158c2ecf20Sopenharmony_ci	dma_addr_t dma_addr;
4168c2ecf20Sopenharmony_ci	dma_cookie_t cookie;
4178c2ecf20Sopenharmony_ci	unsigned char *buf;
4188c2ecf20Sopenharmony_ci	int len;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	/* Do various checks to see if DMA is feasible at all */
4218c2ecf20Sopenharmony_ci	if (IS_ERR(chan) || msg->len < RCAR_MIN_DMA_LEN ||
4228c2ecf20Sopenharmony_ci	    !(msg->flags & I2C_M_DMA_SAFE) || (read && priv->flags & ID_P_NO_RXDMA))
4238c2ecf20Sopenharmony_ci		return false;
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_ci	if (read) {
4268c2ecf20Sopenharmony_ci		/*
4278c2ecf20Sopenharmony_ci		 * The last two bytes needs to be fetched using PIO in
4288c2ecf20Sopenharmony_ci		 * order for the STOP phase to work.
4298c2ecf20Sopenharmony_ci		 */
4308c2ecf20Sopenharmony_ci		buf = priv->msg->buf;
4318c2ecf20Sopenharmony_ci		len = priv->msg->len - 2;
4328c2ecf20Sopenharmony_ci	} else {
4338c2ecf20Sopenharmony_ci		/*
4348c2ecf20Sopenharmony_ci		 * First byte in message was sent using PIO.
4358c2ecf20Sopenharmony_ci		 */
4368c2ecf20Sopenharmony_ci		buf = priv->msg->buf + 1;
4378c2ecf20Sopenharmony_ci		len = priv->msg->len - 1;
4388c2ecf20Sopenharmony_ci	}
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	dma_addr = dma_map_single(chan->device->dev, buf, len, dir);
4418c2ecf20Sopenharmony_ci	if (dma_mapping_error(chan->device->dev, dma_addr)) {
4428c2ecf20Sopenharmony_ci		dev_dbg(dev, "dma map failed, using PIO\n");
4438c2ecf20Sopenharmony_ci		return false;
4448c2ecf20Sopenharmony_ci	}
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci	sg_dma_len(&priv->sg) = len;
4478c2ecf20Sopenharmony_ci	sg_dma_address(&priv->sg) = dma_addr;
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	priv->dma_direction = dir;
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci	txdesc = dmaengine_prep_slave_sg(chan, &priv->sg, 1,
4528c2ecf20Sopenharmony_ci					 read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV,
4538c2ecf20Sopenharmony_ci					 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
4548c2ecf20Sopenharmony_ci	if (!txdesc) {
4558c2ecf20Sopenharmony_ci		dev_dbg(dev, "dma prep slave sg failed, using PIO\n");
4568c2ecf20Sopenharmony_ci		rcar_i2c_cleanup_dma(priv);
4578c2ecf20Sopenharmony_ci		return false;
4588c2ecf20Sopenharmony_ci	}
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci	txdesc->callback = rcar_i2c_dma_callback;
4618c2ecf20Sopenharmony_ci	txdesc->callback_param = priv;
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	cookie = dmaengine_submit(txdesc);
4648c2ecf20Sopenharmony_ci	if (dma_submit_error(cookie)) {
4658c2ecf20Sopenharmony_ci		dev_dbg(dev, "submitting dma failed, using PIO\n");
4668c2ecf20Sopenharmony_ci		rcar_i2c_cleanup_dma(priv);
4678c2ecf20Sopenharmony_ci		return false;
4688c2ecf20Sopenharmony_ci	}
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	/* Enable DMA Master Received/Transmitted */
4718c2ecf20Sopenharmony_ci	if (read)
4728c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICDMAER, RMDMAE);
4738c2ecf20Sopenharmony_ci	else
4748c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICDMAER, TMDMAE);
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_ci	dma_async_issue_pending(chan);
4778c2ecf20Sopenharmony_ci	return true;
4788c2ecf20Sopenharmony_ci}
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_cistatic void rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
4818c2ecf20Sopenharmony_ci{
4828c2ecf20Sopenharmony_ci	struct i2c_msg *msg = priv->msg;
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	/* FIXME: sometimes, unknown interrupt happened. Do nothing */
4858c2ecf20Sopenharmony_ci	if (!(msr & MDE))
4868c2ecf20Sopenharmony_ci		return;
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	/* Check if DMA can be enabled and take over */
4898c2ecf20Sopenharmony_ci	if (priv->pos == 1 && rcar_i2c_dma(priv))
4908c2ecf20Sopenharmony_ci		return;
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	if (priv->pos < msg->len) {
4938c2ecf20Sopenharmony_ci		/*
4948c2ecf20Sopenharmony_ci		 * Prepare next data to ICRXTX register.
4958c2ecf20Sopenharmony_ci		 * This data will go to _SHIFT_ register.
4968c2ecf20Sopenharmony_ci		 *
4978c2ecf20Sopenharmony_ci		 *    *
4988c2ecf20Sopenharmony_ci		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
4998c2ecf20Sopenharmony_ci		 */
5008c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]);
5018c2ecf20Sopenharmony_ci		priv->pos++;
5028c2ecf20Sopenharmony_ci	} else {
5038c2ecf20Sopenharmony_ci		/*
5048c2ecf20Sopenharmony_ci		 * The last data was pushed to ICRXTX on _PREV_ empty irq.
5058c2ecf20Sopenharmony_ci		 * It is on _SHIFT_ register, and will sent to I2C bus.
5068c2ecf20Sopenharmony_ci		 *
5078c2ecf20Sopenharmony_ci		 *		  *
5088c2ecf20Sopenharmony_ci		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
5098c2ecf20Sopenharmony_ci		 */
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci		if (priv->flags & ID_LAST_MSG) {
5128c2ecf20Sopenharmony_ci			/*
5138c2ecf20Sopenharmony_ci			 * If current msg is the _LAST_ msg,
5148c2ecf20Sopenharmony_ci			 * prepare stop condition here.
5158c2ecf20Sopenharmony_ci			 * ID_DONE will be set on STOP irq.
5168c2ecf20Sopenharmony_ci			 */
5178c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
5188c2ecf20Sopenharmony_ci		} else {
5198c2ecf20Sopenharmony_ci			rcar_i2c_next_msg(priv);
5208c2ecf20Sopenharmony_ci			return;
5218c2ecf20Sopenharmony_ci		}
5228c2ecf20Sopenharmony_ci	}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_SEND);
5258c2ecf20Sopenharmony_ci}
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_cistatic void rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
5288c2ecf20Sopenharmony_ci{
5298c2ecf20Sopenharmony_ci	struct i2c_msg *msg = priv->msg;
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci	/* FIXME: sometimes, unknown interrupt happened. Do nothing */
5328c2ecf20Sopenharmony_ci	if (!(msr & MDR))
5338c2ecf20Sopenharmony_ci		return;
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	if (msr & MAT) {
5368c2ecf20Sopenharmony_ci		/*
5378c2ecf20Sopenharmony_ci		 * Address transfer phase finished, but no data at this point.
5388c2ecf20Sopenharmony_ci		 * Try to use DMA to receive data.
5398c2ecf20Sopenharmony_ci		 */
5408c2ecf20Sopenharmony_ci		rcar_i2c_dma(priv);
5418c2ecf20Sopenharmony_ci	} else if (priv->pos < msg->len) {
5428c2ecf20Sopenharmony_ci		/* get received data */
5438c2ecf20Sopenharmony_ci		msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX);
5448c2ecf20Sopenharmony_ci		priv->pos++;
5458c2ecf20Sopenharmony_ci	}
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_ci	/* If next received data is the _LAST_, go to new phase. */
5488c2ecf20Sopenharmony_ci	if (priv->pos + 1 == msg->len) {
5498c2ecf20Sopenharmony_ci		if (priv->flags & ID_LAST_MSG) {
5508c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_STOP);
5518c2ecf20Sopenharmony_ci		} else {
5528c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_START);
5538c2ecf20Sopenharmony_ci			priv->flags |= ID_P_REP_AFTER_RD;
5548c2ecf20Sopenharmony_ci		}
5558c2ecf20Sopenharmony_ci	}
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	if (priv->pos == msg->len && !(priv->flags & ID_LAST_MSG))
5588c2ecf20Sopenharmony_ci		rcar_i2c_next_msg(priv);
5598c2ecf20Sopenharmony_ci	else
5608c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMSR, RCAR_IRQ_ACK_RECV);
5618c2ecf20Sopenharmony_ci}
5628c2ecf20Sopenharmony_ci
5638c2ecf20Sopenharmony_cistatic bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
5648c2ecf20Sopenharmony_ci{
5658c2ecf20Sopenharmony_ci	u32 ssr_raw, ssr_filtered;
5668c2ecf20Sopenharmony_ci	u8 value;
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff;
5698c2ecf20Sopenharmony_ci	ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER);
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	if (!ssr_filtered)
5728c2ecf20Sopenharmony_ci		return false;
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	/* address detected */
5758c2ecf20Sopenharmony_ci	if (ssr_filtered & SAR) {
5768c2ecf20Sopenharmony_ci		/* read or write request */
5778c2ecf20Sopenharmony_ci		if (ssr_raw & STM) {
5788c2ecf20Sopenharmony_ci			i2c_slave_event(priv->slave, I2C_SLAVE_READ_REQUESTED, &value);
5798c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICRXTX, value);
5808c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
5818c2ecf20Sopenharmony_ci		} else {
5828c2ecf20Sopenharmony_ci			i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
5838c2ecf20Sopenharmony_ci			rcar_i2c_read(priv, ICRXTX);	/* dummy read */
5848c2ecf20Sopenharmony_ci			rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
5858c2ecf20Sopenharmony_ci		}
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci		/* Clear SSR, too, because of old STOPs to other clients than us */
5888c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSSR, ~(SAR | SSR) & 0xff);
5898c2ecf20Sopenharmony_ci	}
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci	/* master sent stop */
5928c2ecf20Sopenharmony_ci	if (ssr_filtered & SSR) {
5938c2ecf20Sopenharmony_ci		i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
5948c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
5958c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSIER, SAR);
5968c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
5978c2ecf20Sopenharmony_ci	}
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	/* master wants to write to us */
6008c2ecf20Sopenharmony_ci	if (ssr_filtered & SDR) {
6018c2ecf20Sopenharmony_ci		int ret;
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci		value = rcar_i2c_read(priv, ICRXTX);
6048c2ecf20Sopenharmony_ci		ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
6058c2ecf20Sopenharmony_ci		/* Send NACK in case of error */
6068c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0));
6078c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
6088c2ecf20Sopenharmony_ci	}
6098c2ecf20Sopenharmony_ci
6108c2ecf20Sopenharmony_ci	/* master wants to read from us */
6118c2ecf20Sopenharmony_ci	if (ssr_filtered & SDE) {
6128c2ecf20Sopenharmony_ci		i2c_slave_event(priv->slave, I2C_SLAVE_READ_PROCESSED, &value);
6138c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICRXTX, value);
6148c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICSSR, ~SDE & 0xff);
6158c2ecf20Sopenharmony_ci	}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci	return true;
6188c2ecf20Sopenharmony_ci}
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_ci/*
6218c2ecf20Sopenharmony_ci * This driver has a lock-free design because there are IP cores (at least
6228c2ecf20Sopenharmony_ci * R-Car Gen2) which have an inherent race condition in their hardware design.
6238c2ecf20Sopenharmony_ci * There, we need to switch to RCAR_BUS_PHASE_DATA as soon as possible after
6248c2ecf20Sopenharmony_ci * the interrupt was generated, otherwise an unwanted repeated message gets
6258c2ecf20Sopenharmony_ci * generated. It turned out that taking a spinlock at the beginning of the ISR
6268c2ecf20Sopenharmony_ci * was already causing repeated messages. Thus, this driver was converted to
6278c2ecf20Sopenharmony_ci * the now lockless behaviour. Please keep this in mind when hacking the driver.
6288c2ecf20Sopenharmony_ci * R-Car Gen3 seems to have this fixed but earlier versions than R-Car Gen2 are
6298c2ecf20Sopenharmony_ci * likely affected. Therefore, we have different interrupt handler entries.
6308c2ecf20Sopenharmony_ci */
6318c2ecf20Sopenharmony_cistatic irqreturn_t rcar_i2c_irq(int irq, struct rcar_i2c_priv *priv, u32 msr)
6328c2ecf20Sopenharmony_ci{
6338c2ecf20Sopenharmony_ci	if (!msr) {
6348c2ecf20Sopenharmony_ci		if (rcar_i2c_slave_irq(priv))
6358c2ecf20Sopenharmony_ci			return IRQ_HANDLED;
6368c2ecf20Sopenharmony_ci
6378c2ecf20Sopenharmony_ci		return IRQ_NONE;
6388c2ecf20Sopenharmony_ci	}
6398c2ecf20Sopenharmony_ci
6408c2ecf20Sopenharmony_ci	/* Arbitration lost */
6418c2ecf20Sopenharmony_ci	if (msr & MAL) {
6428c2ecf20Sopenharmony_ci		priv->flags |= ID_DONE | ID_ARBLOST;
6438c2ecf20Sopenharmony_ci		goto out;
6448c2ecf20Sopenharmony_ci	}
6458c2ecf20Sopenharmony_ci
6468c2ecf20Sopenharmony_ci	/* Nack */
6478c2ecf20Sopenharmony_ci	if (msr & MNR) {
6488c2ecf20Sopenharmony_ci		/* HW automatically sends STOP after received NACK */
6498c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMIER, RCAR_IRQ_STOP);
6508c2ecf20Sopenharmony_ci		priv->flags |= ID_NACK;
6518c2ecf20Sopenharmony_ci		goto out;
6528c2ecf20Sopenharmony_ci	}
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_ci	/* Stop */
6558c2ecf20Sopenharmony_ci	if (msr & MST) {
6568c2ecf20Sopenharmony_ci		priv->msgs_left--; /* The last message also made it */
6578c2ecf20Sopenharmony_ci		priv->flags |= ID_DONE;
6588c2ecf20Sopenharmony_ci		goto out;
6598c2ecf20Sopenharmony_ci	}
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	if (rcar_i2c_is_recv(priv))
6628c2ecf20Sopenharmony_ci		rcar_i2c_irq_recv(priv, msr);
6638c2ecf20Sopenharmony_ci	else
6648c2ecf20Sopenharmony_ci		rcar_i2c_irq_send(priv, msr);
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ciout:
6678c2ecf20Sopenharmony_ci	if (priv->flags & ID_DONE) {
6688c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMIER, 0);
6698c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMSR, 0);
6708c2ecf20Sopenharmony_ci		wake_up(&priv->wait);
6718c2ecf20Sopenharmony_ci	}
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
6748c2ecf20Sopenharmony_ci}
6758c2ecf20Sopenharmony_ci
6768c2ecf20Sopenharmony_cistatic irqreturn_t rcar_i2c_gen2_irq(int irq, void *ptr)
6778c2ecf20Sopenharmony_ci{
6788c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = ptr;
6798c2ecf20Sopenharmony_ci	u32 msr;
6808c2ecf20Sopenharmony_ci
6818c2ecf20Sopenharmony_ci	/* Clear START or STOP immediately, except for REPSTART after read */
6828c2ecf20Sopenharmony_ci	if (likely(!(priv->flags & ID_P_REP_AFTER_RD)))
6838c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci	/* Only handle interrupts that are currently enabled */
6868c2ecf20Sopenharmony_ci	msr = rcar_i2c_read(priv, ICMSR);
6878c2ecf20Sopenharmony_ci	msr &= rcar_i2c_read(priv, ICMIER);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	return rcar_i2c_irq(irq, priv, msr);
6908c2ecf20Sopenharmony_ci}
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_cistatic irqreturn_t rcar_i2c_gen3_irq(int irq, void *ptr)
6938c2ecf20Sopenharmony_ci{
6948c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = ptr;
6958c2ecf20Sopenharmony_ci	u32 msr;
6968c2ecf20Sopenharmony_ci
6978c2ecf20Sopenharmony_ci	/* Only handle interrupts that are currently enabled */
6988c2ecf20Sopenharmony_ci	msr = rcar_i2c_read(priv, ICMSR);
6998c2ecf20Sopenharmony_ci	msr &= rcar_i2c_read(priv, ICMIER);
7008c2ecf20Sopenharmony_ci
7018c2ecf20Sopenharmony_ci	/*
7028c2ecf20Sopenharmony_ci	 * Clear START or STOP immediately, except for REPSTART after read or
7038c2ecf20Sopenharmony_ci	 * if a spurious interrupt was detected.
7048c2ecf20Sopenharmony_ci	 */
7058c2ecf20Sopenharmony_ci	if (likely(!(priv->flags & ID_P_REP_AFTER_RD) && msr))
7068c2ecf20Sopenharmony_ci		rcar_i2c_write(priv, ICMCR, RCAR_BUS_PHASE_DATA);
7078c2ecf20Sopenharmony_ci
7088c2ecf20Sopenharmony_ci	return rcar_i2c_irq(irq, priv, msr);
7098c2ecf20Sopenharmony_ci}
7108c2ecf20Sopenharmony_ci
7118c2ecf20Sopenharmony_cistatic struct dma_chan *rcar_i2c_request_dma_chan(struct device *dev,
7128c2ecf20Sopenharmony_ci					enum dma_transfer_direction dir,
7138c2ecf20Sopenharmony_ci					dma_addr_t port_addr)
7148c2ecf20Sopenharmony_ci{
7158c2ecf20Sopenharmony_ci	struct dma_chan *chan;
7168c2ecf20Sopenharmony_ci	struct dma_slave_config cfg;
7178c2ecf20Sopenharmony_ci	char *chan_name = dir == DMA_MEM_TO_DEV ? "tx" : "rx";
7188c2ecf20Sopenharmony_ci	int ret;
7198c2ecf20Sopenharmony_ci
7208c2ecf20Sopenharmony_ci	chan = dma_request_chan(dev, chan_name);
7218c2ecf20Sopenharmony_ci	if (IS_ERR(chan)) {
7228c2ecf20Sopenharmony_ci		dev_dbg(dev, "request_channel failed for %s (%ld)\n",
7238c2ecf20Sopenharmony_ci			chan_name, PTR_ERR(chan));
7248c2ecf20Sopenharmony_ci		return chan;
7258c2ecf20Sopenharmony_ci	}
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci	memset(&cfg, 0, sizeof(cfg));
7288c2ecf20Sopenharmony_ci	cfg.direction = dir;
7298c2ecf20Sopenharmony_ci	if (dir == DMA_MEM_TO_DEV) {
7308c2ecf20Sopenharmony_ci		cfg.dst_addr = port_addr;
7318c2ecf20Sopenharmony_ci		cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
7328c2ecf20Sopenharmony_ci	} else {
7338c2ecf20Sopenharmony_ci		cfg.src_addr = port_addr;
7348c2ecf20Sopenharmony_ci		cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
7358c2ecf20Sopenharmony_ci	}
7368c2ecf20Sopenharmony_ci
7378c2ecf20Sopenharmony_ci	ret = dmaengine_slave_config(chan, &cfg);
7388c2ecf20Sopenharmony_ci	if (ret) {
7398c2ecf20Sopenharmony_ci		dev_dbg(dev, "slave_config failed for %s (%d)\n",
7408c2ecf20Sopenharmony_ci			chan_name, ret);
7418c2ecf20Sopenharmony_ci		dma_release_channel(chan);
7428c2ecf20Sopenharmony_ci		return ERR_PTR(ret);
7438c2ecf20Sopenharmony_ci	}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	dev_dbg(dev, "got DMA channel for %s\n", chan_name);
7468c2ecf20Sopenharmony_ci	return chan;
7478c2ecf20Sopenharmony_ci}
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_cistatic void rcar_i2c_request_dma(struct rcar_i2c_priv *priv,
7508c2ecf20Sopenharmony_ci				 struct i2c_msg *msg)
7518c2ecf20Sopenharmony_ci{
7528c2ecf20Sopenharmony_ci	struct device *dev = rcar_i2c_priv_to_dev(priv);
7538c2ecf20Sopenharmony_ci	bool read;
7548c2ecf20Sopenharmony_ci	struct dma_chan *chan;
7558c2ecf20Sopenharmony_ci	enum dma_transfer_direction dir;
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_ci	read = msg->flags & I2C_M_RD;
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ci	chan = read ? priv->dma_rx : priv->dma_tx;
7608c2ecf20Sopenharmony_ci	if (PTR_ERR(chan) != -EPROBE_DEFER)
7618c2ecf20Sopenharmony_ci		return;
7628c2ecf20Sopenharmony_ci
7638c2ecf20Sopenharmony_ci	dir = read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
7648c2ecf20Sopenharmony_ci	chan = rcar_i2c_request_dma_chan(dev, dir, priv->res->start + ICRXTX);
7658c2ecf20Sopenharmony_ci
7668c2ecf20Sopenharmony_ci	if (read)
7678c2ecf20Sopenharmony_ci		priv->dma_rx = chan;
7688c2ecf20Sopenharmony_ci	else
7698c2ecf20Sopenharmony_ci		priv->dma_tx = chan;
7708c2ecf20Sopenharmony_ci}
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_cistatic void rcar_i2c_release_dma(struct rcar_i2c_priv *priv)
7738c2ecf20Sopenharmony_ci{
7748c2ecf20Sopenharmony_ci	if (!IS_ERR(priv->dma_tx)) {
7758c2ecf20Sopenharmony_ci		dma_release_channel(priv->dma_tx);
7768c2ecf20Sopenharmony_ci		priv->dma_tx = ERR_PTR(-EPROBE_DEFER);
7778c2ecf20Sopenharmony_ci	}
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	if (!IS_ERR(priv->dma_rx)) {
7808c2ecf20Sopenharmony_ci		dma_release_channel(priv->dma_rx);
7818c2ecf20Sopenharmony_ci		priv->dma_rx = ERR_PTR(-EPROBE_DEFER);
7828c2ecf20Sopenharmony_ci	}
7838c2ecf20Sopenharmony_ci}
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci/* I2C is a special case, we need to poll the status of a reset */
7868c2ecf20Sopenharmony_cistatic int rcar_i2c_do_reset(struct rcar_i2c_priv *priv)
7878c2ecf20Sopenharmony_ci{
7888c2ecf20Sopenharmony_ci	int ret;
7898c2ecf20Sopenharmony_ci
7908c2ecf20Sopenharmony_ci	ret = reset_control_reset(priv->rstc);
7918c2ecf20Sopenharmony_ci	if (ret)
7928c2ecf20Sopenharmony_ci		return ret;
7938c2ecf20Sopenharmony_ci
7948c2ecf20Sopenharmony_ci	return read_poll_timeout_atomic(reset_control_status, ret, ret == 0, 1,
7958c2ecf20Sopenharmony_ci					100, false, priv->rstc);
7968c2ecf20Sopenharmony_ci}
7978c2ecf20Sopenharmony_ci
7988c2ecf20Sopenharmony_cistatic int rcar_i2c_master_xfer(struct i2c_adapter *adap,
7998c2ecf20Sopenharmony_ci				struct i2c_msg *msgs,
8008c2ecf20Sopenharmony_ci				int num)
8018c2ecf20Sopenharmony_ci{
8028c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
8038c2ecf20Sopenharmony_ci	struct device *dev = rcar_i2c_priv_to_dev(priv);
8048c2ecf20Sopenharmony_ci	int i, ret;
8058c2ecf20Sopenharmony_ci	long time_left;
8068c2ecf20Sopenharmony_ci
8078c2ecf20Sopenharmony_ci	pm_runtime_get_sync(dev);
8088c2ecf20Sopenharmony_ci
8098c2ecf20Sopenharmony_ci	/* Check bus state before init otherwise bus busy info will be lost */
8108c2ecf20Sopenharmony_ci	ret = rcar_i2c_bus_barrier(priv);
8118c2ecf20Sopenharmony_ci	if (ret < 0)
8128c2ecf20Sopenharmony_ci		goto out;
8138c2ecf20Sopenharmony_ci
8148c2ecf20Sopenharmony_ci	/* Gen3 needs a reset before allowing RXDMA once */
8158c2ecf20Sopenharmony_ci	if (priv->devtype == I2C_RCAR_GEN3) {
8168c2ecf20Sopenharmony_ci		priv->flags |= ID_P_NO_RXDMA;
8178c2ecf20Sopenharmony_ci		if (!IS_ERR(priv->rstc)) {
8188c2ecf20Sopenharmony_ci			ret = rcar_i2c_do_reset(priv);
8198c2ecf20Sopenharmony_ci			if (ret == 0)
8208c2ecf20Sopenharmony_ci				priv->flags &= ~ID_P_NO_RXDMA;
8218c2ecf20Sopenharmony_ci		}
8228c2ecf20Sopenharmony_ci	}
8238c2ecf20Sopenharmony_ci
8248c2ecf20Sopenharmony_ci	rcar_i2c_init(priv);
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++)
8278c2ecf20Sopenharmony_ci		rcar_i2c_request_dma(priv, msgs + i);
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci	/* init first message */
8308c2ecf20Sopenharmony_ci	priv->msg = msgs;
8318c2ecf20Sopenharmony_ci	priv->msgs_left = num;
8328c2ecf20Sopenharmony_ci	priv->flags = (priv->flags & ID_P_MASK) | ID_FIRST_MSG;
8338c2ecf20Sopenharmony_ci	rcar_i2c_prepare_msg(priv);
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_ci	time_left = wait_event_timeout(priv->wait, priv->flags & ID_DONE,
8368c2ecf20Sopenharmony_ci				     num * adap->timeout);
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_ci	/* cleanup DMA if it couldn't complete properly due to an error */
8398c2ecf20Sopenharmony_ci	if (priv->dma_direction != DMA_NONE)
8408c2ecf20Sopenharmony_ci		rcar_i2c_cleanup_dma(priv);
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	if (!time_left) {
8438c2ecf20Sopenharmony_ci		rcar_i2c_init(priv);
8448c2ecf20Sopenharmony_ci		ret = -ETIMEDOUT;
8458c2ecf20Sopenharmony_ci	} else if (priv->flags & ID_NACK) {
8468c2ecf20Sopenharmony_ci		ret = -ENXIO;
8478c2ecf20Sopenharmony_ci	} else if (priv->flags & ID_ARBLOST) {
8488c2ecf20Sopenharmony_ci		ret = -EAGAIN;
8498c2ecf20Sopenharmony_ci	} else {
8508c2ecf20Sopenharmony_ci		ret = num - priv->msgs_left; /* The number of transfer */
8518c2ecf20Sopenharmony_ci	}
8528c2ecf20Sopenharmony_ciout:
8538c2ecf20Sopenharmony_ci	pm_runtime_put(dev);
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci	if (ret < 0 && ret != -ENXIO)
8568c2ecf20Sopenharmony_ci		dev_err(dev, "error %d : %x\n", ret, priv->flags);
8578c2ecf20Sopenharmony_ci
8588c2ecf20Sopenharmony_ci	return ret;
8598c2ecf20Sopenharmony_ci}
8608c2ecf20Sopenharmony_ci
8618c2ecf20Sopenharmony_cistatic int rcar_reg_slave(struct i2c_client *slave)
8628c2ecf20Sopenharmony_ci{
8638c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter);
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (priv->slave)
8668c2ecf20Sopenharmony_ci		return -EBUSY;
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci	if (slave->flags & I2C_CLIENT_TEN)
8698c2ecf20Sopenharmony_ci		return -EAFNOSUPPORT;
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_ci	/* Keep device active for slave address detection logic */
8728c2ecf20Sopenharmony_ci	pm_runtime_get_sync(rcar_i2c_priv_to_dev(priv));
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci	priv->slave = slave;
8758c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSAR, slave->addr);
8768c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSSR, 0);
8778c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSIER, SAR);
8788c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSCR, SIE | SDBS);
8798c2ecf20Sopenharmony_ci
8808c2ecf20Sopenharmony_ci	return 0;
8818c2ecf20Sopenharmony_ci}
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_cistatic int rcar_unreg_slave(struct i2c_client *slave)
8848c2ecf20Sopenharmony_ci{
8858c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(slave->adapter);
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci	WARN_ON(!priv->slave);
8888c2ecf20Sopenharmony_ci
8898c2ecf20Sopenharmony_ci	/* ensure no irq is running before clearing ptr */
8908c2ecf20Sopenharmony_ci	disable_irq(priv->irq);
8918c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSIER, 0);
8928c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSSR, 0);
8938c2ecf20Sopenharmony_ci	enable_irq(priv->irq);
8948c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSCR, SDBS);
8958c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
8968c2ecf20Sopenharmony_ci
8978c2ecf20Sopenharmony_ci	priv->slave = NULL;
8988c2ecf20Sopenharmony_ci
8998c2ecf20Sopenharmony_ci	pm_runtime_put(rcar_i2c_priv_to_dev(priv));
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	return 0;
9028c2ecf20Sopenharmony_ci}
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_cistatic u32 rcar_i2c_func(struct i2c_adapter *adap)
9058c2ecf20Sopenharmony_ci{
9068c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci	/*
9098c2ecf20Sopenharmony_ci	 * This HW can't do:
9108c2ecf20Sopenharmony_ci	 * I2C_SMBUS_QUICK (setting FSB during START didn't work)
9118c2ecf20Sopenharmony_ci	 * I2C_M_NOSTART (automatically sends address after START)
9128c2ecf20Sopenharmony_ci	 * I2C_M_IGNORE_NAK (automatically sends STOP after NAK)
9138c2ecf20Sopenharmony_ci	 */
9148c2ecf20Sopenharmony_ci	u32 func = I2C_FUNC_I2C | I2C_FUNC_SLAVE |
9158c2ecf20Sopenharmony_ci		   (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
9168c2ecf20Sopenharmony_ci
9178c2ecf20Sopenharmony_ci	if (priv->flags & ID_P_HOST_NOTIFY)
9188c2ecf20Sopenharmony_ci		func |= I2C_FUNC_SMBUS_HOST_NOTIFY;
9198c2ecf20Sopenharmony_ci
9208c2ecf20Sopenharmony_ci	return func;
9218c2ecf20Sopenharmony_ci}
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_cistatic const struct i2c_algorithm rcar_i2c_algo = {
9248c2ecf20Sopenharmony_ci	.master_xfer	= rcar_i2c_master_xfer,
9258c2ecf20Sopenharmony_ci	.functionality	= rcar_i2c_func,
9268c2ecf20Sopenharmony_ci	.reg_slave	= rcar_reg_slave,
9278c2ecf20Sopenharmony_ci	.unreg_slave	= rcar_unreg_slave,
9288c2ecf20Sopenharmony_ci};
9298c2ecf20Sopenharmony_ci
9308c2ecf20Sopenharmony_cistatic const struct i2c_adapter_quirks rcar_i2c_quirks = {
9318c2ecf20Sopenharmony_ci	.flags = I2C_AQ_NO_ZERO_LEN,
9328c2ecf20Sopenharmony_ci};
9338c2ecf20Sopenharmony_ci
9348c2ecf20Sopenharmony_cistatic const struct of_device_id rcar_i2c_dt_ids[] = {
9358c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 },
9368c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 },
9378c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 },
9388c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7791", .data = (void *)I2C_RCAR_GEN2 },
9398c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7792", .data = (void *)I2C_RCAR_GEN2 },
9408c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7793", .data = (void *)I2C_RCAR_GEN2 },
9418c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7794", .data = (void *)I2C_RCAR_GEN2 },
9428c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7795", .data = (void *)I2C_RCAR_GEN3 },
9438c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-r8a7796", .data = (void *)I2C_RCAR_GEN3 },
9448c2ecf20Sopenharmony_ci	{ .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 },	/* Deprecated */
9458c2ecf20Sopenharmony_ci	{ .compatible = "renesas,rcar-gen1-i2c", .data = (void *)I2C_RCAR_GEN1 },
9468c2ecf20Sopenharmony_ci	{ .compatible = "renesas,rcar-gen2-i2c", .data = (void *)I2C_RCAR_GEN2 },
9478c2ecf20Sopenharmony_ci	{ .compatible = "renesas,rcar-gen3-i2c", .data = (void *)I2C_RCAR_GEN3 },
9488c2ecf20Sopenharmony_ci	{},
9498c2ecf20Sopenharmony_ci};
9508c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids);
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_cistatic int rcar_i2c_probe(struct platform_device *pdev)
9538c2ecf20Sopenharmony_ci{
9548c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv;
9558c2ecf20Sopenharmony_ci	struct i2c_adapter *adap;
9568c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
9578c2ecf20Sopenharmony_ci	unsigned long irqflags = 0;
9588c2ecf20Sopenharmony_ci	irqreturn_t (*irqhandler)(int irq, void *ptr) = rcar_i2c_gen3_irq;
9598c2ecf20Sopenharmony_ci	int ret;
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci	/* Otherwise logic will break because some bytes must always use PIO */
9628c2ecf20Sopenharmony_ci	BUILD_BUG_ON_MSG(RCAR_MIN_DMA_LEN < 3, "Invalid min DMA length");
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
9658c2ecf20Sopenharmony_ci	if (!priv)
9668c2ecf20Sopenharmony_ci		return -ENOMEM;
9678c2ecf20Sopenharmony_ci
9688c2ecf20Sopenharmony_ci	priv->clk = devm_clk_get(dev, NULL);
9698c2ecf20Sopenharmony_ci	if (IS_ERR(priv->clk)) {
9708c2ecf20Sopenharmony_ci		dev_err(dev, "cannot get clock\n");
9718c2ecf20Sopenharmony_ci		return PTR_ERR(priv->clk);
9728c2ecf20Sopenharmony_ci	}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci	priv->io = devm_platform_get_and_ioremap_resource(pdev, 0, &priv->res);
9758c2ecf20Sopenharmony_ci	if (IS_ERR(priv->io))
9768c2ecf20Sopenharmony_ci		return PTR_ERR(priv->io);
9778c2ecf20Sopenharmony_ci
9788c2ecf20Sopenharmony_ci	priv->devtype = (enum rcar_i2c_type)of_device_get_match_data(dev);
9798c2ecf20Sopenharmony_ci	init_waitqueue_head(&priv->wait);
9808c2ecf20Sopenharmony_ci
9818c2ecf20Sopenharmony_ci	adap = &priv->adap;
9828c2ecf20Sopenharmony_ci	adap->nr = pdev->id;
9838c2ecf20Sopenharmony_ci	adap->algo = &rcar_i2c_algo;
9848c2ecf20Sopenharmony_ci	adap->class = I2C_CLASS_DEPRECATED;
9858c2ecf20Sopenharmony_ci	adap->retries = 3;
9868c2ecf20Sopenharmony_ci	adap->dev.parent = dev;
9878c2ecf20Sopenharmony_ci	adap->dev.of_node = dev->of_node;
9888c2ecf20Sopenharmony_ci	adap->bus_recovery_info = &rcar_i2c_bri;
9898c2ecf20Sopenharmony_ci	adap->quirks = &rcar_i2c_quirks;
9908c2ecf20Sopenharmony_ci	i2c_set_adapdata(adap, priv);
9918c2ecf20Sopenharmony_ci	strlcpy(adap->name, pdev->name, sizeof(adap->name));
9928c2ecf20Sopenharmony_ci
9938c2ecf20Sopenharmony_ci	/* Init DMA */
9948c2ecf20Sopenharmony_ci	sg_init_table(&priv->sg, 1);
9958c2ecf20Sopenharmony_ci	priv->dma_direction = DMA_NONE;
9968c2ecf20Sopenharmony_ci	priv->dma_rx = priv->dma_tx = ERR_PTR(-EPROBE_DEFER);
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci	/* Activate device for clock calculation */
9998c2ecf20Sopenharmony_ci	pm_runtime_enable(dev);
10008c2ecf20Sopenharmony_ci	pm_runtime_get_sync(dev);
10018c2ecf20Sopenharmony_ci	ret = rcar_i2c_clock_calculate(priv);
10028c2ecf20Sopenharmony_ci	if (ret < 0) {
10038c2ecf20Sopenharmony_ci		pm_runtime_put(dev);
10048c2ecf20Sopenharmony_ci		goto out_pm_disable;
10058c2ecf20Sopenharmony_ci	}
10068c2ecf20Sopenharmony_ci
10078c2ecf20Sopenharmony_ci	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_ci	if (priv->devtype < I2C_RCAR_GEN3) {
10108c2ecf20Sopenharmony_ci		irqflags |= IRQF_NO_THREAD;
10118c2ecf20Sopenharmony_ci		irqhandler = rcar_i2c_gen2_irq;
10128c2ecf20Sopenharmony_ci	}
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_ci	if (priv->devtype == I2C_RCAR_GEN3) {
10158c2ecf20Sopenharmony_ci		priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
10168c2ecf20Sopenharmony_ci		if (!IS_ERR(priv->rstc)) {
10178c2ecf20Sopenharmony_ci			ret = reset_control_status(priv->rstc);
10188c2ecf20Sopenharmony_ci			if (ret < 0)
10198c2ecf20Sopenharmony_ci				priv->rstc = ERR_PTR(-ENOTSUPP);
10208c2ecf20Sopenharmony_ci		}
10218c2ecf20Sopenharmony_ci	}
10228c2ecf20Sopenharmony_ci
10238c2ecf20Sopenharmony_ci	/* Stay always active when multi-master to keep arbitration working */
10248c2ecf20Sopenharmony_ci	if (of_property_read_bool(dev->of_node, "multi-master"))
10258c2ecf20Sopenharmony_ci		priv->flags |= ID_P_PM_BLOCKED;
10268c2ecf20Sopenharmony_ci	else
10278c2ecf20Sopenharmony_ci		pm_runtime_put(dev);
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	if (of_property_read_bool(dev->of_node, "smbus"))
10308c2ecf20Sopenharmony_ci		priv->flags |= ID_P_HOST_NOTIFY;
10318c2ecf20Sopenharmony_ci
10328c2ecf20Sopenharmony_ci	ret = platform_get_irq(pdev, 0);
10338c2ecf20Sopenharmony_ci	if (ret < 0)
10348c2ecf20Sopenharmony_ci		goto out_pm_put;
10358c2ecf20Sopenharmony_ci	priv->irq = ret;
10368c2ecf20Sopenharmony_ci	ret = devm_request_irq(dev, priv->irq, irqhandler, irqflags, dev_name(dev), priv);
10378c2ecf20Sopenharmony_ci	if (ret < 0) {
10388c2ecf20Sopenharmony_ci		dev_err(dev, "cannot get irq %d\n", priv->irq);
10398c2ecf20Sopenharmony_ci		goto out_pm_put;
10408c2ecf20Sopenharmony_ci	}
10418c2ecf20Sopenharmony_ci
10428c2ecf20Sopenharmony_ci	platform_set_drvdata(pdev, priv);
10438c2ecf20Sopenharmony_ci
10448c2ecf20Sopenharmony_ci	ret = i2c_add_numbered_adapter(adap);
10458c2ecf20Sopenharmony_ci	if (ret < 0)
10468c2ecf20Sopenharmony_ci		goto out_pm_put;
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_ci	if (priv->flags & ID_P_HOST_NOTIFY) {
10498c2ecf20Sopenharmony_ci		priv->host_notify_client = i2c_new_slave_host_notify_device(adap);
10508c2ecf20Sopenharmony_ci		if (IS_ERR(priv->host_notify_client)) {
10518c2ecf20Sopenharmony_ci			ret = PTR_ERR(priv->host_notify_client);
10528c2ecf20Sopenharmony_ci			goto out_del_device;
10538c2ecf20Sopenharmony_ci		}
10548c2ecf20Sopenharmony_ci	}
10558c2ecf20Sopenharmony_ci
10568c2ecf20Sopenharmony_ci	dev_info(dev, "probed\n");
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci	return 0;
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci out_del_device:
10618c2ecf20Sopenharmony_ci	i2c_del_adapter(&priv->adap);
10628c2ecf20Sopenharmony_ci out_pm_put:
10638c2ecf20Sopenharmony_ci	if (priv->flags & ID_P_PM_BLOCKED)
10648c2ecf20Sopenharmony_ci		pm_runtime_put(dev);
10658c2ecf20Sopenharmony_ci out_pm_disable:
10668c2ecf20Sopenharmony_ci	pm_runtime_disable(dev);
10678c2ecf20Sopenharmony_ci	return ret;
10688c2ecf20Sopenharmony_ci}
10698c2ecf20Sopenharmony_ci
10708c2ecf20Sopenharmony_cistatic int rcar_i2c_remove(struct platform_device *pdev)
10718c2ecf20Sopenharmony_ci{
10728c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
10738c2ecf20Sopenharmony_ci	struct device *dev = &pdev->dev;
10748c2ecf20Sopenharmony_ci
10758c2ecf20Sopenharmony_ci	if (priv->host_notify_client)
10768c2ecf20Sopenharmony_ci		i2c_free_slave_host_notify_device(priv->host_notify_client);
10778c2ecf20Sopenharmony_ci	i2c_del_adapter(&priv->adap);
10788c2ecf20Sopenharmony_ci	rcar_i2c_release_dma(priv);
10798c2ecf20Sopenharmony_ci	if (priv->flags & ID_P_PM_BLOCKED)
10808c2ecf20Sopenharmony_ci		pm_runtime_put(dev);
10818c2ecf20Sopenharmony_ci	pm_runtime_disable(dev);
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	return 0;
10848c2ecf20Sopenharmony_ci}
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci#ifdef CONFIG_PM_SLEEP
10878c2ecf20Sopenharmony_cistatic int rcar_i2c_suspend(struct device *dev)
10888c2ecf20Sopenharmony_ci{
10898c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = dev_get_drvdata(dev);
10908c2ecf20Sopenharmony_ci
10918c2ecf20Sopenharmony_ci	i2c_mark_adapter_suspended(&priv->adap);
10928c2ecf20Sopenharmony_ci	return 0;
10938c2ecf20Sopenharmony_ci}
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_cistatic int rcar_i2c_resume(struct device *dev)
10968c2ecf20Sopenharmony_ci{
10978c2ecf20Sopenharmony_ci	struct rcar_i2c_priv *priv = dev_get_drvdata(dev);
10988c2ecf20Sopenharmony_ci
10998c2ecf20Sopenharmony_ci	i2c_mark_adapter_resumed(&priv->adap);
11008c2ecf20Sopenharmony_ci	return 0;
11018c2ecf20Sopenharmony_ci}
11028c2ecf20Sopenharmony_ci
11038c2ecf20Sopenharmony_cistatic const struct dev_pm_ops rcar_i2c_pm_ops = {
11048c2ecf20Sopenharmony_ci	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rcar_i2c_suspend, rcar_i2c_resume)
11058c2ecf20Sopenharmony_ci};
11068c2ecf20Sopenharmony_ci
11078c2ecf20Sopenharmony_ci#define DEV_PM_OPS (&rcar_i2c_pm_ops)
11088c2ecf20Sopenharmony_ci#else
11098c2ecf20Sopenharmony_ci#define DEV_PM_OPS NULL
11108c2ecf20Sopenharmony_ci#endif /* CONFIG_PM_SLEEP */
11118c2ecf20Sopenharmony_ci
11128c2ecf20Sopenharmony_cistatic struct platform_driver rcar_i2c_driver = {
11138c2ecf20Sopenharmony_ci	.driver	= {
11148c2ecf20Sopenharmony_ci		.name	= "i2c-rcar",
11158c2ecf20Sopenharmony_ci		.of_match_table = rcar_i2c_dt_ids,
11168c2ecf20Sopenharmony_ci		.pm	= DEV_PM_OPS,
11178c2ecf20Sopenharmony_ci	},
11188c2ecf20Sopenharmony_ci	.probe		= rcar_i2c_probe,
11198c2ecf20Sopenharmony_ci	.remove		= rcar_i2c_remove,
11208c2ecf20Sopenharmony_ci};
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_cimodule_platform_driver(rcar_i2c_driver);
11238c2ecf20Sopenharmony_ci
11248c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
11258c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Renesas R-Car I2C bus driver");
11268c2ecf20Sopenharmony_ciMODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
1127