Path: blob/master/drivers/i2c/busses/i2c-bfin-twi.c
15111 views
/*1* Blackfin On-Chip Two Wire Interface Driver2*3* Copyright 2005-2007 Analog Devices Inc.4*5* Enter bugs at http://blackfin.uclinux.org/6*7* Licensed under the GPL-2 or later.8*/910#include <linux/module.h>11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/i2c.h>14#include <linux/slab.h>15#include <linux/io.h>16#include <linux/mm.h>17#include <linux/timer.h>18#include <linux/spinlock.h>19#include <linux/completion.h>20#include <linux/interrupt.h>21#include <linux/platform_device.h>22#include <linux/delay.h>2324#include <asm/blackfin.h>25#include <asm/portmux.h>26#include <asm/irq.h>2728/* SMBus mode*/29#define TWI_I2C_MODE_STANDARD 130#define TWI_I2C_MODE_STANDARDSUB 231#define TWI_I2C_MODE_COMBINED 332#define TWI_I2C_MODE_REPEAT 43334struct bfin_twi_iface {35int irq;36spinlock_t lock;37char read_write;38u8 command;39u8 *transPtr;40int readNum;41int writeNum;42int cur_mode;43int manual_stop;44int result;45struct i2c_adapter adap;46struct completion complete;47struct i2c_msg *pmsg;48int msg_num;49int cur_msg;50u16 saved_clkdiv;51u16 saved_control;52void __iomem *regs_base;53};545556#define DEFINE_TWI_REG(reg, off) \57static inline u16 read_##reg(struct bfin_twi_iface *iface) \58{ return bfin_read16(iface->regs_base + (off)); } \59static inline void write_##reg(struct bfin_twi_iface *iface, u16 v) \60{ bfin_write16(iface->regs_base + (off), v); }6162DEFINE_TWI_REG(CLKDIV, 0x00)63DEFINE_TWI_REG(CONTROL, 0x04)64DEFINE_TWI_REG(SLAVE_CTL, 0x08)65DEFINE_TWI_REG(SLAVE_STAT, 0x0C)66DEFINE_TWI_REG(SLAVE_ADDR, 0x10)67DEFINE_TWI_REG(MASTER_CTL, 0x14)68DEFINE_TWI_REG(MASTER_STAT, 0x18)69DEFINE_TWI_REG(MASTER_ADDR, 0x1C)70DEFINE_TWI_REG(INT_STAT, 0x20)71DEFINE_TWI_REG(INT_MASK, 0x24)72DEFINE_TWI_REG(FIFO_CTL, 0x28)73DEFINE_TWI_REG(FIFO_STAT, 0x2C)74DEFINE_TWI_REG(XMT_DATA8, 0x80)75DEFINE_TWI_REG(XMT_DATA16, 0x84)76DEFINE_TWI_REG(RCV_DATA8, 0x88)77DEFINE_TWI_REG(RCV_DATA16, 0x8C)7879static const u16 pin_req[2][3] = {80{P_TWI0_SCL, P_TWI0_SDA, 0},81{P_TWI1_SCL, P_TWI1_SDA, 0},82};8384static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface,85unsigned short twi_int_status)86{87unsigned short mast_stat = read_MASTER_STAT(iface);8889if (twi_int_status & XMTSERV) {90/* Transmit next data */91if (iface->writeNum > 0) {92SSYNC();93write_XMT_DATA8(iface, *(iface->transPtr++));94iface->writeNum--;95}96/* start receive immediately after complete sending in97* combine mode.98*/99else if (iface->cur_mode == TWI_I2C_MODE_COMBINED)100write_MASTER_CTL(iface,101read_MASTER_CTL(iface) | MDIR | RSTART);102else if (iface->manual_stop)103write_MASTER_CTL(iface,104read_MASTER_CTL(iface) | STOP);105else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&106iface->cur_msg + 1 < iface->msg_num) {107if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)108write_MASTER_CTL(iface,109read_MASTER_CTL(iface) | RSTART | MDIR);110else111write_MASTER_CTL(iface,112(read_MASTER_CTL(iface) | RSTART) & ~MDIR);113}114}115if (twi_int_status & RCVSERV) {116if (iface->readNum > 0) {117/* Receive next data */118*(iface->transPtr) = read_RCV_DATA8(iface);119if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {120/* Change combine mode into sub mode after121* read first data.122*/123iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;124/* Get read number from first byte in block125* combine mode.126*/127if (iface->readNum == 1 && iface->manual_stop)128iface->readNum = *iface->transPtr + 1;129}130iface->transPtr++;131iface->readNum--;132} else if (iface->manual_stop) {133write_MASTER_CTL(iface,134read_MASTER_CTL(iface) | STOP);135} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&136iface->cur_msg + 1 < iface->msg_num) {137if (iface->pmsg[iface->cur_msg + 1].flags & I2C_M_RD)138write_MASTER_CTL(iface,139read_MASTER_CTL(iface) | RSTART | MDIR);140else141write_MASTER_CTL(iface,142(read_MASTER_CTL(iface) | RSTART) & ~MDIR);143}144}145if (twi_int_status & MERR) {146write_INT_MASK(iface, 0);147write_MASTER_STAT(iface, 0x3e);148write_MASTER_CTL(iface, 0);149iface->result = -EIO;150151if (mast_stat & LOSTARB)152dev_dbg(&iface->adap.dev, "Lost Arbitration\n");153if (mast_stat & ANAK)154dev_dbg(&iface->adap.dev, "Address Not Acknowledged\n");155if (mast_stat & DNAK)156dev_dbg(&iface->adap.dev, "Data Not Acknowledged\n");157if (mast_stat & BUFRDERR)158dev_dbg(&iface->adap.dev, "Buffer Read Error\n");159if (mast_stat & BUFWRERR)160dev_dbg(&iface->adap.dev, "Buffer Write Error\n");161162/* Faulty slave devices, may drive SDA low after a transfer163* finishes. To release the bus this code generates up to 9164* extra clocks until SDA is released.165*/166167if (read_MASTER_STAT(iface) & SDASEN) {168int cnt = 9;169do {170write_MASTER_CTL(iface, SCLOVR);171udelay(6);172write_MASTER_CTL(iface, 0);173udelay(6);174} while ((read_MASTER_STAT(iface) & SDASEN) && cnt--);175176write_MASTER_CTL(iface, SDAOVR | SCLOVR);177udelay(6);178write_MASTER_CTL(iface, SDAOVR);179udelay(6);180write_MASTER_CTL(iface, 0);181}182183/* If it is a quick transfer, only address without data,184* not an err, return 1.185*/186if (iface->cur_mode == TWI_I2C_MODE_STANDARD &&187iface->transPtr == NULL &&188(twi_int_status & MCOMP) && (mast_stat & DNAK))189iface->result = 1;190191complete(&iface->complete);192return;193}194if (twi_int_status & MCOMP) {195if ((read_MASTER_CTL(iface) & MEN) == 0 &&196(iface->cur_mode == TWI_I2C_MODE_REPEAT ||197iface->cur_mode == TWI_I2C_MODE_COMBINED)) {198iface->result = -1;199write_INT_MASK(iface, 0);200write_MASTER_CTL(iface, 0);201} else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {202if (iface->readNum == 0) {203/* set the read number to 1 and ask for manual204* stop in block combine mode205*/206iface->readNum = 1;207iface->manual_stop = 1;208write_MASTER_CTL(iface,209read_MASTER_CTL(iface) | (0xff << 6));210} else {211/* set the readd number in other212* combine mode.213*/214write_MASTER_CTL(iface,215(read_MASTER_CTL(iface) &216(~(0xff << 6))) |217(iface->readNum << 6));218}219/* remove restart bit and enable master receive */220write_MASTER_CTL(iface,221read_MASTER_CTL(iface) & ~RSTART);222} else if (iface->cur_mode == TWI_I2C_MODE_REPEAT &&223iface->cur_msg+1 < iface->msg_num) {224iface->cur_msg++;225iface->transPtr = iface->pmsg[iface->cur_msg].buf;226iface->writeNum = iface->readNum =227iface->pmsg[iface->cur_msg].len;228/* Set Transmit device address */229write_MASTER_ADDR(iface,230iface->pmsg[iface->cur_msg].addr);231if (iface->pmsg[iface->cur_msg].flags & I2C_M_RD)232iface->read_write = I2C_SMBUS_READ;233else {234iface->read_write = I2C_SMBUS_WRITE;235/* Transmit first data */236if (iface->writeNum > 0) {237write_XMT_DATA8(iface,238*(iface->transPtr++));239iface->writeNum--;240}241}242243if (iface->pmsg[iface->cur_msg].len <= 255)244write_MASTER_CTL(iface,245(read_MASTER_CTL(iface) &246(~(0xff << 6))) |247(iface->pmsg[iface->cur_msg].len << 6));248else {249write_MASTER_CTL(iface,250(read_MASTER_CTL(iface) |251(0xff << 6)));252iface->manual_stop = 1;253}254/* remove restart bit and enable master receive */255write_MASTER_CTL(iface,256read_MASTER_CTL(iface) & ~RSTART);257} else {258iface->result = 1;259write_INT_MASK(iface, 0);260write_MASTER_CTL(iface, 0);261}262}263complete(&iface->complete);264}265266/* Interrupt handler */267static irqreturn_t bfin_twi_interrupt_entry(int irq, void *dev_id)268{269struct bfin_twi_iface *iface = dev_id;270unsigned long flags;271unsigned short twi_int_status;272273spin_lock_irqsave(&iface->lock, flags);274while (1) {275twi_int_status = read_INT_STAT(iface);276if (!twi_int_status)277break;278/* Clear interrupt status */279write_INT_STAT(iface, twi_int_status);280bfin_twi_handle_interrupt(iface, twi_int_status);281SSYNC();282}283spin_unlock_irqrestore(&iface->lock, flags);284return IRQ_HANDLED;285}286287/*288* One i2c master transfer289*/290static int bfin_twi_do_master_xfer(struct i2c_adapter *adap,291struct i2c_msg *msgs, int num)292{293struct bfin_twi_iface *iface = adap->algo_data;294struct i2c_msg *pmsg;295int rc = 0;296297if (!(read_CONTROL(iface) & TWI_ENA))298return -ENXIO;299300while (read_MASTER_STAT(iface) & BUSBUSY)301yield();302303iface->pmsg = msgs;304iface->msg_num = num;305iface->cur_msg = 0;306307pmsg = &msgs[0];308if (pmsg->flags & I2C_M_TEN) {309dev_err(&adap->dev, "10 bits addr not supported!\n");310return -EINVAL;311}312313iface->cur_mode = TWI_I2C_MODE_REPEAT;314iface->manual_stop = 0;315iface->transPtr = pmsg->buf;316iface->writeNum = iface->readNum = pmsg->len;317iface->result = 0;318init_completion(&(iface->complete));319/* Set Transmit device address */320write_MASTER_ADDR(iface, pmsg->addr);321322/* FIFO Initiation. Data in FIFO should be323* discarded before start a new operation.324*/325write_FIFO_CTL(iface, 0x3);326SSYNC();327write_FIFO_CTL(iface, 0);328SSYNC();329330if (pmsg->flags & I2C_M_RD)331iface->read_write = I2C_SMBUS_READ;332else {333iface->read_write = I2C_SMBUS_WRITE;334/* Transmit first data */335if (iface->writeNum > 0) {336write_XMT_DATA8(iface, *(iface->transPtr++));337iface->writeNum--;338SSYNC();339}340}341342/* clear int stat */343write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);344345/* Interrupt mask . Enable XMT, RCV interrupt */346write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);347SSYNC();348349if (pmsg->len <= 255)350write_MASTER_CTL(iface, pmsg->len << 6);351else {352write_MASTER_CTL(iface, 0xff << 6);353iface->manual_stop = 1;354}355356/* Master enable */357write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |358((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |359((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));360SSYNC();361362while (!iface->result) {363if (!wait_for_completion_timeout(&iface->complete,364adap->timeout)) {365iface->result = -1;366dev_err(&adap->dev, "master transfer timeout\n");367}368}369370if (iface->result == 1)371rc = iface->cur_msg + 1;372else373rc = iface->result;374375return rc;376}377378/*379* Generic i2c master transfer entrypoint380*/381static int bfin_twi_master_xfer(struct i2c_adapter *adap,382struct i2c_msg *msgs, int num)383{384return bfin_twi_do_master_xfer(adap, msgs, num);385}386387/*388* One I2C SMBus transfer389*/390int bfin_twi_do_smbus_xfer(struct i2c_adapter *adap, u16 addr,391unsigned short flags, char read_write,392u8 command, int size, union i2c_smbus_data *data)393{394struct bfin_twi_iface *iface = adap->algo_data;395int rc = 0;396397if (!(read_CONTROL(iface) & TWI_ENA))398return -ENXIO;399400while (read_MASTER_STAT(iface) & BUSBUSY)401yield();402403iface->writeNum = 0;404iface->readNum = 0;405406/* Prepare datas & select mode */407switch (size) {408case I2C_SMBUS_QUICK:409iface->transPtr = NULL;410iface->cur_mode = TWI_I2C_MODE_STANDARD;411break;412case I2C_SMBUS_BYTE:413if (data == NULL)414iface->transPtr = NULL;415else {416if (read_write == I2C_SMBUS_READ)417iface->readNum = 1;418else419iface->writeNum = 1;420iface->transPtr = &data->byte;421}422iface->cur_mode = TWI_I2C_MODE_STANDARD;423break;424case I2C_SMBUS_BYTE_DATA:425if (read_write == I2C_SMBUS_READ) {426iface->readNum = 1;427iface->cur_mode = TWI_I2C_MODE_COMBINED;428} else {429iface->writeNum = 1;430iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;431}432iface->transPtr = &data->byte;433break;434case I2C_SMBUS_WORD_DATA:435if (read_write == I2C_SMBUS_READ) {436iface->readNum = 2;437iface->cur_mode = TWI_I2C_MODE_COMBINED;438} else {439iface->writeNum = 2;440iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;441}442iface->transPtr = (u8 *)&data->word;443break;444case I2C_SMBUS_PROC_CALL:445iface->writeNum = 2;446iface->readNum = 2;447iface->cur_mode = TWI_I2C_MODE_COMBINED;448iface->transPtr = (u8 *)&data->word;449break;450case I2C_SMBUS_BLOCK_DATA:451if (read_write == I2C_SMBUS_READ) {452iface->readNum = 0;453iface->cur_mode = TWI_I2C_MODE_COMBINED;454} else {455iface->writeNum = data->block[0] + 1;456iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;457}458iface->transPtr = data->block;459break;460case I2C_SMBUS_I2C_BLOCK_DATA:461if (read_write == I2C_SMBUS_READ) {462iface->readNum = data->block[0];463iface->cur_mode = TWI_I2C_MODE_COMBINED;464} else {465iface->writeNum = data->block[0];466iface->cur_mode = TWI_I2C_MODE_STANDARDSUB;467}468iface->transPtr = (u8 *)&data->block[1];469break;470default:471return -1;472}473474iface->result = 0;475iface->manual_stop = 0;476iface->read_write = read_write;477iface->command = command;478init_completion(&(iface->complete));479480/* FIFO Initiation. Data in FIFO should be discarded before481* start a new operation.482*/483write_FIFO_CTL(iface, 0x3);484SSYNC();485write_FIFO_CTL(iface, 0);486487/* clear int stat */488write_INT_STAT(iface, MERR | MCOMP | XMTSERV | RCVSERV);489490/* Set Transmit device address */491write_MASTER_ADDR(iface, addr);492SSYNC();493494switch (iface->cur_mode) {495case TWI_I2C_MODE_STANDARDSUB:496write_XMT_DATA8(iface, iface->command);497write_INT_MASK(iface, MCOMP | MERR |498((iface->read_write == I2C_SMBUS_READ) ?499RCVSERV : XMTSERV));500SSYNC();501502if (iface->writeNum + 1 <= 255)503write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);504else {505write_MASTER_CTL(iface, 0xff << 6);506iface->manual_stop = 1;507}508/* Master enable */509write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |510((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));511break;512case TWI_I2C_MODE_COMBINED:513write_XMT_DATA8(iface, iface->command);514write_INT_MASK(iface, MCOMP | MERR | RCVSERV | XMTSERV);515SSYNC();516517if (iface->writeNum > 0)518write_MASTER_CTL(iface, (iface->writeNum + 1) << 6);519else520write_MASTER_CTL(iface, 0x1 << 6);521/* Master enable */522write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |523((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ>100) ? FAST : 0));524break;525default:526write_MASTER_CTL(iface, 0);527if (size != I2C_SMBUS_QUICK) {528/* Don't access xmit data register when this is a529* read operation.530*/531if (iface->read_write != I2C_SMBUS_READ) {532if (iface->writeNum > 0) {533write_XMT_DATA8(iface,534*(iface->transPtr++));535if (iface->writeNum <= 255)536write_MASTER_CTL(iface,537iface->writeNum << 6);538else {539write_MASTER_CTL(iface,5400xff << 6);541iface->manual_stop = 1;542}543iface->writeNum--;544} else {545write_XMT_DATA8(iface, iface->command);546write_MASTER_CTL(iface, 1 << 6);547}548} else {549if (iface->readNum > 0 && iface->readNum <= 255)550write_MASTER_CTL(iface,551iface->readNum << 6);552else if (iface->readNum > 255) {553write_MASTER_CTL(iface, 0xff << 6);554iface->manual_stop = 1;555} else556break;557}558}559write_INT_MASK(iface, MCOMP | MERR |560((iface->read_write == I2C_SMBUS_READ) ?561RCVSERV : XMTSERV));562SSYNC();563564/* Master enable */565write_MASTER_CTL(iface, read_MASTER_CTL(iface) | MEN |566((iface->read_write == I2C_SMBUS_READ) ? MDIR : 0) |567((CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ > 100) ? FAST : 0));568break;569}570SSYNC();571572while (!iface->result) {573if (!wait_for_completion_timeout(&iface->complete,574adap->timeout)) {575iface->result = -1;576dev_err(&adap->dev, "smbus transfer timeout\n");577}578}579580rc = (iface->result >= 0) ? 0 : -1;581582return rc;583}584585/*586* Generic I2C SMBus transfer entrypoint587*/588int bfin_twi_smbus_xfer(struct i2c_adapter *adap, u16 addr,589unsigned short flags, char read_write,590u8 command, int size, union i2c_smbus_data *data)591{592return bfin_twi_do_smbus_xfer(adap, addr, flags,593read_write, command, size, data);594}595596/*597* Return what the adapter supports598*/599static u32 bfin_twi_functionality(struct i2c_adapter *adap)600{601return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |602I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |603I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |604I2C_FUNC_I2C | I2C_FUNC_SMBUS_I2C_BLOCK;605}606607static struct i2c_algorithm bfin_twi_algorithm = {608.master_xfer = bfin_twi_master_xfer,609.smbus_xfer = bfin_twi_smbus_xfer,610.functionality = bfin_twi_functionality,611};612613static int i2c_bfin_twi_suspend(struct platform_device *pdev, pm_message_t state)614{615struct bfin_twi_iface *iface = platform_get_drvdata(pdev);616617iface->saved_clkdiv = read_CLKDIV(iface);618iface->saved_control = read_CONTROL(iface);619620free_irq(iface->irq, iface);621622/* Disable TWI */623write_CONTROL(iface, iface->saved_control & ~TWI_ENA);624625return 0;626}627628static int i2c_bfin_twi_resume(struct platform_device *pdev)629{630struct bfin_twi_iface *iface = platform_get_drvdata(pdev);631632int rc = request_irq(iface->irq, bfin_twi_interrupt_entry,633IRQF_DISABLED, pdev->name, iface);634if (rc) {635dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);636return -ENODEV;637}638639/* Resume TWI interface clock as specified */640write_CLKDIV(iface, iface->saved_clkdiv);641642/* Resume TWI */643write_CONTROL(iface, iface->saved_control);644645return 0;646}647648static int i2c_bfin_twi_probe(struct platform_device *pdev)649{650struct bfin_twi_iface *iface;651struct i2c_adapter *p_adap;652struct resource *res;653int rc;654unsigned int clkhilow;655656iface = kzalloc(sizeof(struct bfin_twi_iface), GFP_KERNEL);657if (!iface) {658dev_err(&pdev->dev, "Cannot allocate memory\n");659rc = -ENOMEM;660goto out_error_nomem;661}662663spin_lock_init(&(iface->lock));664665/* Find and map our resources */666res = platform_get_resource(pdev, IORESOURCE_MEM, 0);667if (res == NULL) {668dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n");669rc = -ENOENT;670goto out_error_get_res;671}672673iface->regs_base = ioremap(res->start, resource_size(res));674if (iface->regs_base == NULL) {675dev_err(&pdev->dev, "Cannot map IO\n");676rc = -ENXIO;677goto out_error_ioremap;678}679680iface->irq = platform_get_irq(pdev, 0);681if (iface->irq < 0) {682dev_err(&pdev->dev, "No IRQ specified\n");683rc = -ENOENT;684goto out_error_no_irq;685}686687p_adap = &iface->adap;688p_adap->nr = pdev->id;689strlcpy(p_adap->name, pdev->name, sizeof(p_adap->name));690p_adap->algo = &bfin_twi_algorithm;691p_adap->algo_data = iface;692p_adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;693p_adap->dev.parent = &pdev->dev;694p_adap->timeout = 5 * HZ;695p_adap->retries = 3;696697rc = peripheral_request_list(pin_req[pdev->id], "i2c-bfin-twi");698if (rc) {699dev_err(&pdev->dev, "Can't setup pin mux!\n");700goto out_error_pin_mux;701}702703rc = request_irq(iface->irq, bfin_twi_interrupt_entry,704IRQF_DISABLED, pdev->name, iface);705if (rc) {706dev_err(&pdev->dev, "Can't get IRQ %d !\n", iface->irq);707rc = -ENODEV;708goto out_error_req_irq;709}710711/* Set TWI internal clock as 10MHz */712write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F);713714/*715* We will not end up with a CLKDIV=0 because no one will specify716* 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)717*/718clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2;719720/* Set Twi interface clock as specified */721write_CLKDIV(iface, (clkhilow << 8) | clkhilow);722723/* Enable TWI */724write_CONTROL(iface, read_CONTROL(iface) | TWI_ENA);725SSYNC();726727rc = i2c_add_numbered_adapter(p_adap);728if (rc < 0) {729dev_err(&pdev->dev, "Can't add i2c adapter!\n");730goto out_error_add_adapter;731}732733platform_set_drvdata(pdev, iface);734735dev_info(&pdev->dev, "Blackfin BF5xx on-chip I2C TWI Contoller, "736"regs_base@%p\n", iface->regs_base);737738return 0;739740out_error_add_adapter:741free_irq(iface->irq, iface);742out_error_req_irq:743out_error_no_irq:744peripheral_free_list(pin_req[pdev->id]);745out_error_pin_mux:746iounmap(iface->regs_base);747out_error_ioremap:748out_error_get_res:749kfree(iface);750out_error_nomem:751return rc;752}753754static int i2c_bfin_twi_remove(struct platform_device *pdev)755{756struct bfin_twi_iface *iface = platform_get_drvdata(pdev);757758platform_set_drvdata(pdev, NULL);759760i2c_del_adapter(&(iface->adap));761free_irq(iface->irq, iface);762peripheral_free_list(pin_req[pdev->id]);763iounmap(iface->regs_base);764kfree(iface);765766return 0;767}768769static struct platform_driver i2c_bfin_twi_driver = {770.probe = i2c_bfin_twi_probe,771.remove = i2c_bfin_twi_remove,772.suspend = i2c_bfin_twi_suspend,773.resume = i2c_bfin_twi_resume,774.driver = {775.name = "i2c-bfin-twi",776.owner = THIS_MODULE,777},778};779780static int __init i2c_bfin_twi_init(void)781{782return platform_driver_register(&i2c_bfin_twi_driver);783}784785static void __exit i2c_bfin_twi_exit(void)786{787platform_driver_unregister(&i2c_bfin_twi_driver);788}789790subsys_initcall(i2c_bfin_twi_init);791module_exit(i2c_bfin_twi_exit);792793MODULE_AUTHOR("Bryan Wu, Sonic Zhang");794MODULE_DESCRIPTION("Blackfin BF5xx on-chip I2C TWI Contoller Driver");795MODULE_LICENSE("GPL");796MODULE_ALIAS("platform:i2c-bfin-twi");797798799