brintos

brintos / linux-shallow public Read only

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