Merge branch 'for-linus/2639/i2c-1' of git://git.fluff.org/bjdooks/linux
* 'for-linus/2639/i2c-1' of git://git.fluff.org/bjdooks/linux: i2c-mpc: Add support for 64bit system i2c: add driver for Freescale i.MX28 i2c: tegra: Add i2c support
···433433434434config I2C_MPC435435 tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"436436- depends on PPC32436436+ depends on PPC437437 help438438 If you say yes to this option, support will be included for the439439 built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,···451451452452 This driver can also be built as a module. If so, the module453453 will be called i2c-mv64xxx.454454+455455+config I2C_MXS456456+ tristate "Freescale i.MX28 I2C interface"457457+ depends on SOC_IMX28458458+ help459459+ Say Y here if you want to use the I2C bus controller on460460+ the Freescale i.MX28 processors.461461+462462+ This driver can also be built as a module. If so, the module463463+ will be called i2c-mxs.454464455465config I2C_NOMADIK456466 tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"···627617628618 This driver can also be built as a module. If so, the module629619 will be called i2c-stu300.620620+621621+config I2C_TEGRA622622+ tristate "NVIDIA Tegra internal I2C controller"623623+ depends on ARCH_TEGRA624624+ help625625+ If you say yes to this option, support will be included for the626626+ I2C controller embedded in NVIDIA Tegra SOCs630627631628config I2C_VERSATILE632629 tristate "ARM Versatile/Realview I2C bus support"
···11+/*22+ * Freescale MXS I2C bus driver33+ *44+ * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.55+ *66+ * based on a (non-working) driver which was:77+ *88+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.99+ *1010+ * TODO: add dma-support if platform-support for it is available1111+ *1212+ * This program is free software; you can redistribute it and/or modify1313+ * it under the terms of the GNU General Public License as published by1414+ * the Free Software Foundation; either version 2 of the License, or1515+ * (at your option) any later version.1616+ *1717+ */1818+1919+#include <linux/slab.h>2020+#include <linux/device.h>2121+#include <linux/module.h>2222+#include <linux/i2c.h>2323+#include <linux/err.h>2424+#include <linux/interrupt.h>2525+#include <linux/completion.h>2626+#include <linux/platform_device.h>2727+#include <linux/jiffies.h>2828+#include <linux/io.h>2929+3030+#include <mach/common.h>3131+3232+#define DRIVER_NAME "mxs-i2c"3333+3434+#define MXS_I2C_CTRL0 (0x00)3535+#define MXS_I2C_CTRL0_SET (0x04)3636+3737+#define MXS_I2C_CTRL0_SFTRST 0x800000003838+#define MXS_I2C_CTRL0_SEND_NAK_ON_LAST 0x020000003939+#define MXS_I2C_CTRL0_RETAIN_CLOCK 0x002000004040+#define MXS_I2C_CTRL0_POST_SEND_STOP 0x001000004141+#define MXS_I2C_CTRL0_PRE_SEND_START 0x000800004242+#define MXS_I2C_CTRL0_MASTER_MODE 0x000200004343+#define MXS_I2C_CTRL0_DIRECTION 0x000100004444+#define MXS_I2C_CTRL0_XFER_COUNT(v) ((v) & 0x0000FFFF)4545+4646+#define MXS_I2C_CTRL1 (0x40)4747+#define MXS_I2C_CTRL1_SET (0x44)4848+#define MXS_I2C_CTRL1_CLR (0x48)4949+5050+#define MXS_I2C_CTRL1_BUS_FREE_IRQ 0x805151+#define MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ 0x405252+#define MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ 0x205353+#define MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ 0x105454+#define MXS_I2C_CTRL1_EARLY_TERM_IRQ 0x085555+#define MXS_I2C_CTRL1_MASTER_LOSS_IRQ 0x045656+#define MXS_I2C_CTRL1_SLAVE_STOP_IRQ 0x025757+#define MXS_I2C_CTRL1_SLAVE_IRQ 0x015858+5959+#define MXS_I2C_IRQ_MASK (MXS_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ | \6060+ MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ | \6161+ MXS_I2C_CTRL1_EARLY_TERM_IRQ | \6262+ MXS_I2C_CTRL1_MASTER_LOSS_IRQ | \6363+ MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \6464+ MXS_I2C_CTRL1_SLAVE_IRQ)6565+6666+#define MXS_I2C_QUEUECTRL (0x60)6767+#define MXS_I2C_QUEUECTRL_SET (0x64)6868+#define MXS_I2C_QUEUECTRL_CLR (0x68)6969+7070+#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x207171+#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x047272+7373+#define MXS_I2C_QUEUESTAT (0x70)7474+#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x000020007575+7676+#define MXS_I2C_QUEUECMD (0x80)7777+7878+#define MXS_I2C_QUEUEDATA (0x90)7979+8080+#define MXS_I2C_DATA (0xa0)8181+8282+8383+#define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \8484+ MXS_I2C_CTRL0_PRE_SEND_START | \8585+ MXS_I2C_CTRL0_MASTER_MODE | \8686+ MXS_I2C_CTRL0_DIRECTION | \8787+ MXS_I2C_CTRL0_XFER_COUNT(1))8888+8989+#define MXS_CMD_I2C_WRITE (MXS_I2C_CTRL0_PRE_SEND_START | \9090+ MXS_I2C_CTRL0_MASTER_MODE | \9191+ MXS_I2C_CTRL0_DIRECTION)9292+9393+#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \9494+ MXS_I2C_CTRL0_MASTER_MODE)9595+9696+/**9797+ * struct mxs_i2c_dev - per device, private MXS-I2C data9898+ *9999+ * @dev: driver model device node100100+ * @regs: IO registers pointer101101+ * @cmd_complete: completion object for transaction wait102102+ * @cmd_err: error code for last transaction103103+ * @adapter: i2c subsystem adapter node104104+ */105105+struct mxs_i2c_dev {106106+ struct device *dev;107107+ void __iomem *regs;108108+ struct completion cmd_complete;109109+ u32 cmd_err;110110+ struct i2c_adapter adapter;111111+};112112+113113+/*114114+ * TODO: check if calls to here are really needed. If not, we could get rid of115115+ * mxs_reset_block and the mach-dependency. Needs an I2C analyzer, probably.116116+ */117117+static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)118118+{119119+ mxs_reset_block(i2c->regs);120120+ writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);121121+}122122+123123+static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,124124+ int flags)125125+{126126+ u32 data;127127+128128+ writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD);129129+130130+ data = (addr << 1) | I2C_SMBUS_READ;131131+ writel(data, i2c->regs + MXS_I2C_DATA);132132+133133+ data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags;134134+ writel(data, i2c->regs + MXS_I2C_QUEUECMD);135135+}136136+137137+static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c,138138+ u8 addr, u8 *buf, int len, int flags)139139+{140140+ u32 data;141141+ int i, shifts_left;142142+143143+ data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags;144144+ writel(data, i2c->regs + MXS_I2C_QUEUECMD);145145+146146+ /*147147+ * We have to copy the slave address (u8) and buffer (arbitrary number148148+ * of u8) into the data register (u32). To achieve that, the u8 are put149149+ * into the MSBs of 'data' which is then shifted for the next u8. When150150+ * apropriate, 'data' is written to MXS_I2C_DATA. So, the first u32151151+ * looks like this:152152+ *153153+ * 3 2 1 0154154+ * 10987654|32109876|54321098|76543210155155+ * --------+--------+--------+--------156156+ * buffer+2|buffer+1|buffer+0|slave_addr157157+ */158158+159159+ data = ((addr << 1) | I2C_SMBUS_WRITE) << 24;160160+161161+ for (i = 0; i < len; i++) {162162+ data >>= 8;163163+ data |= buf[i] << 24;164164+ if ((i & 3) == 2)165165+ writel(data, i2c->regs + MXS_I2C_DATA);166166+ }167167+168168+ /* Write out the remaining bytes if any */169169+ shifts_left = 24 - (i & 3) * 8;170170+ if (shifts_left)171171+ writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA);172172+}173173+174174+/*175175+ * TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the176176+ * rd_threshold to 1). Couldn't get this to work, though.177177+ */178178+static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c)179179+{180180+ unsigned long timeout = jiffies + msecs_to_jiffies(1000);181181+182182+ while (readl(i2c->regs + MXS_I2C_QUEUESTAT)183183+ & MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) {184184+ if (time_after(jiffies, timeout))185185+ return -ETIMEDOUT;186186+ cond_resched();187187+ }188188+189189+ return 0;190190+}191191+192192+static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len)193193+{194194+ u32 data;195195+ int i;196196+197197+ for (i = 0; i < len; i++) {198198+ if ((i & 3) == 0) {199199+ if (mxs_i2c_wait_for_data(i2c))200200+ return -ETIMEDOUT;201201+ data = readl(i2c->regs + MXS_I2C_QUEUEDATA);202202+ }203203+ buf[i] = data & 0xff;204204+ data >>= 8;205205+ }206206+207207+ return 0;208208+}209209+210210+/*211211+ * Low level master read/write transaction.212212+ */213213+static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,214214+ int stop)215215+{216216+ struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);217217+ int ret;218218+ int flags;219219+220220+ init_completion(&i2c->cmd_complete);221221+222222+ dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",223223+ msg->addr, msg->len, msg->flags, stop);224224+225225+ if (msg->len == 0)226226+ return -EINVAL;227227+228228+ flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;229229+230230+ if (msg->flags & I2C_M_RD)231231+ mxs_i2c_pioq_setup_read(i2c, msg->addr, msg->len, flags);232232+ else233233+ mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, msg->len,234234+ flags);235235+236236+ writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,237237+ i2c->regs + MXS_I2C_QUEUECTRL_SET);238238+239239+ ret = wait_for_completion_timeout(&i2c->cmd_complete,240240+ msecs_to_jiffies(1000));241241+ if (ret == 0)242242+ goto timeout;243243+244244+ if ((!i2c->cmd_err) && (msg->flags & I2C_M_RD)) {245245+ ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);246246+ if (ret)247247+ goto timeout;248248+ }249249+250250+ if (i2c->cmd_err == -ENXIO)251251+ mxs_i2c_reset(i2c);252252+253253+ dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);254254+255255+ return i2c->cmd_err;256256+257257+timeout:258258+ dev_dbg(i2c->dev, "Timeout!\n");259259+ mxs_i2c_reset(i2c);260260+ return -ETIMEDOUT;261261+}262262+263263+static int mxs_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],264264+ int num)265265+{266266+ int i;267267+ int err;268268+269269+ for (i = 0; i < num; i++) {270270+ err = mxs_i2c_xfer_msg(adap, &msgs[i], i == (num - 1));271271+ if (err)272272+ return err;273273+ }274274+275275+ return num;276276+}277277+278278+static u32 mxs_i2c_func(struct i2c_adapter *adap)279279+{280280+ return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);281281+}282282+283283+static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)284284+{285285+ struct mxs_i2c_dev *i2c = dev_id;286286+ u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;287287+288288+ if (!stat)289289+ return IRQ_NONE;290290+291291+ if (stat & MXS_I2C_CTRL1_NO_SLAVE_ACK_IRQ)292292+ i2c->cmd_err = -ENXIO;293293+ else if (stat & (MXS_I2C_CTRL1_EARLY_TERM_IRQ |294294+ MXS_I2C_CTRL1_MASTER_LOSS_IRQ |295295+ MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ))296296+ /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */297297+ i2c->cmd_err = -EIO;298298+ else299299+ i2c->cmd_err = 0;300300+301301+ complete(&i2c->cmd_complete);302302+303303+ writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);304304+ return IRQ_HANDLED;305305+}306306+307307+static const struct i2c_algorithm mxs_i2c_algo = {308308+ .master_xfer = mxs_i2c_xfer,309309+ .functionality = mxs_i2c_func,310310+};311311+312312+static int __devinit mxs_i2c_probe(struct platform_device *pdev)313313+{314314+ struct device *dev = &pdev->dev;315315+ struct mxs_i2c_dev *i2c;316316+ struct i2c_adapter *adap;317317+ struct resource *res;318318+ resource_size_t res_size;319319+ int err, irq;320320+321321+ i2c = devm_kzalloc(dev, sizeof(struct mxs_i2c_dev), GFP_KERNEL);322322+ if (!i2c)323323+ return -ENOMEM;324324+325325+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);326326+ if (!res)327327+ return -ENOENT;328328+329329+ res_size = resource_size(res);330330+ if (!devm_request_mem_region(dev, res->start, res_size, res->name))331331+ return -EBUSY;332332+333333+ i2c->regs = devm_ioremap_nocache(dev, res->start, res_size);334334+ if (!i2c->regs)335335+ return -EBUSY;336336+337337+ irq = platform_get_irq(pdev, 0);338338+ if (irq < 0)339339+ return irq;340340+341341+ err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);342342+ if (err)343343+ return err;344344+345345+ i2c->dev = dev;346346+ platform_set_drvdata(pdev, i2c);347347+348348+ /* Do reset to enforce correct startup after pinmuxing */349349+ mxs_i2c_reset(i2c);350350+ writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,351351+ i2c->regs + MXS_I2C_QUEUECTRL_SET);352352+353353+ adap = &i2c->adapter;354354+ strlcpy(adap->name, "MXS I2C adapter", sizeof(adap->name));355355+ adap->owner = THIS_MODULE;356356+ adap->algo = &mxs_i2c_algo;357357+ adap->dev.parent = dev;358358+ adap->nr = pdev->id;359359+ i2c_set_adapdata(adap, i2c);360360+ err = i2c_add_numbered_adapter(adap);361361+ if (err) {362362+ dev_err(dev, "Failed to add adapter (%d)\n", err);363363+ writel(MXS_I2C_CTRL0_SFTRST,364364+ i2c->regs + MXS_I2C_CTRL0_SET);365365+ return err;366366+ }367367+368368+ return 0;369369+}370370+371371+static int __devexit mxs_i2c_remove(struct platform_device *pdev)372372+{373373+ struct mxs_i2c_dev *i2c = platform_get_drvdata(pdev);374374+ int ret;375375+376376+ ret = i2c_del_adapter(&i2c->adapter);377377+ if (ret)378378+ return -EBUSY;379379+380380+ writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,381381+ i2c->regs + MXS_I2C_QUEUECTRL_CLR);382382+ writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);383383+384384+ platform_set_drvdata(pdev, NULL);385385+386386+ return 0;387387+}388388+389389+static struct platform_driver mxs_i2c_driver = {390390+ .driver = {391391+ .name = DRIVER_NAME,392392+ .owner = THIS_MODULE,393393+ },394394+ .remove = __devexit_p(mxs_i2c_remove),395395+};396396+397397+static int __init mxs_i2c_init(void)398398+{399399+ return platform_driver_probe(&mxs_i2c_driver, mxs_i2c_probe);400400+}401401+subsys_initcall(mxs_i2c_init);402402+403403+static void __exit mxs_i2c_exit(void)404404+{405405+ platform_driver_unregister(&mxs_i2c_driver);406406+}407407+module_exit(mxs_i2c_exit);408408+409409+MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");410410+MODULE_DESCRIPTION("MXS I2C Bus Driver");411411+MODULE_LICENSE("GPL");412412+MODULE_ALIAS("platform:" DRIVER_NAME);
+700
drivers/i2c/busses/i2c-tegra.c
···11+/*22+ * drivers/i2c/busses/i2c-tegra.c33+ *44+ * Copyright (C) 2010 Google, Inc.55+ * Author: Colin Cross <ccross@android.com>66+ *77+ * This software is licensed under the terms of the GNU General Public88+ * License version 2, as published by the Free Software Foundation, and99+ * may be copied, distributed, and modified under those terms.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ */1717+1818+#include <linux/kernel.h>1919+#include <linux/init.h>2020+#include <linux/platform_device.h>2121+#include <linux/clk.h>2222+#include <linux/err.h>2323+#include <linux/i2c.h>2424+#include <linux/io.h>2525+#include <linux/interrupt.h>2626+#include <linux/delay.h>2727+#include <linux/slab.h>2828+#include <linux/i2c-tegra.h>2929+3030+#include <asm/unaligned.h>3131+3232+#include <mach/clk.h>3333+3434+#define TEGRA_I2C_TIMEOUT (msecs_to_jiffies(1000))3535+#define BYTES_PER_FIFO_WORD 43636+3737+#define I2C_CNFG 0x0003838+#define I2C_CNFG_PACKET_MODE_EN (1<<10)3939+#define I2C_CNFG_NEW_MASTER_FSM (1<<11)4040+#define I2C_SL_CNFG 0x0204141+#define I2C_SL_CNFG_NEWSL (1<<2)4242+#define I2C_SL_ADDR1 0x02c4343+#define I2C_TX_FIFO 0x0504444+#define I2C_RX_FIFO 0x0544545+#define I2C_PACKET_TRANSFER_STATUS 0x0584646+#define I2C_FIFO_CONTROL 0x05c4747+#define I2C_FIFO_CONTROL_TX_FLUSH (1<<1)4848+#define I2C_FIFO_CONTROL_RX_FLUSH (1<<0)4949+#define I2C_FIFO_CONTROL_TX_TRIG_SHIFT 55050+#define I2C_FIFO_CONTROL_RX_TRIG_SHIFT 25151+#define I2C_FIFO_STATUS 0x0605252+#define I2C_FIFO_STATUS_TX_MASK 0xF05353+#define I2C_FIFO_STATUS_TX_SHIFT 45454+#define I2C_FIFO_STATUS_RX_MASK 0x0F5555+#define I2C_FIFO_STATUS_RX_SHIFT 05656+#define I2C_INT_MASK 0x0645757+#define I2C_INT_STATUS 0x0685858+#define I2C_INT_PACKET_XFER_COMPLETE (1<<7)5959+#define I2C_INT_ALL_PACKETS_XFER_COMPLETE (1<<6)6060+#define I2C_INT_TX_FIFO_OVERFLOW (1<<5)6161+#define I2C_INT_RX_FIFO_UNDERFLOW (1<<4)6262+#define I2C_INT_NO_ACK (1<<3)6363+#define I2C_INT_ARBITRATION_LOST (1<<2)6464+#define I2C_INT_TX_FIFO_DATA_REQ (1<<1)6565+#define I2C_INT_RX_FIFO_DATA_REQ (1<<0)6666+#define I2C_CLK_DIVISOR 0x06c6767+6868+#define DVC_CTRL_REG1 0x0006969+#define DVC_CTRL_REG1_INTR_EN (1<<10)7070+#define DVC_CTRL_REG2 0x0047171+#define DVC_CTRL_REG3 0x0087272+#define DVC_CTRL_REG3_SW_PROG (1<<26)7373+#define DVC_CTRL_REG3_I2C_DONE_INTR_EN (1<<30)7474+#define DVC_STATUS 0x00c7575+#define DVC_STATUS_I2C_DONE_INTR (1<<30)7676+7777+#define I2C_ERR_NONE 0x007878+#define I2C_ERR_NO_ACK 0x017979+#define I2C_ERR_ARBITRATION_LOST 0x028080+8181+#define PACKET_HEADER0_HEADER_SIZE_SHIFT 288282+#define PACKET_HEADER0_PACKET_ID_SHIFT 168383+#define PACKET_HEADER0_CONT_ID_SHIFT 128484+#define PACKET_HEADER0_PROTOCOL_I2C (1<<4)8585+8686+#define I2C_HEADER_HIGHSPEED_MODE (1<<22)8787+#define I2C_HEADER_CONT_ON_NAK (1<<21)8888+#define I2C_HEADER_SEND_START_BYTE (1<<20)8989+#define I2C_HEADER_READ (1<<19)9090+#define I2C_HEADER_10BIT_ADDR (1<<18)9191+#define I2C_HEADER_IE_ENABLE (1<<17)9292+#define I2C_HEADER_REPEAT_START (1<<16)9393+#define I2C_HEADER_MASTER_ADDR_SHIFT 129494+#define I2C_HEADER_SLAVE_ADDR_SHIFT 19595+9696+/**9797+ * struct tegra_i2c_dev - per device i2c context9898+ * @dev: device reference for power management9999+ * @adapter: core i2c layer adapter information100100+ * @clk: clock reference for i2c controller101101+ * @i2c_clk: clock reference for i2c bus102102+ * @iomem: memory resource for registers103103+ * @base: ioremapped registers cookie104104+ * @cont_id: i2c controller id, used for for packet header105105+ * @irq: irq number of transfer complete interrupt106106+ * @is_dvc: identifies the DVC i2c controller, has a different register layout107107+ * @msg_complete: transfer completion notifier108108+ * @msg_err: error code for completed message109109+ * @msg_buf: pointer to current message data110110+ * @msg_buf_remaining: size of unsent data in the message buffer111111+ * @msg_read: identifies read transfers112112+ * @bus_clk_rate: current i2c bus clock rate113113+ * @is_suspended: prevents i2c controller accesses after suspend is called114114+ */115115+struct tegra_i2c_dev {116116+ struct device *dev;117117+ struct i2c_adapter adapter;118118+ struct clk *clk;119119+ struct clk *i2c_clk;120120+ struct resource *iomem;121121+ void __iomem *base;122122+ int cont_id;123123+ int irq;124124+ int is_dvc;125125+ struct completion msg_complete;126126+ int msg_err;127127+ u8 *msg_buf;128128+ size_t msg_buf_remaining;129129+ int msg_read;130130+ unsigned long bus_clk_rate;131131+ bool is_suspended;132132+};133133+134134+static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long reg)135135+{136136+ writel(val, i2c_dev->base + reg);137137+}138138+139139+static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)140140+{141141+ return readl(i2c_dev->base + reg);142142+}143143+144144+/*145145+ * i2c_writel and i2c_readl will offset the register if necessary to talk146146+ * to the I2C block inside the DVC block147147+ */148148+static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,149149+ unsigned long reg)150150+{151151+ if (i2c_dev->is_dvc)152152+ reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;153153+ return reg;154154+}155155+156156+static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,157157+ unsigned long reg)158158+{159159+ writel(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));160160+}161161+162162+static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)163163+{164164+ return readl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));165165+}166166+167167+static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,168168+ unsigned long reg, int len)169169+{170170+ writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);171171+}172172+173173+static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,174174+ unsigned long reg, int len)175175+{176176+ readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);177177+}178178+179179+static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)180180+{181181+ u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);182182+ int_mask &= ~mask;183183+ i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);184184+}185185+186186+static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)187187+{188188+ u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);189189+ int_mask |= mask;190190+ i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);191191+}192192+193193+static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)194194+{195195+ unsigned long timeout = jiffies + HZ;196196+ u32 val = i2c_readl(i2c_dev, I2C_FIFO_CONTROL);197197+ val |= I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH;198198+ i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);199199+200200+ while (i2c_readl(i2c_dev, I2C_FIFO_CONTROL) &201201+ (I2C_FIFO_CONTROL_TX_FLUSH | I2C_FIFO_CONTROL_RX_FLUSH)) {202202+ if (time_after(jiffies, timeout)) {203203+ dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");204204+ return -ETIMEDOUT;205205+ }206206+ msleep(1);207207+ }208208+ return 0;209209+}210210+211211+static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)212212+{213213+ u32 val;214214+ int rx_fifo_avail;215215+ u8 *buf = i2c_dev->msg_buf;216216+ size_t buf_remaining = i2c_dev->msg_buf_remaining;217217+ int words_to_transfer;218218+219219+ val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);220220+ rx_fifo_avail = (val & I2C_FIFO_STATUS_RX_MASK) >>221221+ I2C_FIFO_STATUS_RX_SHIFT;222222+223223+ /* Rounds down to not include partial word at the end of buf */224224+ words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;225225+ if (words_to_transfer > rx_fifo_avail)226226+ words_to_transfer = rx_fifo_avail;227227+228228+ i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);229229+230230+ buf += words_to_transfer * BYTES_PER_FIFO_WORD;231231+ buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;232232+ rx_fifo_avail -= words_to_transfer;233233+234234+ /*235235+ * If there is a partial word at the end of buf, handle it manually to236236+ * prevent overwriting past the end of buf237237+ */238238+ if (rx_fifo_avail > 0 && buf_remaining > 0) {239239+ BUG_ON(buf_remaining > 3);240240+ val = i2c_readl(i2c_dev, I2C_RX_FIFO);241241+ memcpy(buf, &val, buf_remaining);242242+ buf_remaining = 0;243243+ rx_fifo_avail--;244244+ }245245+246246+ BUG_ON(rx_fifo_avail > 0 && buf_remaining > 0);247247+ i2c_dev->msg_buf_remaining = buf_remaining;248248+ i2c_dev->msg_buf = buf;249249+ return 0;250250+}251251+252252+static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)253253+{254254+ u32 val;255255+ int tx_fifo_avail;256256+ u8 *buf = i2c_dev->msg_buf;257257+ size_t buf_remaining = i2c_dev->msg_buf_remaining;258258+ int words_to_transfer;259259+260260+ val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);261261+ tx_fifo_avail = (val & I2C_FIFO_STATUS_TX_MASK) >>262262+ I2C_FIFO_STATUS_TX_SHIFT;263263+264264+ /* Rounds down to not include partial word at the end of buf */265265+ words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;266266+ if (words_to_transfer > tx_fifo_avail)267267+ words_to_transfer = tx_fifo_avail;268268+269269+ i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);270270+271271+ buf += words_to_transfer * BYTES_PER_FIFO_WORD;272272+ buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;273273+ tx_fifo_avail -= words_to_transfer;274274+275275+ /*276276+ * If there is a partial word at the end of buf, handle it manually to277277+ * prevent reading past the end of buf, which could cross a page278278+ * boundary and fault.279279+ */280280+ if (tx_fifo_avail > 0 && buf_remaining > 0) {281281+ BUG_ON(buf_remaining > 3);282282+ memcpy(&val, buf, buf_remaining);283283+ i2c_writel(i2c_dev, val, I2C_TX_FIFO);284284+ buf_remaining = 0;285285+ tx_fifo_avail--;286286+ }287287+288288+ BUG_ON(tx_fifo_avail > 0 && buf_remaining > 0);289289+ i2c_dev->msg_buf_remaining = buf_remaining;290290+ i2c_dev->msg_buf = buf;291291+ return 0;292292+}293293+294294+/*295295+ * One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller)296296+ * block. This block is identical to the rest of the I2C blocks, except that297297+ * it only supports master mode, it has registers moved around, and it needs298298+ * some extra init to get it into I2C mode. The register moves are handled299299+ * by i2c_readl and i2c_writel300300+ */301301+static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)302302+{303303+ u32 val = 0;304304+ val = dvc_readl(i2c_dev, DVC_CTRL_REG3);305305+ val |= DVC_CTRL_REG3_SW_PROG;306306+ val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;307307+ dvc_writel(i2c_dev, val, DVC_CTRL_REG3);308308+309309+ val = dvc_readl(i2c_dev, DVC_CTRL_REG1);310310+ val |= DVC_CTRL_REG1_INTR_EN;311311+ dvc_writel(i2c_dev, val, DVC_CTRL_REG1);312312+}313313+314314+static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)315315+{316316+ u32 val;317317+ int err = 0;318318+319319+ clk_enable(i2c_dev->clk);320320+321321+ tegra_periph_reset_assert(i2c_dev->clk);322322+ udelay(2);323323+ tegra_periph_reset_deassert(i2c_dev->clk);324324+325325+ if (i2c_dev->is_dvc)326326+ tegra_dvc_init(i2c_dev);327327+328328+ val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN;329329+ i2c_writel(i2c_dev, val, I2C_CNFG);330330+ i2c_writel(i2c_dev, 0, I2C_INT_MASK);331331+ clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8);332332+333333+ val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |334334+ 0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;335335+ i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);336336+337337+ if (tegra_i2c_flush_fifos(i2c_dev))338338+ err = -ETIMEDOUT;339339+340340+ clk_disable(i2c_dev->clk);341341+ return err;342342+}343343+344344+static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)345345+{346346+ u32 status;347347+ const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;348348+ struct tegra_i2c_dev *i2c_dev = dev_id;349349+350350+ status = i2c_readl(i2c_dev, I2C_INT_STATUS);351351+352352+ if (status == 0) {353353+ dev_warn(i2c_dev->dev, "interrupt with no status\n");354354+ return IRQ_NONE;355355+ }356356+357357+ if (unlikely(status & status_err)) {358358+ if (status & I2C_INT_NO_ACK)359359+ i2c_dev->msg_err |= I2C_ERR_NO_ACK;360360+ if (status & I2C_INT_ARBITRATION_LOST)361361+ i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST;362362+ complete(&i2c_dev->msg_complete);363363+ goto err;364364+ }365365+366366+ if (i2c_dev->msg_read && (status & I2C_INT_RX_FIFO_DATA_REQ)) {367367+ if (i2c_dev->msg_buf_remaining)368368+ tegra_i2c_empty_rx_fifo(i2c_dev);369369+ else370370+ BUG();371371+ }372372+373373+ if (!i2c_dev->msg_read && (status & I2C_INT_TX_FIFO_DATA_REQ)) {374374+ if (i2c_dev->msg_buf_remaining)375375+ tegra_i2c_fill_tx_fifo(i2c_dev);376376+ else377377+ tegra_i2c_mask_irq(i2c_dev, I2C_INT_TX_FIFO_DATA_REQ);378378+ }379379+380380+ if ((status & I2C_INT_PACKET_XFER_COMPLETE) &&381381+ !i2c_dev->msg_buf_remaining)382382+ complete(&i2c_dev->msg_complete);383383+384384+ i2c_writel(i2c_dev, status, I2C_INT_STATUS);385385+ if (i2c_dev->is_dvc)386386+ dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);387387+ return IRQ_HANDLED;388388+err:389389+ /* An error occured, mask all interrupts */390390+ tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |391391+ I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |392392+ I2C_INT_RX_FIFO_DATA_REQ);393393+ i2c_writel(i2c_dev, status, I2C_INT_STATUS);394394+ return IRQ_HANDLED;395395+}396396+397397+static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,398398+ struct i2c_msg *msg, int stop)399399+{400400+ u32 packet_header;401401+ u32 int_mask;402402+ int ret;403403+404404+ tegra_i2c_flush_fifos(i2c_dev);405405+ i2c_writel(i2c_dev, 0xFF, I2C_INT_STATUS);406406+407407+ if (msg->len == 0)408408+ return -EINVAL;409409+410410+ i2c_dev->msg_buf = msg->buf;411411+ i2c_dev->msg_buf_remaining = msg->len;412412+ i2c_dev->msg_err = I2C_ERR_NONE;413413+ i2c_dev->msg_read = (msg->flags & I2C_M_RD);414414+ INIT_COMPLETION(i2c_dev->msg_complete);415415+416416+ packet_header = (0 << PACKET_HEADER0_HEADER_SIZE_SHIFT) |417417+ PACKET_HEADER0_PROTOCOL_I2C |418418+ (i2c_dev->cont_id << PACKET_HEADER0_CONT_ID_SHIFT) |419419+ (1 << PACKET_HEADER0_PACKET_ID_SHIFT);420420+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);421421+422422+ packet_header = msg->len - 1;423423+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);424424+425425+ packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;426426+ packet_header |= I2C_HEADER_IE_ENABLE;427427+ if (msg->flags & I2C_M_TEN)428428+ packet_header |= I2C_HEADER_10BIT_ADDR;429429+ if (msg->flags & I2C_M_IGNORE_NAK)430430+ packet_header |= I2C_HEADER_CONT_ON_NAK;431431+ if (msg->flags & I2C_M_NOSTART)432432+ packet_header |= I2C_HEADER_REPEAT_START;433433+ if (msg->flags & I2C_M_RD)434434+ packet_header |= I2C_HEADER_READ;435435+ i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);436436+437437+ if (!(msg->flags & I2C_M_RD))438438+ tegra_i2c_fill_tx_fifo(i2c_dev);439439+440440+ int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;441441+ if (msg->flags & I2C_M_RD)442442+ int_mask |= I2C_INT_RX_FIFO_DATA_REQ;443443+ else if (i2c_dev->msg_buf_remaining)444444+ int_mask |= I2C_INT_TX_FIFO_DATA_REQ;445445+ tegra_i2c_unmask_irq(i2c_dev, int_mask);446446+ dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",447447+ i2c_readl(i2c_dev, I2C_INT_MASK));448448+449449+ ret = wait_for_completion_timeout(&i2c_dev->msg_complete, TEGRA_I2C_TIMEOUT);450450+ tegra_i2c_mask_irq(i2c_dev, int_mask);451451+452452+ if (WARN_ON(ret == 0)) {453453+ dev_err(i2c_dev->dev, "i2c transfer timed out\n");454454+455455+ tegra_i2c_init(i2c_dev);456456+ return -ETIMEDOUT;457457+ }458458+459459+ dev_dbg(i2c_dev->dev, "transfer complete: %d %d %d\n",460460+ ret, completion_done(&i2c_dev->msg_complete), i2c_dev->msg_err);461461+462462+ if (likely(i2c_dev->msg_err == I2C_ERR_NONE))463463+ return 0;464464+465465+ tegra_i2c_init(i2c_dev);466466+ if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {467467+ if (msg->flags & I2C_M_IGNORE_NAK)468468+ return 0;469469+ return -EREMOTEIO;470470+ }471471+472472+ return -EIO;473473+}474474+475475+static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],476476+ int num)477477+{478478+ struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);479479+ int i;480480+ int ret = 0;481481+482482+ if (i2c_dev->is_suspended)483483+ return -EBUSY;484484+485485+ clk_enable(i2c_dev->clk);486486+ for (i = 0; i < num; i++) {487487+ int stop = (i == (num - 1)) ? 1 : 0;488488+ ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], stop);489489+ if (ret)490490+ break;491491+ }492492+ clk_disable(i2c_dev->clk);493493+ return ret ?: i;494494+}495495+496496+static u32 tegra_i2c_func(struct i2c_adapter *adap)497497+{498498+ return I2C_FUNC_I2C;499499+}500500+501501+static const struct i2c_algorithm tegra_i2c_algo = {502502+ .master_xfer = tegra_i2c_xfer,503503+ .functionality = tegra_i2c_func,504504+};505505+506506+static int tegra_i2c_probe(struct platform_device *pdev)507507+{508508+ struct tegra_i2c_dev *i2c_dev;509509+ struct tegra_i2c_platform_data *pdata = pdev->dev.platform_data;510510+ struct resource *res;511511+ struct resource *iomem;512512+ struct clk *clk;513513+ struct clk *i2c_clk;514514+ void *base;515515+ int irq;516516+ int ret = 0;517517+518518+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);519519+ if (!res) {520520+ dev_err(&pdev->dev, "no mem resource\n");521521+ return -EINVAL;522522+ }523523+ iomem = request_mem_region(res->start, resource_size(res), pdev->name);524524+ if (!iomem) {525525+ dev_err(&pdev->dev, "I2C region already claimed\n");526526+ return -EBUSY;527527+ }528528+529529+ base = ioremap(iomem->start, resource_size(iomem));530530+ if (!base) {531531+ dev_err(&pdev->dev, "Cannot ioremap I2C region\n");532532+ return -ENOMEM;533533+ }534534+535535+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);536536+ if (!res) {537537+ dev_err(&pdev->dev, "no irq resource\n");538538+ ret = -EINVAL;539539+ goto err_iounmap;540540+ }541541+ irq = res->start;542542+543543+ clk = clk_get(&pdev->dev, NULL);544544+ if (IS_ERR(clk)) {545545+ dev_err(&pdev->dev, "missing controller clock");546546+ ret = PTR_ERR(clk);547547+ goto err_release_region;548548+ }549549+550550+ i2c_clk = clk_get(&pdev->dev, "i2c");551551+ if (IS_ERR(i2c_clk)) {552552+ dev_err(&pdev->dev, "missing bus clock");553553+ ret = PTR_ERR(i2c_clk);554554+ goto err_clk_put;555555+ }556556+557557+ i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev), GFP_KERNEL);558558+ if (!i2c_dev) {559559+ ret = -ENOMEM;560560+ goto err_i2c_clk_put;561561+ }562562+563563+ i2c_dev->base = base;564564+ i2c_dev->clk = clk;565565+ i2c_dev->i2c_clk = i2c_clk;566566+ i2c_dev->iomem = iomem;567567+ i2c_dev->adapter.algo = &tegra_i2c_algo;568568+ i2c_dev->irq = irq;569569+ i2c_dev->cont_id = pdev->id;570570+ i2c_dev->dev = &pdev->dev;571571+ i2c_dev->bus_clk_rate = pdata ? pdata->bus_clk_rate : 100000;572572+573573+ if (pdev->id == 3)574574+ i2c_dev->is_dvc = 1;575575+ init_completion(&i2c_dev->msg_complete);576576+577577+ platform_set_drvdata(pdev, i2c_dev);578578+579579+ ret = tegra_i2c_init(i2c_dev);580580+ if (ret) {581581+ dev_err(&pdev->dev, "Failed to initialize i2c controller");582582+ goto err_free;583583+ }584584+585585+ ret = request_irq(i2c_dev->irq, tegra_i2c_isr, 0, pdev->name, i2c_dev);586586+ if (ret) {587587+ dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);588588+ goto err_free;589589+ }590590+591591+ clk_enable(i2c_dev->i2c_clk);592592+593593+ i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);594594+ i2c_dev->adapter.owner = THIS_MODULE;595595+ i2c_dev->adapter.class = I2C_CLASS_HWMON;596596+ strlcpy(i2c_dev->adapter.name, "Tegra I2C adapter",597597+ sizeof(i2c_dev->adapter.name));598598+ i2c_dev->adapter.algo = &tegra_i2c_algo;599599+ i2c_dev->adapter.dev.parent = &pdev->dev;600600+ i2c_dev->adapter.nr = pdev->id;601601+602602+ ret = i2c_add_numbered_adapter(&i2c_dev->adapter);603603+ if (ret) {604604+ dev_err(&pdev->dev, "Failed to add I2C adapter\n");605605+ goto err_free_irq;606606+ }607607+608608+ return 0;609609+err_free_irq:610610+ free_irq(i2c_dev->irq, i2c_dev);611611+err_free:612612+ kfree(i2c_dev);613613+err_i2c_clk_put:614614+ clk_put(i2c_clk);615615+err_clk_put:616616+ clk_put(clk);617617+err_release_region:618618+ release_mem_region(iomem->start, resource_size(iomem));619619+err_iounmap:620620+ iounmap(base);621621+ return ret;622622+}623623+624624+static int tegra_i2c_remove(struct platform_device *pdev)625625+{626626+ struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);627627+ i2c_del_adapter(&i2c_dev->adapter);628628+ free_irq(i2c_dev->irq, i2c_dev);629629+ clk_put(i2c_dev->i2c_clk);630630+ clk_put(i2c_dev->clk);631631+ release_mem_region(i2c_dev->iomem->start,632632+ resource_size(i2c_dev->iomem));633633+ iounmap(i2c_dev->base);634634+ kfree(i2c_dev);635635+ return 0;636636+}637637+638638+#ifdef CONFIG_PM639639+static int tegra_i2c_suspend(struct platform_device *pdev, pm_message_t state)640640+{641641+ struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);642642+643643+ i2c_lock_adapter(&i2c_dev->adapter);644644+ i2c_dev->is_suspended = true;645645+ i2c_unlock_adapter(&i2c_dev->adapter);646646+647647+ return 0;648648+}649649+650650+static int tegra_i2c_resume(struct platform_device *pdev)651651+{652652+ struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);653653+ int ret;654654+655655+ i2c_lock_adapter(&i2c_dev->adapter);656656+657657+ ret = tegra_i2c_init(i2c_dev);658658+659659+ if (ret) {660660+ i2c_unlock_adapter(&i2c_dev->adapter);661661+ return ret;662662+ }663663+664664+ i2c_dev->is_suspended = false;665665+666666+ i2c_unlock_adapter(&i2c_dev->adapter);667667+668668+ return 0;669669+}670670+#endif671671+672672+static struct platform_driver tegra_i2c_driver = {673673+ .probe = tegra_i2c_probe,674674+ .remove = tegra_i2c_remove,675675+#ifdef CONFIG_PM676676+ .suspend = tegra_i2c_suspend,677677+ .resume = tegra_i2c_resume,678678+#endif679679+ .driver = {680680+ .name = "tegra-i2c",681681+ .owner = THIS_MODULE,682682+ },683683+};684684+685685+static int __init tegra_i2c_init_driver(void)686686+{687687+ return platform_driver_register(&tegra_i2c_driver);688688+}689689+690690+static void __exit tegra_i2c_exit_driver(void)691691+{692692+ platform_driver_unregister(&tegra_i2c_driver);693693+}694694+695695+subsys_initcall(tegra_i2c_init_driver);696696+module_exit(tegra_i2c_exit_driver);697697+698698+MODULE_DESCRIPTION("nVidia Tegra2 I2C Bus Controller driver");699699+MODULE_AUTHOR("Colin Cross");700700+MODULE_LICENSE("GPL v2");
+25
include/linux/i2c-tegra.h
···11+/*22+ * drivers/i2c/busses/i2c-tegra.c33+ *44+ * Copyright (C) 2010 Google, Inc.55+ * Author: Colin Cross <ccross@android.com>66+ *77+ * This software is licensed under the terms of the GNU General Public88+ * License version 2, as published by the Free Software Foundation, and99+ * may be copied, distributed, and modified under those terms.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ */1717+1818+#ifndef _LINUX_I2C_TEGRA_H1919+#define _LINUX_I2C_TEGRA_H2020+2121+struct tegra_i2c_platform_data {2222+ unsigned long bus_clk_rate;2323+};2424+2525+#endif /* _LINUX_I2C_TEGRA_H */