xref: /OK3568_Linux_fs/kernel/drivers/i2c/busses/i2c-brcmstb.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2014 Broadcom Corporation
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or
5*4882a593Smuzhiyun  * modify it under the terms of the GNU General Public License as
6*4882a593Smuzhiyun  * published by the Free Software Foundation version 2.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
9*4882a593Smuzhiyun  * kind, whether express or implied; without even the implied warranty
10*4882a593Smuzhiyun  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*4882a593Smuzhiyun  * GNU General Public License for more details.
12*4882a593Smuzhiyun  */
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/clk.h>
15*4882a593Smuzhiyun #include <linux/delay.h>
16*4882a593Smuzhiyun #include <linux/device.h>
17*4882a593Smuzhiyun #include <linux/i2c.h>
18*4882a593Smuzhiyun #include <linux/interrupt.h>
19*4882a593Smuzhiyun #include <linux/io.h>
20*4882a593Smuzhiyun #include <linux/kernel.h>
21*4882a593Smuzhiyun #include <linux/module.h>
22*4882a593Smuzhiyun #include <linux/platform_device.h>
23*4882a593Smuzhiyun #include <linux/sched.h>
24*4882a593Smuzhiyun #include <linux/slab.h>
25*4882a593Smuzhiyun #include <linux/version.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define N_DATA_REGS					8
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun  * PER_I2C/BSC count register mask depends on 1 byte/4 byte data register
31*4882a593Smuzhiyun  * size. Cable modem and DSL SoCs with Peripheral i2c cores use 1 byte per
32*4882a593Smuzhiyun  * data register whereas STB SoCs use 4 byte per data register transfer,
33*4882a593Smuzhiyun  * account for this difference in total count per transaction and mask to
34*4882a593Smuzhiyun  * use.
35*4882a593Smuzhiyun  */
36*4882a593Smuzhiyun #define BSC_CNT_REG1_MASK(nb)	(nb == 1 ? GENMASK(3, 0) : GENMASK(5, 0))
37*4882a593Smuzhiyun #define BSC_CNT_REG1_SHIFT	0
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun /* BSC CTL register field definitions */
40*4882a593Smuzhiyun #define BSC_CTL_REG_DTF_MASK				0x00000003
41*4882a593Smuzhiyun #define BSC_CTL_REG_SCL_SEL_MASK			0x00000030
42*4882a593Smuzhiyun #define BSC_CTL_REG_SCL_SEL_SHIFT			4
43*4882a593Smuzhiyun #define BSC_CTL_REG_INT_EN_MASK				0x00000040
44*4882a593Smuzhiyun #define BSC_CTL_REG_INT_EN_SHIFT			6
45*4882a593Smuzhiyun #define BSC_CTL_REG_DIV_CLK_MASK			0x00000080
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* BSC_IIC_ENABLE r/w enable and interrupt field definitions */
48*4882a593Smuzhiyun #define BSC_IIC_EN_RESTART_MASK				0x00000040
49*4882a593Smuzhiyun #define BSC_IIC_EN_NOSTART_MASK				0x00000020
50*4882a593Smuzhiyun #define BSC_IIC_EN_NOSTOP_MASK				0x00000010
51*4882a593Smuzhiyun #define BSC_IIC_EN_NOACK_MASK				0x00000004
52*4882a593Smuzhiyun #define BSC_IIC_EN_INTRP_MASK				0x00000002
53*4882a593Smuzhiyun #define BSC_IIC_EN_ENABLE_MASK				0x00000001
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun /* BSC_CTLHI control register field definitions */
56*4882a593Smuzhiyun #define BSC_CTLHI_REG_INPUT_SWITCHING_LEVEL_MASK	0x00000080
57*4882a593Smuzhiyun #define BSC_CTLHI_REG_DATAREG_SIZE_MASK			0x00000040
58*4882a593Smuzhiyun #define BSC_CTLHI_REG_IGNORE_ACK_MASK			0x00000002
59*4882a593Smuzhiyun #define BSC_CTLHI_REG_WAIT_DIS_MASK			0x00000001
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #define I2C_TIMEOUT					100 /* msecs */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /* Condition mask used for non combined transfer */
64*4882a593Smuzhiyun #define COND_RESTART		BSC_IIC_EN_RESTART_MASK
65*4882a593Smuzhiyun #define COND_NOSTART		BSC_IIC_EN_NOSTART_MASK
66*4882a593Smuzhiyun #define COND_NOSTOP		BSC_IIC_EN_NOSTOP_MASK
67*4882a593Smuzhiyun #define COND_START_STOP		(COND_RESTART | COND_NOSTART | COND_NOSTOP)
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun /* BSC data transfer direction */
70*4882a593Smuzhiyun #define DTF_WR_MASK		0x00000000
71*4882a593Smuzhiyun #define DTF_RD_MASK		0x00000001
72*4882a593Smuzhiyun /* BSC data transfer direction combined format */
73*4882a593Smuzhiyun #define DTF_RD_WR_MASK		0x00000002
74*4882a593Smuzhiyun #define DTF_WR_RD_MASK		0x00000003
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define INT_ENABLE		true
77*4882a593Smuzhiyun #define INT_DISABLE		false
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /* BSC block register map structure to cache fields to be written */
80*4882a593Smuzhiyun struct bsc_regs {
81*4882a593Smuzhiyun 	u32	chip_address;           /* slave address */
82*4882a593Smuzhiyun 	u32	data_in[N_DATA_REGS];   /* tx data buffer*/
83*4882a593Smuzhiyun 	u32	cnt_reg;		/* rx/tx data length */
84*4882a593Smuzhiyun 	u32	ctl_reg;		/* control register */
85*4882a593Smuzhiyun 	u32	iic_enable;		/* xfer enable and status */
86*4882a593Smuzhiyun 	u32	data_out[N_DATA_REGS];  /* rx data buffer */
87*4882a593Smuzhiyun 	u32	ctlhi_reg;		/* more control fields */
88*4882a593Smuzhiyun 	u32	scl_param;		/* reserved */
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun struct bsc_clk_param {
92*4882a593Smuzhiyun 	u32 hz;
93*4882a593Smuzhiyun 	u32 scl_mask;
94*4882a593Smuzhiyun 	u32 div_mask;
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun enum bsc_xfer_cmd {
98*4882a593Smuzhiyun 	CMD_WR,
99*4882a593Smuzhiyun 	CMD_RD,
100*4882a593Smuzhiyun 	CMD_WR_NOACK,
101*4882a593Smuzhiyun 	CMD_RD_NOACK,
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun static char const *cmd_string[] = {
105*4882a593Smuzhiyun 	[CMD_WR] = "WR",
106*4882a593Smuzhiyun 	[CMD_RD] = "RD",
107*4882a593Smuzhiyun 	[CMD_WR_NOACK] = "WR NOACK",
108*4882a593Smuzhiyun 	[CMD_RD_NOACK] = "RD NOACK",
109*4882a593Smuzhiyun };
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun enum bus_speeds {
112*4882a593Smuzhiyun 	SPD_375K,
113*4882a593Smuzhiyun 	SPD_390K,
114*4882a593Smuzhiyun 	SPD_187K,
115*4882a593Smuzhiyun 	SPD_200K,
116*4882a593Smuzhiyun 	SPD_93K,
117*4882a593Smuzhiyun 	SPD_97K,
118*4882a593Smuzhiyun 	SPD_46K,
119*4882a593Smuzhiyun 	SPD_50K
120*4882a593Smuzhiyun };
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun static const struct bsc_clk_param bsc_clk[] = {
123*4882a593Smuzhiyun 	[SPD_375K] = {
124*4882a593Smuzhiyun 		.hz = 375000,
125*4882a593Smuzhiyun 		.scl_mask = SPD_375K << BSC_CTL_REG_SCL_SEL_SHIFT,
126*4882a593Smuzhiyun 		.div_mask = 0
127*4882a593Smuzhiyun 	},
128*4882a593Smuzhiyun 	[SPD_390K] = {
129*4882a593Smuzhiyun 		.hz = 390000,
130*4882a593Smuzhiyun 		.scl_mask = SPD_390K << BSC_CTL_REG_SCL_SEL_SHIFT,
131*4882a593Smuzhiyun 		.div_mask = 0
132*4882a593Smuzhiyun 	},
133*4882a593Smuzhiyun 	[SPD_187K] = {
134*4882a593Smuzhiyun 		.hz = 187500,
135*4882a593Smuzhiyun 		.scl_mask = SPD_187K << BSC_CTL_REG_SCL_SEL_SHIFT,
136*4882a593Smuzhiyun 		.div_mask = 0
137*4882a593Smuzhiyun 	},
138*4882a593Smuzhiyun 	[SPD_200K] = {
139*4882a593Smuzhiyun 		.hz = 200000,
140*4882a593Smuzhiyun 		.scl_mask = SPD_200K << BSC_CTL_REG_SCL_SEL_SHIFT,
141*4882a593Smuzhiyun 		.div_mask = 0
142*4882a593Smuzhiyun 	},
143*4882a593Smuzhiyun 	[SPD_93K]  = {
144*4882a593Smuzhiyun 		.hz = 93750,
145*4882a593Smuzhiyun 		.scl_mask = SPD_375K << BSC_CTL_REG_SCL_SEL_SHIFT,
146*4882a593Smuzhiyun 		.div_mask = BSC_CTL_REG_DIV_CLK_MASK
147*4882a593Smuzhiyun 	},
148*4882a593Smuzhiyun 	[SPD_97K]  = {
149*4882a593Smuzhiyun 		.hz = 97500,
150*4882a593Smuzhiyun 		.scl_mask = SPD_390K << BSC_CTL_REG_SCL_SEL_SHIFT,
151*4882a593Smuzhiyun 		.div_mask = BSC_CTL_REG_DIV_CLK_MASK
152*4882a593Smuzhiyun 	},
153*4882a593Smuzhiyun 	[SPD_46K]  = {
154*4882a593Smuzhiyun 		.hz = 46875,
155*4882a593Smuzhiyun 		.scl_mask = SPD_187K << BSC_CTL_REG_SCL_SEL_SHIFT,
156*4882a593Smuzhiyun 		.div_mask = BSC_CTL_REG_DIV_CLK_MASK
157*4882a593Smuzhiyun 	},
158*4882a593Smuzhiyun 	[SPD_50K]  = {
159*4882a593Smuzhiyun 		.hz = 50000,
160*4882a593Smuzhiyun 		.scl_mask = SPD_200K << BSC_CTL_REG_SCL_SEL_SHIFT,
161*4882a593Smuzhiyun 		.div_mask = BSC_CTL_REG_DIV_CLK_MASK
162*4882a593Smuzhiyun 	}
163*4882a593Smuzhiyun };
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun struct brcmstb_i2c_dev {
166*4882a593Smuzhiyun 	struct device *device;
167*4882a593Smuzhiyun 	void __iomem *base;
168*4882a593Smuzhiyun 	int irq;
169*4882a593Smuzhiyun 	struct bsc_regs *bsc_regmap;
170*4882a593Smuzhiyun 	struct i2c_adapter adapter;
171*4882a593Smuzhiyun 	struct completion done;
172*4882a593Smuzhiyun 	u32 clk_freq_hz;
173*4882a593Smuzhiyun 	int data_regsz;
174*4882a593Smuzhiyun };
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /* register accessors for both be and le cpu arch */
177*4882a593Smuzhiyun #ifdef CONFIG_CPU_BIG_ENDIAN
178*4882a593Smuzhiyun #define __bsc_readl(_reg) ioread32be(_reg)
179*4882a593Smuzhiyun #define __bsc_writel(_val, _reg) iowrite32be(_val, _reg)
180*4882a593Smuzhiyun #else
181*4882a593Smuzhiyun #define __bsc_readl(_reg) ioread32(_reg)
182*4882a593Smuzhiyun #define __bsc_writel(_val, _reg) iowrite32(_val, _reg)
183*4882a593Smuzhiyun #endif
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun #define bsc_readl(_dev, _reg)						\
186*4882a593Smuzhiyun 	__bsc_readl(_dev->base + offsetof(struct bsc_regs, _reg))
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun #define bsc_writel(_dev, _val, _reg)					\
189*4882a593Smuzhiyun 	__bsc_writel(_val, _dev->base + offsetof(struct bsc_regs, _reg))
190*4882a593Smuzhiyun 
brcmstb_i2c_get_xfersz(struct brcmstb_i2c_dev * dev)191*4882a593Smuzhiyun static inline int brcmstb_i2c_get_xfersz(struct brcmstb_i2c_dev *dev)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun 	return (N_DATA_REGS * dev->data_regsz);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
brcmstb_i2c_get_data_regsz(struct brcmstb_i2c_dev * dev)196*4882a593Smuzhiyun static inline int brcmstb_i2c_get_data_regsz(struct brcmstb_i2c_dev *dev)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun 	return dev->data_regsz;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
brcmstb_i2c_enable_disable_irq(struct brcmstb_i2c_dev * dev,bool int_en)201*4882a593Smuzhiyun static void brcmstb_i2c_enable_disable_irq(struct brcmstb_i2c_dev *dev,
202*4882a593Smuzhiyun 					   bool int_en)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	if (int_en)
206*4882a593Smuzhiyun 		/* Enable BSC  CTL interrupt line */
207*4882a593Smuzhiyun 		dev->bsc_regmap->ctl_reg |= BSC_CTL_REG_INT_EN_MASK;
208*4882a593Smuzhiyun 	else
209*4882a593Smuzhiyun 		/* Disable BSC CTL interrupt line */
210*4882a593Smuzhiyun 		dev->bsc_regmap->ctl_reg &= ~BSC_CTL_REG_INT_EN_MASK;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	barrier();
213*4882a593Smuzhiyun 	bsc_writel(dev, dev->bsc_regmap->ctl_reg, ctl_reg);
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun 
brcmstb_i2c_isr(int irq,void * devid)216*4882a593Smuzhiyun static irqreturn_t brcmstb_i2c_isr(int irq, void *devid)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *dev = devid;
219*4882a593Smuzhiyun 	u32 status_bsc_ctl = bsc_readl(dev, ctl_reg);
220*4882a593Smuzhiyun 	u32 status_iic_intrp = bsc_readl(dev, iic_enable);
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	dev_dbg(dev->device, "isr CTL_REG %x IIC_EN %x\n",
223*4882a593Smuzhiyun 		status_bsc_ctl, status_iic_intrp);
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	if (!(status_bsc_ctl & BSC_CTL_REG_INT_EN_MASK))
226*4882a593Smuzhiyun 		return IRQ_NONE;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
229*4882a593Smuzhiyun 	complete(&dev->done);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	dev_dbg(dev->device, "isr handled");
232*4882a593Smuzhiyun 	return IRQ_HANDLED;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun /* Wait for device to be ready */
brcmstb_i2c_wait_if_busy(struct brcmstb_i2c_dev * dev)236*4882a593Smuzhiyun static int brcmstb_i2c_wait_if_busy(struct brcmstb_i2c_dev *dev)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun 	unsigned long timeout = jiffies + msecs_to_jiffies(I2C_TIMEOUT);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	while ((bsc_readl(dev, iic_enable) & BSC_IIC_EN_INTRP_MASK)) {
241*4882a593Smuzhiyun 		if (time_after(jiffies, timeout))
242*4882a593Smuzhiyun 			return -ETIMEDOUT;
243*4882a593Smuzhiyun 		cpu_relax();
244*4882a593Smuzhiyun 	}
245*4882a593Smuzhiyun 	return 0;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun /* i2c xfer completion function, handles both irq and polling mode */
brcmstb_i2c_wait_for_completion(struct brcmstb_i2c_dev * dev)249*4882a593Smuzhiyun static int brcmstb_i2c_wait_for_completion(struct brcmstb_i2c_dev *dev)
250*4882a593Smuzhiyun {
251*4882a593Smuzhiyun 	int ret = 0;
252*4882a593Smuzhiyun 	unsigned long timeout = msecs_to_jiffies(I2C_TIMEOUT);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (dev->irq >= 0) {
255*4882a593Smuzhiyun 		if (!wait_for_completion_timeout(&dev->done, timeout))
256*4882a593Smuzhiyun 			ret = -ETIMEDOUT;
257*4882a593Smuzhiyun 	} else {
258*4882a593Smuzhiyun 		/* we are in polling mode */
259*4882a593Smuzhiyun 		u32 bsc_intrp;
260*4882a593Smuzhiyun 		unsigned long time_left = jiffies + timeout;
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 		do {
263*4882a593Smuzhiyun 			bsc_intrp = bsc_readl(dev, iic_enable) &
264*4882a593Smuzhiyun 				BSC_IIC_EN_INTRP_MASK;
265*4882a593Smuzhiyun 			if (time_after(jiffies, time_left)) {
266*4882a593Smuzhiyun 				ret = -ETIMEDOUT;
267*4882a593Smuzhiyun 				break;
268*4882a593Smuzhiyun 			}
269*4882a593Smuzhiyun 			cpu_relax();
270*4882a593Smuzhiyun 		} while (!bsc_intrp);
271*4882a593Smuzhiyun 	}
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	if (dev->irq < 0 || ret == -ETIMEDOUT)
274*4882a593Smuzhiyun 		brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	return ret;
277*4882a593Smuzhiyun }
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun /* Set xfer START/STOP conditions for subsequent transfer */
brcmstb_set_i2c_start_stop(struct brcmstb_i2c_dev * dev,u32 cond_flag)280*4882a593Smuzhiyun static void brcmstb_set_i2c_start_stop(struct brcmstb_i2c_dev *dev,
281*4882a593Smuzhiyun 				       u32 cond_flag)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun 	u32 regval = dev->bsc_regmap->iic_enable;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	dev->bsc_regmap->iic_enable = (regval & ~COND_START_STOP) | cond_flag;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun /* Send I2C request check completion */
brcmstb_send_i2c_cmd(struct brcmstb_i2c_dev * dev,enum bsc_xfer_cmd cmd)289*4882a593Smuzhiyun static int brcmstb_send_i2c_cmd(struct brcmstb_i2c_dev *dev,
290*4882a593Smuzhiyun 				enum bsc_xfer_cmd cmd)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun 	int rc = 0;
293*4882a593Smuzhiyun 	struct bsc_regs *pi2creg = dev->bsc_regmap;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	/* Make sure the hardware is ready */
296*4882a593Smuzhiyun 	rc = brcmstb_i2c_wait_if_busy(dev);
297*4882a593Smuzhiyun 	if (rc < 0)
298*4882a593Smuzhiyun 		return rc;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	/* only if we are in interrupt mode */
301*4882a593Smuzhiyun 	if (dev->irq >= 0)
302*4882a593Smuzhiyun 		reinit_completion(&dev->done);
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* enable BSC CTL interrupt line */
305*4882a593Smuzhiyun 	brcmstb_i2c_enable_disable_irq(dev, INT_ENABLE);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	/* initiate transfer by setting iic_enable */
308*4882a593Smuzhiyun 	pi2creg->iic_enable |= BSC_IIC_EN_ENABLE_MASK;
309*4882a593Smuzhiyun 	bsc_writel(dev, pi2creg->iic_enable, iic_enable);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	/* Wait for transaction to finish or timeout */
312*4882a593Smuzhiyun 	rc = brcmstb_i2c_wait_for_completion(dev);
313*4882a593Smuzhiyun 	if (rc) {
314*4882a593Smuzhiyun 		dev_dbg(dev->device, "intr timeout for cmd %s\n",
315*4882a593Smuzhiyun 			cmd_string[cmd]);
316*4882a593Smuzhiyun 		goto cmd_out;
317*4882a593Smuzhiyun 	}
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 	if ((cmd == CMD_RD || cmd == CMD_WR) &&
320*4882a593Smuzhiyun 	    bsc_readl(dev, iic_enable) & BSC_IIC_EN_NOACK_MASK) {
321*4882a593Smuzhiyun 		rc = -EREMOTEIO;
322*4882a593Smuzhiyun 		dev_dbg(dev->device, "controller received NOACK intr for %s\n",
323*4882a593Smuzhiyun 			cmd_string[cmd]);
324*4882a593Smuzhiyun 	}
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun cmd_out:
327*4882a593Smuzhiyun 	bsc_writel(dev, 0, cnt_reg);
328*4882a593Smuzhiyun 	bsc_writel(dev, 0, iic_enable);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	return rc;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun /* Actual data transfer through the BSC master */
brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev * dev,u8 * buf,unsigned int len,struct i2c_msg * pmsg)334*4882a593Smuzhiyun static int brcmstb_i2c_xfer_bsc_data(struct brcmstb_i2c_dev *dev,
335*4882a593Smuzhiyun 				     u8 *buf, unsigned int len,
336*4882a593Smuzhiyun 				     struct i2c_msg *pmsg)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun 	int cnt, byte, i, rc;
339*4882a593Smuzhiyun 	enum bsc_xfer_cmd cmd;
340*4882a593Smuzhiyun 	u32 ctl_reg;
341*4882a593Smuzhiyun 	struct bsc_regs *pi2creg = dev->bsc_regmap;
342*4882a593Smuzhiyun 	int no_ack = pmsg->flags & I2C_M_IGNORE_NAK;
343*4882a593Smuzhiyun 	int data_regsz = brcmstb_i2c_get_data_regsz(dev);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	/* see if the transaction needs to check NACK conditions */
346*4882a593Smuzhiyun 	if (no_ack) {
347*4882a593Smuzhiyun 		cmd = (pmsg->flags & I2C_M_RD) ? CMD_RD_NOACK
348*4882a593Smuzhiyun 			: CMD_WR_NOACK;
349*4882a593Smuzhiyun 		pi2creg->ctlhi_reg |= BSC_CTLHI_REG_IGNORE_ACK_MASK;
350*4882a593Smuzhiyun 	} else {
351*4882a593Smuzhiyun 		cmd = (pmsg->flags & I2C_M_RD) ? CMD_RD : CMD_WR;
352*4882a593Smuzhiyun 		pi2creg->ctlhi_reg &= ~BSC_CTLHI_REG_IGNORE_ACK_MASK;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun 	bsc_writel(dev, pi2creg->ctlhi_reg, ctlhi_reg);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	/* set data transfer direction */
357*4882a593Smuzhiyun 	ctl_reg = pi2creg->ctl_reg & ~BSC_CTL_REG_DTF_MASK;
358*4882a593Smuzhiyun 	if (cmd == CMD_WR || cmd == CMD_WR_NOACK)
359*4882a593Smuzhiyun 		pi2creg->ctl_reg = ctl_reg | DTF_WR_MASK;
360*4882a593Smuzhiyun 	else
361*4882a593Smuzhiyun 		pi2creg->ctl_reg = ctl_reg | DTF_RD_MASK;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	/* set the read/write length */
364*4882a593Smuzhiyun 	bsc_writel(dev, BSC_CNT_REG1_MASK(data_regsz) &
365*4882a593Smuzhiyun 		   (len << BSC_CNT_REG1_SHIFT), cnt_reg);
366*4882a593Smuzhiyun 
367*4882a593Smuzhiyun 	/* Write data into data_in register */
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	if (cmd == CMD_WR || cmd == CMD_WR_NOACK) {
370*4882a593Smuzhiyun 		for (cnt = 0, i = 0; cnt < len; cnt += data_regsz, i++) {
371*4882a593Smuzhiyun 			u32 word = 0;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 			for (byte = 0; byte < data_regsz; byte++) {
374*4882a593Smuzhiyun 				word >>= BITS_PER_BYTE;
375*4882a593Smuzhiyun 				if ((cnt + byte) < len)
376*4882a593Smuzhiyun 					word |= buf[cnt + byte] <<
377*4882a593Smuzhiyun 					(BITS_PER_BYTE * (data_regsz - 1));
378*4882a593Smuzhiyun 			}
379*4882a593Smuzhiyun 			bsc_writel(dev, word, data_in[i]);
380*4882a593Smuzhiyun 		}
381*4882a593Smuzhiyun 	}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 	/* Initiate xfer, the function will return on completion */
384*4882a593Smuzhiyun 	rc = brcmstb_send_i2c_cmd(dev, cmd);
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	if (rc != 0) {
387*4882a593Smuzhiyun 		dev_dbg(dev->device, "%s failure", cmd_string[cmd]);
388*4882a593Smuzhiyun 		return rc;
389*4882a593Smuzhiyun 	}
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/* Read data from data_out register */
392*4882a593Smuzhiyun 	if (cmd == CMD_RD || cmd == CMD_RD_NOACK) {
393*4882a593Smuzhiyun 		for (cnt = 0, i = 0; cnt < len; cnt += data_regsz, i++) {
394*4882a593Smuzhiyun 			u32 data = bsc_readl(dev, data_out[i]);
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 			for (byte = 0; byte < data_regsz &&
397*4882a593Smuzhiyun 				     (byte + cnt) < len; byte++) {
398*4882a593Smuzhiyun 				buf[cnt + byte] = data & 0xff;
399*4882a593Smuzhiyun 				data >>= BITS_PER_BYTE;
400*4882a593Smuzhiyun 			}
401*4882a593Smuzhiyun 		}
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	return 0;
405*4882a593Smuzhiyun }
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun /* Write a single byte of data to the i2c bus */
brcmstb_i2c_write_data_byte(struct brcmstb_i2c_dev * dev,u8 * buf,unsigned int nak_expected)408*4882a593Smuzhiyun static int brcmstb_i2c_write_data_byte(struct brcmstb_i2c_dev *dev,
409*4882a593Smuzhiyun 				       u8 *buf, unsigned int nak_expected)
410*4882a593Smuzhiyun {
411*4882a593Smuzhiyun 	enum bsc_xfer_cmd cmd = nak_expected ? CMD_WR : CMD_WR_NOACK;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	bsc_writel(dev, 1, cnt_reg);
414*4882a593Smuzhiyun 	bsc_writel(dev, *buf, data_in);
415*4882a593Smuzhiyun 
416*4882a593Smuzhiyun 	return brcmstb_send_i2c_cmd(dev, cmd);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun /* Send i2c address */
brcmstb_i2c_do_addr(struct brcmstb_i2c_dev * dev,struct i2c_msg * msg)420*4882a593Smuzhiyun static int brcmstb_i2c_do_addr(struct brcmstb_i2c_dev *dev,
421*4882a593Smuzhiyun 			       struct i2c_msg *msg)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun 	unsigned char addr;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	if (msg->flags & I2C_M_TEN) {
426*4882a593Smuzhiyun 		/* First byte is 11110XX0 where XX is upper 2 bits */
427*4882a593Smuzhiyun 		addr = 0xF0 | ((msg->addr & 0x300) >> 7);
428*4882a593Smuzhiyun 		bsc_writel(dev, addr, chip_address);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 		/* Second byte is the remaining 8 bits */
431*4882a593Smuzhiyun 		addr = msg->addr & 0xFF;
432*4882a593Smuzhiyun 		if (brcmstb_i2c_write_data_byte(dev, &addr, 0) < 0)
433*4882a593Smuzhiyun 			return -EREMOTEIO;
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 		if (msg->flags & I2C_M_RD) {
436*4882a593Smuzhiyun 			/* For read, send restart without stop condition */
437*4882a593Smuzhiyun 			brcmstb_set_i2c_start_stop(dev, COND_RESTART
438*4882a593Smuzhiyun 						   | COND_NOSTOP);
439*4882a593Smuzhiyun 			/* Then re-send the first byte with the read bit set */
440*4882a593Smuzhiyun 			addr = 0xF0 | ((msg->addr & 0x300) >> 7) | 0x01;
441*4882a593Smuzhiyun 			if (brcmstb_i2c_write_data_byte(dev, &addr, 0) < 0)
442*4882a593Smuzhiyun 				return -EREMOTEIO;
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 		}
445*4882a593Smuzhiyun 	} else {
446*4882a593Smuzhiyun 		addr = i2c_8bit_addr_from_msg(msg);
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 		bsc_writel(dev, addr, chip_address);
449*4882a593Smuzhiyun 	}
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return 0;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun /* Master transfer function */
brcmstb_i2c_xfer(struct i2c_adapter * adapter,struct i2c_msg msgs[],int num)455*4882a593Smuzhiyun static int brcmstb_i2c_xfer(struct i2c_adapter *adapter,
456*4882a593Smuzhiyun 			    struct i2c_msg msgs[], int num)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *dev = i2c_get_adapdata(adapter);
459*4882a593Smuzhiyun 	struct i2c_msg *pmsg;
460*4882a593Smuzhiyun 	int rc = 0;
461*4882a593Smuzhiyun 	int i;
462*4882a593Smuzhiyun 	int bytes_to_xfer;
463*4882a593Smuzhiyun 	u8 *tmp_buf;
464*4882a593Smuzhiyun 	int len = 0;
465*4882a593Smuzhiyun 	int xfersz = brcmstb_i2c_get_xfersz(dev);
466*4882a593Smuzhiyun 	u32 cond, cond_per_msg;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/* Loop through all messages */
469*4882a593Smuzhiyun 	for (i = 0; i < num; i++) {
470*4882a593Smuzhiyun 		pmsg = &msgs[i];
471*4882a593Smuzhiyun 		len = pmsg->len;
472*4882a593Smuzhiyun 		tmp_buf = pmsg->buf;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 		dev_dbg(dev->device,
475*4882a593Smuzhiyun 			"msg# %d/%d flg %x buf %x len %d\n", i,
476*4882a593Smuzhiyun 			num - 1, pmsg->flags,
477*4882a593Smuzhiyun 			pmsg->buf ? pmsg->buf[0] : '0', pmsg->len);
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 		if (i < (num - 1) && (msgs[i + 1].flags & I2C_M_NOSTART))
480*4882a593Smuzhiyun 			cond = ~COND_START_STOP;
481*4882a593Smuzhiyun 		else
482*4882a593Smuzhiyun 			cond = COND_RESTART | COND_NOSTOP;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 		brcmstb_set_i2c_start_stop(dev, cond);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 		/* Send slave address */
487*4882a593Smuzhiyun 		if (!(pmsg->flags & I2C_M_NOSTART)) {
488*4882a593Smuzhiyun 			rc = brcmstb_i2c_do_addr(dev, pmsg);
489*4882a593Smuzhiyun 			if (rc < 0) {
490*4882a593Smuzhiyun 				dev_dbg(dev->device,
491*4882a593Smuzhiyun 					"NACK for addr %2.2x msg#%d rc = %d\n",
492*4882a593Smuzhiyun 					pmsg->addr, i, rc);
493*4882a593Smuzhiyun 				goto out;
494*4882a593Smuzhiyun 			}
495*4882a593Smuzhiyun 		}
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 		cond_per_msg = cond;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 		/* Perform data transfer */
500*4882a593Smuzhiyun 		while (len) {
501*4882a593Smuzhiyun 			bytes_to_xfer = min(len, xfersz);
502*4882a593Smuzhiyun 
503*4882a593Smuzhiyun 			if (len <= xfersz) {
504*4882a593Smuzhiyun 				if (i == (num - 1))
505*4882a593Smuzhiyun 					cond_per_msg = cond_per_msg &
506*4882a593Smuzhiyun 						~(COND_RESTART | COND_NOSTOP);
507*4882a593Smuzhiyun 				else
508*4882a593Smuzhiyun 					cond_per_msg = cond;
509*4882a593Smuzhiyun 			} else {
510*4882a593Smuzhiyun 				cond_per_msg = (cond_per_msg & ~COND_RESTART) |
511*4882a593Smuzhiyun 					COND_NOSTOP;
512*4882a593Smuzhiyun 			}
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 			brcmstb_set_i2c_start_stop(dev, cond_per_msg);
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 			rc = brcmstb_i2c_xfer_bsc_data(dev, tmp_buf,
517*4882a593Smuzhiyun 						       bytes_to_xfer, pmsg);
518*4882a593Smuzhiyun 			if (rc < 0)
519*4882a593Smuzhiyun 				goto out;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 			len -=  bytes_to_xfer;
522*4882a593Smuzhiyun 			tmp_buf += bytes_to_xfer;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 			cond_per_msg = COND_NOSTART | COND_NOSTOP;
525*4882a593Smuzhiyun 		}
526*4882a593Smuzhiyun 	}
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	rc = num;
529*4882a593Smuzhiyun out:
530*4882a593Smuzhiyun 	return rc;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun 
brcmstb_i2c_functionality(struct i2c_adapter * adap)534*4882a593Smuzhiyun static u32 brcmstb_i2c_functionality(struct i2c_adapter *adap)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR
537*4882a593Smuzhiyun 		| I2C_FUNC_NOSTART | I2C_FUNC_PROTOCOL_MANGLING;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun static const struct i2c_algorithm brcmstb_i2c_algo = {
541*4882a593Smuzhiyun 	.master_xfer = brcmstb_i2c_xfer,
542*4882a593Smuzhiyun 	.functionality = brcmstb_i2c_functionality,
543*4882a593Smuzhiyun };
544*4882a593Smuzhiyun 
brcmstb_i2c_set_bus_speed(struct brcmstb_i2c_dev * dev)545*4882a593Smuzhiyun static void brcmstb_i2c_set_bus_speed(struct brcmstb_i2c_dev *dev)
546*4882a593Smuzhiyun {
547*4882a593Smuzhiyun 	int i = 0, num_speeds = ARRAY_SIZE(bsc_clk);
548*4882a593Smuzhiyun 	u32 clk_freq_hz = dev->clk_freq_hz;
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun 	for (i = 0; i < num_speeds; i++) {
551*4882a593Smuzhiyun 		if (bsc_clk[i].hz == clk_freq_hz) {
552*4882a593Smuzhiyun 			dev->bsc_regmap->ctl_reg &= ~(BSC_CTL_REG_SCL_SEL_MASK
553*4882a593Smuzhiyun 						| BSC_CTL_REG_DIV_CLK_MASK);
554*4882a593Smuzhiyun 			dev->bsc_regmap->ctl_reg |= (bsc_clk[i].scl_mask |
555*4882a593Smuzhiyun 						     bsc_clk[i].div_mask);
556*4882a593Smuzhiyun 			bsc_writel(dev, dev->bsc_regmap->ctl_reg, ctl_reg);
557*4882a593Smuzhiyun 			break;
558*4882a593Smuzhiyun 		}
559*4882a593Smuzhiyun 	}
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	/* in case we did not get find a valid speed */
562*4882a593Smuzhiyun 	if (i == num_speeds) {
563*4882a593Smuzhiyun 		i = (bsc_readl(dev, ctl_reg) & BSC_CTL_REG_SCL_SEL_MASK) >>
564*4882a593Smuzhiyun 			BSC_CTL_REG_SCL_SEL_SHIFT;
565*4882a593Smuzhiyun 		dev_warn(dev->device, "leaving current clock-frequency @ %dHz\n",
566*4882a593Smuzhiyun 			bsc_clk[i].hz);
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun 
brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev * dev)570*4882a593Smuzhiyun static void brcmstb_i2c_set_bsc_reg_defaults(struct brcmstb_i2c_dev *dev)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun 	if (brcmstb_i2c_get_data_regsz(dev) == sizeof(u32))
573*4882a593Smuzhiyun 		/* set 4 byte data in/out xfers  */
574*4882a593Smuzhiyun 		dev->bsc_regmap->ctlhi_reg = BSC_CTLHI_REG_DATAREG_SIZE_MASK;
575*4882a593Smuzhiyun 	else
576*4882a593Smuzhiyun 		dev->bsc_regmap->ctlhi_reg &= ~BSC_CTLHI_REG_DATAREG_SIZE_MASK;
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	bsc_writel(dev, dev->bsc_regmap->ctlhi_reg, ctlhi_reg);
579*4882a593Smuzhiyun 	/* set bus speed */
580*4882a593Smuzhiyun 	brcmstb_i2c_set_bus_speed(dev);
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun #define AUTOI2C_CTRL0		0x26c
584*4882a593Smuzhiyun #define AUTOI2C_CTRL0_RELEASE_BSC	BIT(1)
585*4882a593Smuzhiyun 
bcm2711_release_bsc(struct brcmstb_i2c_dev * dev)586*4882a593Smuzhiyun static int bcm2711_release_bsc(struct brcmstb_i2c_dev *dev)
587*4882a593Smuzhiyun {
588*4882a593Smuzhiyun 	struct platform_device *pdev = to_platform_device(dev->device);
589*4882a593Smuzhiyun 	struct resource *iomem;
590*4882a593Smuzhiyun 	void __iomem *autoi2c;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 	/* Map hardware registers */
593*4882a593Smuzhiyun 	iomem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "auto-i2c");
594*4882a593Smuzhiyun 	autoi2c = devm_ioremap_resource(&pdev->dev, iomem);
595*4882a593Smuzhiyun 	if (IS_ERR(autoi2c))
596*4882a593Smuzhiyun 		return PTR_ERR(autoi2c);
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 	writel(AUTOI2C_CTRL0_RELEASE_BSC, autoi2c + AUTOI2C_CTRL0);
599*4882a593Smuzhiyun 	devm_iounmap(&pdev->dev, autoi2c);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	/* We need to reset the controller after the release */
602*4882a593Smuzhiyun 	dev->bsc_regmap->iic_enable = 0;
603*4882a593Smuzhiyun 	bsc_writel(dev, dev->bsc_regmap->iic_enable, iic_enable);
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	return 0;
606*4882a593Smuzhiyun }
607*4882a593Smuzhiyun 
brcmstb_i2c_probe(struct platform_device * pdev)608*4882a593Smuzhiyun static int brcmstb_i2c_probe(struct platform_device *pdev)
609*4882a593Smuzhiyun {
610*4882a593Smuzhiyun 	int rc = 0;
611*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *dev;
612*4882a593Smuzhiyun 	struct i2c_adapter *adap;
613*4882a593Smuzhiyun 	struct resource *iomem;
614*4882a593Smuzhiyun 	const char *int_name;
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun 	/* Allocate memory for private data structure */
617*4882a593Smuzhiyun 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
618*4882a593Smuzhiyun 	if (!dev)
619*4882a593Smuzhiyun 		return -ENOMEM;
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(*dev->bsc_regmap), GFP_KERNEL);
622*4882a593Smuzhiyun 	if (!dev->bsc_regmap)
623*4882a593Smuzhiyun 		return -ENOMEM;
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun 	platform_set_drvdata(pdev, dev);
626*4882a593Smuzhiyun 	dev->device = &pdev->dev;
627*4882a593Smuzhiyun 	init_completion(&dev->done);
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 	/* Map hardware registers */
630*4882a593Smuzhiyun 	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
631*4882a593Smuzhiyun 	dev->base = devm_ioremap_resource(dev->device, iomem);
632*4882a593Smuzhiyun 	if (IS_ERR(dev->base)) {
633*4882a593Smuzhiyun 		rc = -ENOMEM;
634*4882a593Smuzhiyun 		goto probe_errorout;
635*4882a593Smuzhiyun 	}
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun 	if (of_device_is_compatible(dev->device->of_node,
638*4882a593Smuzhiyun 				    "brcm,bcm2711-hdmi-i2c")) {
639*4882a593Smuzhiyun 		rc = bcm2711_release_bsc(dev);
640*4882a593Smuzhiyun 		if (rc)
641*4882a593Smuzhiyun 			goto probe_errorout;
642*4882a593Smuzhiyun 	}
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	rc = of_property_read_string(dev->device->of_node, "interrupt-names",
645*4882a593Smuzhiyun 				     &int_name);
646*4882a593Smuzhiyun 	if (rc < 0)
647*4882a593Smuzhiyun 		int_name = NULL;
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	/* Get the interrupt number */
650*4882a593Smuzhiyun 	dev->irq = platform_get_irq_optional(pdev, 0);
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	/* disable the bsc interrupt line */
653*4882a593Smuzhiyun 	brcmstb_i2c_enable_disable_irq(dev, INT_DISABLE);
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	/* register the ISR handler */
656*4882a593Smuzhiyun 	if (dev->irq >= 0) {
657*4882a593Smuzhiyun 		rc = devm_request_irq(&pdev->dev, dev->irq, brcmstb_i2c_isr,
658*4882a593Smuzhiyun 				      IRQF_SHARED,
659*4882a593Smuzhiyun 				      int_name ? int_name : pdev->name,
660*4882a593Smuzhiyun 				      dev);
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 		if (rc) {
663*4882a593Smuzhiyun 			dev_dbg(dev->device, "falling back to polling mode");
664*4882a593Smuzhiyun 			dev->irq = -1;
665*4882a593Smuzhiyun 		}
666*4882a593Smuzhiyun 	}
667*4882a593Smuzhiyun 
668*4882a593Smuzhiyun 	if (of_property_read_u32(dev->device->of_node,
669*4882a593Smuzhiyun 				 "clock-frequency", &dev->clk_freq_hz)) {
670*4882a593Smuzhiyun 		dev_warn(dev->device, "setting clock-frequency@%dHz\n",
671*4882a593Smuzhiyun 			 bsc_clk[0].hz);
672*4882a593Smuzhiyun 		dev->clk_freq_hz = bsc_clk[0].hz;
673*4882a593Smuzhiyun 	}
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 	/* set the data in/out register size for compatible SoCs */
676*4882a593Smuzhiyun 	if (of_device_is_compatible(dev->device->of_node,
677*4882a593Smuzhiyun 				    "brcm,brcmper-i2c"))
678*4882a593Smuzhiyun 		dev->data_regsz = sizeof(u8);
679*4882a593Smuzhiyun 	else
680*4882a593Smuzhiyun 		dev->data_regsz = sizeof(u32);
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	brcmstb_i2c_set_bsc_reg_defaults(dev);
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	/* Add the i2c adapter */
685*4882a593Smuzhiyun 	adap = &dev->adapter;
686*4882a593Smuzhiyun 	i2c_set_adapdata(adap, dev);
687*4882a593Smuzhiyun 	adap->owner = THIS_MODULE;
688*4882a593Smuzhiyun 	strlcpy(adap->name, "Broadcom STB : ", sizeof(adap->name));
689*4882a593Smuzhiyun 	if (int_name)
690*4882a593Smuzhiyun 		strlcat(adap->name, int_name, sizeof(adap->name));
691*4882a593Smuzhiyun 	adap->algo = &brcmstb_i2c_algo;
692*4882a593Smuzhiyun 	adap->dev.parent = &pdev->dev;
693*4882a593Smuzhiyun 	adap->dev.of_node = pdev->dev.of_node;
694*4882a593Smuzhiyun 	rc = i2c_add_adapter(adap);
695*4882a593Smuzhiyun 	if (rc)
696*4882a593Smuzhiyun 		goto probe_errorout;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	dev_info(dev->device, "%s@%dhz registered in %s mode\n",
699*4882a593Smuzhiyun 		 int_name ? int_name : " ", dev->clk_freq_hz,
700*4882a593Smuzhiyun 		 (dev->irq >= 0) ? "interrupt" : "polling");
701*4882a593Smuzhiyun 
702*4882a593Smuzhiyun 	return 0;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun probe_errorout:
705*4882a593Smuzhiyun 	return rc;
706*4882a593Smuzhiyun }
707*4882a593Smuzhiyun 
brcmstb_i2c_remove(struct platform_device * pdev)708*4882a593Smuzhiyun static int brcmstb_i2c_remove(struct platform_device *pdev)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *dev = platform_get_drvdata(pdev);
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 	i2c_del_adapter(&dev->adapter);
713*4882a593Smuzhiyun 	return 0;
714*4882a593Smuzhiyun }
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
brcmstb_i2c_suspend(struct device * dev)717*4882a593Smuzhiyun static int brcmstb_i2c_suspend(struct device *dev)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	i2c_mark_adapter_suspended(&i2c_dev->adapter);
722*4882a593Smuzhiyun 	return 0;
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun 
brcmstb_i2c_resume(struct device * dev)725*4882a593Smuzhiyun static int brcmstb_i2c_resume(struct device *dev)
726*4882a593Smuzhiyun {
727*4882a593Smuzhiyun 	struct brcmstb_i2c_dev *i2c_dev = dev_get_drvdata(dev);
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	brcmstb_i2c_set_bsc_reg_defaults(i2c_dev);
730*4882a593Smuzhiyun 	i2c_mark_adapter_resumed(&i2c_dev->adapter);
731*4882a593Smuzhiyun 
732*4882a593Smuzhiyun 	return 0;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun #endif
735*4882a593Smuzhiyun 
736*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(brcmstb_i2c_pm, brcmstb_i2c_suspend,
737*4882a593Smuzhiyun 			 brcmstb_i2c_resume);
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun static const struct of_device_id brcmstb_i2c_of_match[] = {
740*4882a593Smuzhiyun 	{.compatible = "brcm,brcmstb-i2c"},
741*4882a593Smuzhiyun 	{.compatible = "brcm,brcmper-i2c"},
742*4882a593Smuzhiyun 	{.compatible = "brcm,bcm2711-hdmi-i2c"},
743*4882a593Smuzhiyun 	{},
744*4882a593Smuzhiyun };
745*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, brcmstb_i2c_of_match);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun static struct platform_driver brcmstb_i2c_driver = {
748*4882a593Smuzhiyun 	.driver = {
749*4882a593Smuzhiyun 		   .name = "brcmstb-i2c",
750*4882a593Smuzhiyun 		   .of_match_table = brcmstb_i2c_of_match,
751*4882a593Smuzhiyun 		   .pm = &brcmstb_i2c_pm,
752*4882a593Smuzhiyun 		   },
753*4882a593Smuzhiyun 	.probe = brcmstb_i2c_probe,
754*4882a593Smuzhiyun 	.remove = brcmstb_i2c_remove,
755*4882a593Smuzhiyun };
756*4882a593Smuzhiyun module_platform_driver(brcmstb_i2c_driver);
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun MODULE_AUTHOR("Kamal Dasu <kdasu@broadcom.com>");
759*4882a593Smuzhiyun MODULE_DESCRIPTION("Broadcom Settop I2C Driver");
760*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
761