xref: /OK3568_Linux_fs/kernel/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  *  mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  *  Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include "mxl111sf-i2c.h"
9*4882a593Smuzhiyun #include "mxl111sf.h"
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /* SW-I2C ----------------------------------------------------------------- */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #define SW_I2C_ADDR		0x1a
14*4882a593Smuzhiyun #define SW_I2C_EN		0x02
15*4882a593Smuzhiyun #define SW_SCL_OUT		0x04
16*4882a593Smuzhiyun #define SW_SDA_OUT		0x08
17*4882a593Smuzhiyun #define SW_SDA_IN		0x04
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define SW_I2C_BUSY_ADDR	0x2f
20*4882a593Smuzhiyun #define SW_I2C_BUSY		0x02
21*4882a593Smuzhiyun 
mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state * state,u8 byte)22*4882a593Smuzhiyun static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
23*4882a593Smuzhiyun 					 u8 byte)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	int i, ret;
26*4882a593Smuzhiyun 	u8 data = 0;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 	mxl_i2c("(0x%02x)", byte);
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 	ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
31*4882a593Smuzhiyun 	if (mxl_fail(ret))
32*4882a593Smuzhiyun 		goto fail;
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun 	for (i = 0; i < 8; i++) {
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun 		data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
39*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN | data);
40*4882a593Smuzhiyun 		if (mxl_fail(ret))
41*4882a593Smuzhiyun 			goto fail;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
44*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN | data | SW_SCL_OUT);
45*4882a593Smuzhiyun 		if (mxl_fail(ret))
46*4882a593Smuzhiyun 			goto fail;
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
49*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN | data);
50*4882a593Smuzhiyun 		if (mxl_fail(ret))
51*4882a593Smuzhiyun 			goto fail;
52*4882a593Smuzhiyun 	}
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	/* last bit was 0 so we need to release SDA */
55*4882a593Smuzhiyun 	if (!(byte & 1)) {
56*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
57*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN | SW_SDA_OUT);
58*4882a593Smuzhiyun 		if (mxl_fail(ret))
59*4882a593Smuzhiyun 			goto fail;
60*4882a593Smuzhiyun 	}
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	/* CLK high for ACK readback */
63*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
64*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
65*4882a593Smuzhiyun 	if (mxl_fail(ret))
66*4882a593Smuzhiyun 		goto fail;
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun 	ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
69*4882a593Smuzhiyun 	if (mxl_fail(ret))
70*4882a593Smuzhiyun 		goto fail;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	/* drop the CLK after getting ACK, SDA will go high right away */
73*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
74*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SDA_OUT);
75*4882a593Smuzhiyun 	if (mxl_fail(ret))
76*4882a593Smuzhiyun 		goto fail;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	if (data & SW_SDA_IN)
79*4882a593Smuzhiyun 		ret = -EIO;
80*4882a593Smuzhiyun fail:
81*4882a593Smuzhiyun 	return ret;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun 
mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state * state,u8 * pbyte)84*4882a593Smuzhiyun static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
85*4882a593Smuzhiyun 					 u8 *pbyte)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun 	int i, ret;
88*4882a593Smuzhiyun 	u8 byte = 0;
89*4882a593Smuzhiyun 	u8 data = 0;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	mxl_i2c("()");
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	*pbyte = 0;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
96*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SDA_OUT);
97*4882a593Smuzhiyun 	if (mxl_fail(ret))
98*4882a593Smuzhiyun 		goto fail;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	for (i = 0; i < 8; i++) {
101*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
102*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN |
103*4882a593Smuzhiyun 					 SW_SCL_OUT | SW_SDA_OUT);
104*4882a593Smuzhiyun 		if (mxl_fail(ret))
105*4882a593Smuzhiyun 			goto fail;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 		ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
108*4882a593Smuzhiyun 		if (mxl_fail(ret))
109*4882a593Smuzhiyun 			goto fail;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 		if (data & SW_SDA_IN)
112*4882a593Smuzhiyun 			byte |= (0x80 >> i);
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 		ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
115*4882a593Smuzhiyun 					 0x10 | SW_I2C_EN | SW_SDA_OUT);
116*4882a593Smuzhiyun 		if (mxl_fail(ret))
117*4882a593Smuzhiyun 			goto fail;
118*4882a593Smuzhiyun 	}
119*4882a593Smuzhiyun 	*pbyte = byte;
120*4882a593Smuzhiyun fail:
121*4882a593Smuzhiyun 	return ret;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun 
mxl111sf_i2c_start(struct mxl111sf_state * state)124*4882a593Smuzhiyun static int mxl111sf_i2c_start(struct mxl111sf_state *state)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	int ret;
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	mxl_i2c("()");
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
131*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
132*4882a593Smuzhiyun 	if (mxl_fail(ret))
133*4882a593Smuzhiyun 		goto fail;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
136*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT);
137*4882a593Smuzhiyun 	if (mxl_fail(ret))
138*4882a593Smuzhiyun 		goto fail;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
141*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN); /* start */
142*4882a593Smuzhiyun 	mxl_fail(ret);
143*4882a593Smuzhiyun fail:
144*4882a593Smuzhiyun 	return ret;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun 
mxl111sf_i2c_stop(struct mxl111sf_state * state)147*4882a593Smuzhiyun static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	int ret;
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 	mxl_i2c("()");
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
154*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN); /* stop */
155*4882a593Smuzhiyun 	if (mxl_fail(ret))
156*4882a593Smuzhiyun 		goto fail;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
159*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT);
160*4882a593Smuzhiyun 	if (mxl_fail(ret))
161*4882a593Smuzhiyun 		goto fail;
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
164*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
165*4882a593Smuzhiyun 	if (mxl_fail(ret))
166*4882a593Smuzhiyun 		goto fail;
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
169*4882a593Smuzhiyun 				 0x10 | SW_SCL_OUT | SW_SDA_OUT);
170*4882a593Smuzhiyun 	mxl_fail(ret);
171*4882a593Smuzhiyun fail:
172*4882a593Smuzhiyun 	return ret;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun 
mxl111sf_i2c_ack(struct mxl111sf_state * state)175*4882a593Smuzhiyun static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
176*4882a593Smuzhiyun {
177*4882a593Smuzhiyun 	int ret;
178*4882a593Smuzhiyun 	u8 b = 0;
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 	mxl_i2c("()");
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 	ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
183*4882a593Smuzhiyun 	if (mxl_fail(ret))
184*4882a593Smuzhiyun 		goto fail;
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
187*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN);
188*4882a593Smuzhiyun 	if (mxl_fail(ret))
189*4882a593Smuzhiyun 		goto fail;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	/* pull SDA low */
192*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
193*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT);
194*4882a593Smuzhiyun 	if (mxl_fail(ret))
195*4882a593Smuzhiyun 		goto fail;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
198*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SDA_OUT);
199*4882a593Smuzhiyun 	mxl_fail(ret);
200*4882a593Smuzhiyun fail:
201*4882a593Smuzhiyun 	return ret;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun 
mxl111sf_i2c_nack(struct mxl111sf_state * state)204*4882a593Smuzhiyun static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun 	int ret;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	mxl_i2c("()");
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun 	/* SDA high to signal last byte read from slave */
211*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
212*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
213*4882a593Smuzhiyun 	if (mxl_fail(ret))
214*4882a593Smuzhiyun 		goto fail;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
217*4882a593Smuzhiyun 				 0x10 | SW_I2C_EN | SW_SDA_OUT);
218*4882a593Smuzhiyun 	mxl_fail(ret);
219*4882a593Smuzhiyun fail:
220*4882a593Smuzhiyun 	return ret;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun /* ------------------------------------------------------------------------ */
224*4882a593Smuzhiyun 
mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state * state,struct i2c_msg * msg)225*4882a593Smuzhiyun static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
226*4882a593Smuzhiyun 				    struct i2c_msg *msg)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun 	int i, ret;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	mxl_i2c("()");
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	if (msg->flags & I2C_M_RD) {
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		ret = mxl111sf_i2c_start(state);
235*4882a593Smuzhiyun 		if (mxl_fail(ret))
236*4882a593Smuzhiyun 			goto fail;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 		ret = mxl111sf_i2c_bitbang_sendbyte(state,
239*4882a593Smuzhiyun 						    (msg->addr << 1) | 0x01);
240*4882a593Smuzhiyun 		if (mxl_fail(ret)) {
241*4882a593Smuzhiyun 			mxl111sf_i2c_stop(state);
242*4882a593Smuzhiyun 			goto fail;
243*4882a593Smuzhiyun 		}
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 		for (i = 0; i < msg->len; i++) {
246*4882a593Smuzhiyun 			ret = mxl111sf_i2c_bitbang_recvbyte(state,
247*4882a593Smuzhiyun 							    &msg->buf[i]);
248*4882a593Smuzhiyun 			if (mxl_fail(ret)) {
249*4882a593Smuzhiyun 				mxl111sf_i2c_stop(state);
250*4882a593Smuzhiyun 				goto fail;
251*4882a593Smuzhiyun 			}
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 			if (i < msg->len - 1)
254*4882a593Smuzhiyun 				mxl111sf_i2c_ack(state);
255*4882a593Smuzhiyun 		}
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 		mxl111sf_i2c_nack(state);
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 		ret = mxl111sf_i2c_stop(state);
260*4882a593Smuzhiyun 		if (mxl_fail(ret))
261*4882a593Smuzhiyun 			goto fail;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	} else {
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 		ret = mxl111sf_i2c_start(state);
266*4882a593Smuzhiyun 		if (mxl_fail(ret))
267*4882a593Smuzhiyun 			goto fail;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 		ret = mxl111sf_i2c_bitbang_sendbyte(state,
270*4882a593Smuzhiyun 						    (msg->addr << 1) & 0xfe);
271*4882a593Smuzhiyun 		if (mxl_fail(ret)) {
272*4882a593Smuzhiyun 			mxl111sf_i2c_stop(state);
273*4882a593Smuzhiyun 			goto fail;
274*4882a593Smuzhiyun 		}
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 		for (i = 0; i < msg->len; i++) {
277*4882a593Smuzhiyun 			ret = mxl111sf_i2c_bitbang_sendbyte(state,
278*4882a593Smuzhiyun 							    msg->buf[i]);
279*4882a593Smuzhiyun 			if (mxl_fail(ret)) {
280*4882a593Smuzhiyun 				mxl111sf_i2c_stop(state);
281*4882a593Smuzhiyun 				goto fail;
282*4882a593Smuzhiyun 			}
283*4882a593Smuzhiyun 		}
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 		/* FIXME: we only want to do this on the last transaction */
286*4882a593Smuzhiyun 		mxl111sf_i2c_stop(state);
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun fail:
289*4882a593Smuzhiyun 	return ret;
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun /* HW-I2C ----------------------------------------------------------------- */
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun #define USB_WRITE_I2C_CMD     0x99
295*4882a593Smuzhiyun #define USB_READ_I2C_CMD      0xdd
296*4882a593Smuzhiyun #define USB_END_I2C_CMD       0xfe
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun #define USB_WRITE_I2C_CMD_LEN   26
299*4882a593Smuzhiyun #define USB_READ_I2C_CMD_LEN    24
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun #define I2C_MUX_REG           0x30
302*4882a593Smuzhiyun #define I2C_CONTROL_REG       0x00
303*4882a593Smuzhiyun #define I2C_SLAVE_ADDR_REG    0x08
304*4882a593Smuzhiyun #define I2C_DATA_REG          0x0c
305*4882a593Smuzhiyun #define I2C_INT_STATUS_REG    0x10
306*4882a593Smuzhiyun 
mxl111sf_i2c_send_data(struct mxl111sf_state * state,u8 index,u8 * wdata)307*4882a593Smuzhiyun static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
308*4882a593Smuzhiyun 				  u8 index, u8 *wdata)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun 	int ret = mxl111sf_ctrl_msg(state, wdata[0],
311*4882a593Smuzhiyun 				    &wdata[1], 25, NULL, 0);
312*4882a593Smuzhiyun 	mxl_fail(ret);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	return ret;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
mxl111sf_i2c_get_data(struct mxl111sf_state * state,u8 index,u8 * wdata,u8 * rdata)317*4882a593Smuzhiyun static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
318*4882a593Smuzhiyun 				 u8 index, u8 *wdata, u8 *rdata)
319*4882a593Smuzhiyun {
320*4882a593Smuzhiyun 	int ret = mxl111sf_ctrl_msg(state, wdata[0],
321*4882a593Smuzhiyun 				    &wdata[1], 25, rdata, 24);
322*4882a593Smuzhiyun 	mxl_fail(ret);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	return ret;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun 
mxl111sf_i2c_check_status(struct mxl111sf_state * state)327*4882a593Smuzhiyun static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	u8 status = 0;
330*4882a593Smuzhiyun 	u8 buf[26];
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	mxl_i2c_adv("()");
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 	buf[0] = USB_READ_I2C_CMD;
335*4882a593Smuzhiyun 	buf[1] = 0x00;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	buf[2] = I2C_INT_STATUS_REG;
338*4882a593Smuzhiyun 	buf[3] = 0x00;
339*4882a593Smuzhiyun 	buf[4] = 0x00;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	buf[5] = USB_END_I2C_CMD;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	mxl111sf_i2c_get_data(state, 0, buf, buf);
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	if (buf[1] & 0x04)
346*4882a593Smuzhiyun 		status = 1;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	return status;
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun 
mxl111sf_i2c_check_fifo(struct mxl111sf_state * state)351*4882a593Smuzhiyun static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun 	u8 status = 0;
354*4882a593Smuzhiyun 	u8 buf[26];
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	mxl_i2c("()");
357*4882a593Smuzhiyun 
358*4882a593Smuzhiyun 	buf[0] = USB_READ_I2C_CMD;
359*4882a593Smuzhiyun 	buf[1] = 0x00;
360*4882a593Smuzhiyun 
361*4882a593Smuzhiyun 	buf[2] = I2C_MUX_REG;
362*4882a593Smuzhiyun 	buf[3] = 0x00;
363*4882a593Smuzhiyun 	buf[4] = 0x00;
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	buf[5] = I2C_INT_STATUS_REG;
366*4882a593Smuzhiyun 	buf[6] = 0x00;
367*4882a593Smuzhiyun 	buf[7] = 0x00;
368*4882a593Smuzhiyun 	buf[8] = USB_END_I2C_CMD;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	mxl111sf_i2c_get_data(state, 0, buf, buf);
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 	if (0x08 == (buf[1] & 0x08))
373*4882a593Smuzhiyun 		status = 1;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	if ((buf[5] & 0x02) == 0x02)
376*4882a593Smuzhiyun 		mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	return status;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun 
mxl111sf_i2c_readagain(struct mxl111sf_state * state,u8 count,u8 * rbuf)381*4882a593Smuzhiyun static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
382*4882a593Smuzhiyun 				  u8 count, u8 *rbuf)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	u8 i2c_w_data[26];
385*4882a593Smuzhiyun 	u8 i2c_r_data[24];
386*4882a593Smuzhiyun 	u8 i = 0;
387*4882a593Smuzhiyun 	u8 fifo_status = 0;
388*4882a593Smuzhiyun 	int status = 0;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun 	mxl_i2c("read %d bytes", count);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	while ((fifo_status == 0) && (i++ < 5))
393*4882a593Smuzhiyun 		fifo_status = mxl111sf_i2c_check_fifo(state);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	i2c_w_data[0] = 0xDD;
396*4882a593Smuzhiyun 	i2c_w_data[1] = 0x00;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	for (i = 2; i < 26; i++)
399*4882a593Smuzhiyun 		i2c_w_data[i] = 0xFE;
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	for (i = 0; i < count; i++) {
402*4882a593Smuzhiyun 		i2c_w_data[2+(i*3)] = 0x0C;
403*4882a593Smuzhiyun 		i2c_w_data[3+(i*3)] = 0x00;
404*4882a593Smuzhiyun 		i2c_w_data[4+(i*3)] = 0x00;
405*4882a593Smuzhiyun 	}
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	/* Check for I2C NACK status */
410*4882a593Smuzhiyun 	if (mxl111sf_i2c_check_status(state) == 1) {
411*4882a593Smuzhiyun 		mxl_i2c("error!");
412*4882a593Smuzhiyun 	} else {
413*4882a593Smuzhiyun 		for (i = 0; i < count; i++) {
414*4882a593Smuzhiyun 			rbuf[i] = i2c_r_data[(i*3)+1];
415*4882a593Smuzhiyun 			mxl_i2c("%02x\t %02x",
416*4882a593Smuzhiyun 				i2c_r_data[(i*3)+1],
417*4882a593Smuzhiyun 				i2c_r_data[(i*3)+2]);
418*4882a593Smuzhiyun 		}
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun 		status = 1;
421*4882a593Smuzhiyun 	}
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 	return status;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun #define HWI2C400 1
mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state * state,struct i2c_msg * msg)427*4882a593Smuzhiyun static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
428*4882a593Smuzhiyun 				    struct i2c_msg *msg)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	int i, k, ret = 0;
431*4882a593Smuzhiyun 	u16 index = 0;
432*4882a593Smuzhiyun 	u8 buf[26];
433*4882a593Smuzhiyun 	u8 i2c_r_data[24];
434*4882a593Smuzhiyun 	u16 block_len;
435*4882a593Smuzhiyun 	u16 left_over_len;
436*4882a593Smuzhiyun 	u8 rd_status[8];
437*4882a593Smuzhiyun 	u8 ret_status;
438*4882a593Smuzhiyun 	u8 readbuff[26];
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
441*4882a593Smuzhiyun 		msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
442*4882a593Smuzhiyun 		(!(msg->flags & I2C_M_RD)) ? msg->len : 0);
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun 	for (index = 0; index < 26; index++)
445*4882a593Smuzhiyun 		buf[index] = USB_END_I2C_CMD;
446*4882a593Smuzhiyun 
447*4882a593Smuzhiyun 	/* command to indicate data payload is destined for I2C interface */
448*4882a593Smuzhiyun 	buf[0] = USB_WRITE_I2C_CMD;
449*4882a593Smuzhiyun 	buf[1] = 0x00;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	/* enable I2C interface */
452*4882a593Smuzhiyun 	buf[2] = I2C_MUX_REG;
453*4882a593Smuzhiyun 	buf[3] = 0x80;
454*4882a593Smuzhiyun 	buf[4] = 0x00;
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun 	/* enable I2C interface */
457*4882a593Smuzhiyun 	buf[5] = I2C_MUX_REG;
458*4882a593Smuzhiyun 	buf[6] = 0x81;
459*4882a593Smuzhiyun 	buf[7] = 0x00;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	/* set Timeout register on I2C interface */
462*4882a593Smuzhiyun 	buf[8] = 0x14;
463*4882a593Smuzhiyun 	buf[9] = 0xff;
464*4882a593Smuzhiyun 	buf[10] = 0x00;
465*4882a593Smuzhiyun #if 0
466*4882a593Smuzhiyun 	/* enable Interrupts on I2C interface */
467*4882a593Smuzhiyun 	buf[8] = 0x24;
468*4882a593Smuzhiyun 	buf[9] = 0xF7;
469*4882a593Smuzhiyun 	buf[10] = 0x00;
470*4882a593Smuzhiyun #endif
471*4882a593Smuzhiyun 	buf[11] = 0x24;
472*4882a593Smuzhiyun 	buf[12] = 0xF7;
473*4882a593Smuzhiyun 	buf[13] = 0x00;
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun 	ret = mxl111sf_i2c_send_data(state, 0, buf);
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	/* write data on I2C bus */
478*4882a593Smuzhiyun 	if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
479*4882a593Smuzhiyun 		mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 		/* control register on I2C interface to initialize I2C bus */
482*4882a593Smuzhiyun 		buf[2] = I2C_CONTROL_REG;
483*4882a593Smuzhiyun 		buf[3] = 0x5E;
484*4882a593Smuzhiyun 		buf[4] = (HWI2C400) ? 0x03 : 0x0D;
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun 		/* I2C Slave device Address */
487*4882a593Smuzhiyun 		buf[5] = I2C_SLAVE_ADDR_REG;
488*4882a593Smuzhiyun 		buf[6] = (msg->addr);
489*4882a593Smuzhiyun 		buf[7] = 0x00;
490*4882a593Smuzhiyun 		buf[8] = USB_END_I2C_CMD;
491*4882a593Smuzhiyun 		ret = mxl111sf_i2c_send_data(state, 0, buf);
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 		/* check for slave device status */
494*4882a593Smuzhiyun 		if (mxl111sf_i2c_check_status(state) == 1) {
495*4882a593Smuzhiyun 			mxl_i2c("NACK writing slave address %02x",
496*4882a593Smuzhiyun 				msg->addr);
497*4882a593Smuzhiyun 			/* if NACK, stop I2C bus and exit */
498*4882a593Smuzhiyun 			buf[2] = I2C_CONTROL_REG;
499*4882a593Smuzhiyun 			buf[3] = 0x4E;
500*4882a593Smuzhiyun 			buf[4] = (HWI2C400) ? 0x03 : 0x0D;
501*4882a593Smuzhiyun 			ret = -EIO;
502*4882a593Smuzhiyun 			goto exit;
503*4882a593Smuzhiyun 		}
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 		/* I2C interface can do I2C operations in block of 8 bytes of
506*4882a593Smuzhiyun 		   I2C data. calculation to figure out number of blocks of i2c
507*4882a593Smuzhiyun 		   data required to program */
508*4882a593Smuzhiyun 		block_len = (msg->len / 8);
509*4882a593Smuzhiyun 		left_over_len = (msg->len % 8);
510*4882a593Smuzhiyun 
511*4882a593Smuzhiyun 		mxl_i2c("block_len %d, left_over_len %d",
512*4882a593Smuzhiyun 			block_len, left_over_len);
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 		for (index = 0; index < block_len; index++) {
515*4882a593Smuzhiyun 			for (i = 0; i < 8; i++) {
516*4882a593Smuzhiyun 				/* write data on I2C interface */
517*4882a593Smuzhiyun 				buf[2+(i*3)] = I2C_DATA_REG;
518*4882a593Smuzhiyun 				buf[3+(i*3)] = msg->buf[(index*8)+i];
519*4882a593Smuzhiyun 				buf[4+(i*3)] = 0x00;
520*4882a593Smuzhiyun 			}
521*4882a593Smuzhiyun 
522*4882a593Smuzhiyun 			ret = mxl111sf_i2c_send_data(state, 0, buf);
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 			/* check for I2C NACK status */
525*4882a593Smuzhiyun 			if (mxl111sf_i2c_check_status(state) == 1) {
526*4882a593Smuzhiyun 				mxl_i2c("NACK writing slave address %02x",
527*4882a593Smuzhiyun 					msg->addr);
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 				/* if NACK, stop I2C bus and exit */
530*4882a593Smuzhiyun 				buf[2] = I2C_CONTROL_REG;
531*4882a593Smuzhiyun 				buf[3] = 0x4E;
532*4882a593Smuzhiyun 				buf[4] = (HWI2C400) ? 0x03 : 0x0D;
533*4882a593Smuzhiyun 				ret = -EIO;
534*4882a593Smuzhiyun 				goto exit;
535*4882a593Smuzhiyun 			}
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		if (left_over_len) {
540*4882a593Smuzhiyun 			for (k = 0; k < 26; k++)
541*4882a593Smuzhiyun 				buf[k] = USB_END_I2C_CMD;
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 			buf[0] = 0x99;
544*4882a593Smuzhiyun 			buf[1] = 0x00;
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 			for (i = 0; i < left_over_len; i++) {
547*4882a593Smuzhiyun 				buf[2+(i*3)] = I2C_DATA_REG;
548*4882a593Smuzhiyun 				buf[3+(i*3)] = msg->buf[(index*8)+i];
549*4882a593Smuzhiyun 				mxl_i2c("index = %d %d data %d",
550*4882a593Smuzhiyun 					index, i, msg->buf[(index*8)+i]);
551*4882a593Smuzhiyun 				buf[4+(i*3)] = 0x00;
552*4882a593Smuzhiyun 			}
553*4882a593Smuzhiyun 			ret = mxl111sf_i2c_send_data(state, 0, buf);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 			/* check for I2C NACK status */
556*4882a593Smuzhiyun 			if (mxl111sf_i2c_check_status(state) == 1) {
557*4882a593Smuzhiyun 				mxl_i2c("NACK writing slave address %02x",
558*4882a593Smuzhiyun 					msg->addr);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 				/* if NACK, stop I2C bus and exit */
561*4882a593Smuzhiyun 				buf[2] = I2C_CONTROL_REG;
562*4882a593Smuzhiyun 				buf[3] = 0x4E;
563*4882a593Smuzhiyun 				buf[4] = (HWI2C400) ? 0x03 : 0x0D;
564*4882a593Smuzhiyun 				ret = -EIO;
565*4882a593Smuzhiyun 				goto exit;
566*4882a593Smuzhiyun 			}
567*4882a593Smuzhiyun 
568*4882a593Smuzhiyun 		}
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun 		/* issue I2C STOP after write */
571*4882a593Smuzhiyun 		buf[2] = I2C_CONTROL_REG;
572*4882a593Smuzhiyun 		buf[3] = 0x4E;
573*4882a593Smuzhiyun 		buf[4] = (HWI2C400) ? 0x03 : 0x0D;
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun 	}
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	/* read data from I2C bus */
578*4882a593Smuzhiyun 	if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
579*4882a593Smuzhiyun 		mxl_i2c("read buf len %d", msg->len);
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun 		/* command to indicate data payload is
582*4882a593Smuzhiyun 		   destined for I2C interface */
583*4882a593Smuzhiyun 		buf[2] = I2C_CONTROL_REG;
584*4882a593Smuzhiyun 		buf[3] = 0xDF;
585*4882a593Smuzhiyun 		buf[4] = (HWI2C400) ? 0x03 : 0x0D;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 		/* I2C xfer length */
588*4882a593Smuzhiyun 		buf[5] = 0x14;
589*4882a593Smuzhiyun 		buf[6] = (msg->len & 0xFF);
590*4882a593Smuzhiyun 		buf[7] = 0;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun 		/* I2C slave device Address */
593*4882a593Smuzhiyun 		buf[8] = I2C_SLAVE_ADDR_REG;
594*4882a593Smuzhiyun 		buf[9] = msg->addr;
595*4882a593Smuzhiyun 		buf[10] = 0x00;
596*4882a593Smuzhiyun 		buf[11] = USB_END_I2C_CMD;
597*4882a593Smuzhiyun 		ret = mxl111sf_i2c_send_data(state, 0, buf);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 		/* check for I2C NACK status */
600*4882a593Smuzhiyun 		if (mxl111sf_i2c_check_status(state) == 1) {
601*4882a593Smuzhiyun 			mxl_i2c("NACK reading slave address %02x",
602*4882a593Smuzhiyun 				msg->addr);
603*4882a593Smuzhiyun 
604*4882a593Smuzhiyun 			/* if NACK, stop I2C bus and exit */
605*4882a593Smuzhiyun 			buf[2] = I2C_CONTROL_REG;
606*4882a593Smuzhiyun 			buf[3] = 0xC7;
607*4882a593Smuzhiyun 			buf[4] = (HWI2C400) ? 0x03 : 0x0D;
608*4882a593Smuzhiyun 			ret = -EIO;
609*4882a593Smuzhiyun 			goto exit;
610*4882a593Smuzhiyun 		}
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 		/* I2C interface can do I2C operations in block of 8 bytes of
613*4882a593Smuzhiyun 		   I2C data. calculation to figure out number of blocks of
614*4882a593Smuzhiyun 		   i2c data required to program */
615*4882a593Smuzhiyun 		block_len = ((msg->len) / 8);
616*4882a593Smuzhiyun 		left_over_len = ((msg->len) % 8);
617*4882a593Smuzhiyun 		index = 0;
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 		mxl_i2c("block_len %d, left_over_len %d",
620*4882a593Smuzhiyun 			block_len, left_over_len);
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 		/* command to read data from I2C interface */
623*4882a593Smuzhiyun 		buf[0] = USB_READ_I2C_CMD;
624*4882a593Smuzhiyun 		buf[1] = 0x00;
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 		for (index = 0; index < block_len; index++) {
627*4882a593Smuzhiyun 			/* setup I2C read request packet on I2C interface */
628*4882a593Smuzhiyun 			for (i = 0; i < 8; i++) {
629*4882a593Smuzhiyun 				buf[2+(i*3)] = I2C_DATA_REG;
630*4882a593Smuzhiyun 				buf[3+(i*3)] = 0x00;
631*4882a593Smuzhiyun 				buf[4+(i*3)] = 0x00;
632*4882a593Smuzhiyun 			}
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 			ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 			/* check for I2C NACK status */
637*4882a593Smuzhiyun 			if (mxl111sf_i2c_check_status(state) == 1) {
638*4882a593Smuzhiyun 				mxl_i2c("NACK reading slave address %02x",
639*4882a593Smuzhiyun 					msg->addr);
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 				/* if NACK, stop I2C bus and exit */
642*4882a593Smuzhiyun 				buf[2] = I2C_CONTROL_REG;
643*4882a593Smuzhiyun 				buf[3] = 0xC7;
644*4882a593Smuzhiyun 				buf[4] = (HWI2C400) ? 0x03 : 0x0D;
645*4882a593Smuzhiyun 				ret = -EIO;
646*4882a593Smuzhiyun 				goto exit;
647*4882a593Smuzhiyun 			}
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 			/* copy data from i2c data payload to read buffer */
650*4882a593Smuzhiyun 			for (i = 0; i < 8; i++) {
651*4882a593Smuzhiyun 				rd_status[i] = i2c_r_data[(i*3)+2];
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun 				if (rd_status[i] == 0x04) {
654*4882a593Smuzhiyun 					if (i < 7) {
655*4882a593Smuzhiyun 						mxl_i2c("i2c fifo empty! @ %d",
656*4882a593Smuzhiyun 							i);
657*4882a593Smuzhiyun 						msg->buf[(index*8)+i] =
658*4882a593Smuzhiyun 							i2c_r_data[(i*3)+1];
659*4882a593Smuzhiyun 						/* read again */
660*4882a593Smuzhiyun 						ret_status =
661*4882a593Smuzhiyun 							mxl111sf_i2c_readagain(
662*4882a593Smuzhiyun 								state, 8-(i+1),
663*4882a593Smuzhiyun 								readbuff);
664*4882a593Smuzhiyun 						if (ret_status == 1) {
665*4882a593Smuzhiyun 							for (k = 0;
666*4882a593Smuzhiyun 							     k < 8-(i+1);
667*4882a593Smuzhiyun 							     k++) {
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 					msg->buf[(index*8)+(k+i+1)] =
670*4882a593Smuzhiyun 						readbuff[k];
671*4882a593Smuzhiyun 					mxl_i2c("read data: %02x\t %02x",
672*4882a593Smuzhiyun 						msg->buf[(index*8)+(k+i)],
673*4882a593Smuzhiyun 						(index*8)+(k+i));
674*4882a593Smuzhiyun 					mxl_i2c("read data: %02x\t %02x",
675*4882a593Smuzhiyun 						msg->buf[(index*8)+(k+i+1)],
676*4882a593Smuzhiyun 						readbuff[k]);
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 							}
679*4882a593Smuzhiyun 							goto stop_copy;
680*4882a593Smuzhiyun 						} else {
681*4882a593Smuzhiyun 							mxl_i2c("readagain ERROR!");
682*4882a593Smuzhiyun 						}
683*4882a593Smuzhiyun 					} else {
684*4882a593Smuzhiyun 						msg->buf[(index*8)+i] =
685*4882a593Smuzhiyun 							i2c_r_data[(i*3)+1];
686*4882a593Smuzhiyun 					}
687*4882a593Smuzhiyun 				} else {
688*4882a593Smuzhiyun 					msg->buf[(index*8)+i] =
689*4882a593Smuzhiyun 						i2c_r_data[(i*3)+1];
690*4882a593Smuzhiyun 				}
691*4882a593Smuzhiyun 			}
692*4882a593Smuzhiyun stop_copy:
693*4882a593Smuzhiyun 			;
694*4882a593Smuzhiyun 
695*4882a593Smuzhiyun 		}
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 		if (left_over_len) {
698*4882a593Smuzhiyun 			for (k = 0; k < 26; k++)
699*4882a593Smuzhiyun 				buf[k] = USB_END_I2C_CMD;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 			buf[0] = 0xDD;
702*4882a593Smuzhiyun 			buf[1] = 0x00;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 			for (i = 0; i < left_over_len; i++) {
705*4882a593Smuzhiyun 				buf[2+(i*3)] = I2C_DATA_REG;
706*4882a593Smuzhiyun 				buf[3+(i*3)] = 0x00;
707*4882a593Smuzhiyun 				buf[4+(i*3)] = 0x00;
708*4882a593Smuzhiyun 			}
709*4882a593Smuzhiyun 			ret = mxl111sf_i2c_get_data(state, 0, buf,
710*4882a593Smuzhiyun 						    i2c_r_data);
711*4882a593Smuzhiyun 
712*4882a593Smuzhiyun 			/* check for I2C NACK status */
713*4882a593Smuzhiyun 			if (mxl111sf_i2c_check_status(state) == 1) {
714*4882a593Smuzhiyun 				mxl_i2c("NACK reading slave address %02x",
715*4882a593Smuzhiyun 					msg->addr);
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 				/* if NACK, stop I2C bus and exit */
718*4882a593Smuzhiyun 				buf[2] = I2C_CONTROL_REG;
719*4882a593Smuzhiyun 				buf[3] = 0xC7;
720*4882a593Smuzhiyun 				buf[4] = (HWI2C400) ? 0x03 : 0x0D;
721*4882a593Smuzhiyun 				ret = -EIO;
722*4882a593Smuzhiyun 				goto exit;
723*4882a593Smuzhiyun 			}
724*4882a593Smuzhiyun 
725*4882a593Smuzhiyun 			for (i = 0; i < left_over_len; i++) {
726*4882a593Smuzhiyun 				msg->buf[(block_len*8)+i] =
727*4882a593Smuzhiyun 					i2c_r_data[(i*3)+1];
728*4882a593Smuzhiyun 				mxl_i2c("read data: %02x\t %02x",
729*4882a593Smuzhiyun 					i2c_r_data[(i*3)+1],
730*4882a593Smuzhiyun 					i2c_r_data[(i*3)+2]);
731*4882a593Smuzhiyun 			}
732*4882a593Smuzhiyun 		}
733*4882a593Smuzhiyun 
734*4882a593Smuzhiyun 		/* indicate I2C interface to issue NACK
735*4882a593Smuzhiyun 		   after next I2C read op */
736*4882a593Smuzhiyun 		buf[0] = USB_WRITE_I2C_CMD;
737*4882a593Smuzhiyun 		buf[1] = 0x00;
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 		/* control register */
740*4882a593Smuzhiyun 		buf[2] = I2C_CONTROL_REG;
741*4882a593Smuzhiyun 		buf[3] = 0x17;
742*4882a593Smuzhiyun 		buf[4] = (HWI2C400) ? 0x03 : 0x0D;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun 		buf[5] = USB_END_I2C_CMD;
745*4882a593Smuzhiyun 		ret = mxl111sf_i2c_send_data(state, 0, buf);
746*4882a593Smuzhiyun 
747*4882a593Smuzhiyun 		/* control register */
748*4882a593Smuzhiyun 		buf[2] = I2C_CONTROL_REG;
749*4882a593Smuzhiyun 		buf[3] = 0xC7;
750*4882a593Smuzhiyun 		buf[4] = (HWI2C400) ? 0x03 : 0x0D;
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	}
753*4882a593Smuzhiyun exit:
754*4882a593Smuzhiyun 	/* STOP and disable I2C MUX */
755*4882a593Smuzhiyun 	buf[0] = USB_WRITE_I2C_CMD;
756*4882a593Smuzhiyun 	buf[1] = 0x00;
757*4882a593Smuzhiyun 
758*4882a593Smuzhiyun 	/* de-initilize I2C BUS */
759*4882a593Smuzhiyun 	buf[5] = USB_END_I2C_CMD;
760*4882a593Smuzhiyun 	mxl111sf_i2c_send_data(state, 0, buf);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	/* Control Register */
763*4882a593Smuzhiyun 	buf[2] = I2C_CONTROL_REG;
764*4882a593Smuzhiyun 	buf[3] = 0xDF;
765*4882a593Smuzhiyun 	buf[4] = 0x03;
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 	/* disable I2C interface */
768*4882a593Smuzhiyun 	buf[5] = I2C_MUX_REG;
769*4882a593Smuzhiyun 	buf[6] = 0x00;
770*4882a593Smuzhiyun 	buf[7] = 0x00;
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 	/* de-initilize I2C BUS */
773*4882a593Smuzhiyun 	buf[8] = USB_END_I2C_CMD;
774*4882a593Smuzhiyun 	mxl111sf_i2c_send_data(state, 0, buf);
775*4882a593Smuzhiyun 
776*4882a593Smuzhiyun 	/* disable I2C interface */
777*4882a593Smuzhiyun 	buf[2] = I2C_MUX_REG;
778*4882a593Smuzhiyun 	buf[3] = 0x81;
779*4882a593Smuzhiyun 	buf[4] = 0x00;
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 	/* disable I2C interface */
782*4882a593Smuzhiyun 	buf[5] = I2C_MUX_REG;
783*4882a593Smuzhiyun 	buf[6] = 0x00;
784*4882a593Smuzhiyun 	buf[7] = 0x00;
785*4882a593Smuzhiyun 
786*4882a593Smuzhiyun 	/* disable I2C interface */
787*4882a593Smuzhiyun 	buf[8] = I2C_MUX_REG;
788*4882a593Smuzhiyun 	buf[9] = 0x00;
789*4882a593Smuzhiyun 	buf[10] = 0x00;
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 	buf[11] = USB_END_I2C_CMD;
792*4882a593Smuzhiyun 	mxl111sf_i2c_send_data(state, 0, buf);
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	return ret;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun 
797*4882a593Smuzhiyun /* ------------------------------------------------------------------------ */
798*4882a593Smuzhiyun 
mxl111sf_i2c_xfer(struct i2c_adapter * adap,struct i2c_msg msg[],int num)799*4882a593Smuzhiyun int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
800*4882a593Smuzhiyun 		      struct i2c_msg msg[], int num)
801*4882a593Smuzhiyun {
802*4882a593Smuzhiyun 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
803*4882a593Smuzhiyun 	struct mxl111sf_state *state = d->priv;
804*4882a593Smuzhiyun 	int hwi2c = (state->chip_rev > MXL111SF_V6);
805*4882a593Smuzhiyun 	int i, ret;
806*4882a593Smuzhiyun 
807*4882a593Smuzhiyun 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
808*4882a593Smuzhiyun 		return -EAGAIN;
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun 	for (i = 0; i < num; i++) {
811*4882a593Smuzhiyun 		ret = (hwi2c) ?
812*4882a593Smuzhiyun 			mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
813*4882a593Smuzhiyun 			mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
814*4882a593Smuzhiyun 		if (mxl_fail(ret)) {
815*4882a593Smuzhiyun 			mxl_debug_adv("failed with error %d on i2c transaction %d of %d, %sing %d bytes to/from 0x%02x",
816*4882a593Smuzhiyun 				      ret, i+1, num,
817*4882a593Smuzhiyun 				      (msg[i].flags & I2C_M_RD) ?
818*4882a593Smuzhiyun 				      "read" : "writ",
819*4882a593Smuzhiyun 				      msg[i].len, msg[i].addr);
820*4882a593Smuzhiyun 
821*4882a593Smuzhiyun 			break;
822*4882a593Smuzhiyun 		}
823*4882a593Smuzhiyun 	}
824*4882a593Smuzhiyun 
825*4882a593Smuzhiyun 	mutex_unlock(&d->i2c_mutex);
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	return i == num ? num : -EREMOTEIO;
828*4882a593Smuzhiyun }
829