/*
 * 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;

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

	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 = 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
