diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/i2c-davinci.c | 26 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 60 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-s3c2410.c | 5 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-sh_mobile.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-simtec.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-stu300.c | 155 | ||||
| -rw-r--r-- | drivers/i2c/chips/tsl2550.c | 17 | 
8 files changed, 175 insertions, 103 deletions
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 3fae3a91ce5..c89687a1083 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c @@ -187,6 +187,11 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)  	davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);  	davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); +	/* Respond at reserved "SMBus Host" slave address" (and zero); +	 * we seem to have no option to not respond... +	 */ +	davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); +  	dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);  	dev_dbg(dev->dev, "PSC  = %d\n",  		davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); @@ -387,7 +392,7 @@ static void terminate_write(struct davinci_i2c_dev *dev)  	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);  	if (!dev->terminate) -		dev_err(dev->dev, "TDR IRQ while no data to send\n"); +		dev_dbg(dev->dev, "TDR IRQ while no data to send\n");  }  /* @@ -473,9 +478,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)  			break;  		case DAVINCI_I2C_IVR_AAS: -			dev_warn(dev->dev, "Address as slave interrupt\n"); -		}/* switch */ -	}/* while */ +			dev_dbg(dev->dev, "Address as slave interrupt\n"); +			break; + +		default: +			dev_warn(dev->dev, "Unrecognized irq stat %d\n", stat); +			break; +		} +	}  	return count ? IRQ_HANDLED : IRQ_NONE;  } @@ -505,7 +515,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  		return -ENODEV;  	} -	ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, +	ioarea = request_mem_region(mem->start, resource_size(mem),  				    pdev->name);  	if (!ioarea) {  		dev_err(&pdev->dev, "I2C region already claimed\n"); @@ -523,7 +533,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)  	dev->irq = irq->start;  	platform_set_drvdata(pdev, dev); -	dev->clk = clk_get(&pdev->dev, "I2CCLK"); +	dev->clk = clk_get(&pdev->dev, NULL);  	if (IS_ERR(dev->clk)) {  		r = -ENODEV;  		goto err_free_mem; @@ -568,7 +578,7 @@ err_free_mem:  	put_device(&pdev->dev);  	kfree(dev);  err_release_region: -	release_mem_region(mem->start, (mem->end - mem->start) + 1); +	release_mem_region(mem->start, resource_size(mem));  	return r;  } @@ -591,7 +601,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)  	kfree(dev);  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, (mem->end - mem->start) + 1); +	release_mem_region(mem->start, resource_size(mem));  	return 0;  } diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index e4476743f20..b1bc6e277d2 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -85,10 +85,11 @@ static void dump_iic_regs(const char* header, struct ibm_iic_private* dev)  {  	volatile struct iic_regs __iomem *iic = dev->vaddr;  	printk(KERN_DEBUG "ibm-iic%d: %s\n", dev->idx, header); -	printk(KERN_DEBUG "  cntl     = 0x%02x, mdcntl = 0x%02x\n" -	       KERN_DEBUG "  sts      = 0x%02x, extsts = 0x%02x\n" -	       KERN_DEBUG "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n" -	       KERN_DEBUG "  xtcntlss = 0x%02x, directcntl = 0x%02x\n", +	printk(KERN_DEBUG +	       "  cntl     = 0x%02x, mdcntl = 0x%02x\n" +	       "  sts      = 0x%02x, extsts = 0x%02x\n" +	       "  clkdiv   = 0x%02x, xfrcnt = 0x%02x\n" +	       "  xtcntlss = 0x%02x, directcntl = 0x%02x\n",  		in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts),  		in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt),  		in_8(&iic->xtcntlss), in_8(&iic->directcntl)); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index ad8d2010c92..827da085813 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -672,9 +672,17 @@ omap_i2c_isr(int this_irq, void *dev_id)  			break;  		} -		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat); -  		err = 0; +complete: +		/* +		 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be +		 * acked after the data operation is complete. +		 * Ref: TRM SWPU114Q Figure 18-31 +		 */ +		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat & +				~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | +				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); +  		if (stat & OMAP_I2C_STAT_NACK) {  			err |= OMAP_I2C_STAT_NACK;  			omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -685,16 +693,22 @@ omap_i2c_isr(int this_irq, void *dev_id)  			err |= OMAP_I2C_STAT_AL;  		}  		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | -					OMAP_I2C_STAT_AL)) +					OMAP_I2C_STAT_AL)) { +			omap_i2c_ack_stat(dev, stat & +				(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | +				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));  			omap_i2c_complete_cmd(dev, err); +			return IRQ_HANDLED; +		}  		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {  			u8 num_bytes = 1;  			if (dev->fifo_size) {  				if (stat & OMAP_I2C_STAT_RRDY)  					num_bytes = dev->fifo_size; -				else -					num_bytes = omap_i2c_read_reg(dev, -							OMAP_I2C_BUFSTAT_REG); +				else    /* read RXSTAT on RDR interrupt */ +					num_bytes = (omap_i2c_read_reg(dev, +							OMAP_I2C_BUFSTAT_REG) +							>> 8) & 0x3F;  			}  			while (num_bytes) {  				num_bytes--; @@ -731,9 +745,10 @@ omap_i2c_isr(int this_irq, void *dev_id)  			if (dev->fifo_size) {  				if (stat & OMAP_I2C_STAT_XRDY)  					num_bytes = dev->fifo_size; -				else +				else    /* read TXSTAT on XDR interrupt */  					num_bytes = omap_i2c_read_reg(dev, -							OMAP_I2C_BUFSTAT_REG); +							OMAP_I2C_BUFSTAT_REG) +							& 0x3F;  			}  			while (num_bytes) {  				num_bytes--; @@ -760,6 +775,27 @@ omap_i2c_isr(int this_irq, void *dev_id)  							"data to send\n");  					break;  				} + +				/* +				 * OMAP3430 Errata 1.153: When an XRDY/XDR +				 * is hit, wait for XUDF before writing data +				 * to DATA_REG. Otherwise some data bytes can +				 * be lost while transferring them from the +				 * memory to the I2C interface. +				 */ + +				if (dev->rev <= OMAP_I2C_REV_ON_3430) { +						while (!(stat & OMAP_I2C_STAT_XUDF)) { +							if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { +								omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); +								err |= OMAP_I2C_STAT_XUDF; +								goto complete; +							} +							cpu_relax(); +							stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); +						} +				} +  				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);  			}  			omap_i2c_ack_stat(dev, @@ -806,7 +842,7 @@ omap_i2c_probe(struct platform_device *pdev)  		return -ENODEV;  	} -	ioarea = request_mem_region(mem->start, (mem->end - mem->start) + 1, +	ioarea = request_mem_region(mem->start, resource_size(mem),  			pdev->name);  	if (!ioarea) {  		dev_err(&pdev->dev, "I2C region already claimed\n"); @@ -879,7 +915,7 @@ omap_i2c_probe(struct platform_device *pdev)  	i2c_set_adapdata(adap, dev);  	adap->owner = THIS_MODULE;  	adap->class = I2C_CLASS_HWMON; -	strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); +	strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));  	adap->algo = &omap_i2c_algo;  	adap->dev.parent = &pdev->dev; @@ -905,7 +941,7 @@ err_free_mem:  	platform_set_drvdata(pdev, NULL);  	kfree(dev);  err_release_region: -	release_mem_region(mem->start, (mem->end - mem->start) + 1); +	release_mem_region(mem->start, resource_size(mem));  	return r;  } @@ -925,7 +961,7 @@ omap_i2c_remove(struct platform_device *pdev)  	iounmap(dev->base);  	kfree(dev);  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	release_mem_region(mem->start, (mem->end - mem->start) + 1); +	release_mem_region(mem->start, resource_size(mem));  	return 0;  } diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 8f42a4536cd..20bb0ceb027 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -763,11 +763,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)  	dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);  	dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon); -	/* check for s3c2440 i2c controller  */ - -	if (s3c24xx_i2c_is2440(i2c)) -		writel(0x0, i2c->regs + S3C2440_IICLC); -  	return 0;  } diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c index 1c01083b01b..820487d0d5c 100644 --- a/drivers/i2c/busses/i2c-sh_mobile.c +++ b/drivers/i2c/busses/i2c-sh_mobile.c @@ -563,7 +563,7 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)  		goto err_irq;  	} -	size = (res->end - res->start) + 1; +	size = resource_size(res);  	pd->reg = ioremap(res->start, size);  	if (pd->reg == NULL) { @@ -637,7 +637,7 @@ static void __exit sh_mobile_i2c_adap_exit(void)  	platform_driver_unregister(&sh_mobile_i2c_driver);  } -module_init(sh_mobile_i2c_adap_init); +subsys_initcall(sh_mobile_i2c_adap_init);  module_exit(sh_mobile_i2c_adap_exit);  MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver"); diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 042fda295f3..6407f47bda8 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -92,7 +92,7 @@ static int simtec_i2c_probe(struct platform_device *dev)  		goto err;  	} -	size = (res->end-res->start)+1; +	size = resource_size(res);  	pd->ioarea = request_mem_region(res->start, size, dev->name);  	if (pd->ioarea == NULL) { diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 182e711318b..d2728a28a8d 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -117,7 +117,8 @@ enum stu300_error {  	STU300_ERROR_NONE = 0,  	STU300_ERROR_ACKNOWLEDGE_FAILURE,  	STU300_ERROR_BUS_ERROR, -	STU300_ERROR_ARBITRATION_LOST +	STU300_ERROR_ARBITRATION_LOST, +	STU300_ERROR_UNKNOWN  };  /* timeout waiting for the controller to respond */ @@ -127,7 +128,7 @@ enum stu300_error {   * The number of address send athemps tried before giving up.   * If the first one failes it seems like 5 to 8 attempts are required.   */ -#define NUM_ADDR_RESEND_ATTEMPTS 10 +#define NUM_ADDR_RESEND_ATTEMPTS 12  /* I2C clock speed, in Hz 0-400kHz*/  static unsigned int scl_frequency = 100000; @@ -149,6 +150,7 @@ module_param(scl_frequency, uint,  0644);   * @msg_index: index of current message   * @msg_len: length of current message   */ +  struct stu300_dev {  	struct platform_device	*pdev;  	struct i2c_adapter	adapter; @@ -188,6 +190,27 @@ static inline u32 stu300_r8(void __iomem *address)  	return readl(address) & 0x000000FFU;  } +static void stu300_irq_enable(struct stu300_dev *dev) +{ +	u32 val; +	val = stu300_r8(dev->virtbase + I2C_CR); +	val |= I2C_CR_INTERRUPT_ENABLE; +	/* Twice paranoia (possible HW glitch) */ +	stu300_wr8(val, dev->virtbase + I2C_CR); +	stu300_wr8(val, dev->virtbase + I2C_CR); +} + +static void stu300_irq_disable(struct stu300_dev *dev) +{ +	u32 val; +	val = stu300_r8(dev->virtbase + I2C_CR); +	val &= ~I2C_CR_INTERRUPT_ENABLE; +	/* Twice paranoia (possible HW glitch) */ +	stu300_wr8(val, dev->virtbase + I2C_CR); +	stu300_wr8(val, dev->virtbase + I2C_CR); +} + +  /*   * Tells whether a certain event or events occurred in   * response to a command. The events represent states in @@ -196,9 +219,10 @@ static inline u32 stu300_r8(void __iomem *address)   * documentation and can only be treated as abstract state   * machine states.   * - * @ret 0 = event has not occurred, any other value means - * the event occurred. + * @ret 0 = event has not occurred or unknown error, any + * other value means the correct event occurred or an error.   */ +  static int stu300_event_occurred(struct stu300_dev *dev,  				   enum stu300_event mr_event) {  	u32 status1; @@ -206,11 +230,28 @@ static int stu300_event_occurred(struct stu300_dev *dev,  	/* What event happened? */  	status1 = stu300_r8(dev->virtbase + I2C_SR1); +  	if (!(status1 & I2C_SR1_EVF_IND))  		/* No event at all */  		return 0; +  	status2 = stu300_r8(dev->virtbase + I2C_SR2); +	/* Block any multiple interrupts */ +	stu300_irq_disable(dev); + +	/* Check for errors first */ +	if (status2 & I2C_SR2_AF_IND) { +		dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; +		return 1; +	} else if (status2 & I2C_SR2_BERR_IND) { +		dev->cmd_err = STU300_ERROR_BUS_ERROR; +		return 1; +	} else if (status2 & I2C_SR2_ARLO_IND) { +		dev->cmd_err = STU300_ERROR_ARBITRATION_LOST; +		return 1; +	} +  	switch (mr_event) {  	case STU300_EVENT_1:  		if (status1 & I2C_SR1_ADSL_IND) @@ -221,10 +262,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,  	case STU300_EVENT_7:  	case STU300_EVENT_8:  		if (status1 & I2C_SR1_BTF_IND) { -			if (status2 & I2C_SR2_AF_IND) -				dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE; -			else if (status2 & I2C_SR2_BERR_IND) -				dev->cmd_err = STU300_ERROR_BUS_ERROR;  			return 1;  		}  		break; @@ -240,8 +277,6 @@ static int stu300_event_occurred(struct stu300_dev *dev,  	case STU300_EVENT_6:  		if (status2 & I2C_SR2_ENDAD_IND) {  			/* First check for any errors */ -			if (status2 & I2C_SR2_AF_IND) -				dev->cmd_err = STU300_ERROR_ACKNOWLEDGE_FAILURE;  			return 1;  		}  		break; @@ -252,8 +287,15 @@ static int stu300_event_occurred(struct stu300_dev *dev,  	default:  		break;  	} -	if (status2 & I2C_SR2_ARLO_IND) -		dev->cmd_err = STU300_ERROR_ARBITRATION_LOST; +	/* If we get here, we're on thin ice. +	 * Here we are in a status where we have +	 * gotten a response that does not match +	 * what we requested. +	 */ +	dev->cmd_err = STU300_ERROR_UNKNOWN; +	dev_err(&dev->pdev->dev, +		"Unhandled interrupt! %d sr1: 0x%x sr2: 0x%x\n", +		mr_event, status1, status2);  	return 0;  } @@ -262,21 +304,20 @@ static irqreturn_t stu300_irh(int irq, void *data)  	struct stu300_dev *dev = data;  	int res; +	/* Just make sure that the block is clocked */ +	clk_enable(dev->clk); +  	/* See if this was what we were waiting for */  	spin_lock(&dev->cmd_issue_lock); -	if (dev->cmd_event != STU300_EVENT_NONE) { -		res = stu300_event_occurred(dev, dev->cmd_event); -		if (res || dev->cmd_err != STU300_ERROR_NONE) { -			u32 val; -			complete(&dev->cmd_complete); -			/* Block any multiple interrupts */ -			val = stu300_r8(dev->virtbase + I2C_CR); -			val &= ~I2C_CR_INTERRUPT_ENABLE; -			stu300_wr8(val, dev->virtbase + I2C_CR); -		} -	} +	res = stu300_event_occurred(dev, dev->cmd_event); +	if (res || dev->cmd_err != STU300_ERROR_NONE) +		complete(&dev->cmd_complete); +  	spin_unlock(&dev->cmd_issue_lock); + +	clk_disable(dev->clk); +  	return IRQ_HANDLED;  } @@ -308,7 +349,6 @@ static int stu300_start_and_await_event(struct stu300_dev *dev,  	stu300_wr8(cr_value, dev->virtbase + I2C_CR);  	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,  							STU300_TIMEOUT); -  	if (ret < 0) {  		dev_err(&dev->pdev->dev,  		       "wait_for_completion_interruptible_timeout() " @@ -342,7 +382,6 @@ static int stu300_await_event(struct stu300_dev *dev,  				enum stu300_event mr_event)  {  	int ret; -	u32 val;  	if (unlikely(irqs_disabled())) {  		/* TODO: implement polling for this case if need be. */ @@ -354,36 +393,18 @@ static int stu300_await_event(struct stu300_dev *dev,  	/* Is it already here? */  	spin_lock_irq(&dev->cmd_issue_lock);  	dev->cmd_err = STU300_ERROR_NONE; -	if (stu300_event_occurred(dev, mr_event)) { -		spin_unlock_irq(&dev->cmd_issue_lock); -		goto exit_await_check_err; -	} -	init_completion(&dev->cmd_complete); -	dev->cmd_err = STU300_ERROR_NONE;  	dev->cmd_event = mr_event; -	/* Turn on the I2C interrupt for current operation */ -	val = stu300_r8(dev->virtbase + I2C_CR); -	val |= I2C_CR_INTERRUPT_ENABLE; -	stu300_wr8(val, dev->virtbase + I2C_CR); - -	/* Twice paranoia (possible HW glitch) */ -	stu300_wr8(val, dev->virtbase + I2C_CR); +	init_completion(&dev->cmd_complete); -	/* Check again: is it already here? */ -	if (unlikely(stu300_event_occurred(dev, mr_event))) { -		/* Disable IRQ again. */ -		val &= ~I2C_CR_INTERRUPT_ENABLE; -		stu300_wr8(val, dev->virtbase + I2C_CR); -		spin_unlock_irq(&dev->cmd_issue_lock); -		goto exit_await_check_err; -	} +	/* Turn on the I2C interrupt for current operation */ +	stu300_irq_enable(dev);  	/* Unlock the command block and wait for the event to occur */  	spin_unlock_irq(&dev->cmd_issue_lock); +  	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,  							STU300_TIMEOUT); -  	if (ret < 0) {  		dev_err(&dev->pdev->dev,  		       "wait_for_completion_interruptible_timeout()" @@ -401,7 +422,6 @@ static int stu300_await_event(struct stu300_dev *dev,  		return -ETIMEDOUT;  	} - exit_await_check_err:  	if (dev->cmd_err != STU300_ERROR_NONE) {  		if (mr_event != STU300_EVENT_6) {  			dev_err(&dev->pdev->dev, "controller " @@ -457,18 +477,19 @@ struct stu300_clkset {  };  static const struct stu300_clkset stu300_clktable[] = { -	{ 0, 0xFFU }, -	{ 2500000, I2C_OAR2_FR_25_10MHZ }, -	{ 10000000, I2C_OAR2_FR_10_1667MHZ }, -	{ 16670000, I2C_OAR2_FR_1667_2667MHZ }, -	{ 26670000, I2C_OAR2_FR_2667_40MHZ }, -	{ 40000000, I2C_OAR2_FR_40_5333MHZ }, -	{ 53330000, I2C_OAR2_FR_5333_66MHZ }, -	{ 66000000, I2C_OAR2_FR_66_80MHZ }, -	{ 80000000, I2C_OAR2_FR_80_100MHZ }, +	{ 0,         0xFFU }, +	{ 2500000,   I2C_OAR2_FR_25_10MHZ }, +	{ 10000000,  I2C_OAR2_FR_10_1667MHZ }, +	{ 16670000,  I2C_OAR2_FR_1667_2667MHZ }, +	{ 26670000,  I2C_OAR2_FR_2667_40MHZ }, +	{ 40000000,  I2C_OAR2_FR_40_5333MHZ }, +	{ 53330000,  I2C_OAR2_FR_5333_66MHZ }, +	{ 66000000,  I2C_OAR2_FR_66_80MHZ }, +	{ 80000000,  I2C_OAR2_FR_80_100MHZ },  	{ 100000000, 0xFFU },  }; +  static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)  { @@ -494,10 +515,10 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate)  	if (dev->speed > 100000)  		/* Fast Mode I2C */ -		val = ((clkrate/dev->speed)-9)/3; +		val = ((clkrate/dev->speed) - 9)/3 + 1;  	else  		/* Standard Mode I2C */ -		val = ((clkrate/dev->speed)-7)/2; +		val = ((clkrate/dev->speed) - 7)/2 + 1;  	/* According to spec the divider must be > 2 */  	if (val < 0x002) { @@ -557,6 +578,7 @@ static int stu300_init_hw(struct stu300_dev *dev)  	 */  	clkrate = clk_get_rate(dev->clk);  	ret = stu300_set_clk(dev, clkrate); +  	if (ret)  		return ret;  	/* @@ -641,7 +663,6 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,  	int attempts = 0;  	struct stu300_dev *dev = i2c_get_adapdata(adap); -  	clk_enable(dev->clk);  	/* Remove this if (0) to trace each and every message. */ @@ -715,14 +736,15 @@ static int stu300_xfer_msg(struct i2c_adapter *adap,  	if (attempts < NUM_ADDR_RESEND_ATTEMPTS && attempts > 0) {  		dev_dbg(&dev->pdev->dev, "managed to get address " -		       "through after %d attempts\n", attempts); +			"through after %d attempts\n", attempts);  	} else if (attempts == NUM_ADDR_RESEND_ATTEMPTS) {  		dev_dbg(&dev->pdev->dev, "I give up, tried %d times " -		       "to resend address.\n", -		       NUM_ADDR_RESEND_ATTEMPTS); +			"to resend address.\n", +			NUM_ADDR_RESEND_ATTEMPTS);  		goto exit_disable;  	} +  	if (msg->flags & I2C_M_RD) {  		/* READ: we read the actual bytes one at a time */  		for (i = 0; i < msg->len; i++) { @@ -804,8 +826,10 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,  {  	int ret = -1;  	int i; +  	struct stu300_dev *dev = i2c_get_adapdata(adap);  	dev->msg_len = num; +  	for (i = 0; i < num; i++) {  		/*  		 * Another driver appears to send stop for each message, @@ -817,6 +841,7 @@ static int stu300_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,  		dev->msg_index = i;  		ret = stu300_xfer_msg(adap, &msgs[i], (i == (num - 1))); +  		if (ret != 0) {  			num = ret;  			break; @@ -845,6 +870,7 @@ stu300_probe(struct platform_device *pdev)  	struct resource *res;  	int bus_nr;  	int ret = 0; +	char clk_name[] = "I2C0";  	dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL);  	if (!dev) { @@ -854,7 +880,8 @@ stu300_probe(struct platform_device *pdev)  	}  	bus_nr = pdev->id; -	dev->clk = clk_get(&pdev->dev, NULL); +	clk_name[3] += (char)bus_nr; +	dev->clk = clk_get(&pdev->dev, clk_name);  	if (IS_ERR(dev->clk)) {  		ret = PTR_ERR(dev->clk);  		dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index 1a9cc135219..b96f3025e58 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c @@ -27,7 +27,7 @@  #include <linux/delay.h>  #define TSL2550_DRV_NAME	"tsl2550" -#define DRIVER_VERSION		"1.1.1" +#define DRIVER_VERSION		"1.1.2"  /*   * Defines @@ -189,13 +189,16 @@ static int tsl2550_calculate_lux(u8 ch0, u8 ch1)  	u8 r = 128;  	/* Avoid division by 0 and count 1 cannot be greater than count 0 */ -	if (c0 && (c1 <= c0)) -		r = c1 * 128 / c0; -	else -		return -1; +	if (c1 <= c0) +		if (c0) { +			r = c1 * 128 / c0; -	/* Calculate LUX */ -	lux = ((c0 - c1) * ratio_lut[r]) / 256; +			/* Calculate LUX */ +			lux = ((c0 - c1) * ratio_lut[r]) / 256; +		} else +			lux = 0; +	else +		return -EAGAIN;  	/* LUX range check */  	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;  |