aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-14 20:36:54 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-06-14 20:36:54 -0400
commit7dafd239ab522d38979ebe44d79aa68ad7b1a383 (patch)
tree04754a0c6495e57c1fe5f417fbfc99272d353c0e /drivers/i2c/busses
parentbc47ab0241c7c86da4f5e5f82fbca7d45387c18d (diff)
parent45e3e1935e2857c54783291107d33323b3ef33c8 (diff)
Merge commit 'origin/master' into next
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c59
-rw-r--r--drivers/i2c/busses/i2c-ocores.c5
-rw-r--r--drivers/i2c/busses/i2c-omap.c39
-rw-r--r--drivers/i2c/busses/i2c-pxa.c22
-rw-r--r--drivers/i2c/busses/i2c-s3c2410.c48
6 files changed, 118 insertions, 57 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index f1c6ca7e2852..c8460fa9cfac 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -298,7 +298,7 @@ config I2C_BLACKFIN_TWI
298config I2C_BLACKFIN_TWI_CLK_KHZ 298config I2C_BLACKFIN_TWI_CLK_KHZ
299 int "Blackfin TWI I2C clock (kHz)" 299 int "Blackfin TWI I2C clock (kHz)"
300 depends on I2C_BLACKFIN_TWI 300 depends on I2C_BLACKFIN_TWI
301 range 10 400 301 range 21 400
302 default 50 302 default 50
303 help 303 help
304 The unit of the TWI clock is kHz. 304 The unit of the TWI clock is kHz.
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index fc548b3d002e..26d8987e69bf 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -104,9 +104,14 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
104 write_MASTER_CTL(iface, 104 write_MASTER_CTL(iface,
105 read_MASTER_CTL(iface) | STOP); 105 read_MASTER_CTL(iface) | STOP);
106 else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && 106 else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
107 iface->cur_msg+1 < iface->msg_num) 107 iface->cur_msg + 1 < iface->msg_num) {
108 write_MASTER_CTL(iface, 108 if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
109 read_MASTER_CTL(iface) | RSTART); 109 write_MASTER_CTL(iface,
110 read_MASTER_CTL(iface) | RSTART | MDIR);
111 else
112 write_MASTER_CTL(iface,
113 (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
114 }
110 SSYNC(); 115 SSYNC();
111 /* Clear status */ 116 /* Clear status */
112 write_INT_STAT(iface, XMTSERV); 117 write_INT_STAT(iface, XMTSERV);
@@ -134,9 +139,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
134 read_MASTER_CTL(iface) | STOP); 139 read_MASTER_CTL(iface) | STOP);
135 SSYNC(); 140 SSYNC();
136 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && 141 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
137 iface->cur_msg+1 < iface->msg_num) { 142 iface->cur_msg + 1 < iface->msg_num) {
138 write_MASTER_CTL(iface, 143 if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)
139 read_MASTER_CTL(iface) | RSTART); 144 write_MASTER_CTL(iface,
145 read_MASTER_CTL(iface) | RSTART | MDIR);
146 else
147 write_MASTER_CTL(iface,
148 (read_MASTER_CTL(iface) | RSTART) & ~MDIR);
140 SSYNC(); 149 SSYNC();
141 } 150 }
142 /* Clear interrupt source */ 151 /* Clear interrupt source */
@@ -196,8 +205,6 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
196 /* remove restart bit and enable master receive */ 205 /* remove restart bit and enable master receive */
197 write_MASTER_CTL(iface, 206 write_MASTER_CTL(iface,
198 read_MASTER_CTL(iface) & ~RSTART); 207 read_MASTER_CTL(iface) & ~RSTART);
199 write_MASTER_CTL(iface,
200 read_MASTER_CTL(iface) | MEN | MDIR);
201 SSYNC(); 208 SSYNC();
202 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT && 209 } else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&
203 iface->cur_msg+1 < iface->msg_num) { 210 iface->cur_msg+1 < iface->msg_num) {
@@ -222,18 +229,19 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface)
222 } 229 }
223 230
224 if (iface->pmsg[iface->cur_msg].len <= 255) 231 if (iface->pmsg[iface->cur_msg].len <= 255)
225 write_MASTER_CTL(iface, 232 write_MASTER_CTL(iface,
226 iface->pmsg[iface->cur_msg].len << 6); 233 (read_MASTER_CTL(iface) &
234 (~(0xff << 6))) |
235 (iface->pmsg[iface->cur_msg].len << 6));
227 else { 236 else {
228 write_MASTER_CTL(iface, 0xff << 6); 237 write_MASTER_CTL(iface,
238 (read_MASTER_CTL(iface) |
239 (0xff << 6)));
229 iface->manual_stop = 1; 240 iface->manual_stop = 1;
230 } 241 }
231 /* remove restart bit and enable master receive */ 242 /* remove restart bit and enable master receive */
232 write_MASTER_CTL(iface, 243 write_MASTER_CTL(iface,
233 read_MASTER_CTL(iface) & ~RSTART); 244 read_MASTER_CTL(iface) & ~RSTART);
234 write_MASTER_CTL(iface, read_MASTER_CTL(iface) |
235 MEN | ((iface->read_write == I2C_SMBUS_READ) ?
236 MDIR : 0));
237 SSYNC(); 245 SSYNC();
238 } else { 246 } else {
239 iface->result = 1; 247 iface->result = 1;
@@ -441,6 +449,16 @@ int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,
441 } 449 }
442 iface->transPtr = data->block; 450 iface->transPtr = data->block;
443 break; 451 break;
452 case I2C_SMBUS_I2C_BLOCK_DATA:
453 if (read_write == I2C_SMBUS_READ) {
454 iface->readNum = data->block[0];
455 iface->cur_mode = TWI_I2C_MODE_COMBINED;
456 } else {
457 iface->writeNum = data->block[0];
458 iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;
459 }
460 iface->transPtr = (u8 *)&data->block[1];
461 break;
444 default: 462 default:
445 return -1; 463 return -1;
446 } 464 }
@@ -564,7 +582,7 @@ static u32 bfin_twi_functionality(struct i2c_adapter *adap)
564 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 582 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
565 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 583 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
566 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL | 584 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
567 I2C_FUNC_I2C; 585 I2C_FUNC_I2C | I2C_FUNC_SMBUS_I2C_BLOCK;
568} 586}
569 587
570static struct i2c_algorithm bfin_twi_algorithm = { 588static struct i2c_algorithm bfin_twi_algorithm = {
@@ -614,6 +632,7 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
614 struct i2c_adapter *p_adap; 632 struct i2c_adapter *p_adap;
615 struct resource *res; 633 struct resource *res;
616 int rc; 634 int rc;
635 unsigned int clkhilow;
617 636
618 iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL); 637 iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);
619 if (!iface) { 638 if (!iface) {
@@ -675,10 +694,14 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
675 /* Set TWI internal clock as 10MHz */ 694 /* Set TWI internal clock as 10MHz */
676 write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); 695 write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F);
677 696
697 /*
698 * We will not end up with a CLKDIV=0 because no one will specify
699 * 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100)
700 */
701 clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ;
702
678 /* Set Twi interface clock as specified */ 703 /* Set Twi interface clock as specified */
679 write_CLKDIV(iface, ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) 704 write_CLKDIV(iface, (clkhilow << 8) | clkhilow);
680 << 8) | ((5*1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ)
681 & 0xFF));
682 705
683 /* Enable TWI */ 706 /* Enable TWI */
684 write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA); 707 write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index e5193bf75483..3542c6ba98f1 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -216,6 +216,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
216 struct ocores_i2c_platform_data *pdata; 216 struct ocores_i2c_platform_data *pdata;
217 struct resource *res, *res2; 217 struct resource *res, *res2;
218 int ret; 218 int ret;
219 int i;
219 220
220 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 221 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
221 if (!res) 222 if (!res)
@@ -271,6 +272,10 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
271 goto add_adapter_failed; 272 goto add_adapter_failed;
272 } 273 }
273 274
275 /* add in known devices to the bus */
276 for (i = 0; i < pdata->num_devices; i++)
277 i2c_new_device(&i2c->adap, pdata->devices + i);
278
274 return 0; 279 return 0;
275 280
276add_adapter_failed: 281add_adapter_failed:
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ece0125a1ee5..c73475dd0fba 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -333,8 +333,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
333 333
334 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 334 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
335 335
336 /* HSI2C controller internal clk rate should be 19.2 Mhz */ 336 /*
337 internal_clk = 19200; 337 * HSI2C controller internal clk rate should be 19.2 Mhz for
338 * HS and for all modes on 2430. On 34xx we can use lower rate
339 * to get longer filter period for better noise suppression.
340 * The filter is iclk (fclk for HS) period.
341 */
342 if (dev->speed > 400 || cpu_is_omap_2430())
343 internal_clk = 19200;
344 else if (dev->speed > 100)
345 internal_clk = 9600;
346 else
347 internal_clk = 4000;
338 fclk_rate = clk_get_rate(dev->fclk) / 1000; 348 fclk_rate = clk_get_rate(dev->fclk) / 1000;
339 349
340 /* Compute prescaler divisor */ 350 /* Compute prescaler divisor */
@@ -343,17 +353,28 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
343 353
344 /* If configured for High Speed */ 354 /* If configured for High Speed */
345 if (dev->speed > 400) { 355 if (dev->speed > 400) {
356 unsigned long scl;
357
346 /* For first phase of HS mode */ 358 /* For first phase of HS mode */
347 fsscll = internal_clk / (400 * 2) - 6; 359 scl = internal_clk / 400;
348 fssclh = internal_clk / (400 * 2) - 6; 360 fsscll = scl - (scl / 3) - 7;
361 fssclh = (scl / 3) - 5;
349 362
350 /* For second phase of HS mode */ 363 /* For second phase of HS mode */
351 hsscll = fclk_rate / (dev->speed * 2) - 6; 364 scl = fclk_rate / dev->speed;
352 hssclh = fclk_rate / (dev->speed * 2) - 6; 365 hsscll = scl - (scl / 3) - 7;
366 hssclh = (scl / 3) - 5;
367 } else if (dev->speed > 100) {
368 unsigned long scl;
369
370 /* Fast mode */
371 scl = internal_clk / dev->speed;
372 fsscll = scl - (scl / 3) - 7;
373 fssclh = (scl / 3) - 5;
353 } else { 374 } else {
354 /* To handle F/S modes */ 375 /* Standard mode */
355 fsscll = internal_clk / (dev->speed * 2) - 6; 376 fsscll = internal_clk / (dev->speed * 2) - 7;
356 fssclh = internal_clk / (dev->speed * 2) - 6; 377 fssclh = internal_clk / (dev->speed * 2) - 5;
357 } 378 }
358 scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll; 379 scll = (hsscll << OMAP_I2C_SCLL_HSSCLL) | fsscll;
359 sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh; 380 sclh = (hssclh << OMAP_I2C_SCLH_HSSCLH) | fssclh;
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index acc7143d9655..035a6c7e59df 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -34,10 +34,24 @@
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36 36
37#include <mach/hardware.h>
38#include <asm/irq.h> 37#include <asm/irq.h>
39#include <asm/io.h> 38#include <asm/io.h>
40#include <mach/i2c.h> 39#include <plat/i2c.h>
40
41/*
42 * I2C register offsets will be shifted 0 or 1 bit left, depending on
43 * different SoCs
44 */
45#define REG_SHIFT_0 (0 << 0)
46#define REG_SHIFT_1 (1 << 0)
47#define REG_SHIFT(d) ((d) & 0x1)
48
49static const struct platform_device_id i2c_pxa_id_table[] = {
50 { "pxa2xx-i2c", REG_SHIFT_1 },
51 { "pxa3xx-pwri2c", REG_SHIFT_0 },
52 { },
53};
54MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
41 55
42/* 56/*
43 * I2C registers and bit definitions 57 * I2C registers and bit definitions
@@ -985,6 +999,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
985 struct pxa_i2c *i2c; 999 struct pxa_i2c *i2c;
986 struct resource *res; 1000 struct resource *res;
987 struct i2c_pxa_platform_data *plat = dev->dev.platform_data; 1001 struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
1002 struct platform_device_id *id = platform_get_device_id(dev);
988 int ret; 1003 int ret;
989 int irq; 1004 int irq;
990 1005
@@ -1028,7 +1043,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
1028 ret = -EIO; 1043 ret = -EIO;
1029 goto eremap; 1044 goto eremap;
1030 } 1045 }
1031 i2c->reg_shift = (cpu_is_pxa3xx() && (dev->id == 1)) ? 0 : 1; 1046 i2c->reg_shift = REG_SHIFT(id->driver_data);
1032 1047
1033 i2c->iobase = res->start; 1048 i2c->iobase = res->start;
1034 i2c->iosize = res_len(res); 1049 i2c->iosize = res_len(res);
@@ -1150,6 +1165,7 @@ static struct platform_driver i2c_pxa_driver = {
1150 .name = "pxa2xx-i2c", 1165 .name = "pxa2xx-i2c",
1151 .owner = THIS_MODULE, 1166 .owner = THIS_MODULE,
1152 }, 1167 },
1168 .id_table = i2c_pxa_id_table,
1153}; 1169};
1154 1170
1155static int __init i2c_adap_pxa_init(void) 1171static int __init i2c_adap_pxa_init(void)
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 1691ef0f1ee1..079a312d36fd 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -51,6 +51,11 @@ enum s3c24xx_i2c_state {
51 STATE_STOP 51 STATE_STOP
52}; 52};
53 53
54enum s3c24xx_i2c_type {
55 TYPE_S3C2410,
56 TYPE_S3C2440,
57};
58
54struct s3c24xx_i2c { 59struct s3c24xx_i2c {
55 spinlock_t lock; 60 spinlock_t lock;
56 wait_queue_head_t wait; 61 wait_queue_head_t wait;
@@ -88,8 +93,10 @@ struct s3c24xx_i2c {
88static inline int s3c24xx_i2c_is2440(struct s3c24xx_i2c *i2c) 93static inline int s3c24xx_i2c_is2440(struct s3c24xx_i2c *i2c)
89{ 94{
90 struct platform_device *pdev = to_platform_device(i2c->dev); 95 struct platform_device *pdev = to_platform_device(i2c->dev);
96 enum s3c24xx_i2c_type type;
91 97
92 return !strcmp(pdev->name, "s3c2440-i2c"); 98 type = platform_get_device_id(pdev)->driver_data;
99 return type == TYPE_S3C2440;
93} 100}
94 101
95/* s3c24xx_i2c_master_complete 102/* s3c24xx_i2c_master_complete
@@ -969,52 +976,41 @@ static int s3c24xx_i2c_resume(struct platform_device *dev)
969 976
970/* device driver for platform bus bits */ 977/* device driver for platform bus bits */
971 978
972static struct platform_driver s3c2410_i2c_driver = { 979static struct platform_device_id s3c24xx_driver_ids[] = {
973 .probe = s3c24xx_i2c_probe, 980 {
974 .remove = s3c24xx_i2c_remove, 981 .name = "s3c2410-i2c",
975 .suspend_late = s3c24xx_i2c_suspend_late, 982 .driver_data = TYPE_S3C2410,
976 .resume = s3c24xx_i2c_resume, 983 }, {
977 .driver = { 984 .name = "s3c2440-i2c",
978 .owner = THIS_MODULE, 985 .driver_data = TYPE_S3C2440,
979 .name = "s3c2410-i2c", 986 }, { },
980 },
981}; 987};
988MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
982 989
983static struct platform_driver s3c2440_i2c_driver = { 990static struct platform_driver s3c24xx_i2c_driver = {
984 .probe = s3c24xx_i2c_probe, 991 .probe = s3c24xx_i2c_probe,
985 .remove = s3c24xx_i2c_remove, 992 .remove = s3c24xx_i2c_remove,
986 .suspend_late = s3c24xx_i2c_suspend_late, 993 .suspend_late = s3c24xx_i2c_suspend_late,
987 .resume = s3c24xx_i2c_resume, 994 .resume = s3c24xx_i2c_resume,
995 .id_table = s3c24xx_driver_ids,
988 .driver = { 996 .driver = {
989 .owner = THIS_MODULE, 997 .owner = THIS_MODULE,
990 .name = "s3c2440-i2c", 998 .name = "s3c-i2c",
991 }, 999 },
992}; 1000};
993 1001
994static int __init i2c_adap_s3c_init(void) 1002static int __init i2c_adap_s3c_init(void)
995{ 1003{
996 int ret; 1004 return platform_driver_register(&s3c24xx_i2c_driver);
997
998 ret = platform_driver_register(&s3c2410_i2c_driver);
999 if (ret == 0) {
1000 ret = platform_driver_register(&s3c2440_i2c_driver);
1001 if (ret)
1002 platform_driver_unregister(&s3c2410_i2c_driver);
1003 }
1004
1005 return ret;
1006} 1005}
1007subsys_initcall(i2c_adap_s3c_init); 1006subsys_initcall(i2c_adap_s3c_init);
1008 1007
1009static void __exit i2c_adap_s3c_exit(void) 1008static void __exit i2c_adap_s3c_exit(void)
1010{ 1009{
1011 platform_driver_unregister(&s3c2410_i2c_driver); 1010 platform_driver_unregister(&s3c24xx_i2c_driver);
1012 platform_driver_unregister(&s3c2440_i2c_driver);
1013} 1011}
1014module_exit(i2c_adap_s3c_exit); 1012module_exit(i2c_adap_s3c_exit);
1015 1013
1016MODULE_DESCRIPTION("S3C24XX I2C Bus driver"); 1014MODULE_DESCRIPTION("S3C24XX I2C Bus driver");
1017MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 1015MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
1018MODULE_LICENSE("GPL"); 1016MODULE_LICENSE("GPL");
1019MODULE_ALIAS("platform:s3c2410-i2c");
1020MODULE_ALIAS("platform:s3c2440-i2c");