1fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie/* 2fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Synopsys DesignWare I2C adapter driver (master only). 3fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 4fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Based on the TI DAVINCI I2C adapter driver. 5fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 6fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Copyright (C) 2006 Texas Instruments. 7fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Copyright (C) 2007 MontaVista Software Inc. 8fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Copyright (C) 2009 Provigent Ltd. 9fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * Copyright (C) 2011 Intel corporation. 10fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 11fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * ---------------------------------------------------------------------------- 12fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 13fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * This program is free software; you can redistribute it and/or modify 14fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * it under the terms of the GNU General Public License as published by 15fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * the Free Software Foundation; either version 2 of the License, or 16fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * (at your option) any later version. 17fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 18fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * This program is distributed in the hope that it will be useful, 19fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * but WITHOUT ANY WARRANTY; without even the implied warranty of 20fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * GNU General Public License for more details. 22fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * ---------------------------------------------------------------------------- 23fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie * 24fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie */ 25fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 26fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/kernel.h> 27fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/module.h> 28fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/delay.h> 29fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/i2c.h> 30fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/errno.h> 31fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/sched.h> 32fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/err.h> 33fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/interrupt.h> 34fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/io.h> 35fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/slab.h> 36fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include <linux/pci.h> 3718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie#include <linux/pm_runtime.h> 38fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#include "i2c-designware-core.h" 39fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 40fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#define DRIVER_NAME "i2c-designware-pci" 41fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 42fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewieenum dw_pci_ctl_id_t { 43fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie moorestown_0, 44fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie moorestown_1, 45fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie moorestown_2, 46fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 47fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_0, 48fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_1, 49fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_2, 50fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_3, 51fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_4, 52fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie medfield_5, 53089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg 54089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg baytrail, 55157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg haswell, 56fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 57fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 588efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Eestruct dw_scl_sda_cfg { 598efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee u32 ss_hcnt; 608efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee u32 fs_hcnt; 618efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee u32 ss_lcnt; 628efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee u32 fs_lcnt; 638efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee u32 sda_hold; 648efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee}; 658efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee 66fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewiestruct dw_pci_controller { 67fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie u32 bus_num; 68fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie u32 bus_cfg; 69fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie u32 tx_fifo_depth; 70fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie u32 rx_fifo_depth; 71fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie u32 clk_khz; 72ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee u32 functionality; 738efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee struct dw_scl_sda_cfg *scl_sda_cfg; 74fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 75fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 76fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie#define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \ 77fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie DW_IC_CON_SLAVE_DISABLE | \ 78fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie DW_IC_CON_RESTART_EN) 79fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 80ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee#define DW_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \ 81ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee I2C_FUNC_SMBUS_BYTE | \ 82ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee I2C_FUNC_SMBUS_BYTE_DATA | \ 83ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee I2C_FUNC_SMBUS_WORD_DATA | \ 84ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee I2C_FUNC_SMBUS_I2C_BLOCK) 85ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee 868efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee/* BayTrail HCNT/LCNT/SDA hold time */ 878efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Eestatic struct dw_scl_sda_cfg byt_config = { 888efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .ss_hcnt = 0x200, 898efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .fs_hcnt = 0x55, 908efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .ss_lcnt = 0x200, 918efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .fs_lcnt = 0x99, 928efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .sda_hold = 0x6, 938efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee}; 948efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee 95157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg/* Haswell HCNT/LCNT/SDA hold time */ 96157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerbergstatic struct dw_scl_sda_cfg hsw_config = { 97157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .ss_hcnt = 0x01b0, 98157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .fs_hcnt = 0x48, 99157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .ss_lcnt = 0x01fb, 100157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .fs_lcnt = 0xa0, 101157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .sda_hold = 0x9, 102157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg}; 103157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg 104fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewiestatic struct dw_pci_controller dw_pci_controllers[] = { 105fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [moorestown_0] = { 106fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 0, 107fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 108fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 109fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 110fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 111fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 112fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [moorestown_1] = { 113fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 1, 114fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 115fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 116fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 117fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 118fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 119fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [moorestown_2] = { 120fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 2, 121fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 122fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 123fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 124fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 125fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 126fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_0] = { 127fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 0, 128fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 129fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 130fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 131fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 132fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 133fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_1] = { 134fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 1, 135fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 136fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 137fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 138fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 139fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 140fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_2] = { 141fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 2, 142fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 143fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 144fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 145fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 146fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 147fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_3] = { 148fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 3, 149fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_STD, 150fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 151fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 152fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 153fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 154fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_4] = { 155fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 4, 156fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 157fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 158fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 159fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 160fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 161fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie [medfield_5] = { 162fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_num = 5, 163fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 164fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .tx_fifo_depth = 32, 165fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .rx_fifo_depth = 32, 166fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .clk_khz = 25000, 167fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie }, 168089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg [baytrail] = { 169089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg .bus_num = -1, 170089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 171089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg .tx_fifo_depth = 32, 172089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg .rx_fifo_depth = 32, 173089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg .clk_khz = 100000, 174ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee .functionality = I2C_FUNC_10BIT_ADDR, 1758efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee .scl_sda_cfg = &byt_config, 176089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg }, 177157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg [haswell] = { 178157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .bus_num = -1, 179157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .bus_cfg = INTEL_MID_STD_CFG | DW_IC_CON_SPEED_FAST, 180157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .tx_fifo_depth = 32, 181157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .rx_fifo_depth = 32, 182157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .clk_khz = 100000, 183157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .functionality = I2C_FUNC_10BIT_ADDR, 184157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg .scl_sda_cfg = &hsw_config, 185157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg }, 186fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 1870409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox 188fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewiestatic struct i2c_algorithm i2c_dw_algo = { 189fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .master_xfer = i2c_dw_xfer, 190fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .functionality = i2c_dw_func, 191fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 192fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 193be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg#ifdef CONFIG_PM 19452c2843322362bfd847bdda1d3cebc751de68e5bOctavian Purdilastatic int i2c_dw_pci_suspend(struct device *dev) 19518dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie{ 19652c2843322362bfd847bdda1d3cebc751de68e5bOctavian Purdila struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); 19718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 198be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg i2c_dw_disable(pci_get_drvdata(pdev)); 19918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie return 0; 20018dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie} 20118dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 20252c2843322362bfd847bdda1d3cebc751de68e5bOctavian Purdilastatic int i2c_dw_pci_resume(struct device *dev) 20318dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie{ 20452c2843322362bfd847bdda1d3cebc751de68e5bOctavian Purdila struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); 20518dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 206be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg return i2c_dw_init(pci_get_drvdata(pdev)); 20718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie} 208be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg#endif 20918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 210be58eda775c8753a3e92ec398124279abc59aa0dMika Westerbergstatic UNIVERSAL_DEV_PM_OPS(i2c_dw_pm_ops, i2c_dw_pci_suspend, 211be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg i2c_dw_pci_resume, NULL); 21218dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 213fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewiestatic u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) 214fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie{ 215fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie return dev->controller->clk_khz; 216fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie} 217fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 2180b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic int i2c_dw_pci_probe(struct pci_dev *pdev, 219ca0c1ff528a332e6f83d4566c2c8eb05b108c83cAndy Shevchenko const struct pci_device_id *id) 220fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie{ 221fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie struct dw_i2c_dev *dev; 222fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie struct i2c_adapter *adap; 223fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie int r; 224fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie struct dw_pci_controller *controller; 2258efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee struct dw_scl_sda_cfg *cfg; 226fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 227fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) { 228ca0c1ff528a332e6f83d4566c2c8eb05b108c83cAndy Shevchenko dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__, 229fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie id->driver_data); 230fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie return -EINVAL; 231fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie } 232fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 233fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie controller = &dw_pci_controllers[id->driver_data]; 234fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 23576cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko r = pcim_enable_device(pdev); 236fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (r) { 237fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev_err(&pdev->dev, "Failed to enable I2C PCI device (%d)\n", 238fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie r); 23976cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return r; 240fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie } 241fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 24276cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko r = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); 243fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (r) { 244fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev_err(&pdev->dev, "I/O memory remapping failed\n"); 24576cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return r; 246fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie } 247fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 24876cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL); 24976cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko if (!dev) 25076cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return -ENOMEM; 251fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 252fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie init_completion(&dev->cmd_complete); 253fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie mutex_init(&dev->lock); 254fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->clk = NULL; 255fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->controller = controller; 256fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz; 25776cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko dev->base = pcim_iomap_table(pdev)[0]; 25876cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko dev->dev = &pdev->dev; 259ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee dev->functionality = controller->functionality | 260ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee DW_DEFAULT_FUNCTIONALITY; 261ceccd298f6fd537457576017d604fc5aa6d3c82aChew, Chiau Ee 262fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->master_cfg = controller->bus_cfg; 2638efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee if (controller->scl_sda_cfg) { 2648efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee cfg = controller->scl_sda_cfg; 2658efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee dev->ss_hcnt = cfg->ss_hcnt; 2668efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee dev->fs_hcnt = cfg->fs_hcnt; 2678efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee dev->ss_lcnt = cfg->ss_lcnt; 2688efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee dev->fs_lcnt = cfg->fs_lcnt; 2698efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee dev->sda_hold_time = cfg->sda_hold; 2708efd1e9ee3bd55e20cb36e56ca53096cf2b3a930Chew, Chiau Ee } 271fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 272fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie pci_set_drvdata(pdev, dev); 273fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 274fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->tx_fifo_depth = controller->tx_fifo_depth; 275fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev->rx_fifo_depth = controller->rx_fifo_depth; 276fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie r = i2c_dw_init(dev); 277fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (r) 27876cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return r; 279fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 280fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap = &dev->adapter; 281fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie i2c_set_adapdata(adap, dev); 282fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap->owner = THIS_MODULE; 283fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap->class = 0; 284fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap->algo = &i2c_dw_algo; 285fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap->dev.parent = &pdev->dev; 286fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie adap->nr = controller->bus_num; 287089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg 288089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg snprintf(adap->name, sizeof(adap->name), "i2c-designware-pci"); 289fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 29076cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko r = devm_request_irq(&pdev->dev, pdev->irq, i2c_dw_isr, IRQF_SHARED, 29176cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko adap->name, dev); 292fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (r) { 293fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); 29476cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return r; 295fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie } 296fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 297fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie i2c_dw_disable_int(dev); 298fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie i2c_dw_clear_int(dev); 299fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie r = i2c_add_numbered_adapter(adap); 300fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie if (r) { 301fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie dev_err(&pdev->dev, "failure adding adapter\n"); 30276cf3fc844a46b5cdb94da98bffcbd45d4c355b8Andy Shevchenko return r; 303fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie } 304fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 30543452335224bc0cbd605c6aee82b5c9c33e94cc6Mika Westerberg pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); 30643452335224bc0cbd605c6aee82b5c9c33e94cc6Mika Westerberg pm_runtime_use_autosuspend(&pdev->dev); 307be58eda775c8753a3e92ec398124279abc59aa0dMika Westerberg pm_runtime_put_autosuspend(&pdev->dev); 30818dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie pm_runtime_allow(&pdev->dev); 30918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 310fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie return 0; 311fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie} 312fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 3130b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic void i2c_dw_pci_remove(struct pci_dev *pdev) 314fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie{ 315fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie struct dw_i2c_dev *dev = pci_get_drvdata(pdev); 316fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 31718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie i2c_dw_disable(dev); 31818dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie pm_runtime_forbid(&pdev->dev); 31918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie pm_runtime_get_noresume(&pdev->dev); 32018dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie 321fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie i2c_del_adapter(&dev->adapter); 322fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie} 323fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 324fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie/* work with hotplug and coldplug */ 325fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk BrandewieMODULE_ALIAS("i2c_designware-pci"); 326fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 327392debf11656dedd79da44416747d5b2b1747f5eJingoo Hanstatic const struct pci_device_id i2_designware_pci_ids[] = { 328fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie /* Moorestown */ 329fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 }, 330fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 }, 331fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0804), moorestown_2 }, 332fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie /* Medfield */ 333fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0817), medfield_3,}, 334fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0818), medfield_4 }, 335fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x0819), medfield_5 }, 336fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x082C), medfield_0 }, 337fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x082D), medfield_1 }, 338fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { PCI_VDEVICE(INTEL, 0x082E), medfield_2 }, 339089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg /* Baytrail */ 340089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F41), baytrail }, 341089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F42), baytrail }, 342089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F43), baytrail }, 343089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F44), baytrail }, 344089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F45), baytrail }, 345089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F46), baytrail }, 346089c729ae440c6df35eeac7998525718fcee0323Mika Westerberg { PCI_VDEVICE(INTEL, 0x0F47), baytrail }, 347157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg /* Haswell */ 348157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg { PCI_VDEVICE(INTEL, 0x9c61), haswell }, 349157a801e5042c7da5323c7d77bd818c7d845af14Mika Westerberg { PCI_VDEVICE(INTEL, 0x9c62), haswell }, 3500409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox /* Braswell / Cherrytrail */ 3510409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C1), baytrail,}, 3520409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C2), baytrail }, 3530409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C3), baytrail }, 3540409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C4), baytrail }, 3550409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C5), baytrail }, 3560409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C6), baytrail }, 3570409516a2d29fcaca53ed4c90c22f11af9600199Alan Cox { PCI_VDEVICE(INTEL, 0x22C7), baytrail }, 358fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie { 0,} 359fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 360fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk BrandewieMODULE_DEVICE_TABLE(pci, i2_designware_pci_ids); 361fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 362fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewiestatic struct pci_driver dw_i2c_driver = { 363fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .name = DRIVER_NAME, 364fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .id_table = i2_designware_pci_ids, 365fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie .probe = i2c_dw_pci_probe, 3660b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pemberton .remove = i2c_dw_pci_remove, 36718dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie .driver = { 36818dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie .pm = &i2c_dw_pm_ops, 36918dbdda89f5cf0540e577280395f16079308e87dDirk Brandewie }, 370fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie}; 371fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 37256f2178898ffca84dcdfb351f0127bf5732b1610Axel Linmodule_pci_driver(dw_i2c_driver); 373fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk Brandewie 374fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk BrandewieMODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); 375fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk BrandewieMODULE_DESCRIPTION("Synopsys DesignWare PCI I2C bus adapter"); 376fe20ff5c7e9ca7f5369aacc7d7ca3efeda3b90feDirk BrandewieMODULE_LICENSE("GPL"); 377