saa7146_i2c.c revision afd1a0c9ac281eed3b22b293ccd92af7b0d60889
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. */ 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *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 */ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(op,0,sizeof(u32)*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; 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] |= ( (u8)addr << ((3-h2)*8)); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] |= (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; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] |= ( (u32)((u8)m[i].buf[j]) << ((3-h2)*8)); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] |= ( 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; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( SAA7146_I2C_CONT == (0x3 & (op[h1] >> ((3-h2)*2))) ) { 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] &= ~(0x2 << ((3-h2)*2)); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds op[h1] |= (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. */ 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *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 */ 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m[i].buf[j] = (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) */ 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* 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); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, I2C_TRANSFER, *dword); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->i2c_op = 1; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SAA7146_IER_ENABLE(dev, MASK_16|MASK_17); 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, MC2, (MASK_00 | MASK_16)); 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wait_event_interruptible(dev->i2c_wq, dev->i2c_op == 0); 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (signal_pending (current)) { 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* a signal arrived */ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ERESTARTSYS; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = saa7146_read(dev, I2C_STATUS); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, I2C_TRANSFER, *dword); 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, MC2, (MASK_00 | MASK_16)); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* do not poll for i2c-status before upload is complete */ 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timeout = jiffies + HZ/100 + 1; /* 10ms */ 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(1) { 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mc2 = (saa7146_read(dev, MC2) & 0x1); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != mc2 ) { 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (time_after(jiffies,timeout)) { 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING "saa7146_i2c_writeout: timed out waiting for MC2\n"); 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait until we get a transfer done or error */ 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds timeout = jiffies + HZ/100 + 1; /* 10ms */ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(1) { 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /** 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * first read usually delivers bogus results... 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_i2c_status(dev); 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds status = saa7146_i2c_status(dev); 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((status & 0x3) != 1) 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (time_after(jiffies,timeout)) { 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is normal when probing the bus 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (no answer from nonexisistant device...) 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("saa7146_i2c_writeout: timed out waiting for end of xfer\n")); 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((++trial < 20) && short_delay) 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(10); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(1); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* give a detailed status report */ 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( 0 != (status & SAA7146_I2C_ERR)) { 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (status & SAA7146_I2C_SPERR) ) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error due to invalid start/stop condition.\n")); 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (status & SAA7146_I2C_DTERR) ) { 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error in data transmission.\n")); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (status & SAA7146_I2C_DRERR) ) { 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error when receiving data.\n")); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (status & SAA7146_I2C_AL) ) { 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error because arbitration lost.\n")); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we handle address-errors here */ 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (status & SAA7146_I2C_APERR) ) { 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error in address phase.\n")); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EREMOTEIO; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* read back data, just in case we were reading ... */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *dword = saa7146_read(dev, I2C_TRANSFER); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("after: 0x%08x\n",*dword)); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0, count = 0; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32* buffer = dev->d_i2c.cpu_addr; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err = 0; 279afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab int address_err = 0; 280afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab int short_delay = 0; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (down_interruptible (&dev->i2c_lock)) 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ERESTARTSYS; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i=0;i<num;i++) { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("msg:%d/%d\n",i+1,num)); 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* prepare the message(s), get number of u32s to transfer */ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = saa7146_i2c_msg_prepare(msgs, num, buffer); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( 0 > count ) { 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -1; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) ) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds short_delay = 1; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* reset the i2c-device if necessary */ 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = saa7146_i2c_reset(dev); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( 0 > err ) { 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("could not reset i2c-device.\n")); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* write out the u32s one after another */ 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < count; i++) { 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = saa7146_i2c_writeout(dev, &buffer[i], short_delay); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( 0 != err) { 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this one is unsatisfying: some i2c slaves on some 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dvb cards don't acknowledge correctly, so the saa7146 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds thinks that an address error occured. in that case, the 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds transaction should be retrying, even if an address error 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds occured. analog saa7146 based cards extensively rely on 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c address probing, however, and address errors indicate that a 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds device is really *not* there. retrying in that case 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds increases the time the device needs to probe greatly, so 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it should be avoided. because of the fact, that only 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds analog based cards use irq based i2c transactions (for dvb 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cards, this screwes up other interrupt sources), we bail out 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds completely for analog cards after an address error and trust 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the saa7146 address error detection. */ 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( -EREMOTEIO == err ) { 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 328afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab address_err++; 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("error while sending message(s). starting again.\n")); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 == err ) { 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = num; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 339afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab /* delay a bit before retrying */ 340afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab msleep(10); 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (err != num && retries--); 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 344afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab /* if every retry had an address error, exit right away */ 345afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab if (address_err == retries) { 346afd1a0c9ac281eed3b22b293ccd92af7b0d60889Mauro Carvalho Chehab goto out; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* if any things had to be read, get the results */ 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) { 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("could not cleanup i2c-message.\n")); 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = -1; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* return the number of delivered messages */ 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_I2C(("transmission successful. (msg:%d).\n",err)); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* another bug in revision 0: the i2c-registers get uploaded randomly by other 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uploads, so we better clear them out before continueing */ 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 == dev->revision ) { 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 zero = 0; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_i2c_reset(dev); 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) { 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds INFO(("revision 0 error. this should never happen.\n")); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds up(&dev->i2c_lock); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* utility functions */ 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct saa7146_dev* dev = i2c_get_adapdata(adapter); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* use helper function to transfer data */ 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return saa7146_i2c_transfer(dev, msg, num, adapter->retries); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*****************************************************************************/ 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* i2c-adapter helper functions */ 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c-id.h> 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* exported algorithm data */ 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct i2c_algorithm saa7146_algo = { 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .master_xfer = saa7146_i2c_xfer, 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .functionality = saa7146_i2c_func, 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate) 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEB_EE(("bitrate: 0x%08x\n",bitrate)); 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* enable i2c-port pins */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, MC1, (MASK_08 | MASK_24)); 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->i2c_bitrate = bitrate; 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_i2c_reset(dev); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( NULL != i2c_adapter ) { 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds BUG_ON(!i2c_adapter->class); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_set_adapdata(i2c_adapter,dev); 4061ac2854cbc637de7e958cfa8d153ccf9e6668ddaPhilipp Matthias Hahn i2c_adapter->dev.parent = &dev->pci->dev; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_adapter->algo = &saa7146_algo; 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_adapter->algo_data = NULL; 4091684a984303abbfc39aa8b59b0fe825c717811a9Jean Delvare i2c_adapter->id = I2C_HW_SAA7146; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_adapter->timeout = SAA7146_I2C_TIMEOUT; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_adapter->retries = SAA7146_I2C_RETRIES; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 416