/*
 * This file is part of wl1271
 *
 * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.
 * Copyright (C) 2008-2010 Nokia Corporation
 *
 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#ifndef __IO_H__
#define __IO_H__

#include <linux/irqreturn.h>

#define HW_ACCESS_MEMORY_MAX_RANGE	0x1FFC0

#define HW_PARTITION_REGISTERS_ADDR     0x1FFC0
#define HW_PART0_SIZE_ADDR              (HW_PARTITION_REGISTERS_ADDR)
#define HW_PART0_START_ADDR             (HW_PARTITION_REGISTERS_ADDR + 4)
#define HW_PART1_SIZE_ADDR              (HW_PARTITION_REGISTERS_ADDR + 8)
#define HW_PART1_START_ADDR             (HW_PARTITION_REGISTERS_ADDR + 12)
#define HW_PART2_SIZE_ADDR              (HW_PARTITION_REGISTERS_ADDR + 16)
#define HW_PART2_START_ADDR             (HW_PARTITION_REGISTERS_ADDR + 20)
#define HW_PART3_START_ADDR             (HW_PARTITION_REGISTERS_ADDR + 24)

#define HW_ACCESS_REGISTER_SIZE         4

#define HW_ACCESS_PRAM_MAX_RANGE	0x3c000

struct wl1271;

void wlcore_disable_interrupts(struct wl1271 *wl);
void wlcore_disable_interrupts_nosync(struct wl1271 *wl);
void wlcore_enable_interrupts(struct wl1271 *wl);
void wlcore_synchronize_interrupts(struct wl1271 *wl);

void wl1271_io_reset(struct wl1271 *wl);
void wl1271_io_init(struct wl1271 *wl);
int wlcore_translate_addr(struct wl1271 *wl, int addr);

/* Raw target IO, address is not translated */
static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr,
						void *buf, size_t len,
						bool fixed)
{
	int ret;

	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags))
		return -EIO;

	ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed);
	if (ret && wl->state != WLCORE_STATE_OFF)
		set_bit(WL1271_FLAG_IO_FAILED, &wl->flags);

	return ret;
}

static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr,
					       void *buf, size_t len,
					       bool fixed)
{
	int ret;

	if (test_bit(WL1271_FLAG_IO_FAILED, &wl->flags))
		return -EIO;

	ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed);
	if (ret && wl->state != WLCORE_STATE_OFF)
		set_bit(WL1271_FLAG_IO_FAILED, &wl->flags);

	return ret;
}

static inline int __must_check wlcore_raw_read_data(struct wl1271 *wl, int reg,
						    void *buf, size_t len,
						    bool fixed)
{
	return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed);
}

static inline int __must_check wlcore_raw_write_data(struct wl1271 *wl, int reg,
						     void *buf, size_t len,
						     bool fixed)
{
	return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed);
}

static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr,
						 u32 *val)
{
	int ret;

	ret = wlcore_raw_read(wl, addr, wl->buffer_32,
			      sizeof(*wl->buffer_32), false);
	if (ret < 0)
		return ret;

	if (val)
		*val = le32_to_cpu(*wl->buffer_32);

	return 0;
}

static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr,
						  u32 val)
{
	*wl->buffer_32 = cpu_to_le32(val);
	return wlcore_raw_write(wl, addr, wl->buffer_32,
				sizeof(*wl->buffer_32), false);
}

static inline int __must_check wlcore_read(struct wl1271 *wl, int addr,
					   void *buf, size_t len, bool fixed)
{
	int physical;

	physical = wlcore_translate_addr(wl, addr);

	return wlcore_raw_read(wl, physical, buf, len, fixed);
}

static inline int __must_check wlcore_write(struct wl1271 *wl, int addr,
					    void *buf, size_t len, bool fixed)
{
	int physical;

	physical = wlcore_translate_addr(wl, addr);

	return wlcore_raw_write(wl, physical, buf, len, fixed);
}

static inline int __must_check wlcore_write_data(struct wl1271 *wl, int reg,
						 void *buf, size_t len,
						 bool fixed)
{
	return wlcore_write(wl, wl->rtable[reg], buf, len, fixed);
}

static inline int __must_check wlcore_read_data(struct wl1271 *wl, int reg,
						void *buf, size_t len,
						bool fixed)
{
	return wlcore_read(wl, wl->rtable[reg], buf, len, fixed);
}

static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr,
						  void *buf, size_t len,
						  bool fixed)
{
	int physical;
	int addr;

	/* Addresses are stored internally as addresses to 32 bytes blocks */
	addr = hwaddr << 5;

	physical = wlcore_translate_addr(wl, addr);

	return wlcore_raw_read(wl, physical, buf, len, fixed);
}

static inline int __must_check wlcore_read32(struct wl1271 *wl, int addr,
					     u32 *val)
{
	return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val);
}

static inline int __must_check wlcore_write32(struct wl1271 *wl, int addr,
					      u32 val)
{
	return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val);
}

static inline int __must_check wlcore_read_reg(struct wl1271 *wl, int reg,
					       u32 *val)
{
	return wlcore_raw_read32(wl,
				 wlcore_translate_addr(wl, wl->rtable[reg]),
				 val);
}

static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg,
						u32 val)
{
	return wlcore_raw_write32(wl,
				  wlcore_translate_addr(wl, wl->rtable[reg]),
				  val);
}

static inline void wl1271_power_off(struct wl1271 *wl)
{
	int ret = 0;

	if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags))
		return;

	if (wl->if_ops->power)
		ret = wl->if_ops->power(wl->dev, false);
	if (!ret)
		clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
}

static inline int wl1271_power_on(struct wl1271 *wl)
{
	int ret = 0;

	if (wl->if_ops->power)
		ret = wl->if_ops->power(wl->dev, true);
	if (ret == 0)
		set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);

	return ret;
}

int wlcore_set_partition(struct wl1271 *wl,
			 const struct wlcore_partition_set *p);

bool wl1271_set_block_size(struct wl1271 *wl);

/* Functions from wl1271_main.c */

int wl1271_tx_dummy_packet(struct wl1271 *wl);

#endif
