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