1aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* 2aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Copyright (C) 2002 Motorola GSG-China 3aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 4aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * This program is free software; you can redistribute it and/or 5aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * modify it under the terms of the GNU General Public License 6aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * as published by the Free Software Foundation; either version 2 7aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * of the License, or (at your option) any later version. 8aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 9aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * This program is distributed in the hope that it will be useful, 10aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * but WITHOUT ANY WARRANTY; without even the implied warranty of 11aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * GNU General Public License for more details. 13aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 14aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * You should have received a copy of the GNU General Public License 15aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * along with this program; if not, write to the Free Software 16aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 17aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * USA. 18aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 19aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Author: 20aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Darius Augulis, Teltonika Inc. 21aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 22aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Desc.: 23aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Implementation of I2C Adapter/Algorithm Driver 24aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * for I2C Bus integrated in Freescale i.MX/MXC processors 25aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 26aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Derived from Motorola GSG China I2C example driver 27aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 28aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de 29aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de 30aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Copyright (C) 2007 RightHand Technologies, Inc. 31aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt> 32aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 33aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis */ 34aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 35aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/** Includes ******************************************************************* 36aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis*******************************************************************************/ 37aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 38aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/init.h> 39aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/kernel.h> 40aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/module.h> 41aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/errno.h> 42aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/err.h> 43aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/interrupt.h> 44aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/delay.h> 45aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/i2c.h> 46aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/io.h> 47aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/sched.h> 48aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/platform_device.h> 49aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <linux/clk.h> 505a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 51dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo#include <linux/of.h> 52dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo#include <linux/of_device.h> 53dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo#include <linux/of_i2c.h> 54aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 55aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <mach/irqs.h> 56aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <mach/hardware.h> 57aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#include <mach/i2c.h> 58aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 59aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/** Defines ******************************************************************** 60aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis*******************************************************************************/ 61aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 62aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* This will be the driver name the kernel reports */ 63aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define DRIVER_NAME "imx-i2c" 64aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 65aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* Default value */ 66aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_BIT_RATE 100000 /* 100kHz */ 67aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 68aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* IMX I2C registers */ 69aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_IADR 0x00 /* i2c slave address */ 70aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_IFDR 0x04 /* i2c frequency divider */ 71aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_I2CR 0x08 /* i2c control */ 72aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_I2SR 0x0C /* i2c status */ 73aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define IMX_I2C_I2DR 0x10 /* i2c transfer data */ 74aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 75aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* Bits of IMX I2C registers */ 76aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_RXAK 0x01 77aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_IIF 0x02 78aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_SRW 0x04 79aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_IAL 0x10 80aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_IBB 0x20 81aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_IAAS 0x40 82aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2SR_ICF 0x80 83aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_RSTA 0x04 84aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_TXAK 0x08 85aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_MTX 0x10 86aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_MSTA 0x20 87aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_IIEN 0x40 88aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#define I2CR_IEN 0x80 89aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 90aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/** Variables ****************************************************************** 91aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis*******************************************************************************/ 92aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 93aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/* 94aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * sorted list of clock divider, register value pairs 95aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * taken from table 26-5, p.26-9, Freescale i.MX 96aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Integrated Portable System Processor Reference Manual 97aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007 98aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * 99aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * Duplicated divider values removed from list 100aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis */ 101aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 102aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic u16 __initdata i2c_clk_div[50][2] = { 103aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 }, 104aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 }, 105aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 }, 106aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B }, 107aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, 108aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 }, 109aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, 110aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 }, 111aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 }, 112aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, 113aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E }, 114aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, 115aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis { 3072, 0x1E }, { 3840, 0x1F } 116aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis}; 117aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 118aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstruct imx_i2c_struct { 119aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct i2c_adapter adapter; 120aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct resource *res; 121aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct clk *clk; 122aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis void __iomem *base; 123aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int irq; 124aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis wait_queue_head_t queue; 125aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned long i2csr; 12665de394df21f8ccc61525f77b0e4ee6940a0932eWolfram Sang unsigned int disable_delay; 12743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao int stopped; 128db3a3d4ef7f676501325ae9c7ce0c193c2c1b28fRichard Zhao unsigned int ifdr; /* IMX_I2C_IFDR */ 129aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis}; 130aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 131dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guostatic const struct of_device_id i2c_imx_dt_ids[] = { 132dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo { .compatible = "fsl,imx1-i2c", }, 133dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo { /* sentinel */ } 134dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo}; 135dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo 136aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis/** Functions for IMX I2C adapter driver *************************************** 137aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis*******************************************************************************/ 138aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 13943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhaostatic int i2c_imx_bus_busy(struct imx_i2c_struct *i2c_imx, int for_busy) 140aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 141aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned long orig_jiffies = jiffies; 14243309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao unsigned int temp; 143aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 144aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); 145aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 14643309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao while (1) { 14743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao temp = readb(i2c_imx->base + IMX_I2C_I2SR); 14843309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao if (for_busy && (temp & I2SR_IBB)) 14943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao break; 15043309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao if (!for_busy && !(temp & I2SR_IBB)) 15143309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao break; 152da9c99fc32e2d84f80672d192a7aaf7239057a2eArnaud Patard if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) { 153aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 154aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> I2C bus is busy\n", __func__); 155da9c99fc32e2d84f80672d192a7aaf7239057a2eArnaud Patard return -ETIMEDOUT; 156aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 157aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis schedule(); 158aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 159aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 160aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 161aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 162aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 163aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int i2c_imx_trx_complete(struct imx_i2c_struct *i2c_imx) 164aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 165e39428d53d080ad2615b772d7f99d2a70c2aaab2Marc Kleine-Budde wait_event_timeout(i2c_imx->queue, i2c_imx->i2csr & I2SR_IIF, HZ / 10); 166aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 167e39428d53d080ad2615b772d7f99d2a70c2aaab2Marc Kleine-Budde if (unlikely(!(i2c_imx->i2csr & I2SR_IIF))) { 168aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> Timeout\n", __func__); 169aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return -ETIMEDOUT; 170aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 171aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> TRX complete\n", __func__); 172aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->i2csr = 0; 173aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 174aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 175aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 176aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int i2c_imx_acked(struct imx_i2c_struct *i2c_imx) 177aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 178aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (readb(i2c_imx->base + IMX_I2C_I2SR) & I2SR_RXAK) { 179aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> No ACK\n", __func__); 180aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return -EIO; /* No ACK */ 181aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 182aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 183aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> ACK received\n", __func__); 184aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 185aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 186aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 18743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhaostatic int i2c_imx_start(struct imx_i2c_struct *i2c_imx) 188aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 189aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int temp = 0; 19043309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao int result; 191aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 192aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); 193aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 19483914337d117ac6537c2fff6c32e2c3a9810f7d4Richard Zhao clk_prepare_enable(i2c_imx->clk); 195db3a3d4ef7f676501325ae9c7ce0c193c2c1b28fRichard Zhao writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR); 196aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Enable I2C controller */ 19743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao writeb(0, i2c_imx->base + IMX_I2C_I2SR); 198aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(I2CR_IEN, i2c_imx->base + IMX_I2C_I2CR); 19943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao 20043309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao /* Wait controller to be stable */ 20143309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao udelay(50); 20243309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao 203aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Start I2C transaction */ 204aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 205aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp |= I2CR_MSTA; 206aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 20743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao result = i2c_imx_bus_busy(i2c_imx, 1); 20843309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao if (result) 20943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao return result; 21043309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao i2c_imx->stopped = 0; 21143309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao 212aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp |= I2CR_IIEN | I2CR_MTX | I2CR_TXAK; 213aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 21443309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao return result; 215aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 216aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 217aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) 218aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 219aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int temp = 0; 220aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 22143309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao if (!i2c_imx->stopped) { 22243309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao /* Stop I2C transaction */ 22343309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); 22443309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao temp = readb(i2c_imx->base + IMX_I2C_I2CR); 22543309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao temp &= ~(I2CR_MSTA | I2CR_MTX); 22643309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 22743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao } 228a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao if (cpu_is_mx1()) { 229a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao /* 230a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao * This delay caused by an i.MXL hardware bug. 231a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao * If no (or too short) delay, no "STOP" bit will be generated. 232a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao */ 233a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao udelay(i2c_imx->disable_delay); 234a4094a76e6a45691b8f9108060b750a48b4c4563Richard Zhao } 23543309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao 236a1ee06b72968d80ab9362ec61143c4f090cc2d1bValentin Longchamp if (!i2c_imx->stopped) { 23743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao i2c_imx_bus_busy(i2c_imx, 0); 238a1ee06b72968d80ab9362ec61143c4f090cc2d1bValentin Longchamp i2c_imx->stopped = 1; 239a1ee06b72968d80ab9362ec61143c4f090cc2d1bValentin Longchamp } 24043309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao 241aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Disable I2C controller */ 242aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_I2CR); 24383914337d117ac6537c2fff6c32e2c3a9810f7d4Richard Zhao clk_disable_unprepare(i2c_imx->clk); 244aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 245aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 246aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, 247aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int rate) 248aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 249aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int i2c_clk_rate; 250aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int div; 251aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int i; 252aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 253aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Divider value calculation */ 254aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_clk_rate = clk_get_rate(i2c_imx->clk); 255aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis div = (i2c_clk_rate + rate - 1) / rate; 256aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (div < i2c_clk_div[0][0]) 257aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i = 0; 258aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0]) 259aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i = ARRAY_SIZE(i2c_clk_div) - 1; 260aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis else 261aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis for (i = 0; i2c_clk_div[i][0] < div; i++); 262aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 263db3a3d4ef7f676501325ae9c7ce0c193c2c1b28fRichard Zhao /* Store divider value */ 264db3a3d4ef7f676501325ae9c7ce0c193c2c1b28fRichard Zhao i2c_imx->ifdr = i2c_clk_div[i][1]; 265aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 266aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* 267aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * There dummy delay is calculated. 268aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * It should be about one I2C clock period long. 269aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * This delay is used in I2C bus disable function 270aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis * to fix chip hardware bug. 271aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis */ 27265de394df21f8ccc61525f77b0e4ee6940a0932eWolfram Sang i2c_imx->disable_delay = (500000U * i2c_clk_div[i][0] 273aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis + (i2c_clk_rate / 2) - 1) / (i2c_clk_rate / 2); 274aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 275aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* dev_dbg() can't be used, because adapter is not yet registered */ 276aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#ifdef CONFIG_I2C_DEBUG_BUS 277aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n", 278aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, i2c_clk_rate, div); 279aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n", 280aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, i2c_clk_div[i][1], i2c_clk_div[i][0]); 281aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#endif 282aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 283aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 284aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic irqreturn_t i2c_imx_isr(int irq, void *dev_id) 285aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 286aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct imx_i2c_struct *i2c_imx = dev_id; 287aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int temp; 288aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 289aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2SR); 290aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (temp & I2SR_IIF) { 291aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* save status register */ 292aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->i2csr = temp; 293aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp &= ~I2SR_IIF; 294aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2SR); 295e39428d53d080ad2615b772d7f99d2a70c2aaab2Marc Kleine-Budde wake_up(&i2c_imx->queue); 296aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return IRQ_HANDLED; 297aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 298aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 299aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return IRQ_NONE; 300aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 301aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 302aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int i2c_imx_write(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) 303aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 304aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int i, result; 305aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 306aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> write slave address: addr=0x%x\n", 307aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, msgs->addr << 1); 308aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 309aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* write slave address */ 310aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(msgs->addr << 1, i2c_imx->base + IMX_I2C_I2DR); 311aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_trx_complete(i2c_imx); 312aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 313aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 314aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_acked(i2c_imx); 315aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 316aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 317aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> write data\n", __func__); 318aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 319aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* write data */ 320aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis for (i = 0; i < msgs->len; i++) { 321aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 322aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> write byte: B%d=0x%X\n", 323aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, i, msgs->buf[i]); 324aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(msgs->buf[i], i2c_imx->base + IMX_I2C_I2DR); 325aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_trx_complete(i2c_imx); 326aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 327aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 328aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_acked(i2c_imx); 329aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 330aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 331aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 332aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 333aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 334aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 335aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int i2c_imx_read(struct imx_i2c_struct *i2c_imx, struct i2c_msg *msgs) 336aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 337aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int i, result; 338aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int temp; 339aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 340aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 341aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> write slave address: addr=0x%x\n", 342aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, (msgs->addr << 1) | 0x01); 343aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 344aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* write slave address */ 345aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb((msgs->addr << 1) | 0x01, i2c_imx->base + IMX_I2C_I2DR); 346aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_trx_complete(i2c_imx); 347aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 348aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 349aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_acked(i2c_imx); 350aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 351aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 352aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 353aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> setup bus\n", __func__); 354aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 355aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* setup bus to read data */ 356aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 357aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp &= ~I2CR_MTX; 358aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (msgs->len - 1) 359aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp &= ~I2CR_TXAK; 360aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 361aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis readb(i2c_imx->base + IMX_I2C_I2DR); /* dummy read */ 362aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 363aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> read data\n", __func__); 364aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 365aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* read data */ 366aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis for (i = 0; i < msgs->len; i++) { 367aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_trx_complete(i2c_imx); 368aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 369aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return result; 370aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (i == (msgs->len - 1)) { 37143309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao /* It must generate STOP before read I2DR to prevent 37243309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao controller from generating another clock cycle */ 373aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 374aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> clear MSTA\n", __func__); 375aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 37643309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao temp &= ~(I2CR_MSTA | I2CR_MTX); 377aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 37843309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao i2c_imx_bus_busy(i2c_imx, 0); 37943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao i2c_imx->stopped = 1; 380aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } else if (i == (msgs->len - 2)) { 381aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 382aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> set TXAK\n", __func__); 383aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 384aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp |= I2CR_TXAK; 385aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 386aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 387aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis msgs->buf[i] = readb(i2c_imx->base + IMX_I2C_I2DR); 388aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 389aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> read byte: B%d=0x%X\n", 390aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis __func__, i, msgs->buf[i]); 391aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 392aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 393aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 394aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 395aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int i2c_imx_xfer(struct i2c_adapter *adapter, 396aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct i2c_msg *msgs, int num) 397aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 398aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis unsigned int i, temp; 399aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int result; 400aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct imx_i2c_struct *i2c_imx = i2c_get_adapdata(adapter); 401aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 402aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); 403aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 40443309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao /* Start I2C transfer */ 40543309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao result = i2c_imx_start(i2c_imx); 406aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (result) 407aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis goto fail0; 408aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 409aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* read/write data */ 410aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis for (i = 0; i < num; i++) { 411aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (i) { 412aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 413aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> repeated start\n", __func__); 414aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 415aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp |= I2CR_RSTA; 416aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(temp, i2c_imx->base + IMX_I2C_I2CR); 41743309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao result = i2c_imx_bus_busy(i2c_imx, 1); 41843309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao if (result) 41943309f3b521302bb66c4c9e66704dd3675e4d725Richard Zhao goto fail0; 420aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 421aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 422aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> transfer message: %d\n", __func__, i); 423aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* write/read data */ 424aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#ifdef CONFIG_I2C_DEBUG_BUS 425aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2CR); 426aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> CONTROL: IEN=%d, IIEN=%d, " 427aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "MSTA=%d, MTX=%d, TXAK=%d, RSTA=%d\n", __func__, 428aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2CR_IEN ? 1 : 0), (temp & I2CR_IIEN ? 1 : 0), 429aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2CR_MSTA ? 1 : 0), (temp & I2CR_MTX ? 1 : 0), 430aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2CR_TXAK ? 1 : 0), (temp & I2CR_RSTA ? 1 : 0)); 431aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis temp = readb(i2c_imx->base + IMX_I2C_I2SR); 432aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, 433aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "<%s> STATUS: ICF=%d, IAAS=%d, IBB=%d, " 434aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis "IAL=%d, SRW=%d, IIF=%d, RXAK=%d\n", __func__, 435aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2SR_ICF ? 1 : 0), (temp & I2SR_IAAS ? 1 : 0), 436aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2SR_IBB ? 1 : 0), (temp & I2SR_IAL ? 1 : 0), 437aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2SR_SRW ? 1 : 0), (temp & I2SR_IIF ? 1 : 0), 438aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (temp & I2SR_RXAK ? 1 : 0)); 439aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis#endif 440aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (msgs[i].flags & I2C_M_RD) 441aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_read(i2c_imx, &msgs[i]); 442aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis else 443aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis result = i2c_imx_write(i2c_imx, &msgs[i]); 444da9c99fc32e2d84f80672d192a7aaf7239057a2eArnaud Patard if (result) 445da9c99fc32e2d84f80672d192a7aaf7239057a2eArnaud Patard goto fail0; 446aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 447aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 448aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisfail0: 449aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Stop I2C transfer */ 450aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx_stop(i2c_imx); 451aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 452aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "<%s> exit with: %s: %d\n", __func__, 453aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (result < 0) ? "error" : "success msg", 454aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis (result < 0) ? result : num); 455aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return (result < 0) ? result : num; 456aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 457aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 458aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic u32 i2c_imx_func(struct i2c_adapter *adapter) 459aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 460aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 461aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 462aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 463aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic struct i2c_algorithm i2c_imx_algo = { 464aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .master_xfer = i2c_imx_xfer, 465aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .functionality = i2c_imx_func, 466aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis}; 467aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 468aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int __init i2c_imx_probe(struct platform_device *pdev) 469aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 470aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct imx_i2c_struct *i2c_imx; 471aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct resource *res; 472593702c71a415b153bd81fbc487394979f3e7a63Shawn Guo struct imxi2c_platform_data *pdata = pdev->dev.platform_data; 473aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis void __iomem *base; 474aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis resource_size_t res_size; 475dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo int irq, bitrate; 476aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis int ret; 477aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 478aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&pdev->dev, "<%s>\n", __func__); 479aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 480aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 481aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (!res) { 482aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "can't get device resources\n"); 483aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return -ENOENT; 484aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 485aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis irq = platform_get_irq(pdev, 0); 486aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (irq < 0) { 487aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "can't get irq number\n"); 488aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return -ENOENT; 489aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 490aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 491aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis res_size = resource_size(res); 4924927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König 4934927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König if (!request_mem_region(res->start, res_size, DRIVER_NAME)) { 494593702c71a415b153bd81fbc487394979f3e7a63Shawn Guo dev_err(&pdev->dev, "request_mem_region failed\n"); 495593702c71a415b153bd81fbc487394979f3e7a63Shawn Guo return -EBUSY; 4964927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König } 4974927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König 498aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis base = ioremap(res->start, res_size); 499aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (!base) { 500aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "ioremap failed\n"); 501aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis ret = -EIO; 5024927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König goto fail1; 503aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 504aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 505aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx = kzalloc(sizeof(struct imx_i2c_struct), GFP_KERNEL); 506aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (!i2c_imx) { 507aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "can't allocate interface\n"); 508aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis ret = -ENOMEM; 509309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis goto fail2; 510309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis } 511309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis 512aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Setup i2c_imx driver structure */ 513aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis strcpy(i2c_imx->adapter.name, pdev->name); 514aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->adapter.owner = THIS_MODULE; 515aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->adapter.algo = &i2c_imx_algo; 516aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->adapter.dev.parent = &pdev->dev; 517aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->adapter.nr = pdev->id; 518dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo i2c_imx->adapter.dev.of_node = pdev->dev.of_node; 519aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->irq = irq; 520aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->base = base; 521aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->res = res; 522aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 523aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Get I2C clock */ 524aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->clk = clk_get(&pdev->dev, "i2c_clk"); 525aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (IS_ERR(i2c_imx->clk)) { 526aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis ret = PTR_ERR(i2c_imx->clk); 527aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "can't get I2C clock\n"); 528309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis goto fail3; 529aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 530aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 531aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Request IRQ */ 532aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis ret = request_irq(i2c_imx->irq, i2c_imx_isr, 0, pdev->name, i2c_imx); 533aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (ret) { 534aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "can't claim irq %d\n", i2c_imx->irq); 535309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis goto fail4; 536aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 537aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 538aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Init queue */ 539aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis init_waitqueue_head(&i2c_imx->queue); 540aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 541aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Set up adapter data */ 542aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_set_adapdata(&i2c_imx->adapter, i2c_imx); 543aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 544aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Set up clock divider */ 545dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo bitrate = IMX_I2C_BIT_RATE; 546dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo ret = of_property_read_u32(pdev->dev.of_node, 547dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo "clock-frequency", &bitrate); 548dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo if (ret < 0 && pdata && pdata->bitrate) 549dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo bitrate = pdata->bitrate; 550dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo i2c_imx_set_clk(i2c_imx, bitrate); 551aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 552aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Set up chip registers to defaults */ 553aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_I2CR); 554aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_I2SR); 555aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 556aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Add I2C adapter */ 557aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis ret = i2c_add_numbered_adapter(&i2c_imx->adapter); 558aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis if (ret < 0) { 559aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_err(&pdev->dev, "registration failed\n"); 560309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulis goto fail5; 561aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 562aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 563dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo of_i2c_register_devices(&i2c_imx->adapter); 564dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo 565aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* Set up platform driver data */ 566aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis platform_set_drvdata(pdev, i2c_imx); 567aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 568aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "claimed irq %d\n", i2c_imx->irq); 569aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "device resources from 0x%x to 0x%x\n", 570aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->res->start, i2c_imx->res->end); 571aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "allocated %d bytes at 0x%x \n", 572aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis res_size, i2c_imx->res->start); 573aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n", 574aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_imx->adapter.name); 575aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n"); 576aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 577aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; /* Return OK */ 578aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 579309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulisfail5: 580aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis free_irq(i2c_imx->irq, i2c_imx); 581309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulisfail4: 582aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis clk_put(i2c_imx->clk); 583309c18d2cd7fbef9a30634c031ddfa4fecd22848Darius Augulisfail3: 584aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis kfree(i2c_imx); 5854927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-Königfail2: 586aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis iounmap(base); 5874927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-Königfail1: 5884927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König release_mem_region(res->start, resource_size(res)); 589aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return ret; /* Return error number */ 590aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 591aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 592aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int __exit i2c_imx_remove(struct platform_device *pdev) 593aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 594aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis struct imx_i2c_struct *i2c_imx = platform_get_drvdata(pdev); 595aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 596aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* remove adapter */ 597aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis dev_dbg(&i2c_imx->adapter.dev, "adapter removed\n"); 598aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis i2c_del_adapter(&i2c_imx->adapter); 599aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis platform_set_drvdata(pdev, NULL); 600aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 601aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* free interrupt */ 602aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis free_irq(i2c_imx->irq, i2c_imx); 603aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 604aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis /* setup chip registers to defaults */ 605aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_IADR); 606aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_IFDR); 607aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_I2CR); 608aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis writeb(0, i2c_imx->base + IMX_I2C_I2SR); 609aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 610aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis clk_put(i2c_imx->clk); 611aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 612aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis iounmap(i2c_imx->base); 6134927fbf11dc1057cd9c94dd40358e5f98c999311Uwe Kleine-König release_mem_region(i2c_imx->res->start, resource_size(i2c_imx->res)); 614aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis kfree(i2c_imx); 615aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return 0; 616aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 617aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 618aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic struct platform_driver i2c_imx_driver = { 619aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .remove = __exit_p(i2c_imx_remove), 620aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .driver = { 621aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .name = DRIVER_NAME, 622aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis .owner = THIS_MODULE, 623dfcd04b19d16c0016c705ed96a8b3cfa5315a2e9Shawn Guo .of_match_table = i2c_imx_dt_ids, 624aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis } 625aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis}; 626aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 627aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic int __init i2c_adap_imx_init(void) 628aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 629aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis return platform_driver_probe(&i2c_imx_driver, i2c_imx_probe); 630aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 6315d3f33318a6c1f79f89e3dd2c7ddc11e0da14895Wolfram Sangsubsys_initcall(i2c_adap_imx_init); 632aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 633aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulisstatic void __exit i2c_adap_imx_exit(void) 634aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis{ 635aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis platform_driver_unregister(&i2c_imx_driver); 636aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis} 637aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulismodule_exit(i2c_adap_imx_exit); 638aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius Augulis 639aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius AugulisMODULE_LICENSE("GPL"); 640aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius AugulisMODULE_AUTHOR("Darius Augulis"); 641aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius AugulisMODULE_DESCRIPTION("I2C adapter driver for IMX I2C bus"); 642aa11e38ce6fe8846fec046a95cecd5d4690c48cdDarius AugulisMODULE_ALIAS("platform:" DRIVER_NAME); 643