saa7146_i2c.c revision 632fe9fe440249642845675d97436c667cbbd21e
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <media/saa7146_vv.h>
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u32 saa7146_i2c_func(struct i2c_adapter *adapter)
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds//fm	DEB_I2C(("'%s'.\n", adapter->name));
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return	  I2C_FUNC_I2C
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		| I2C_FUNC_SMBUS_QUICK
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		| I2C_FUNC_SMBUS_READ_BYTE	| I2C_FUNC_SMBUS_WRITE_BYTE
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		| I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this function returns the status-register of our i2c-device */
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u32 saa7146_i2c_status(struct saa7146_dev *dev)
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 iicsta = saa7146_read(dev, I2C_STATUS);
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DEB_I2C(("status: 0x%08x\n",iicsta));
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return iicsta;
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this function runs through the i2c-messages and prepares the data to be
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   sent through the saa7146. have a look at the specifications p. 122 ff
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   to understand this. it returns the number of u32s to send, or -1
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   in case of an error. */
27a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Virostatic int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, __le32 *op)
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int h1, h2;
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i, j, addr;
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int mem = 0, op_count = 0;
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* first determine size of needed memory */
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(i = 0; i < num; i++) {
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mem += m[i].len + 1;
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* worst case: we need one u32 for three bytes to be send
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   plus one extra byte to address the device */
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mem = 1 + ((mem-1) / 3);
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* we assume that op points to a memory of at least SAA7146_I2C_MEM bytes
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   size. if we exceed this limit... */
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( (4*mem) > SAA7146_I2C_MEM ) {
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds//fm		DEB_I2C(("cannot prepare i2c-message.\n"));
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* be careful: clear out the i2c-mem first */
50a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro	memset(op,0,sizeof(__le32)*mem);
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* loop through all messages */
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(i = 0; i < num; i++) {
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* insert the address of the i2c-slave.
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   note: we get 7 bit i2c-addresses,
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   so we have to perform a translation */
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0);
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		h1 = op_count/3; h2 = op_count%3;
60a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		op[h1] |= cpu_to_le32(	    (u8)addr << ((3-h2)*8));
61a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		op[h1] |= cpu_to_le32(SAA7146_I2C_START << ((3-h2)*2));
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		op_count++;
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* loop through all bytes of message i */
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for(j = 0; j < m[i].len; j++) {
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* insert the data bytes */
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			h1 = op_count/3; h2 = op_count%3;
68a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro			op[h1] |= cpu_to_le32( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
69a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro			op[h1] |= cpu_to_le32(       SAA7146_I2C_CONT << ((3-h2)*2));
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			op_count++;
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* have a look at the last byte inserted:
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  if it was: ...CONT change it to ...STOP */
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	h1 = (op_count-1)/3; h2 = (op_count-1)%3;
78a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro	if ( SAA7146_I2C_CONT == (0x3 & (le32_to_cpu(op[h1]) >> ((3-h2)*2))) ) {
79a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		op[h1] &= ~cpu_to_le32(0x2 << ((3-h2)*2));
80a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		op[h1] |= cpu_to_le32(SAA7146_I2C_STOP << ((3-h2)*2));
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* return the number of u32s to send */
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mem;
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this functions loops through all i2c-messages. normally, it should determine
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   which bytes were read through the adapter and write them back to the corresponding
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   i2c-message. but instead, we simply write back all bytes.
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   fixme: this could be improved. */
91a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Virostatic int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op)
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i, j;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int op_count = 0;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* loop through all messages */
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(i = 0; i < num; i++) {
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		op_count++;
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* loop throgh all bytes of message i */
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for(j = 0; j < m[i].len; j++) {
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			/* write back all bytes that could have been read */
104a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro			m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8));
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			op_count++;
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_reset(struct saa7146_dev *dev)
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* get current status */
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 status = saa7146_i2c_status(dev);
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* clear registers for sure */
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	saa7146_write(dev, I2C_TRANSFER, 0);
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* check if any operation is still in progress */
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( 0 != ( status & SAA7146_I2C_BUSY) ) {
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* yes, kill ongoing operation */
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DEB_I2C(("busy_state detected.\n"));
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* set "ABORT-OPERATION"-bit (bit 7)*/
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		msleep(SAA7146_I2C_DELAY);
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* clear all error-bits pending; this is needed because p.123, note 1 */
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		msleep(SAA7146_I2C_DELAY);
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* check if any error is (still) present. (this can be necessary because p.123, note 1) */
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = saa7146_i2c_status(dev);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( dev->i2c_bitrate != status ) {
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DEB_I2C(("error_state detected. status:0x%08x\n",status));
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Repeat the abort operation. This seems to be necessary
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   after serious protocol errors caused by e.g. the SAA7740 */
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		msleep(SAA7146_I2C_DELAY);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* clear all error-bits pending */
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		msleep(SAA7146_I2C_DELAY);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* the data sheet says it might be necessary to clear the status
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   twice after an abort */
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		msleep(SAA7146_I2C_DELAY);
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* if any error is still present, a fatal error has occured ... */
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	status = saa7146_i2c_status(dev);
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( dev->i2c_bitrate != status ) {
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DEB_I2C(("fatal error. status:0x%08x\n",status));
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -1;
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this functions writes out the data-byte 'dword' to the i2c-device.
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   failed badly (e.g. address error) */
177a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Virostatic int saa7146_i2c_writeout(struct saa7146_dev *dev, __le32 *dword, int short_delay)
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 status = 0, mc2 = 0;
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int trial = 0;
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long timeout;
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* write out i2c-command */
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DEB_I2C(("before: 0x%08x (status: 0x%08x), %d\n",*dword,saa7146_read(dev, I2C_STATUS), dev->i2c_op));
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS,	 dev->i2c_bitrate);
189a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		dev->i2c_op = 1;
19235e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr		SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		SAA7146_IER_ENABLE(dev, MASK_16|MASK_17);
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
19635e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr		timeout = HZ/100 + 1; /* 10ms */
19735e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr		timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout);
19835e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr		if (timeout == -ERESTARTSYS || dev->i2c_op) {
19935e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr			SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
20035e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr			SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
20135e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr			if (timeout == -ERESTARTSYS)
20235e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr				/* a signal arrived */
20335e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr				return -ERESTARTSYS;
20435e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr
205276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			printk(KERN_WARNING "%s %s [irq]: timed out waiting for end of xfer\n",
206536a0b119527c8af8e3a70b18f7640a21039a0a7Harvey Harrison				dev->name, __func__);
20735e55255bbe1775c3cdb5d9cff494d72d5a49bf3Hartmut Birr			return -EIO;
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		status = saa7146_read(dev, I2C_STATUS);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, I2C_STATUS,	 dev->i2c_bitrate);
212a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_write(dev, MC2, (MASK_00 | MASK_16));
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* do not poll for i2c-status before upload is complete */
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		timeout = jiffies + HZ/100 + 1; /* 10ms */
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while(1) {
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			mc2 = (saa7146_read(dev, MC2) & 0x1);
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if( 0 != mc2 ) {
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (time_after(jiffies,timeout)) {
223276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss				printk(KERN_WARNING "%s %s: timed out waiting for MC2\n",
224536a0b119527c8af8e3a70b18f7640a21039a0a7Harvey Harrison					dev->name, __func__);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return -EIO;
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* wait until we get a transfer done or error */
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		timeout = jiffies + HZ/100 + 1; /* 10ms */
2309bb6e2593ad4cb94944f547154baee64b4734598Oliver Endriss		/* first read usually delivers bogus results... */
2319bb6e2593ad4cb94944f547154baee64b4734598Oliver Endriss		saa7146_i2c_status(dev);
2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		while(1) {
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			status = saa7146_i2c_status(dev);
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ((status & 0x3) != 1)
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (time_after(jiffies,timeout)) {
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* this is normal when probing the bus
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 * (no answer from nonexisistant device...)
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				 */
240276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss				printk(KERN_WARNING "%s %s [poll]: timed out waiting for end of xfer\n",
241536a0b119527c8af8e3a70b18f7640a21039a0a7Harvey Harrison					dev->name, __func__);
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return -EIO;
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
2449bb6e2593ad4cb94944f547154baee64b4734598Oliver Endriss			if (++trial < 50 && short_delay)
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				udelay(10);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
2479bb6e2593ad4cb94944f547154baee64b4734598Oliver Endriss				msleep(1);
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* give a detailed status report */
252276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss	if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
253276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			     SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
254276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			     SAA7146_I2C_AL    | SAA7146_I2C_ERR   |
255276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			     SAA7146_I2C_BUSY)) ) {
256276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss
257276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss		if ( 0 == (status & SAA7146_I2C_ERR) ||
258276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss		     0 == (status & SAA7146_I2C_BUSY) ) {
259276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			/* it may take some time until ERR goes high - ignore */
260276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss			DEB_I2C(("unexpected i2c status %04x\n", status));
261276e49a01a7e6c4a7bfb78618cf2f5befbf9f5deOliver Endriss		}
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != (status & SAA7146_I2C_SPERR) ) {
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("error due to invalid start/stop condition.\n"));
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != (status & SAA7146_I2C_DTERR) ) {
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("error in data transmission.\n"));
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != (status & SAA7146_I2C_DRERR) ) {
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("error when receiving data.\n"));
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != (status & SAA7146_I2C_AL) ) {
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("error because arbitration lost.\n"));
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* we handle address-errors here */
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != (status & SAA7146_I2C_APERR) ) {
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("error in address phase.\n"));
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return -EREMOTEIO;
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EIO;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* read back data, just in case we were reading ... */
285a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro	*dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER));
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DEB_I2C(("after: 0x%08x\n",*dword));
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
29136c15f8ee41fbc3d8eaf88bba95be3d50268d5d2Oliver Endrissstatic int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i = 0, count = 0;
294a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro	__le32 *buffer = dev->d_i2c.cpu_addr;
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err = 0;
296afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab	int short_delay = 0;
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2983593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar	if (mutex_lock_interruptible(&dev->i2c_lock))
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ERESTARTSYS;
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for(i=0;i<num;i++) {
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DEB_I2C(("msg:%d/%d\n",i+1,num));
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* prepare the message(s), get number of u32s to transfer */
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	count = saa7146_i2c_msg_prepare(msgs, num, buffer);
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( 0 > count ) {
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = -1;
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) )
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		short_delay = 1;
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* reset the i2c-device if necessary */
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = saa7146_i2c_reset(dev);
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if ( 0 > err ) {
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			DEB_I2C(("could not reset i2c-device.\n"));
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto out;
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* write out the u32s one after another */
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for(i = 0; i < count; i++) {
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if ( 0 != err) {
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				/* this one is unsatisfying: some i2c slaves on some
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   dvb cards don't acknowledge correctly, so the saa7146
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   thinks that an address error occured. in that case, the
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   transaction should be retrying, even if an address error
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   occured. analog saa7146 based cards extensively rely on
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   i2c address probing, however, and address errors indicate that a
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   device is really *not* there. retrying in that case
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   increases the time the device needs to probe greatly, so
335632fe9fe440249642845675d97436c667cbbd21eOliver Endriss				   it should be avoided. So we bail out in irq mode after an
336632fe9fe440249642845675d97436c667cbbd21eOliver Endriss				   address error and trust the saa7146 address error detection. */
337632fe9fe440249642845675d97436c667cbbd21eOliver Endriss				if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags))
338632fe9fe440249642845675d97436c667cbbd21eOliver Endriss					goto out;
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				DEB_I2C(("error while sending message(s). starting again.\n"));
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				break;
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 == err ) {
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			err = num;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			break;
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
348afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab		/* delay a bit before retrying */
349afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab		msleep(10);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (err != num && retries--);
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
353632fe9fe440249642845675d97436c667cbbd21eOliver Endriss	/* quit if any error occurred */
354632fe9fe440249642845675d97436c667cbbd21eOliver Endriss	if (err != num)
355afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab		goto out;
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* if any things had to be read, get the results */
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		DEB_I2C(("could not cleanup i2c-message.\n"));
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		err = -1;
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto out;
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* return the number of delivered messages */
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DEB_I2C(("transmission successful. (msg:%d).\n",err));
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout:
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* another bug in revision 0: the i2c-registers get uploaded randomly by other
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	   uploads, so we better clear them out before continueing */
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if( 0 == dev->revision ) {
370a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0faeAl Viro		__le32 zero = 0;
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		saa7146_i2c_reset(dev);
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			INFO(("revision 0 error. this should never happen.\n"));
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3773593cab5d62c4c7abced1076710f9bc2d8847433Ingo Molnar	mutex_unlock(&dev->i2c_lock);
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return err;
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* utility functions */
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
38445d809431daaa3ab01f877388d09676d05b469beHans Verkuil	struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
38545d809431daaa3ab01f877388d09676d05b469beHans Verkuil	struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* use helper function to transfer data */
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* i2c-adapter helper functions                                              */
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c-id.h>
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* exported algorithm data */
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct i2c_algorithm saa7146_algo = {
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.master_xfer	= saa7146_i2c_xfer,
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.functionality	= saa7146_i2c_func,
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate)
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	DEB_EE(("bitrate: 0x%08x\n",bitrate));
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* enable i2c-port pins */
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	saa7146_write(dev, MC1, (MASK_08 | MASK_24));
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	dev->i2c_bitrate = bitrate;
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	saa7146_i2c_reset(dev);
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
412d30e21ddcdc948ecedfb46a0ed021d57f310a6f3Hans Verkuil	if (i2c_adapter) {
41345d809431daaa3ab01f877388d09676d05b469beHans Verkuil		i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
4141ac2854cbc637de7e958cfa8d153ccf9e6668ddaPhilipp Matthias Hahn		i2c_adapter->dev.parent    = &dev->pci->dev;
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i2c_adapter->algo	   = &saa7146_algo;
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i2c_adapter->algo_data     = NULL;
4171684a984303abbfc39aa8b59b0fe825c717811a9Jean Delvare		i2c_adapter->id		   = I2C_HW_SAA7146;
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		i2c_adapter->retries = SAA7146_I2C_RETRIES;
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
424