185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* 285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * (C) Copyright 2009-2010 385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Nokia Siemens Networks, michael.lawnick.ext@nsn.com 485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 5f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney * Portions Copyright (C) 2010, 2011 Cavium Networks, Inc. 685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * This is a driver for the i2c adapter in Cavium Networks' OCTEON processors. 885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * This file is licensed under the terms of the GNU General Public 1085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * License version 2. This program is licensed "as is" without any 1185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * warranty of any kind, whether express or implied. 1285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 1385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 14f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney#include <linux/platform_device.h> 15f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney#include <linux/interrupt.h> 1685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#include <linux/kernel.h> 1785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#include <linux/module.h> 18f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney#include <linux/delay.h> 1985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#include <linux/sched.h> 205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#include <linux/i2c.h> 22f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney#include <linux/io.h> 23f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney#include <linux/of.h> 2485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 2585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#include <asm/octeon/octeon.h> 2685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 2785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define DRV_NAME "i2c-octeon" 2885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 2985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* The previous out-of-tree version was implicitly version 1.0. */ 3085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define DRV_VERSION "2.0" 3185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 3285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* register offsets */ 3385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI 0x00 3485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_INT 0x10 3585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 3685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* Controller command patterns */ 3785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_V 0x8000000000000000ull 3885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_EOP_TWSI_DATA 0x0C00000100000000ull 3985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_EOP_TWSI_CTL 0x0C00000200000000ull 4085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_EOP_TWSI_CLKCTL 0x0C00000300000000ull 4185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_EOP_TWSI_STAT 0x0C00000300000000ull 4285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_EOP_TWSI_RST 0x0C00000700000000ull 4385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_OP_TWSI_CLK 0x0800000000000000ull 4485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define SW_TWSI_R 0x0100000000000000ull 4585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 4685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* Controller command and status bits */ 4785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_CE 0x80 4885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_ENAB 0x40 4985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_STA 0x20 5085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_STP 0x10 5185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_IFLG 0x08 5285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define TWSI_CTL_AAK 0x04 5385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 5485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/* Some status values */ 5585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_START 0x08 5685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_RSTART 0x10 5785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_TXADDR_ACK 0x18 5885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_TXDATA_ACK 0x28 5985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_RXADDR_ACK 0x40 6085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_RXDATA_ACK 0x50 6185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic#define STAT_IDLE 0xF8 6285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 6385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstruct octeon_i2c { 6485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic wait_queue_head_t queue; 6585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct i2c_adapter adap; 6685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int irq; 67f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney u32 twsi_freq; 6885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int sys_freq; 6985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic resource_size_t twsi_phys; 7085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic void __iomem *twsi_base; 7185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic resource_size_t regsize; 7285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct device *dev; 7385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 7485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 7585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 7685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_write_sw - write an I2C core register. 7785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 7885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @eop_reg: Register selector. 7985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @data: Value to be written. 8085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 8185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * The I2C core registers are accessed indirectly via the SW_TWSI CSR. 8285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 8385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic void octeon_i2c_write_sw(struct octeon_i2c *i2c, 8485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u64 eop_reg, 8585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 data) 8685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 8785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u64 tmp; 8885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 8985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic __raw_writeq(SW_TWSI_V | eop_reg | data, i2c->twsi_base + SW_TWSI); 9085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic do { 9185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tmp = __raw_readq(i2c->twsi_base + SW_TWSI); 9285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } while ((tmp & SW_TWSI_V) != 0); 9385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 9485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 9585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 9685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_read_sw - write an I2C core register. 9785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 9885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @eop_reg: Register selector. 9985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 10085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns the data. 10185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 10285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * The I2C core registers are accessed indirectly via the SW_TWSI CSR. 10385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 10485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic u8 octeon_i2c_read_sw(struct octeon_i2c *i2c, u64 eop_reg) 10585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 10685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u64 tmp; 10785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 10885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic __raw_writeq(SW_TWSI_V | eop_reg | SW_TWSI_R, i2c->twsi_base + SW_TWSI); 10985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic do { 11085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tmp = __raw_readq(i2c->twsi_base + SW_TWSI); 11185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } while ((tmp & SW_TWSI_V) != 0); 11285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 11385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return tmp & 0xFF; 11485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 11585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 11685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 11785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_write_int - write the TWSI_INT register 11885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 11985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @data: Value to be written. 12085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 12185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic void octeon_i2c_write_int(struct octeon_i2c *i2c, u64 data) 12285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 12385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic __raw_writeq(data, i2c->twsi_base + TWSI_INT); 124f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney __raw_readq(i2c->twsi_base + TWSI_INT); 12585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 12685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 12785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 12885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_int_enable - enable the TS interrupt. 12985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 13085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 13185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * The interrupt will be asserted when there is non-STAT_IDLE state in 13285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * the SW_TWSI_EOP_TWSI_STAT register. 13385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 13485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic void octeon_i2c_int_enable(struct octeon_i2c *i2c) 13585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 13685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x40); 13785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 13885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 13985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 14085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_int_disable - disable the TS interrupt. 14185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 14285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 14385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic void octeon_i2c_int_disable(struct octeon_i2c *i2c) 14485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 14585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0); 14685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 14785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 14885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 14985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_unblock - unblock the bus. 15085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 15185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 15285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * If there was a reset while a device was driving 0 to bus, 15385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * bus is blocked. We toggle it free manually by some clock 15485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * cycles and send a stop. 15585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 15685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic void octeon_i2c_unblock(struct octeon_i2c *i2c) 15785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 15885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int i; 15985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 16085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_dbg(i2c->dev, "%s\n", __func__); 16185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (i = 0; i < 9; i++) { 16285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x0); 16385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic udelay(5); 16485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x200); 16585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic udelay(5); 16685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 16785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x300); 16885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic udelay(5); 16985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x100); 17085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic udelay(5); 17185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_int(i2c, 0x0); 17285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 17385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 17485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 17585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_isr - the interrupt service routine. 17685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @int: The irq, unused. 17785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @dev_id: Our struct octeon_i2c. 17885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 17985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic irqreturn_t octeon_i2c_isr(int irq, void *dev_id) 18085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 18185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct octeon_i2c *i2c = dev_id; 18285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 18385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_int_disable(i2c); 1842637e5fd232d421b680757944f613d4b1a36ae26송은봉 wake_up(&i2c->queue); 18585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 18685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return IRQ_HANDLED; 18785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 18885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 18985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 19085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_test_iflg(struct octeon_i2c *i2c) 19185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 19285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_CTL) & TWSI_CTL_IFLG) != 0; 19385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 19485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 19585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 19685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_wait - wait for the IFLG to be set. 19785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 19885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 19985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns 0 on success, otherwise a negative errno. 20085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 20185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_wait(struct octeon_i2c *i2c) 20285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 20385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int result; 20485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 20585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_int_enable(i2c); 20685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 2072637e5fd232d421b680757944f613d4b1a36ae26송은봉 result = wait_event_timeout(i2c->queue, 2082637e5fd232d421b680757944f613d4b1a36ae26송은봉 octeon_i2c_test_iflg(i2c), 2092637e5fd232d421b680757944f613d4b1a36ae26송은봉 i2c->adap.timeout); 21085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 21185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_int_disable(i2c); 21285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 21385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result < 0) { 21485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_dbg(i2c->dev, "%s: wait interrupted\n", __func__); 21585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 21685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } else if (result == 0) { 21785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_dbg(i2c->dev, "%s: timeout\n", __func__); 218cc33e54290ed845904dac4b047934207738f0205Bernhard Walle return -ETIMEDOUT; 21985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 22085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 22185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 22285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 22385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 22485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 22585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_start - send START to the bus. 22685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 22785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 22885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns 0 on success, otherwise a negative errno. 22985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 23085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_start(struct octeon_i2c *i2c) 23185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 23285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 data; 23385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int result; 23485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 23585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, 23685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic TWSI_CTL_ENAB | TWSI_CTL_STA); 23785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 23885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 23985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) { 24085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT) == STAT_IDLE) { 24185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* 24285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Controller refused to send start flag May 24385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * be a client is holding SDA low - let's try 24485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * to free it. 24585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 24685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_unblock(i2c); 24785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, 24885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic TWSI_CTL_ENAB | TWSI_CTL_STA); 24985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 25085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 25185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 25285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 25385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 25485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 25585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 25685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); 25785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if ((data != STAT_START) && (data != STAT_RSTART)) { 25885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "%s: bad status (0x%x)\n", __func__, data); 25985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EIO; 26085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 26185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 26285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 26385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 26485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 26585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 26685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_stop - send STOP to the bus. 26785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 26885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 26985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns 0 on success, otherwise a negative errno. 27085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 27185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_stop(struct octeon_i2c *i2c) 27285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 27385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 data; 27485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 27585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, 27685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic TWSI_CTL_ENAB | TWSI_CTL_STP); 27785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 27885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic data = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); 27985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 28085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (data != STAT_IDLE) { 28185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "%s: bad status(0x%x)\n", __func__, data); 28285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EIO; 28385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 28485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 28585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 28685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 28785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 28885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_write - send data to the bus. 28985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 29085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @target: Target address. 29185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @data: Pointer to the data to be sent. 29285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @length: Length of the data. 29385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 29485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * The address is sent over the bus, then the data. 29585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 29685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns 0 on success, otherwise a negative errno. 29785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 29885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_write(struct octeon_i2c *i2c, int target, 29985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic const u8 *data, int length) 30085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 30185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int i, result; 30285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 tmp; 30385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 30485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_start(i2c); 30585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 30685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 30785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 30885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, target << 1); 30985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); 31085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 31185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 31285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 31385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 31485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 31585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (i = 0; i < length; i++) { 31685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); 31785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if ((tmp != STAT_TXADDR_ACK) && (tmp != STAT_TXDATA_ACK)) { 31885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, 31985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic "%s: bad status before write (0x%x)\n", 32085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic __func__, tmp); 32185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EIO; 32285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 32385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 32485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, data[i]); 32585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); 32685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 32785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 32885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 32985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 33085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 33185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 33285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 33385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 33485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 33585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 33685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_read - receive data from the bus. 33785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @i2c: The struct octeon_i2c. 33885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @target: Target address. 33985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @data: Pointer to the location to store the datae . 34085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @length: Length of the data. 34185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 34285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * The address is sent over the bus, then the data is read. 34385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 34485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns 0 on success, otherwise a negative errno. 34585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 34685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_read(struct octeon_i2c *i2c, int target, 34785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 *data, int length) 34885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 34985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int i, result; 35085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 tmp; 35185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 35285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (length < 1) 35385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EINVAL; 35485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 35585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_start(i2c); 35685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 35785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 35885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 35985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_DATA, (target<<1) | 1); 36085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); 36185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 36285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 36385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 36485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 36585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 36685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (i = 0; i < length; i++) { 36785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tmp = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); 36885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if ((tmp != STAT_RXDATA_ACK) && (tmp != STAT_RXADDR_ACK)) { 36985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, 37085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic "%s: bad status before read (0x%x)\n", 37185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic __func__, tmp); 37285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EIO; 37385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 37485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 37585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (i+1 < length) 37685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, 37785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic TWSI_CTL_ENAB | TWSI_CTL_AAK); 37885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic else 37985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, 38085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic TWSI_CTL_ENAB); 38185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 38285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_wait(i2c); 38385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) 38485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 38585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 38685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic data[i] = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_DATA); 38785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 38885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 38985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 39085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 39185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 39285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_xfer - The driver's master_xfer function. 39385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @adap: Pointer to the i2c_adapter structure. 39485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @msgs: Pointer to the messages to be processed. 39585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * @num: Length of the MSGS array. 39685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * 39785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * Returns the number of messages processed, or a negative errno on 39885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * failure. 39985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 40085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic int octeon_i2c_xfer(struct i2c_adapter *adap, 40185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct i2c_msg *msgs, 40285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int num) 40385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 40485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct i2c_msg *pmsg; 40585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int i; 40685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int ret = 0; 40785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct octeon_i2c *i2c = i2c_get_adapdata(adap); 40885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 40985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (i = 0; ret == 0 && i < num; i++) { 41085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic pmsg = &msgs[i]; 41185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_dbg(i2c->dev, 41285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic "Doing %s %d byte(s) to/from 0x%02x - %d of %d messages\n", 41385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic pmsg->flags & I2C_M_RD ? "read" : "write", 41485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic pmsg->len, pmsg->addr, i + 1, num); 41585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (pmsg->flags & I2C_M_RD) 41685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic ret = octeon_i2c_read(i2c, pmsg->addr, pmsg->buf, 41785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic pmsg->len); 41885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic else 41985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic ret = octeon_i2c_write(i2c, pmsg->addr, pmsg->buf, 42085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic pmsg->len); 42185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 42285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_stop(i2c); 42385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 42485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return (ret != 0) ? ret : num; 42585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 42685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 42785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic u32 octeon_i2c_functionality(struct i2c_adapter *adap) 42885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 42985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 43085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 43185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 43285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic const struct i2c_algorithm octeon_i2c_algo = { 43385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .master_xfer = octeon_i2c_xfer, 43485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .functionality = octeon_i2c_functionality, 43585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 43685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 43785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic struct i2c_adapter octeon_i2c_ops = { 43885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .owner = THIS_MODULE, 43985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .name = "OCTEON adapter", 44085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .algo = &octeon_i2c_algo, 44173f37dc3aa566f2533e6fda83a7c0a83657bada5송은봉 .timeout = HZ / 50, 44285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 44385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 44485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic/** 44585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * octeon_i2c_setclock - Calculate and set clock divisors. 44685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 4470b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic int octeon_i2c_setclock(struct octeon_i2c *i2c) 44885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 44985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; 45085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000; 45185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 45285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) { 45385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* 45485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * An mdiv value of less than 2 seems to not work well 45585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * with ds1337 RTCs, so we constrain it to larger 45685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * values. 45785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 45885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) { 45985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* 46085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * For given ndiv and mdiv values check the 46185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic * two closest thp values. 46285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic */ 46385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; 46485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic tclk *= (1 << ndiv_idx); 46585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic thp_base = (i2c->sys_freq / (tclk * 2)) - 1; 46685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (inc = 0; inc <= 1; inc++) { 46785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic thp_idx = thp_base + inc; 46885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (thp_idx < 5 || thp_idx > 0xff) 46985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic continue; 47085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 47185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic foscl = i2c->sys_freq / (2 * (thp_idx + 1)); 47285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic foscl = foscl / (1 << ndiv_idx); 47385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic foscl = foscl / (mdiv_idx + 1) / 10; 47485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic diff = abs(foscl - i2c->twsi_freq); 47585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (diff < delta_hz) { 47685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic delta_hz = diff; 47785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic thp = thp_idx; 47885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic mdiv = mdiv_idx; 47985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic ndiv = ndiv_idx; 48085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 48185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 48285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 48385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 48485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); 48585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); 48685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 48785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 48885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 48985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 4900b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic int octeon_i2c_initlowlevel(struct octeon_i2c *i2c) 49185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 49285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic u8 status; 49385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int tries; 49485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 49585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* disable high level controller, enable bus access */ 49685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); 49785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 49885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* reset controller */ 49985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); 50085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 50185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic for (tries = 10; tries; tries--) { 50285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic udelay(1); 50385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); 50485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (status == STAT_IDLE) 50585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 50685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 50785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); 50885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return -EIO; 50985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic} 51085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 5110b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic int octeon_i2c_probe(struct platform_device *pdev) 51285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 51385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic int irq, result = 0; 51485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct octeon_i2c *i2c; 51585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct resource *res_mem; 51685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 51785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic /* All adaptors have an irq. */ 51885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic irq = platform_get_irq(pdev, 0); 51985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (irq < 0) 52085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return irq; 52185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 522f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); 52385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (!i2c) { 52485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(&pdev->dev, "kzalloc failed\n"); 52585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = -ENOMEM; 52685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic goto out; 52785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 52885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c->dev = &pdev->dev; 52985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 53085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 53185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 53285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (res_mem == NULL) { 53385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "found no memory resource\n"); 53485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = -ENXIO; 535f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 53685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 537f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c->twsi_phys = res_mem->start; 538f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c->regsize = resource_size(res_mem); 53985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 540f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney /* 541f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney * "clock-rate" is a legacy binding, the official binding is 542f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney * "clock-frequency". Try the official one first and then 543f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney * fall back if it doesn't exist. 544f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney */ 545f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney if (of_property_read_u32(pdev->dev.of_node, 546f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney "clock-frequency", &i2c->twsi_freq) && 547f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney of_property_read_u32(pdev->dev.of_node, 548f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney "clock-rate", &i2c->twsi_freq)) { 549f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney dev_err(i2c->dev, 550f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney "no I2C 'clock-rate' or 'clock-frequency' property\n"); 55185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = -ENXIO; 552f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 55385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 55485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 555f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c->sys_freq = octeon_get_io_clock_rate(); 55685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 557f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney if (!devm_request_mem_region(&pdev->dev, i2c->twsi_phys, i2c->regsize, 558f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney res_mem->name)) { 55985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "request_mem_region failed\n"); 560f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 56185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 562f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c->twsi_base = devm_ioremap(&pdev->dev, i2c->twsi_phys, i2c->regsize); 56385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 56485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic init_waitqueue_head(&i2c->queue); 56585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 56685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c->irq = irq; 56785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 568f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney result = devm_request_irq(&pdev->dev, i2c->irq, 569f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney octeon_i2c_isr, 0, DRV_NAME, i2c); 57085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result < 0) { 57185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "failed to attach interrupt\n"); 572f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 57385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 57485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 57585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_initlowlevel(i2c); 57685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) { 57785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "init low level failed\n"); 578f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 57985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 58085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 58185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic result = octeon_i2c_setclock(i2c); 58285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result) { 58385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "clock init failed\n"); 584f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney goto out; 58585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 58685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 58785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c->adap = octeon_i2c_ops; 58885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c->adap.dev.parent = &pdev->dev; 589f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney i2c->adap.dev.of_node = pdev->dev.of_node; 59085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c_set_adapdata(&i2c->adap, i2c); 59185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic platform_set_drvdata(pdev, i2c); 59285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 593f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney result = i2c_add_adapter(&i2c->adap); 59485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic if (result < 0) { 59585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_err(i2c->dev, "failed to add adapter\n"); 59655827f4aa6442ddd1d6a4e1e32f2f457eb113c22Doug Anderson goto out; 59785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic } 59885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic dev_info(i2c->dev, "version %s\n", DRV_VERSION); 59985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 600f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney return 0; 60185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 60285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicout: 60385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return result; 60485660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 60585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 6060b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pembertonstatic int octeon_i2c_remove(struct platform_device *pdev) 60785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic{ 60885660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic struct octeon_i2c *i2c = platform_get_drvdata(pdev); 60985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 61085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic i2c_del_adapter(&i2c->adap); 61185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic return 0; 61285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 61385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 614f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daneystatic struct of_device_id octeon_i2c_match[] = { 615f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney { 616f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney .compatible = "cavium,octeon-3860-twsi", 617f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney }, 618f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney {}, 619f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney}; 620f353a218de6393fb43a5e81c3adbe1aac1a871abDavid DaneyMODULE_DEVICE_TABLE(of, octeon_i2c_match); 621f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney 62285660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozicstatic struct platform_driver octeon_i2c_driver = { 62385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .probe = octeon_i2c_probe, 6240b255e927d47b550620dfd3475ee74b0f52e09c8Bill Pemberton .remove = octeon_i2c_remove, 62585660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .driver = { 62685660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .owner = THIS_MODULE, 62785660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic .name = DRV_NAME, 628f353a218de6393fb43a5e81c3adbe1aac1a871abDavid Daney .of_match_table = octeon_i2c_match, 62985660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic }, 63085660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic}; 63185660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 632a3664b51c783aaa0dde1c95334d1a670d6d54590Axel Linmodule_platform_driver(octeon_i2c_driver); 63385660f43a308cc601b243c1f4dc18a63545c5cfaRade Bozic 63485660f43a308cc601b243c1f4dc18a63545c5cfaRade BozicMODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>"); 63585660f43a308cc601b243c1f4dc18a63545c5cfaRade BozicMODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors"); 63685660f43a308cc601b243c1f4dc18a63545c5cfaRade BozicMODULE_LICENSE("GPL"); 63785660f43a308cc601b243c1f4dc18a63545c5cfaRade BozicMODULE_VERSION(DRV_VERSION); 638