Merge branches 'for-2639/i2c/i2c-ce4100-v6', 'for-2639/i2c/i2c-eg20t-v3' and 'for...
authorBen Dooks <ben-linux@fluff.org>
Mon, 21 Mar 2011 22:57:25 +0000 (22:57 +0000)
committerBen Dooks <ben-linux@fluff.org>
Mon, 21 Mar 2011 22:57:25 +0000 (22:57 +0000)
1  2  3  4 
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-eg20t.c

@@@@@ -433,7 -433,7 -433,7 -433,7 +433,7 @@@@@ config I2C_IXP200
    
    config I2C_MPC
        tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
  --    depends on PPC32
  ++    depends on PPC
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
@@@@@ -452,16 -452,16 -452,6 -452,16 +452,16 @@@@@ config I2C_MV64XX
          This driver can also be built as a module.  If so, the module
          will be called i2c-mv64xxx.
    
  + config I2C_MXS
  +     tristate "Freescale i.MX28 I2C interface"
  +     depends on SOC_IMX28
  +     help
  +       Say Y here if you want to use the I2C bus controller on
  +       the Freescale i.MX28 processors.
  + 
  +       This driver can also be built as a module.  If so, the module
  +       will be called i2c-mxs.
  + 
    config I2C_NOMADIK
        tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
        depends on PLAT_NOMADIK
@@@@@ -533,28 -533,31 -523,17 -533,17 +533,31 @@@@@ config I2C_PN
          This driver can also be built as a module.  If so, the module
          will be called i2c-pnx.
    
  ++config I2C_PUV3
  ++    tristate "PKUnity v3 I2C bus support"
  ++    depends on UNICORE32 && ARCH_PUV3
  ++    select I2C_ALGOBIT
  ++    help
  ++      This driver supports the I2C IP inside the PKUnity-v3 SoC.
  ++      This I2C bus controller is under AMBA/AXI bus.
  ++
  ++      This driver can also be built as a module.  If so, the module
  ++      will be called i2c-puv3.
  ++
    config I2C_PXA
        tristate "Intel PXA2XX I2C adapter"
- --    depends on ARCH_PXA || ARCH_MMP
+ ++    depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
        help
          If you have devices in the PXA I2C bus, say yes to this option.
          This driver can also be built as a module.  If so, the module
          will be called i2c-pxa.
    
+ ++config I2C_PXA_PCI
+ ++    def_bool I2C_PXA && X86_32 && PCI && OF
+ ++
    config I2C_PXA_SLAVE
        bool "Intel PXA2XX I2C Slave comms support"
- --    depends on I2C_PXA
+ ++    depends on I2C_PXA && !X86_32
        help
          Support I2C slave mode communications on the PXA I2C bus.  This
          is necessary for systems where the PXA may be a target on the
@@@@@ -628,13 -631,13 -607,6 -617,6 +631,13 @@@@@ config I2C_STU30
          This driver can also be built as a module. If so, the module
          will be called i2c-stu300.
    
  ++config I2C_TEGRA
  ++    tristate "NVIDIA Tegra internal I2C controller"
  ++    depends on ARCH_TEGRA
  ++    help
  ++      If you say yes to this option, support will be included for the
  ++      I2C controller embedded in NVIDIA Tegra SOCs
  ++
    config I2C_VERSATILE
        tristate "ARM Versatile/Realview I2C bus support"
        depends on ARCH_VERSATILE || ARCH_REALVIEW || ARCH_VEXPRESS
@@@@@ -667,25 -670,15 -639,18 -649,15 +670,28 @@@@@ config I2C_XILIN
          will be called xilinx_i2c.
    
    config I2C_EG20T
-- -        tristate "PCH I2C of Intel EG20T"
-- -        depends on PCI
-- -        help
-- -          This driver is for PCH(Platform controller Hub) I2C of EG20T which
-- -          is an IOH(Input/Output Hub) for x86 embedded processor.
-- -          This driver can access PCH I2C bus device.
++ +    tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
++ +    depends on PCI
++ +    help
++ +      This driver is for PCH(Platform controller Hub) I2C of EG20T which
++ +      is an IOH(Input/Output Hub) for x86 embedded processor.
++ +      This driver can access PCH I2C bus device.
++ +
++ +      This driver also supports the ML7213, a companion chip for the
++ +      Atom E6xx series and compatible with the Intel EG20T PCH.
    
    comment "External I2C/SMBus adapter drivers"
    
 +++config I2C_DIOLAN_U2C
 +++    tristate "Diolan U2C-12 USB adapter"
 +++    depends on USB
 +++    help
 +++      If you say yes to this option, support will be included for Diolan
 +++      U2C-12, a USB to I2C interface.
 +++
 +++      This driver can also be built as a module.  If so, the module
 +++      will be called i2c-diolan-u2c.
 +++
    config I2C_PARPORT
        tristate "Parallel port adapter"
        depends on PARPORT
@@@@@ -43,7 -43,7 -43,6 -43,7 +43,7 @@@@@ obj-$(CONFIG_I2C_IOP3XX)      += i2c-iop3xx.
    obj-$(CONFIG_I2C_IXP2000)   += i2c-ixp2000.o
    obj-$(CONFIG_I2C_MPC)               += i2c-mpc.o
    obj-$(CONFIG_I2C_MV64XXX)   += i2c-mv64xxx.o
  + obj-$(CONFIG_I2C_MXS)               += i2c-mxs.o
    obj-$(CONFIG_I2C_NOMADIK)   += i2c-nomadik.o
    obj-$(CONFIG_I2C_NUC900)    += i2c-nuc900.o
    obj-$(CONFIG_I2C_OCORES)    += i2c-ocores.o
@@@@@ -52,22 -52,22 -51,19 -52,19 +52,23 @@@@@ obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.
    obj-$(CONFIG_I2C_PCA_PLATFORM)      += i2c-pca-platform.o
    obj-$(CONFIG_I2C_PMCMSP)    += i2c-pmcmsp.o
    obj-$(CONFIG_I2C_PNX)               += i2c-pnx.o
  ++obj-$(CONFIG_I2C_PUV3)              += i2c-puv3.o
    obj-$(CONFIG_I2C_PXA)               += i2c-pxa.o
+ ++obj-$(CONFIG_I2C_PXA_PCI)   += i2c-pxa-pci.o
    obj-$(CONFIG_I2C_S3C2410)   += i2c-s3c2410.o
    obj-$(CONFIG_I2C_S6000)             += i2c-s6000.o
    obj-$(CONFIG_I2C_SH7760)    += i2c-sh7760.o
    obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
    obj-$(CONFIG_I2C_SIMTEC)    += i2c-simtec.o
    obj-$(CONFIG_I2C_STU300)    += i2c-stu300.o
  ++obj-$(CONFIG_I2C_TEGRA)             += i2c-tegra.o
    obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
    obj-$(CONFIG_I2C_OCTEON)    += i2c-octeon.o
    obj-$(CONFIG_I2C_XILINX)    += i2c-xiic.o
    obj-$(CONFIG_I2C_EG20T)         += i2c-eg20t.o
    
    # External I2C/SMBus adapter drivers
 +++obj-$(CONFIG_I2C_DIOLAN_U2C)        += i2c-diolan-u2c.o
    obj-$(CONFIG_I2C_PARPORT)   += i2c-parport.o
    obj-$(CONFIG_I2C_PARPORT_LIGHT)     += i2c-parport-light.o
    obj-$(CONFIG_I2C_TAOS_EVM)  += i2c-taos-evm.o
    #include <linux/pci.h>
    #include <linux/mutex.h>
    #include <linux/ktime.h>
  ++#include <linux/slab.h>
    
    #define PCH_EVENT_SET       0       /* I2C Interrupt Event Set Status */
    #define PCH_EVENT_NONE      1       /* I2C Interrupt Event Clear Status */
    #define pch_pci_dbg(pdev, fmt, arg...)  \
        dev_dbg(&pdev->dev, "%s :" fmt, __func__, ##arg)
    
++ +/*
++ +Set the number of I2C instance max
++ +Intel EG20T PCH :           1ch
++ +OKI SEMICONDUCTOR ML7213 IOH :      2ch
++ +*/
++ +#define PCH_I2C_MAX_DEV                     2
++ +
    /**
     * struct i2c_algo_pch_data - for I2C driver functionalities
     * @pch_adapter:            stores the reference to i2c_adapter structure
@@@@@ -156,12 -156,12 -162,14 -155,12 +163,14 @@@@@ struct i2c_algo_pch_data 
     * @pch_data:               stores a list of i2c_algo_pch_data
     * @pch_i2c_suspended:      specifies whether the system is suspended or not
     *                  perhaps with more lines and words.
++ + * @ch_num:         specifies the number of i2c instance
     *
     * pch_data has as many elements as maximum I2C channels
     */
    struct adapter_info {
-- -    struct i2c_algo_pch_data pch_data;
++ +    struct i2c_algo_pch_data pch_data[PCH_I2C_MAX_DEV];
        bool pch_i2c_suspended;
++ +    int ch_num;
    };
    
    
@@@@@ -170,8 -170,8 -178,13 -169,8 +179,13 @@@@@ static int pch_clk = 50000;    /* specifie
    static wait_queue_head_t pch_event;
    static DEFINE_MUTEX(pch_mutex);
    
++ +/* Definition for ML7213 by OKI SEMICONDUCTOR */
++ +#define PCI_VENDOR_ID_ROHM          0x10DB
++ +#define PCI_DEVICE_ID_ML7213_I2C    0x802D
++ +
    static struct pci_device_id __devinitdata pch_pcidev_id[] = {
-- -    {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_I2C)},
++ +    { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },
++ +    { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
        {0,}
    };
    
@@@@@ -212,8 -212,8 -225,7 -211,8 +226,7 @@@@@ static void pch_i2c_init(struct i2c_alg
        /* Initialize I2C registers */
        iowrite32(0x21, p + PCH_I2CNF);
    
-- -    pch_setbit(adap->pch_base_address, PCH_I2CCTL,
-- -                      PCH_I2CCTL_I2CMEN);
++ +    pch_setbit(adap->pch_base_address, PCH_I2CCTL, PCH_I2CCTL_I2CMEN);
    
        if (pch_i2c_speed != 400)
                pch_i2c_speed = 100;
@@@@@ -255,7 -255,7 -267,7 -254,7 +268,7 @@@@@ static inline bool ktime_lt(const ktime
     * @timeout:        waiting time counter (us).
     */
    static s32 pch_i2c_wait_for_bus_idle(struct i2c_algo_pch_data *adap,
-- -                             s32 timeout)
++ +                                 s32 timeout)
    {
        void __iomem *p = adap->pch_base_address;
    
@@@@@ -475,8 -475,8 -487,8 -474,8 +488,8 @@@@@ static void pch_i2c_sendnack(struct i2c
     * @last:   specifies whether last message or not.
     * @first:  specifies whether first message or not.
     */
-- -s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
-- -              u32 last, u32 first)
++ +static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
++ +                         u32 last, u32 first)
    {
        struct i2c_algo_pch_data *adap = i2c_adap->algo_data;
    
    }
    
    /**
-- - * pch_i2c_cb_ch0() - Interrupt handler Call back function
++ + * pch_i2c_cb() - Interrupt handler Call back function
     * @adap:   Pointer to struct i2c_algo_pch_data.
     */
-- -static void pch_i2c_cb_ch0(struct i2c_algo_pch_data *adap)
++ +static void pch_i2c_cb(struct i2c_algo_pch_data *adap)
    {
        u32 sts;
        void __iomem *p = adap->pch_base_address;
     */
    static irqreturn_t pch_i2c_handler(int irq, void *pData)
    {
-- -    s32 reg_val;
-- -
-- -    struct i2c_algo_pch_data *adap_data = (struct i2c_algo_pch_data *)pData;
-- -    void __iomem *p = adap_data->pch_base_address;
-- -    u32 mode = ioread32(p + PCH_I2CMOD) & (BUFFER_MODE | EEPROM_SR_MODE);
-- -
-- -    if (mode != NORMAL_MODE) {
-- -            pch_err(adap_data, "I2C mode is not supported\n");
-- -            return IRQ_NONE;
++ +    u32 reg_val;
++ +    int flag;
++ +    int i;
++ +    struct adapter_info *adap_info = pData;
++ +    void __iomem *p;
++ +    u32 mode;
++ +
++ +    for (i = 0, flag = 0; i < adap_info->ch_num; i++) {
++ +            p = adap_info->pch_data[i].pch_base_address;
++ +            mode = ioread32(p + PCH_I2CMOD);
++ +            mode &= BUFFER_MODE | EEPROM_SR_MODE;
++ +            if (mode != NORMAL_MODE) {
++ +                    pch_err(adap_info->pch_data,
++ +                            "I2C-%d mode(%d) is not supported\n", mode, i);
++ +                    continue;
++ +            }
++ +            reg_val = ioread32(p + PCH_I2CSR);
++ +            if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT)) {
++ +                    pch_i2c_cb(&adap_info->pch_data[i]);
++ +                    flag = 1;
++ +            }
        }
    
-- -    reg_val = ioread32(p + PCH_I2CSR);
-- -    if (reg_val & (I2CMAL_BIT | I2CMCF_BIT | I2CMIF_BIT))
-- -            pch_i2c_cb_ch0(adap_data);
-- -    else
-- -            return IRQ_NONE;
-- -
-- -    return IRQ_HANDLED;
++ +    return flag ? IRQ_HANDLED : IRQ_NONE;
    }
    
    /**
     * @num:    number of messages.
     */
    static s32 pch_i2c_xfer(struct i2c_adapter *i2c_adap,
-- -                struct i2c_msg *msgs, s32 num)
++ +                    struct i2c_msg *msgs, s32 num)
    {
        struct i2c_msg *pmsg;
        u32 i = 0;
@@@@@ -710,11 -710,11 -728,13 -709,11 +729,13 @@@@@ static void pch_i2c_disbl_int(struct i2
    }
    
    static int __devinit pch_i2c_probe(struct pci_dev *pdev,
-- -                           const struct pci_device_id *id)
++ +                               const struct pci_device_id *id)
    {
        void __iomem *base_addr;
-- -    s32 ret;
++ +    int ret;
++ +    int i, j;
        struct adapter_info *adap_info;
++ +    struct i2c_adapter *pch_adap;
    
        pch_pci_dbg(pdev, "Entered.\n");
    
                goto err_pci_iomap;
        }
    
-- -    adap_info->pch_i2c_suspended = false;
++ +    /* Set the number of I2C channel instance */
++ +    adap_info->ch_num = id->driver_data;
    
-- -    adap_info->pch_data.p_adapter_info = adap_info;
++ +    for (i = 0; i < adap_info->ch_num; i++) {
++ +            pch_adap = &adap_info->pch_data[i].pch_adapter;
++ +            adap_info->pch_i2c_suspended = false;
    
-- -    adap_info->pch_data.pch_adapter.owner = THIS_MODULE;
-- -    adap_info->pch_data.pch_adapter.class = I2C_CLASS_HWMON;
-- -    strcpy(adap_info->pch_data.pch_adapter.name, KBUILD_MODNAME);
-- -    adap_info->pch_data.pch_adapter.algo = &pch_algorithm;
-- -    adap_info->pch_data.pch_adapter.algo_data =
-- -                                            &adap_info->pch_data;
++ +            adap_info->pch_data[i].p_adapter_info = adap_info;
    
-- -    /* (i * 0x80) + base_addr; */
-- -    adap_info->pch_data.pch_base_address = base_addr;
++ +            pch_adap->owner = THIS_MODULE;
++ +            pch_adap->class = I2C_CLASS_HWMON;
++ +            strcpy(pch_adap->name, KBUILD_MODNAME);
++ +            pch_adap->algo = &pch_algorithm;
++ +            pch_adap->algo_data = &adap_info->pch_data[i];
    
-- -    adap_info->pch_data.pch_adapter.dev.parent = &pdev->dev;
++ +            /* base_addr + offset; */
++ +            adap_info->pch_data[i].pch_base_address = base_addr + 0x100 * i;
    
-- -    ret = i2c_add_adapter(&(adap_info->pch_data.pch_adapter));
++ +            pch_adap->dev.parent = &pdev->dev;
    
-- -    if (ret) {
-- -            pch_pci_err(pdev, "i2c_add_adapter FAILED\n");
-- -            goto err_i2c_add_adapter;
-- -    }
++ +            ret = i2c_add_adapter(pch_adap);
++ +            if (ret) {
++ +                    pch_pci_err(pdev, "i2c_add_adapter[ch:%d] FAILED\n", i);
++ +                    goto err_i2c_add_adapter;
++ +            }
    
-- -    pch_i2c_init(&adap_info->pch_data);
++ +            pch_i2c_init(&adap_info->pch_data[i]);
++ +    }
        ret = request_irq(pdev->irq, pch_i2c_handler, IRQF_SHARED,
-- -              KBUILD_MODNAME, &adap_info->pch_data);
++ +              KBUILD_MODNAME, adap_info);
        if (ret) {
                pch_pci_err(pdev, "request_irq FAILED\n");
-- -            goto err_request_irq;
++ +            goto err_i2c_add_adapter;
        }
    
        pci_set_drvdata(pdev, adap_info);
        pch_pci_dbg(pdev, "returns %d.\n", ret);
        return 0;
    
-- -err_request_irq:
-- -    i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
    err_i2c_add_adapter:
++ +    for (j = 0; j < i; j++)
++ +            i2c_del_adapter(&adap_info->pch_data[j].pch_adapter);
        pci_iounmap(pdev, base_addr);
    err_pci_iomap:
        pci_release_regions(pdev);
@@@@@ -794,17 -794,17 -818,22 -793,17 +819,22 @@@@@ err_pci_enable
    
    static void __devexit pch_i2c_remove(struct pci_dev *pdev)
    {
++ +    int i;
        struct adapter_info *adap_info = pci_get_drvdata(pdev);
    
-- -    pch_i2c_disbl_int(&adap_info->pch_data);
-- -    free_irq(pdev->irq, &adap_info->pch_data);
-- -    i2c_del_adapter(&(adap_info->pch_data.pch_adapter));
++ +    free_irq(pdev->irq, adap_info);
    
-- -    if (adap_info->pch_data.pch_base_address) {
-- -            pci_iounmap(pdev, adap_info->pch_data.pch_base_address);
-- -            adap_info->pch_data.pch_base_address = 0;
++ +    for (i = 0; i < adap_info->ch_num; i++) {
++ +            pch_i2c_disbl_int(&adap_info->pch_data[i]);
++ +            i2c_del_adapter(&adap_info->pch_data[i].pch_adapter);
        }
    
++ +    if (adap_info->pch_data[0].pch_base_address)
++ +            pci_iounmap(pdev, adap_info->pch_data[0].pch_base_address);
++ +
++ +    for (i = 0; i < adap_info->ch_num; i++)
++ +            adap_info->pch_data[i].pch_base_address = 0;
++ +
        pci_set_drvdata(pdev, NULL);
    
        pci_release_regions(pdev);
    static int pch_i2c_suspend(struct pci_dev *pdev, pm_message_t state)
    {
        int ret;
++ +    int i;
        struct adapter_info *adap_info = pci_get_drvdata(pdev);
-- -    void __iomem *p = adap_info->pch_data.pch_base_address;
++ +    void __iomem *p = adap_info->pch_data[0].pch_base_address;
    
        adap_info->pch_i2c_suspended = true;
    
-- -    while ((adap_info->pch_data.pch_i2c_xfer_in_progress)) {
-- -            /* Wait until all channel transfers are completed */
-- -            msleep(20);
++ +    for (i = 0; i < adap_info->ch_num; i++) {
++ +            while ((adap_info->pch_data[i].pch_i2c_xfer_in_progress)) {
++ +                    /* Wait until all channel transfers are completed */
++ +                    msleep(20);
++ +            }
        }
++ +
        /* Disable the i2c interrupts */
-- -    pch_i2c_disbl_int(&adap_info->pch_data);
++ +    for (i = 0; i < adap_info->ch_num; i++)
++ +            pch_i2c_disbl_int(&adap_info->pch_data[i]);
    
        pch_pci_dbg(pdev, "I2CSR = %x I2CBUFSTA = %x I2CESRSTA = %x "
                "invoked function pch_i2c_disbl_int successfully\n",
    
    static int pch_i2c_resume(struct pci_dev *pdev)
    {
++ +    int i;
        struct adapter_info *adap_info = pci_get_drvdata(pdev);
    
        pci_set_power_state(pdev, PCI_D0);
    
        pci_enable_wake(pdev, PCI_D3hot, 0);
    
-- -    pch_i2c_init(&adap_info->pch_data);
++ +    for (i = 0; i < adap_info->ch_num; i++)
++ +            pch_i2c_init(&adap_info->pch_data[i]);
    
        adap_info->pch_i2c_suspended = false;
    
@@@@@ -894,7 -894,7 -930,7 -893,7 +931,7 @@@@@ static void __exit pch_pci_exit(void
    }
    module_exit(pch_pci_exit);
    
-- -MODULE_DESCRIPTION("PCH I2C PCI Driver");
++ +MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH I2C Driver");
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Tomoya MORINAGA. <tomoya-linux@dsn.okisemi.com>");
    module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR));