diff options
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/Kconfig | 8 | ||||
-rw-r--r-- | drivers/i2c/busses/Makefile | 5 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-core.c | 11 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 3 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-iop3xx.c | 121 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mxs.c | 13 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-pnx.c | 53 |
7 files changed, 122 insertions, 92 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd6728..42d9fdd63de0 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -104,6 +104,7 @@ config I2C_I801 | |||
104 | DH89xxCC (PCH) | 104 | DH89xxCC (PCH) |
105 | Panther Point (PCH) | 105 | Panther Point (PCH) |
106 | Lynx Point (PCH) | 106 | Lynx Point (PCH) |
107 | Lynx Point-LP (PCH) | ||
107 | 108 | ||
108 | This driver can also be built as a module. If so, the module | 109 | This driver can also be built as a module. If so, the module |
109 | will be called i2c-i801. | 110 | will be called i2c-i801. |
@@ -354,9 +355,13 @@ config I2C_DAVINCI | |||
354 | devices such as DaVinci NIC. | 355 | devices such as DaVinci NIC. |
355 | For details please see http://www.ti.com/davinci | 356 | For details please see http://www.ti.com/davinci |
356 | 357 | ||
358 | config I2C_DESIGNWARE_CORE | ||
359 | tristate | ||
360 | |||
357 | config I2C_DESIGNWARE_PLATFORM | 361 | config I2C_DESIGNWARE_PLATFORM |
358 | tristate "Synopsys DesignWare Platform" | 362 | tristate "Synopsys DesignWare Platform" |
359 | depends on HAVE_CLK | 363 | depends on HAVE_CLK |
364 | select I2C_DESIGNWARE_CORE | ||
360 | help | 365 | help |
361 | If you say yes to this option, support will be included for the | 366 | If you say yes to this option, support will be included for the |
362 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 367 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM | |||
367 | config I2C_DESIGNWARE_PCI | 372 | config I2C_DESIGNWARE_PCI |
368 | tristate "Synopsys DesignWare PCI" | 373 | tristate "Synopsys DesignWare PCI" |
369 | depends on PCI | 374 | depends on PCI |
375 | select I2C_DESIGNWARE_CORE | ||
370 | help | 376 | help |
371 | If you say yes to this option, support will be included for the | 377 | If you say yes to this option, support will be included for the |
372 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 378 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -545,7 +551,7 @@ config I2C_PMCMSP | |||
545 | 551 | ||
546 | config I2C_PNX | 552 | config I2C_PNX |
547 | tristate "I2C bus support for Philips PNX and NXP LPC targets" | 553 | tristate "I2C bus support for Philips PNX and NXP LPC targets" |
548 | depends on ARCH_PNX4008 || ARCH_LPC32XX | 554 | depends on ARCH_LPC32XX |
549 | help | 555 | help |
550 | This driver supports the Philips IP3204 I2C IP block master and/or | 556 | This driver supports the Philips IP3204 I2C IP block master and/or |
551 | slave controller | 557 | slave controller |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb40..37c4182cc98b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | |||
33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o | 33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o |
34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o | 34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o |
35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o | 35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o |
36 | obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o | ||
36 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o | 37 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o |
37 | i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o | 38 | i2c-designware-platform-objs := i2c-designware-platdrv.o |
38 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o | 39 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o |
39 | i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o | 40 | i2c-designware-pci-objs := i2c-designware-pcidrv.o |
40 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o | 41 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o |
41 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o | 42 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o |
42 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o | 43 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o |
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80edf..7b8ebbefb581 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * ---------------------------------------------------------------------------- | 25 | * ---------------------------------------------------------------------------- |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | #include <linux/export.h> | ||
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
316 | dw_writel(dev, dev->master_cfg , DW_IC_CON); | 317 | dw_writel(dev, dev->master_cfg , DW_IC_CON); |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(i2c_dw_init); | ||
319 | 321 | ||
320 | /* | 322 | /* |
321 | * Waiting for bus not busy | 323 | * Waiting for bus not busy |
@@ -568,12 +570,14 @@ done: | |||
568 | 570 | ||
569 | return ret; | 571 | return ret; |
570 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(i2c_dw_xfer); | ||
571 | 574 | ||
572 | u32 i2c_dw_func(struct i2c_adapter *adap) | 575 | u32 i2c_dw_func(struct i2c_adapter *adap) |
573 | { | 576 | { |
574 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | 577 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); |
575 | return dev->functionality; | 578 | return dev->functionality; |
576 | } | 579 | } |
580 | EXPORT_SYMBOL_GPL(i2c_dw_func); | ||
577 | 581 | ||
578 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | 582 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
579 | { | 583 | { |
@@ -678,17 +682,20 @@ tx_aborted: | |||
678 | 682 | ||
679 | return IRQ_HANDLED; | 683 | return IRQ_HANDLED; |
680 | } | 684 | } |
685 | EXPORT_SYMBOL_GPL(i2c_dw_isr); | ||
681 | 686 | ||
682 | void i2c_dw_enable(struct dw_i2c_dev *dev) | 687 | void i2c_dw_enable(struct dw_i2c_dev *dev) |
683 | { | 688 | { |
684 | /* Enable the adapter */ | 689 | /* Enable the adapter */ |
685 | dw_writel(dev, 1, DW_IC_ENABLE); | 690 | dw_writel(dev, 1, DW_IC_ENABLE); |
686 | } | 691 | } |
692 | EXPORT_SYMBOL_GPL(i2c_dw_enable); | ||
687 | 693 | ||
688 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) | 694 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) |
689 | { | 695 | { |
690 | return dw_readl(dev, DW_IC_ENABLE); | 696 | return dw_readl(dev, DW_IC_ENABLE); |
691 | } | 697 | } |
698 | EXPORT_SYMBOL_GPL(i2c_dw_is_enabled); | ||
692 | 699 | ||
693 | void i2c_dw_disable(struct dw_i2c_dev *dev) | 700 | void i2c_dw_disable(struct dw_i2c_dev *dev) |
694 | { | 701 | { |
@@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) | |||
699 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 706 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
700 | dw_readl(dev, DW_IC_CLR_INTR); | 707 | dw_readl(dev, DW_IC_CLR_INTR); |
701 | } | 708 | } |
709 | EXPORT_SYMBOL_GPL(i2c_dw_disable); | ||
702 | 710 | ||
703 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) | 711 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) |
704 | { | 712 | { |
705 | dw_readl(dev, DW_IC_CLR_INTR); | 713 | dw_readl(dev, DW_IC_CLR_INTR); |
706 | } | 714 | } |
715 | EXPORT_SYMBOL_GPL(i2c_dw_clear_int); | ||
707 | 716 | ||
708 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) | 717 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) |
709 | { | 718 | { |
710 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 719 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
711 | } | 720 | } |
721 | EXPORT_SYMBOL_GPL(i2c_dw_disable_int); | ||
712 | 722 | ||
713 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) | 723 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) |
714 | { | 724 | { |
715 | return dw_readl(dev, DW_IC_COMP_PARAM_1); | 725 | return dw_readl(dev, DW_IC_COMP_PARAM_1); |
716 | } | 726 | } |
727 | EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); | ||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ade..33e9b0c09af2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -52,6 +52,7 @@ | |||
52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes | 52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes |
53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes | 53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes |
54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes | 54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes |
55 | Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes | ||
55 | 56 | ||
56 | Features supported by this driver: | 57 | Features supported by this driver: |
57 | Software PEC no | 58 | Software PEC no |
@@ -155,6 +156,7 @@ | |||
155 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | 156 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 |
156 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | 157 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 |
157 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 | 158 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 |
159 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 | ||
158 | 160 | ||
159 | struct i801_priv { | 161 | struct i801_priv { |
160 | struct i2c_adapter adapter; | 162 | struct i2c_adapter adapter; |
@@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { | |||
771 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, | 773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, |
772 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, | 774 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, |
773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, | 775 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, |
776 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, | ||
774 | { 0, } | 777 | { 0, } |
775 | }; | 778 | }; |
776 | 779 | ||
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 93f147a96b62..2f99613fd677 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c | |||
@@ -4,13 +4,13 @@ | |||
4 | /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd | 4 | /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd |
5 | * <Peter dot Milne at D hyphen TACQ dot com> | 5 | * <Peter dot Milne at D hyphen TACQ dot com> |
6 | * | 6 | * |
7 | * With acknowledgements to i2c-algo-ibm_ocp.c by | 7 | * With acknowledgements to i2c-algo-ibm_ocp.c by |
8 | * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com | 8 | * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com |
9 | * | 9 | * |
10 | * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: | 10 | * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: |
11 | * | 11 | * |
12 | * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund | 12 | * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund |
13 | * | 13 | * |
14 | * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, | 14 | * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, |
15 | * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> | 15 | * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> |
16 | * | 16 | * |
@@ -39,14 +39,15 @@ | |||
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <linux/gpio.h> | ||
42 | 43 | ||
43 | #include "i2c-iop3xx.h" | 44 | #include "i2c-iop3xx.h" |
44 | 45 | ||
45 | /* global unit counter */ | 46 | /* global unit counter */ |
46 | static int i2c_id; | 47 | static int i2c_id; |
47 | 48 | ||
48 | static inline unsigned char | 49 | static inline unsigned char |
49 | iic_cook_addr(struct i2c_msg *msg) | 50 | iic_cook_addr(struct i2c_msg *msg) |
50 | { | 51 | { |
51 | unsigned char addr; | 52 | unsigned char addr; |
52 | 53 | ||
@@ -55,38 +56,38 @@ iic_cook_addr(struct i2c_msg *msg) | |||
55 | if (msg->flags & I2C_M_RD) | 56 | if (msg->flags & I2C_M_RD) |
56 | addr |= 1; | 57 | addr |= 1; |
57 | 58 | ||
58 | return addr; | 59 | return addr; |
59 | } | 60 | } |
60 | 61 | ||
61 | static void | 62 | static void |
62 | iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) | 63 | iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) |
63 | { | 64 | { |
64 | /* Follows devman 9.3 */ | 65 | /* Follows devman 9.3 */ |
65 | __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); | 66 | __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); |
66 | __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); | 67 | __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); |
67 | __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); | 68 | __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); |
68 | } | 69 | } |
69 | 70 | ||
70 | static void | 71 | static void |
71 | iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) | 72 | iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) |
72 | { | 73 | { |
73 | u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; | 74 | u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; |
74 | 75 | ||
75 | /* | 76 | /* |
76 | * Every time unit enable is asserted, GPOD needs to be cleared | 77 | * Every time unit enable is asserted, GPOD needs to be cleared |
77 | * on IOP3XX to avoid data corruption on the bus. | 78 | * on IOP3XX to avoid data corruption on the bus. |
78 | */ | 79 | */ |
79 | #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) | 80 | #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) |
80 | if (iop3xx_adap->id == 0) { | 81 | if (iop3xx_adap->id == 0) { |
81 | gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); | 82 | gpio_set_value(7, 0); |
82 | gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); | 83 | gpio_set_value(6, 0); |
83 | } else { | 84 | } else { |
84 | gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW); | 85 | gpio_set_value(5, 0); |
85 | gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW); | 86 | gpio_set_value(4, 0); |
86 | } | 87 | } |
87 | #endif | 88 | #endif |
88 | /* NB SR bits not same position as CR IE bits :-( */ | 89 | /* NB SR bits not same position as CR IE bits :-( */ |
89 | iop3xx_adap->SR_enabled = | 90 | iop3xx_adap->SR_enabled = |
90 | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | | 91 | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | |
91 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; | 92 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; |
92 | 93 | ||
@@ -96,23 +97,23 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) | |||
96 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); | 97 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); |
97 | } | 98 | } |
98 | 99 | ||
99 | static void | 100 | static void |
100 | iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) | 101 | iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) |
101 | { | 102 | { |
102 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 103 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
103 | 104 | ||
104 | cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | | 105 | cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | |
105 | IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); | 106 | IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); |
106 | 107 | ||
107 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); | 108 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); |
108 | } | 109 | } |
109 | 110 | ||
110 | /* | 111 | /* |
111 | * NB: the handler has to clear the source of the interrupt! | 112 | * NB: the handler has to clear the source of the interrupt! |
112 | * Then it passes the SR flags of interest to BH via adap data | 113 | * Then it passes the SR flags of interest to BH via adap data |
113 | */ | 114 | */ |
114 | static irqreturn_t | 115 | static irqreturn_t |
115 | iop3xx_i2c_irq_handler(int this_irq, void *dev_id) | 116 | iop3xx_i2c_irq_handler(int this_irq, void *dev_id) |
116 | { | 117 | { |
117 | struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; | 118 | struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; |
118 | u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); | 119 | u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); |
@@ -126,7 +127,7 @@ iop3xx_i2c_irq_handler(int this_irq, void *dev_id) | |||
126 | } | 127 | } |
127 | 128 | ||
128 | /* check all error conditions, clear them , report most important */ | 129 | /* check all error conditions, clear them , report most important */ |
129 | static int | 130 | static int |
130 | iop3xx_i2c_error(u32 sr) | 131 | iop3xx_i2c_error(u32 sr) |
131 | { | 132 | { |
132 | int rc = 0; | 133 | int rc = 0; |
@@ -135,12 +136,12 @@ iop3xx_i2c_error(u32 sr) | |||
135 | if ( !rc ) rc = -I2C_ERR_BERR; | 136 | if ( !rc ) rc = -I2C_ERR_BERR; |
136 | } | 137 | } |
137 | if ((sr & IOP3XX_ISR_ALD)) { | 138 | if ((sr & IOP3XX_ISR_ALD)) { |
138 | if ( !rc ) rc = -I2C_ERR_ALD; | 139 | if ( !rc ) rc = -I2C_ERR_ALD; |
139 | } | 140 | } |
140 | return rc; | 141 | return rc; |
141 | } | 142 | } |
142 | 143 | ||
143 | static inline u32 | 144 | static inline u32 |
144 | iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) | 145 | iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) |
145 | { | 146 | { |
146 | unsigned long flags; | 147 | unsigned long flags; |
@@ -161,8 +162,8 @@ iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) | |||
161 | typedef int (* compare_func)(unsigned test, unsigned mask); | 162 | typedef int (* compare_func)(unsigned test, unsigned mask); |
162 | /* returns 1 on correct comparison */ | 163 | /* returns 1 on correct comparison */ |
163 | 164 | ||
164 | static int | 165 | static int |
165 | iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, | 166 | iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, |
166 | unsigned flags, unsigned* status, | 167 | unsigned flags, unsigned* status, |
167 | compare_func compare) | 168 | compare_func compare) |
168 | { | 169 | { |
@@ -192,47 +193,47 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
192 | } | 193 | } |
193 | 194 | ||
194 | /* | 195 | /* |
195 | * Concrete compare_funcs | 196 | * Concrete compare_funcs |
196 | */ | 197 | */ |
197 | static int | 198 | static int |
198 | all_bits_clear(unsigned test, unsigned mask) | 199 | all_bits_clear(unsigned test, unsigned mask) |
199 | { | 200 | { |
200 | return (test & mask) == 0; | 201 | return (test & mask) == 0; |
201 | } | 202 | } |
202 | 203 | ||
203 | static int | 204 | static int |
204 | any_bits_set(unsigned test, unsigned mask) | 205 | any_bits_set(unsigned test, unsigned mask) |
205 | { | 206 | { |
206 | return (test & mask) != 0; | 207 | return (test & mask) != 0; |
207 | } | 208 | } |
208 | 209 | ||
209 | static int | 210 | static int |
210 | iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 211 | iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
211 | { | 212 | { |
212 | return iop3xx_i2c_wait_event( | 213 | return iop3xx_i2c_wait_event( |
213 | iop3xx_adap, | 214 | iop3xx_adap, |
214 | IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, | 215 | IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, |
215 | status, any_bits_set); | 216 | status, any_bits_set); |
216 | } | 217 | } |
217 | 218 | ||
218 | static int | 219 | static int |
219 | iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 220 | iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
220 | { | 221 | { |
221 | return iop3xx_i2c_wait_event( | 222 | return iop3xx_i2c_wait_event( |
222 | iop3xx_adap, | 223 | iop3xx_adap, |
223 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, | 224 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, |
224 | status, any_bits_set); | 225 | status, any_bits_set); |
225 | } | 226 | } |
226 | 227 | ||
227 | static int | 228 | static int |
228 | iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 229 | iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
229 | { | 230 | { |
230 | return iop3xx_i2c_wait_event( | 231 | return iop3xx_i2c_wait_event( |
231 | iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); | 232 | iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); |
232 | } | 233 | } |
233 | 234 | ||
234 | static int | 235 | static int |
235 | iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | 236 | iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, |
236 | struct i2c_msg* msg) | 237 | struct i2c_msg* msg) |
237 | { | 238 | { |
238 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 239 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -247,7 +248,7 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
247 | } | 248 | } |
248 | 249 | ||
249 | __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); | 250 | __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); |
250 | 251 | ||
251 | cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); | 252 | cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); |
252 | cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; | 253 | cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; |
253 | 254 | ||
@@ -257,8 +258,8 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
257 | return rc; | 258 | return rc; |
258 | } | 259 | } |
259 | 260 | ||
260 | static int | 261 | static int |
261 | iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, | 262 | iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, |
262 | int stop) | 263 | int stop) |
263 | { | 264 | { |
264 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 265 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -277,10 +278,10 @@ iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, | |||
277 | rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); | 278 | rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); |
278 | 279 | ||
279 | return rc; | 280 | return rc; |
280 | } | 281 | } |
281 | 282 | ||
282 | static int | 283 | static int |
283 | iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, | 284 | iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, |
284 | int stop) | 285 | int stop) |
285 | { | 286 | { |
286 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 287 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -304,19 +305,19 @@ iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, | |||
304 | return rc; | 305 | return rc; |
305 | } | 306 | } |
306 | 307 | ||
307 | static int | 308 | static int |
308 | iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) | 309 | iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) |
309 | { | 310 | { |
310 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 311 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
311 | int ii; | 312 | int ii; |
312 | int rc = 0; | 313 | int rc = 0; |
313 | 314 | ||
314 | for (ii = 0; rc == 0 && ii != count; ++ii) | 315 | for (ii = 0; rc == 0 && ii != count; ++ii) |
315 | rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); | 316 | rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); |
316 | return rc; | 317 | return rc; |
317 | } | 318 | } |
318 | 319 | ||
319 | static int | 320 | static int |
320 | iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | 321 | iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) |
321 | { | 322 | { |
322 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 323 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
@@ -325,7 +326,7 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | |||
325 | 326 | ||
326 | for (ii = 0; rc == 0 && ii != count; ++ii) | 327 | for (ii = 0; rc == 0 && ii != count; ++ii) |
327 | rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); | 328 | rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); |
328 | 329 | ||
329 | return rc; | 330 | return rc; |
330 | } | 331 | } |
331 | 332 | ||
@@ -336,8 +337,8 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | |||
336 | * Each transfer (i.e. a read or a write) is separated by a repeated start | 337 | * Each transfer (i.e. a read or a write) is separated by a repeated start |
337 | * condition. | 338 | * condition. |
338 | */ | 339 | */ |
339 | static int | 340 | static int |
340 | iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) | 341 | iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) |
341 | { | 342 | { |
342 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 343 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
343 | int rc; | 344 | int rc; |
@@ -357,8 +358,8 @@ iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) | |||
357 | /* | 358 | /* |
358 | * master_xfer() - main read/write entry | 359 | * master_xfer() - main read/write entry |
359 | */ | 360 | */ |
360 | static int | 361 | static int |
361 | iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | 362 | iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, |
362 | int num) | 363 | int num) |
363 | { | 364 | { |
364 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 365 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
@@ -375,14 +376,14 @@ iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
375 | } | 376 | } |
376 | 377 | ||
377 | iop3xx_i2c_transaction_cleanup(iop3xx_adap); | 378 | iop3xx_i2c_transaction_cleanup(iop3xx_adap); |
378 | 379 | ||
379 | if(ret) | 380 | if(ret) |
380 | return ret; | 381 | return ret; |
381 | 382 | ||
382 | return im; | 383 | return im; |
383 | } | 384 | } |
384 | 385 | ||
385 | static u32 | 386 | static u32 |
386 | iop3xx_i2c_func(struct i2c_adapter *adap) | 387 | iop3xx_i2c_func(struct i2c_adapter *adap) |
387 | { | 388 | { |
388 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 389 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
@@ -393,11 +394,11 @@ static const struct i2c_algorithm iop3xx_i2c_algo = { | |||
393 | .functionality = iop3xx_i2c_func, | 394 | .functionality = iop3xx_i2c_func, |
394 | }; | 395 | }; |
395 | 396 | ||
396 | static int | 397 | static int |
397 | iop3xx_i2c_remove(struct platform_device *pdev) | 398 | iop3xx_i2c_remove(struct platform_device *pdev) |
398 | { | 399 | { |
399 | struct i2c_adapter *padapter = platform_get_drvdata(pdev); | 400 | struct i2c_adapter *padapter = platform_get_drvdata(pdev); |
400 | struct i2c_algo_iop3xx_data *adapter_data = | 401 | struct i2c_algo_iop3xx_data *adapter_data = |
401 | (struct i2c_algo_iop3xx_data *)padapter->algo_data; | 402 | (struct i2c_algo_iop3xx_data *)padapter->algo_data; |
402 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 403 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
403 | unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); | 404 | unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); |
@@ -419,7 +420,7 @@ iop3xx_i2c_remove(struct platform_device *pdev) | |||
419 | return 0; | 420 | return 0; |
420 | } | 421 | } |
421 | 422 | ||
422 | static int | 423 | static int |
423 | iop3xx_i2c_probe(struct platform_device *pdev) | 424 | iop3xx_i2c_probe(struct platform_device *pdev) |
424 | { | 425 | { |
425 | struct resource *res; | 426 | struct resource *res; |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17d..51f05b8520ed 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
365 | struct device_node *node = dev->of_node; | 365 | struct device_node *node = dev->of_node; |
366 | int ret; | 366 | int ret; |
367 | 367 | ||
368 | if (!node) | ||
369 | return -EINVAL; | ||
370 | |||
371 | i2c->speed = &mxs_i2c_95kHz_config; | ||
372 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 368 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
373 | if (ret) | 369 | if (ret) |
374 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); | 370 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); |
@@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) | |||
419 | return err; | 415 | return err; |
420 | 416 | ||
421 | i2c->dev = dev; | 417 | i2c->dev = dev; |
418 | i2c->speed = &mxs_i2c_95kHz_config; | ||
422 | 419 | ||
423 | err = mxs_i2c_get_ofdata(i2c); | 420 | if (dev->of_node) { |
424 | if (err) | 421 | err = mxs_i2c_get_ofdata(i2c); |
425 | return err; | 422 | if (err) |
423 | return err; | ||
424 | } | ||
426 | 425 | ||
427 | platform_set_drvdata(pdev, i2c); | 426 | platform_set_drvdata(pdev, i2c); |
428 | 427 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b0..8488bddfe465 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -48,8 +48,9 @@ enum { | |||
48 | mcntrl_afie = 0x00000002, | 48 | mcntrl_afie = 0x00000002, |
49 | mcntrl_naie = 0x00000004, | 49 | mcntrl_naie = 0x00000004, |
50 | mcntrl_drmie = 0x00000008, | 50 | mcntrl_drmie = 0x00000008, |
51 | mcntrl_daie = 0x00000020, | 51 | mcntrl_drsie = 0x00000010, |
52 | mcntrl_rffie = 0x00000040, | 52 | mcntrl_rffie = 0x00000020, |
53 | mcntrl_daie = 0x00000040, | ||
53 | mcntrl_tffie = 0x00000080, | 54 | mcntrl_tffie = 0x00000080, |
54 | mcntrl_reset = 0x00000100, | 55 | mcntrl_reset = 0x00000100, |
55 | mcntrl_cdbmode = 0x00000400, | 56 | mcntrl_cdbmode = 0x00000400, |
@@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) | |||
290 | * or we didn't 'ask' for it yet. | 291 | * or we didn't 'ask' for it yet. |
291 | */ | 292 | */ |
292 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 293 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
293 | dev_dbg(&alg_data->adapter.dev, | 294 | /* 'Asking' is done asynchronously, e.g. dummy TX of several |
294 | "%s(): Write dummy data to fill Rx-fifo...\n", | 295 | * bytes is done before the first actual RX arrives in FIFO. |
295 | __func__); | 296 | * Therefore, ordered bytes (via TX) are counted separately. |
297 | */ | ||
298 | if (alg_data->mif.order) { | ||
299 | dev_dbg(&alg_data->adapter.dev, | ||
300 | "%s(): Write dummy data to fill Rx-fifo...\n", | ||
301 | __func__); | ||
296 | 302 | ||
297 | if (alg_data->mif.len == 1) { | 303 | if (alg_data->mif.order == 1) { |
298 | /* Last byte, do not acknowledge next rcv. */ | 304 | /* Last byte, do not acknowledge next rcv. */ |
299 | val |= stop_bit; | 305 | val |= stop_bit; |
306 | |||
307 | /* | ||
308 | * Enable interrupt RFDAIE (data in Rx fifo), | ||
309 | * and disable DRMIE (need data for Tx) | ||
310 | */ | ||
311 | ctl = ioread32(I2C_REG_CTL(alg_data)); | ||
312 | ctl |= mcntrl_rffie | mcntrl_daie; | ||
313 | ctl &= ~mcntrl_drmie; | ||
314 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
315 | } | ||
300 | 316 | ||
301 | /* | 317 | /* |
302 | * Enable interrupt RFDAIE (data in Rx fifo), | 318 | * Now we'll 'ask' for data: |
303 | * and disable DRMIE (need data for Tx) | 319 | * For each byte we want to receive, we must |
320 | * write a (dummy) byte to the Tx-FIFO. | ||
304 | */ | 321 | */ |
305 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 322 | iowrite32(val, I2C_REG_TX(alg_data)); |
306 | ctl |= mcntrl_rffie | mcntrl_daie; | 323 | alg_data->mif.order--; |
307 | ctl &= ~mcntrl_drmie; | ||
308 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
309 | } | 324 | } |
310 | |||
311 | /* | ||
312 | * Now we'll 'ask' for data: | ||
313 | * For each byte we want to receive, we must | ||
314 | * write a (dummy) byte to the Tx-FIFO. | ||
315 | */ | ||
316 | iowrite32(val, I2C_REG_TX(alg_data)); | ||
317 | |||
318 | return 0; | 325 | return 0; |
319 | } | 326 | } |
320 | 327 | ||
@@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
514 | 521 | ||
515 | alg_data->mif.buf = pmsg->buf; | 522 | alg_data->mif.buf = pmsg->buf; |
516 | alg_data->mif.len = pmsg->len; | 523 | alg_data->mif.len = pmsg->len; |
524 | alg_data->mif.order = pmsg->len; | ||
517 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? | 525 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? |
518 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; | 526 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; |
519 | alg_data->mif.ret = 0; | 527 | alg_data->mif.ret = 0; |
@@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
566 | /* Cleanup to be sure... */ | 574 | /* Cleanup to be sure... */ |
567 | alg_data->mif.buf = NULL; | 575 | alg_data->mif.buf = NULL; |
568 | alg_data->mif.len = 0; | 576 | alg_data->mif.len = 0; |
577 | alg_data->mif.order = 0; | ||
569 | 578 | ||
570 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", | 579 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
571 | __func__, ioread32(I2C_REG_STS(alg_data))); | 580 | __func__, ioread32(I2C_REG_STS(alg_data))); |