/*
 * Sonics Silicon Backplane
 * SDIO-Hostbus related functions
 *
 * Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
 *
 * Based on drivers/ssb/pcmcia.c
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2007-2008 Michael Buesch <m@bues.ch>
 *
 * Licensed under the GNU/GPL. See COPYING for details.
 *
 */

#include <linux/ssb/ssb.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/etherdevice.h>
#include <linux/mmc/sdio_func.h>

#include "ssb_private.h"

/* Define the following to 1 to enable a printk on each coreswitch. */
#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG		0


/* Hardware invariants CIS tuples */
#define SSB_SDIO_CIS			0x80
#define  SSB_SDIO_CIS_SROMREV		0x00
#define  SSB_SDIO_CIS_ID		0x01
#define  SSB_SDIO_CIS_BOARDREV		0x02
#define  SSB_SDIO_CIS_PA		0x03
#define   SSB_SDIO_CIS_PA_PA0B0_LO	0
#define   SSB_SDIO_CIS_PA_PA0B0_HI	1
#define   SSB_SDIO_CIS_PA_PA0B1_LO	2
#define   SSB_SDIO_CIS_PA_PA0B1_HI	3
#define   SSB_SDIO_CIS_PA_PA0B2_LO	4
#define   SSB_SDIO_CIS_PA_PA0B2_HI	5
#define   SSB_SDIO_CIS_PA_ITSSI		6
#define   SSB_SDIO_CIS_PA_MAXPOW	7
#define  SSB_SDIO_CIS_OEMNAME		0x04
#define  SSB_SDIO_CIS_CCODE		0x05
#define  SSB_SDIO_CIS_ANTENNA		0x06
#define  SSB_SDIO_CIS_ANTGAIN		0x07
#define  SSB_SDIO_CIS_BFLAGS		0x08
#define  SSB_SDIO_CIS_LEDS		0x09

#define CISTPL_FUNCE_LAN_NODE_ID        0x04	/* same as in PCMCIA */


/*
 * Function 1 miscellaneous registers.
 *
 * Definitions match src/include/sbsdio.h from the
 * Android Open Source Project
 * http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
 *
 */
#define SBSDIO_FUNC1_SBADDRLOW	0x1000a	/* SB Address window Low (b15) */
#define SBSDIO_FUNC1_SBADDRMID	0x1000b	/* SB Address window Mid (b23-b16) */
#define SBSDIO_FUNC1_SBADDRHIGH	0x1000c	/* SB Address window High (b24-b31) */

/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
#define SBSDIO_SBADDRLOW_MASK	0x80	/* Valid address bits in SBADDRLOW */
#define SBSDIO_SBADDRMID_MASK	0xff	/* Valid address bits in SBADDRMID */
#define SBSDIO_SBADDRHIGH_MASK	0xff	/* Valid address bits in SBADDRHIGH */

#define SBSDIO_SB_OFT_ADDR_MASK	0x7FFF	/* sb offset addr is <= 15 bits, 32k */

/* REVISIT: this flag doesn't seem to matter */
#define SBSDIO_SB_ACCESS_2_4B_FLAG	0x8000	/* forces 32-bit SB access */


/*
 * Address map within the SDIO function address space (128K).
 *
 *   Start   End     Description
 *   ------- ------- ------------------------------------------
 *   0x00000 0x0ffff selected backplane address window (64K)
 *   0x10000 0x1ffff backplane control registers (max 64K)
 *
 * The current address window is configured by writing to registers
 * SBADDRLOW, SBADDRMID and SBADDRHIGH.
 *
 * In order to access the contents of a 32-bit Silicon Backplane address
 * the backplane address window must be first loaded with the highest
 * 16 bits of the target address. Then, an access must be done to the
 * SDIO function address space using the lower 15 bits of the address.
 * Bit 15 of the address must be set when doing 32 bit accesses.
 *
 * 10987654321098765432109876543210
 * WWWWWWWWWWWWWWWWW                 SB Address Window
 *                 OOOOOOOOOOOOOOOO  Offset within SB Address Window
 *                 a                 32-bit access flag
 */


/*
 * SSB I/O via SDIO.
 *
 * NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
 */

static inline struct device *ssb_sdio_dev(struct ssb_bus *bus)
{
	return &bus->host_sdio->dev;
}

/* host claimed */
static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val)
{
	int error = 0;

	sdio_writeb(bus->host_sdio, val, addr, &error);
	if (unlikely(error)) {
		dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n",
			addr, val, error);
	}

	return error;
}

#if 0
static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
{
	u8 val;
	int error = 0;

	val = sdio_readb(bus->host_sdio, addr, &error);
	if (unlikely(error)) {
		dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
			addr, val, error);
	}

	return val;
}
#endif

/* host claimed */
static int ssb_sdio_set_sbaddr_window(struct ssb_bus *bus, u32 address)
{
	int error;

	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRLOW,
				(address >> 8) & SBSDIO_SBADDRLOW_MASK);
	if (error)
		goto out;
	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRMID,
				(address >> 16) & SBSDIO_SBADDRMID_MASK);
	if (error)
		goto out;
	error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRHIGH,
				(address >> 24) & SBSDIO_SBADDRHIGH_MASK);
	if (error)
		goto out;
	bus->sdio_sbaddr = address;
out:
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "failed to set address window"
			" to 0x%08x, error %d\n", address, error);
	}

	return error;
}

/* for enumeration use only */
u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
{
	u32 val;
	int error;

	sdio_claim_host(bus->host_sdio);
	val = sdio_readl(bus->host_sdio, offset, &error);
	sdio_release_host(bus->host_sdio);
	if (unlikely(error)) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}

	return val;
}

/* for enumeration use only */
int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
{
	u32 sbaddr;
	int error;

	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
	sdio_claim_host(bus->host_sdio);
	error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
	sdio_release_host(bus->host_sdio);
	if (error) {
		dev_err(ssb_sdio_dev(bus), "failed to switch to core %u,"
			" error %d\n", coreidx, error);
		goto out;
	}
out:
	return error;
}

/* host must be already claimed */
static int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
{
	u8 coreidx = dev->core_index;
	u32 sbaddr;
	int error = 0;

	sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
	if (unlikely(bus->sdio_sbaddr != sbaddr)) {
#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
		dev_info(ssb_sdio_dev(bus),
			   "switching to %s core, index %d\n",
			   ssb_core_name(dev->id.coreid), coreidx);
#endif
		error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
		if (error) {
			dev_dbg(ssb_sdio_dev(bus), "failed to switch to"
				" core %u, error %d\n", coreidx, error);
			goto out;
		}
		bus->mapped_device = dev;
	}

out:
	return error;
}

static u8 ssb_sdio_read8(struct ssb_device *dev, u16 offset)
{
	struct ssb_bus *bus = dev->bus;
	u8 val = 0xff;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	val = sdio_readb(bus->host_sdio, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %02x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
out:
	sdio_release_host(bus->host_sdio);

	return val;
}

static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset)
{
	struct ssb_bus *bus = dev->bus;
	u16 val = 0xffff;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	val = sdio_readw(bus->host_sdio, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
out:
	sdio_release_host(bus->host_sdio);

	return val;
}

static u32 ssb_sdio_read32(struct ssb_device *dev, u16 offset)
{
	struct ssb_bus *bus = dev->bus;
	u32 val = 0xffffffff;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
	val = sdio_readl(bus->host_sdio, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
out:
	sdio_release_host(bus->host_sdio);

	return val;
}

#ifdef CONFIG_SSB_BLOCKIO
static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
				  size_t count, u16 offset, u8 reg_width)
{
	size_t saved_count = count;
	struct ssb_bus *bus = dev->bus;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
		error = -EIO;
		memset(buffer, 0xff, count);
		goto err_out;
	}
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;

	switch (reg_width) {
	case sizeof(u8): {
		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
		break;
	}
	case sizeof(u16): {
		SSB_WARN_ON(count & 1);
		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
		break;
	}
	case sizeof(u32): {
		SSB_WARN_ON(count & 3);
		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
		error = sdio_readsb(bus->host_sdio, buffer, offset, count);
		break;
	}
	default:
		SSB_WARN_ON(1);
	}
	if (!error)
		goto out;

err_out:
	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
out:
	sdio_release_host(bus->host_sdio);
}
#endif /* CONFIG_SSB_BLOCKIO */

static void ssb_sdio_write8(struct ssb_device *dev, u16 offset, u8 val)
{
	struct ssb_bus *bus = dev->bus;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	sdio_writeb(bus->host_sdio, val, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %02x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
out:
	sdio_release_host(bus->host_sdio);
}

static void ssb_sdio_write16(struct ssb_device *dev, u16 offset, u16 val)
{
	struct ssb_bus *bus = dev->bus;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	sdio_writew(bus->host_sdio, val, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %04x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
out:
	sdio_release_host(bus->host_sdio);
}

static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val)
{
	struct ssb_bus *bus = dev->bus;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev)))
		goto out;
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;
	offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
	sdio_writel(bus->host_sdio, val, offset, &error);
	if (error) {
		dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n",
			bus->sdio_sbaddr >> 16, offset, val, error);
	}
	if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32)
		sdio_readl(bus->host_sdio, 0, &error);
out:
	sdio_release_host(bus->host_sdio);
}

#ifdef CONFIG_SSB_BLOCKIO
static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
				   size_t count, u16 offset, u8 reg_width)
{
	size_t saved_count = count;
	struct ssb_bus *bus = dev->bus;
	int error = 0;

	sdio_claim_host(bus->host_sdio);
	if (unlikely(ssb_sdio_switch_core(bus, dev))) {
		error = -EIO;
		goto err_out;
	}
	offset |= bus->sdio_sbaddr & 0xffff;
	offset &= SBSDIO_SB_OFT_ADDR_MASK;

	switch (reg_width) {
	case sizeof(u8):
		error = sdio_writesb(bus->host_sdio, offset,
				     (void *)buffer, count);
		break;
	case sizeof(u16):
		SSB_WARN_ON(count & 1);
		error = sdio_writesb(bus->host_sdio, offset,
				     (void *)buffer, count);
		break;
	case sizeof(u32):
		SSB_WARN_ON(count & 3);
		offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;	/* 32 bit data access */
		error = sdio_writesb(bus->host_sdio, offset,
				     (void *)buffer, count);
		break;
	default:
		SSB_WARN_ON(1);
	}
	if (!error)
		goto out;

err_out:
	dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
		bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
out:
	sdio_release_host(bus->host_sdio);
}

#endif /* CONFIG_SSB_BLOCKIO */

/* Not "static", as it's used in main.c */
const struct ssb_bus_ops ssb_sdio_ops = {
	.read8		= ssb_sdio_read8,
	.read16		= ssb_sdio_read16,
	.read32		= ssb_sdio_read32,
	.write8		= ssb_sdio_write8,
	.write16	= ssb_sdio_write16,
	.write32	= ssb_sdio_write32,
#ifdef CONFIG_SSB_BLOCKIO
	.block_read	= ssb_sdio_block_read,
	.block_write	= ssb_sdio_block_write,
#endif
};

#define GOTO_ERROR_ON(condition, description) do {	\
	if (unlikely(condition)) {			\
		error_description = description;	\
		goto error;				\
	}						\
  } while (0)

int ssb_sdio_get_invariants(struct ssb_bus *bus,
			    struct ssb_init_invariants *iv)
{
	struct ssb_sprom *sprom = &iv->sprom;
	struct ssb_boardinfo *bi = &iv->boardinfo;
	const char *error_description = "none";
	struct sdio_func_tuple *tuple;
	void *mac;

	memset(sprom, 0xFF, sizeof(*sprom));
	sprom->boardflags_lo = 0;
	sprom->boardflags_hi = 0;

	tuple = bus->host_sdio->tuples;
	while (tuple) {
		switch (tuple->code) {
		case 0x22: /* extended function */
			switch (tuple->data[0]) {
			case CISTPL_FUNCE_LAN_NODE_ID:
				GOTO_ERROR_ON((tuple->size != 7) &&
					      (tuple->data[1] != 6),
					      "mac tpl size");
				/* fetch the MAC address. */
				mac = tuple->data + 2;
				memcpy(sprom->il0mac, mac, ETH_ALEN);
				memcpy(sprom->et1mac, mac, ETH_ALEN);
				break;
			default:
				break;
			}
			break;
		case 0x80: /* vendor specific tuple */
			switch (tuple->data[0]) {
			case SSB_SDIO_CIS_SROMREV:
				GOTO_ERROR_ON(tuple->size != 2,
					      "sromrev tpl size");
				sprom->revision = tuple->data[1];
				break;
			case SSB_SDIO_CIS_ID:
				GOTO_ERROR_ON((tuple->size != 5) &&
					      (tuple->size != 7),
					      "id tpl size");
				bi->vendor = tuple->data[1] |
					     (tuple->data[2]<<8);
				break;
			case SSB_SDIO_CIS_BOARDREV:
				GOTO_ERROR_ON(tuple->size != 2,
					      "boardrev tpl size");
				sprom->board_rev = tuple->data[1];
				break;
			case SSB_SDIO_CIS_PA:
				GOTO_ERROR_ON((tuple->size != 9) &&
					      (tuple->size != 10),
					      "pa tpl size");
				sprom->pa0b0 = tuple->data[1] |
					 ((u16)tuple->data[2] << 8);
				sprom->pa0b1 = tuple->data[3] |
					 ((u16)tuple->data[4] << 8);
				sprom->pa0b2 = tuple->data[5] |
					 ((u16)tuple->data[6] << 8);
				sprom->itssi_a = tuple->data[7];
				sprom->itssi_bg = tuple->data[7];
				sprom->maxpwr_a = tuple->data[8];
				sprom->maxpwr_bg = tuple->data[8];
				break;
			case SSB_SDIO_CIS_OEMNAME:
				/* Not present */
				break;
			case SSB_SDIO_CIS_CCODE:
				GOTO_ERROR_ON(tuple->size != 2,
					      "ccode tpl size");
				sprom->country_code = tuple->data[1];
				break;
			case SSB_SDIO_CIS_ANTENNA:
				GOTO_ERROR_ON(tuple->size != 2,
					      "ant tpl size");
				sprom->ant_available_a = tuple->data[1];
				sprom->ant_available_bg = tuple->data[1];
				break;
			case SSB_SDIO_CIS_ANTGAIN:
				GOTO_ERROR_ON(tuple->size != 2,
					      "antg tpl size");
				sprom->antenna_gain.a0 = tuple->data[1];
				sprom->antenna_gain.a1 = tuple->data[1];
				sprom->antenna_gain.a2 = tuple->data[1];
				sprom->antenna_gain.a3 = tuple->data[1];
				break;
			case SSB_SDIO_CIS_BFLAGS:
				GOTO_ERROR_ON((tuple->size != 3) &&
					      (tuple->size != 5),
					      "bfl tpl size");
				sprom->boardflags_lo = tuple->data[1] |
						 ((u16)tuple->data[2] << 8);
				break;
			case SSB_SDIO_CIS_LEDS:
				GOTO_ERROR_ON(tuple->size != 5,
					      "leds tpl size");
				sprom->gpio0 = tuple->data[1];
				sprom->gpio1 = tuple->data[2];
				sprom->gpio2 = tuple->data[3];
				sprom->gpio3 = tuple->data[4];
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		tuple = tuple->next;
	}

	return 0;
error:
	dev_err(ssb_sdio_dev(bus), "failed to fetch device invariants: %s\n",
		error_description);
	return -ENODEV;
}

void ssb_sdio_exit(struct ssb_bus *bus)
{
	if (bus->bustype != SSB_BUSTYPE_SDIO)
		return;
	/* Nothing to do here. */
}

int ssb_sdio_init(struct ssb_bus *bus)
{
	if (bus->bustype != SSB_BUSTYPE_SDIO)
		return 0;

	bus->sdio_sbaddr = ~0;

	return 0;
}
