Commit e9287bd2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull i2c updates from Wolfram Sang:
 "Usual driver bugfixes for the I2C subsystem"

* 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: algo: pca: Reapply i2c bus settings after reset
  i2c: npcm7xx: Fix timeout calculation
  misc: eeprom: at24: register nvmem only after eeprom is ready to use
parents 566e24ee 0a355aeb
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -41,8 +41,22 @@ static void pca_reset(struct i2c_algo_pca_data *adap)
		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
		pca_outw(adap, I2C_PCA_IND, 0xA5);
		pca_outw(adap, I2C_PCA_IND, 0x5A);

		/*
		 * After a reset we need to re-apply any configuration
		 * (calculated in pca_init) to get the bus in a working state.
		 */
		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IMODE);
		pca_outw(adap, I2C_PCA_IND, adap->bus_settings.mode);
		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
		pca_outw(adap, I2C_PCA_IND, adap->bus_settings.tlow);
		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
		pca_outw(adap, I2C_PCA_IND, adap->bus_settings.thi);

		pca_set_con(adap, I2C_PCA_CON_ENSIO);
	} else {
		adap->reset_chip(adap->data);
		pca_set_con(adap, I2C_PCA_CON_ENSIO | adap->bus_settings.clock_freq);
	}
}

@@ -423,13 +437,14 @@ static int pca_init(struct i2c_adapter *adap)
				" Use the nominal frequency.\n", adap->name);
		}

		pca_reset(pca_data);

		clock = pca_clock(pca_data);
		printk(KERN_INFO "%s: Clock frequency is %dkHz\n",
		     adap->name, freqs[clock]);

		pca_set_con(pca_data, I2C_PCA_CON_ENSIO | clock);
		/* Store settings as these will be needed when the PCA chip is reset */
		pca_data->bus_settings.clock_freq = clock;

		pca_reset(pca_data);
	} else {
		int clock;
		int mode;
@@ -496,19 +511,15 @@ static int pca_init(struct i2c_adapter *adap)
			thi = tlow * min_thi / min_tlow;
		}

		/* Store settings as these will be needed when the PCA chip is reset */
		pca_data->bus_settings.mode = mode;
		pca_data->bus_settings.tlow = tlow;
		pca_data->bus_settings.thi = thi;

		pca_reset(pca_data);

		printk(KERN_INFO
		     "%s: Clock frequency is %dHz\n", adap->name, clock * 100);

		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IMODE);
		pca_outw(pca_data, I2C_PCA_IND, mode);
		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLL);
		pca_outw(pca_data, I2C_PCA_IND, tlow);
		pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_ISCLH);
		pca_outw(pca_data, I2C_PCA_IND, thi);

		pca_set_con(pca_data, I2C_PCA_CON_ENSIO);
	}
	udelay(500); /* 500 us for oscillator to stabilise */

+6 −2
Original line number Diff line number Diff line
@@ -2093,8 +2093,12 @@ static int npcm_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
		}
	}

	/* Adaptive TimeOut: astimated time in usec + 100% margin */
	timeout_usec = (2 * 10000 / bus->bus_freq) * (2 + nread + nwrite);
	/*
	 * Adaptive TimeOut: estimated time in usec + 100% margin:
	 * 2: double the timeout for clock stretching case
	 * 9: bits per transaction (including the ack/nack)
	 */
	timeout_usec = (2 * 9 * USEC_PER_SEC / bus->bus_freq) * (2 + nread + nwrite);
	timeout = max(msecs_to_jiffies(35), usecs_to_jiffies(timeout_usec));
	if (nwrite >= 32 * 1024 || nread >= 32 * 1024) {
		dev_err(bus->dev, "i2c%d buffer too big\n", bus->num);
+7 −4
Original line number Diff line number Diff line
@@ -692,10 +692,6 @@ static int at24_probe(struct i2c_client *client)
	nvmem_config.word_size = 1;
	nvmem_config.size = byte_len;

	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
	if (IS_ERR(at24->nvmem))
		return PTR_ERR(at24->nvmem);

	i2c_set_clientdata(client, at24);

	err = regulator_enable(at24->vcc_reg);
@@ -708,6 +704,13 @@ static int at24_probe(struct i2c_client *client)
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
	if (IS_ERR(at24->nvmem)) {
		pm_runtime_disable(dev);
		regulator_disable(at24->vcc_reg);
		return PTR_ERR(at24->nvmem);
	}

	/*
	 * Perform a one-byte test read to verify that the
	 * chip is functional.
+15 −0
Original line number Diff line number Diff line
@@ -53,6 +53,20 @@
#define I2C_PCA_CON_SI		0x08 /* Serial Interrupt */
#define I2C_PCA_CON_CR		0x07 /* Clock Rate (MASK) */

/**
 * struct pca_i2c_bus_settings - The configured PCA i2c bus settings
 * @mode: Configured i2c bus mode
 * @tlow: Configured SCL LOW period
 * @thi: Configured SCL HIGH period
 * @clock_freq: The configured clock frequency
 */
struct pca_i2c_bus_settings {
	int mode;
	int tlow;
	int thi;
	int clock_freq;
};

struct i2c_algo_pca_data {
	void 				*data;	/* private low level data */
	void (*write_byte)		(void *data, int reg, int val);
@@ -64,6 +78,7 @@ struct i2c_algo_pca_data {
	 * For PCA9665, use the frequency you want here. */
	unsigned int			i2c_clock;
	unsigned int			chip;
	struct pca_i2c_bus_settings		bus_settings;
};

int i2c_pca_add_bus(struct i2c_adapter *);