diff options
author | Ben Dooks <ben-linux@fluff.org> | 2012-01-17 18:30:41 -0500 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2012-01-17 18:30:41 -0500 |
commit | 6f36a806e588f2ce62571a1859ea1d7f2c7dde83 (patch) | |
tree | 44485aee19bcaf05b0baaf83ea62d7e5ddd78b9c /drivers/i2c | |
parent | 8956dc102ca26357850830f1d26132719c1ce6ee (diff) | |
parent | 6145197be6cc0583fa1a2f4ec1079d366137061e (diff) |
Merge branches 'for-33/i2c/eg20t' and 'for-33/i2c/omap' into for-linus/i2c-33
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 110 |
1 files changed, 70 insertions, 40 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fa23faa20f0e..f713eac55047 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -37,6 +37,9 @@ | |||
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | #include <linux/of.h> | ||
41 | #include <linux/of_i2c.h> | ||
42 | #include <linux/of_device.h> | ||
40 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
41 | #include <linux/i2c-omap.h> | 44 | #include <linux/i2c-omap.h> |
42 | #include <linux/pm_runtime.h> | 45 | #include <linux/pm_runtime.h> |
@@ -182,7 +185,9 @@ struct omap_i2c_dev { | |||
182 | u32 latency; /* maximum mpu wkup latency */ | 185 | u32 latency; /* maximum mpu wkup latency */ |
183 | void (*set_mpu_wkup_lat)(struct device *dev, | 186 | void (*set_mpu_wkup_lat)(struct device *dev, |
184 | long latency); | 187 | long latency); |
185 | u32 speed; /* Speed of bus in Khz */ | 188 | u32 speed; /* Speed of bus in kHz */ |
189 | u32 dtrev; /* extra revision from DT */ | ||
190 | u32 flags; | ||
186 | u16 cmd_err; | 191 | u16 cmd_err; |
187 | u8 *buf; | 192 | u8 *buf; |
188 | u8 *regs; | 193 | u8 *regs; |
@@ -235,7 +240,7 @@ static const u8 reg_map_ip_v2[] = { | |||
235 | [OMAP_I2C_BUF_REG] = 0x94, | 240 | [OMAP_I2C_BUF_REG] = 0x94, |
236 | [OMAP_I2C_CNT_REG] = 0x98, | 241 | [OMAP_I2C_CNT_REG] = 0x98, |
237 | [OMAP_I2C_DATA_REG] = 0x9c, | 242 | [OMAP_I2C_DATA_REG] = 0x9c, |
238 | [OMAP_I2C_SYSC_REG] = 0x20, | 243 | [OMAP_I2C_SYSC_REG] = 0x10, |
239 | [OMAP_I2C_CON_REG] = 0xa4, | 244 | [OMAP_I2C_CON_REG] = 0xa4, |
240 | [OMAP_I2C_OA_REG] = 0xa8, | 245 | [OMAP_I2C_OA_REG] = 0xa8, |
241 | [OMAP_I2C_SA_REG] = 0xac, | 246 | [OMAP_I2C_SA_REG] = 0xac, |
@@ -266,11 +271,7 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) | |||
266 | 271 | ||
267 | static void omap_i2c_unidle(struct omap_i2c_dev *dev) | 272 | static void omap_i2c_unidle(struct omap_i2c_dev *dev) |
268 | { | 273 | { |
269 | struct omap_i2c_bus_platform_data *pdata; | 274 | if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { |
270 | |||
271 | pdata = dev->dev->platform_data; | ||
272 | |||
273 | if (pdata->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { | ||
274 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | 275 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); |
275 | omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); | 276 | omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); |
276 | omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); | 277 | omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate); |
@@ -291,13 +292,10 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) | |||
291 | 292 | ||
292 | static void omap_i2c_idle(struct omap_i2c_dev *dev) | 293 | static void omap_i2c_idle(struct omap_i2c_dev *dev) |
293 | { | 294 | { |
294 | struct omap_i2c_bus_platform_data *pdata; | ||
295 | u16 iv; | 295 | u16 iv; |
296 | 296 | ||
297 | pdata = dev->dev->platform_data; | ||
298 | |||
299 | dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); | 297 | dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); |
300 | if (pdata->rev == OMAP_I2C_IP_VERSION_2) | 298 | if (dev->dtrev == OMAP_I2C_IP_VERSION_2) |
301 | omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1); | 299 | omap_i2c_write_reg(dev, OMAP_I2C_IP_V2_IRQENABLE_CLR, 1); |
302 | else | 300 | else |
303 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); | 301 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); |
@@ -320,9 +318,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
320 | unsigned long timeout; | 318 | unsigned long timeout; |
321 | unsigned long internal_clk = 0; | 319 | unsigned long internal_clk = 0; |
322 | struct clk *fclk; | 320 | struct clk *fclk; |
323 | struct omap_i2c_bus_platform_data *pdata; | ||
324 | |||
325 | pdata = dev->dev->platform_data; | ||
326 | 321 | ||
327 | if (dev->rev >= OMAP_I2C_OMAP1_REV_2) { | 322 | if (dev->rev >= OMAP_I2C_OMAP1_REV_2) { |
328 | /* Disable I2C controller before soft reset */ | 323 | /* Disable I2C controller before soft reset */ |
@@ -373,7 +368,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
373 | } | 368 | } |
374 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); | 369 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); |
375 | 370 | ||
376 | if (pdata->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { | 371 | if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { |
377 | /* | 372 | /* |
378 | * The I2C functional clock is the armxor_ck, so there's | 373 | * The I2C functional clock is the armxor_ck, so there's |
379 | * no need to get "armxor_ck" separately. Now, if OMAP2420 | 374 | * no need to get "armxor_ck" separately. Now, if OMAP2420 |
@@ -397,7 +392,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
397 | psc = fclk_rate / 12000000; | 392 | psc = fclk_rate / 12000000; |
398 | } | 393 | } |
399 | 394 | ||
400 | if (!(pdata->flags & OMAP_I2C_FLAG_SIMPLE_CLOCK)) { | 395 | if (!(dev->flags & OMAP_I2C_FLAG_SIMPLE_CLOCK)) { |
401 | 396 | ||
402 | /* | 397 | /* |
403 | * HSI2C controller internal clk rate should be 19.2 Mhz for | 398 | * HSI2C controller internal clk rate should be 19.2 Mhz for |
@@ -406,7 +401,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
406 | * The filter is iclk (fclk for HS) period. | 401 | * The filter is iclk (fclk for HS) period. |
407 | */ | 402 | */ |
408 | if (dev->speed > 400 || | 403 | if (dev->speed > 400 || |
409 | pdata->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK) | 404 | dev->flags & OMAP_I2C_FLAG_FORCE_19200_INT_CLK) |
410 | internal_clk = 19200; | 405 | internal_clk = 19200; |
411 | else if (dev->speed > 100) | 406 | else if (dev->speed > 100) |
412 | internal_clk = 9600; | 407 | internal_clk = 9600; |
@@ -475,7 +470,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
475 | 470 | ||
476 | dev->errata = 0; | 471 | dev->errata = 0; |
477 | 472 | ||
478 | if (pdata->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207) | 473 | if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207) |
479 | dev->errata |= I2C_OMAP_ERRATA_I207; | 474 | dev->errata |= I2C_OMAP_ERRATA_I207; |
480 | 475 | ||
481 | /* Enable interrupts */ | 476 | /* Enable interrupts */ |
@@ -484,7 +479,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
484 | OMAP_I2C_IE_AL) | ((dev->fifo_size) ? | 479 | OMAP_I2C_IE_AL) | ((dev->fifo_size) ? |
485 | (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); | 480 | (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); |
486 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | 481 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); |
487 | if (pdata->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { | 482 | if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { |
488 | dev->pscstate = psc; | 483 | dev->pscstate = psc; |
489 | dev->scllstate = scll; | 484 | dev->scllstate = scll; |
490 | dev->sclhstate = sclh; | 485 | dev->sclhstate = sclh; |
@@ -804,9 +799,6 @@ omap_i2c_isr(int this_irq, void *dev_id) | |||
804 | u16 bits; | 799 | u16 bits; |
805 | u16 stat, w; | 800 | u16 stat, w; |
806 | int err, count = 0; | 801 | int err, count = 0; |
807 | struct omap_i2c_bus_platform_data *pdata; | ||
808 | |||
809 | pdata = dev->dev->platform_data; | ||
810 | 802 | ||
811 | if (pm_runtime_suspended(dev->dev)) | 803 | if (pm_runtime_suspended(dev->dev)) |
812 | return IRQ_NONE; | 804 | return IRQ_NONE; |
@@ -830,11 +822,9 @@ complete: | |||
830 | ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | | 822 | ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | |
831 | OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); | 823 | OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); |
832 | 824 | ||
833 | if (stat & OMAP_I2C_STAT_NACK) { | 825 | if (stat & OMAP_I2C_STAT_NACK) |
834 | err |= OMAP_I2C_STAT_NACK; | 826 | err |= OMAP_I2C_STAT_NACK; |
835 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, | 827 | |
836 | OMAP_I2C_CON_STP); | ||
837 | } | ||
838 | if (stat & OMAP_I2C_STAT_AL) { | 828 | if (stat & OMAP_I2C_STAT_AL) { |
839 | dev_err(dev->dev, "Arbitration lost\n"); | 829 | dev_err(dev->dev, "Arbitration lost\n"); |
840 | err |= OMAP_I2C_STAT_AL; | 830 | err |= OMAP_I2C_STAT_AL; |
@@ -875,7 +865,7 @@ complete: | |||
875 | * Data reg in 2430, omap3 and | 865 | * Data reg in 2430, omap3 and |
876 | * omap4 is 8 bit wide | 866 | * omap4 is 8 bit wide |
877 | */ | 867 | */ |
878 | if (pdata->flags & | 868 | if (dev->flags & |
879 | OMAP_I2C_FLAG_16BIT_DATA_REG) { | 869 | OMAP_I2C_FLAG_16BIT_DATA_REG) { |
880 | if (dev->buf_len) { | 870 | if (dev->buf_len) { |
881 | *dev->buf++ = w >> 8; | 871 | *dev->buf++ = w >> 8; |
@@ -918,7 +908,7 @@ complete: | |||
918 | * Data reg in 2430, omap3 and | 908 | * Data reg in 2430, omap3 and |
919 | * omap4 is 8 bit wide | 909 | * omap4 is 8 bit wide |
920 | */ | 910 | */ |
921 | if (pdata->flags & | 911 | if (dev->flags & |
922 | OMAP_I2C_FLAG_16BIT_DATA_REG) { | 912 | OMAP_I2C_FLAG_16BIT_DATA_REG) { |
923 | if (dev->buf_len) { | 913 | if (dev->buf_len) { |
924 | w |= *dev->buf++ << 8; | 914 | w |= *dev->buf++ << 8; |
@@ -965,6 +955,32 @@ static const struct i2c_algorithm omap_i2c_algo = { | |||
965 | .functionality = omap_i2c_func, | 955 | .functionality = omap_i2c_func, |
966 | }; | 956 | }; |
967 | 957 | ||
958 | #ifdef CONFIG_OF | ||
959 | static struct omap_i2c_bus_platform_data omap3_pdata = { | ||
960 | .rev = OMAP_I2C_IP_VERSION_1, | ||
961 | .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | | ||
962 | OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | | ||
963 | OMAP_I2C_FLAG_BUS_SHIFT_2, | ||
964 | }; | ||
965 | |||
966 | static struct omap_i2c_bus_platform_data omap4_pdata = { | ||
967 | .rev = OMAP_I2C_IP_VERSION_2, | ||
968 | }; | ||
969 | |||
970 | static const struct of_device_id omap_i2c_of_match[] = { | ||
971 | { | ||
972 | .compatible = "ti,omap4-i2c", | ||
973 | .data = &omap4_pdata, | ||
974 | }, | ||
975 | { | ||
976 | .compatible = "ti,omap3-i2c", | ||
977 | .data = &omap3_pdata, | ||
978 | }, | ||
979 | { }, | ||
980 | }; | ||
981 | MODULE_DEVICE_TABLE(of, omap_i2c_of_match); | ||
982 | #endif | ||
983 | |||
968 | static int __devinit | 984 | static int __devinit |
969 | omap_i2c_probe(struct platform_device *pdev) | 985 | omap_i2c_probe(struct platform_device *pdev) |
970 | { | 986 | { |
@@ -972,9 +988,10 @@ omap_i2c_probe(struct platform_device *pdev) | |||
972 | struct i2c_adapter *adap; | 988 | struct i2c_adapter *adap; |
973 | struct resource *mem, *irq, *ioarea; | 989 | struct resource *mem, *irq, *ioarea; |
974 | struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data; | 990 | struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data; |
991 | struct device_node *node = pdev->dev.of_node; | ||
992 | const struct of_device_id *match; | ||
975 | irq_handler_t isr; | 993 | irq_handler_t isr; |
976 | int r; | 994 | int r; |
977 | u32 speed = 0; | ||
978 | 995 | ||
979 | /* NOTE: driver uses the static register mapping */ | 996 | /* NOTE: driver uses the static register mapping */ |
980 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 997 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1001,15 +1018,24 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1001 | goto err_release_region; | 1018 | goto err_release_region; |
1002 | } | 1019 | } |
1003 | 1020 | ||
1004 | if (pdata != NULL) { | 1021 | match = of_match_device(omap_i2c_of_match, &pdev->dev); |
1005 | speed = pdata->clkrate; | 1022 | if (match) { |
1023 | u32 freq = 100000; /* default to 100000 Hz */ | ||
1024 | |||
1025 | pdata = match->data; | ||
1026 | dev->dtrev = pdata->rev; | ||
1027 | dev->flags = pdata->flags; | ||
1028 | |||
1029 | of_property_read_u32(node, "clock-frequency", &freq); | ||
1030 | /* convert DT freq value in Hz into kHz for speed */ | ||
1031 | dev->speed = freq / 1000; | ||
1032 | } else if (pdata != NULL) { | ||
1033 | dev->speed = pdata->clkrate; | ||
1034 | dev->flags = pdata->flags; | ||
1006 | dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; | 1035 | dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat; |
1007 | } else { | 1036 | dev->dtrev = pdata->rev; |
1008 | speed = 100; /* Default speed */ | ||
1009 | dev->set_mpu_wkup_lat = NULL; | ||
1010 | } | 1037 | } |
1011 | 1038 | ||
1012 | dev->speed = speed; | ||
1013 | dev->dev = &pdev->dev; | 1039 | dev->dev = &pdev->dev; |
1014 | dev->irq = irq->start; | 1040 | dev->irq = irq->start; |
1015 | dev->base = ioremap(mem->start, resource_size(mem)); | 1041 | dev->base = ioremap(mem->start, resource_size(mem)); |
@@ -1020,9 +1046,9 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1020 | 1046 | ||
1021 | platform_set_drvdata(pdev, dev); | 1047 | platform_set_drvdata(pdev, dev); |
1022 | 1048 | ||
1023 | dev->reg_shift = (pdata->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3; | 1049 | dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3; |
1024 | 1050 | ||
1025 | if (pdata->rev == OMAP_I2C_IP_VERSION_2) | 1051 | if (dev->dtrev == OMAP_I2C_IP_VERSION_2) |
1026 | dev->regs = (u8 *)reg_map_ip_v2; | 1052 | dev->regs = (u8 *)reg_map_ip_v2; |
1027 | else | 1053 | else |
1028 | dev->regs = (u8 *)reg_map_ip_v1; | 1054 | dev->regs = (u8 *)reg_map_ip_v1; |
@@ -1035,7 +1061,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1035 | if (dev->rev <= OMAP_I2C_REV_ON_3430) | 1061 | if (dev->rev <= OMAP_I2C_REV_ON_3430) |
1036 | dev->errata |= I2C_OMAP3_1P153; | 1062 | dev->errata |= I2C_OMAP3_1P153; |
1037 | 1063 | ||
1038 | if (!(pdata->flags & OMAP_I2C_FLAG_NO_FIFO)) { | 1064 | if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) { |
1039 | u16 s; | 1065 | u16 s; |
1040 | 1066 | ||
1041 | /* Set up the fifo size - Get total size */ | 1067 | /* Set up the fifo size - Get total size */ |
@@ -1058,7 +1084,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1058 | /* calculate wakeup latency constraint for MPU */ | 1084 | /* calculate wakeup latency constraint for MPU */ |
1059 | if (dev->set_mpu_wkup_lat != NULL) | 1085 | if (dev->set_mpu_wkup_lat != NULL) |
1060 | dev->latency = (1000000 * dev->fifo_size) / | 1086 | dev->latency = (1000000 * dev->fifo_size) / |
1061 | (1000 * speed / 8); | 1087 | (1000 * dev->speed / 8); |
1062 | } | 1088 | } |
1063 | 1089 | ||
1064 | /* reset ASAP, clearing any IRQs */ | 1090 | /* reset ASAP, clearing any IRQs */ |
@@ -1074,7 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1074 | } | 1100 | } |
1075 | 1101 | ||
1076 | dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, | 1102 | dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id, |
1077 | pdata->rev, dev->rev >> 4, dev->rev & 0xf, dev->speed); | 1103 | dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed); |
1078 | 1104 | ||
1079 | pm_runtime_put(dev->dev); | 1105 | pm_runtime_put(dev->dev); |
1080 | 1106 | ||
@@ -1085,6 +1111,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1085 | strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); | 1111 | strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name)); |
1086 | adap->algo = &omap_i2c_algo; | 1112 | adap->algo = &omap_i2c_algo; |
1087 | adap->dev.parent = &pdev->dev; | 1113 | adap->dev.parent = &pdev->dev; |
1114 | adap->dev.of_node = pdev->dev.of_node; | ||
1088 | 1115 | ||
1089 | /* i2c device drivers may be active on return from add_adapter() */ | 1116 | /* i2c device drivers may be active on return from add_adapter() */ |
1090 | adap->nr = pdev->id; | 1117 | adap->nr = pdev->id; |
@@ -1094,6 +1121,8 @@ omap_i2c_probe(struct platform_device *pdev) | |||
1094 | goto err_free_irq; | 1121 | goto err_free_irq; |
1095 | } | 1122 | } |
1096 | 1123 | ||
1124 | of_i2c_register_devices(adap); | ||
1125 | |||
1097 | return 0; | 1126 | return 0; |
1098 | 1127 | ||
1099 | err_free_irq: | 1128 | err_free_irq: |
@@ -1166,6 +1195,7 @@ static struct platform_driver omap_i2c_driver = { | |||
1166 | .name = "omap_i2c", | 1195 | .name = "omap_i2c", |
1167 | .owner = THIS_MODULE, | 1196 | .owner = THIS_MODULE, |
1168 | .pm = OMAP_I2C_PM_OPS, | 1197 | .pm = OMAP_I2C_PM_OPS, |
1198 | .of_match_table = of_match_ptr(omap_i2c_of_match), | ||
1169 | }, | 1199 | }, |
1170 | }; | 1200 | }; |
1171 | 1201 | ||