/*
   This files contains card eeprom (93c46 or 93c56) programming routines,
   memory is addressed by 16 bits words.

   This is part of rtl8180 OpenSource driver.
   Copyright (C) Andrea Merello 2004  <andreamrl@tiscali.it>
   Released under the terms of GPL (General Public Licence)

   Parts of this driver are based on the GPL part of the
   official realtek driver.

   Parts of this driver are based on the rtl8180 driver skeleton
   from Patric Schenke & Andres Salomon.

   Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.

   We want to tanks the Authors of those projects and the Ndiswrapper
   project Authors.
*/

#include "r8180_93cx6.h"

static void eprom_cs(struct net_device *dev, short bit)
{
	if (bit)
		write_nic_byte(dev, EPROM_CMD,
			       (1<<EPROM_CS_SHIFT) |
			       read_nic_byte(dev, EPROM_CMD)); //enable EPROM
	else
		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
			       &~(1<<EPROM_CS_SHIFT)); //disable EPROM

	udelay(EPROM_DELAY);
}


static void eprom_ck_cycle(struct net_device *dev)
{
	write_nic_byte(dev, EPROM_CMD,
		       (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD));
	udelay(EPROM_DELAY);
	write_nic_byte(dev, EPROM_CMD,
		       read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT));
	udelay(EPROM_DELAY);
}


static void eprom_w(struct net_device *dev, short bit)
{
	if (bit)
		write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) |
			       read_nic_byte(dev, EPROM_CMD));
	else
		write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)
			       &~(1<<EPROM_W_SHIFT));

	udelay(EPROM_DELAY);
}


static short eprom_r(struct net_device *dev)
{
	short bit;

	bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT));
	udelay(EPROM_DELAY);

	if (bit)
		return 1;
	return 0;
}


static void eprom_send_bits_string(struct net_device *dev, short b[], int len)
{
	int i;

	for (i = 0; i < len; i++) {
		eprom_w(dev, b[i]);
		eprom_ck_cycle(dev);
	}
}


u32 eprom_read(struct net_device *dev, u32 addr)
{
	struct r8192_priv *priv = ieee80211_priv(dev);
	short read_cmd[] = {1, 1, 0};
	short addr_str[8];
	int i;
	int addr_len;
	u32 ret;

	ret = 0;
        //enable EPROM programming
	write_nic_byte(dev, EPROM_CMD,
		       (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
	udelay(EPROM_DELAY);

	if (priv->epromtype == EPROM_93c56) {
		addr_str[7] = addr & 1;
		addr_str[6] = addr & (1<<1);
		addr_str[5] = addr & (1<<2);
		addr_str[4] = addr & (1<<3);
		addr_str[3] = addr & (1<<4);
		addr_str[2] = addr & (1<<5);
		addr_str[1] = addr & (1<<6);
		addr_str[0] = addr & (1<<7);
		addr_len = 8;
	} else {
		addr_str[5] = addr & 1;
		addr_str[4] = addr & (1<<1);
		addr_str[3] = addr & (1<<2);
		addr_str[2] = addr & (1<<3);
		addr_str[1] = addr & (1<<4);
		addr_str[0] = addr & (1<<5);
		addr_len = 6;
	}
	eprom_cs(dev, 1);
	eprom_ck_cycle(dev);
	eprom_send_bits_string(dev, read_cmd, 3);
	eprom_send_bits_string(dev, addr_str, addr_len);

	//keep chip pin D to low state while reading.
	//I'm unsure if it is necessary, but anyway shouldn't hurt
	eprom_w(dev, 0);

	for (i = 0; i < 16; i++) {
		//eeprom needs a clk cycle between writing opcode&adr
		//and reading data. (eeprom outs a dummy 0)
		eprom_ck_cycle(dev);
		ret |= (eprom_r(dev)<<(15-i));
	}

	eprom_cs(dev, 0);
	eprom_ck_cycle(dev);

	//disable EPROM programming
	write_nic_byte(dev, EPROM_CMD,
		       (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
	return ret;
}
