/*
 * Radio tuning for Maxim max2820 on RTL8180
 *
 * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
 *
 * Code from the BSD driver and the rtl8181 project have been
 * very useful to understand certain things
 *
 * I want to thanks the Authors of such projects and the Ndiswrapper
 * project Authors.
 *
 * A special Big Thanks also is for all people who donated me cards,
 * making possible the creation of the original rtl8180 driver
 * from which this code is derived!
 *
 * 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.
 */

#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <net/mac80211.h>

#include "rtl8180.h"
#include "max2820.h"

static const u32 max2820_chan[] = {
	12, /* CH 1 */
	17,
	22,
	27,
	32,
	37,
	42,
	47,
	52,
	57,
	62,
	67,
	72,
	84, /* CH 14 */
};

static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data)
{
	struct rtl8180_priv *priv = dev->priv;
	u32 phy_config;

	phy_config = 0x90 + (data & 0xf);
	phy_config <<= 16;
	phy_config += addr;
	phy_config <<= 8;
	phy_config += (data >> 4) & 0xff;

	rtl818x_iowrite32(priv,
		(__le32 __iomem *) &priv->map->RFPinsOutput, phy_config);

	msleep(1);
}

static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
{
	struct rtl8180_priv *priv = dev->priv;
	u8 ant;

	ant = MAXIM_ANTENNA;
	if (priv->rfparam & RF_PARAM_ANTBDEFAULT)
		ant |= BB_ANTENNA_B;
	if (chan == 14)
		ant |= BB_ANTATTEN_CHAN14;

	rtl8180_write_phy(dev, 0x10, ant);
}

static u8 max2820_rf_calc_rssi(u8 agc, u8 sq)
{
	bool odd;

	odd = !!(agc & 1);

	agc >>= 1;
	if (odd)
		agc += 76;
	else
		agc += 66;

	/* TODO: change addends above to avoid mult / div below */
	return 65 * agc / 100;
}

static void max2820_rf_set_channel(struct ieee80211_hw *dev,
				   struct ieee80211_conf *conf)
{
	struct rtl8180_priv *priv = dev->priv;
	int channel = conf ?
		ieee80211_frequency_to_channel(conf->channel->center_freq) : 1;
	unsigned int chan_idx = channel - 1;
	u32 txpw = priv->channels[chan_idx].hw_value & 0xFF;
	u32 chan = max2820_chan[chan_idx];

	/* While philips SA2400 drive the PA bias from
	 * sa2400, for MAXIM we do this directly from BB */
	rtl8180_write_phy(dev, 3, txpw);

	max2820_write_phy_antenna(dev, channel);
	write_max2820(dev, 3, chan);
}

static void max2820_rf_stop(struct ieee80211_hw *dev)
{
	rtl8180_write_phy(dev, 3, 0x8);
	write_max2820(dev, 1, 0);
}


static void max2820_rf_init(struct ieee80211_hw *dev)
{
	struct rtl8180_priv *priv = dev->priv;

	/* MAXIM from netbsd driver */
	write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */
	write_max2820(dev, 1, 0x01e); /* enable register */
	write_max2820(dev, 2, 0x001); /* synt register */

	max2820_rf_set_channel(dev, NULL);

	write_max2820(dev, 4, 0x313); /* rx register */

	/* PA is driven directly by the BB, we keep the MAXIM bias
	 * at the highest value in case that setting it to lower
	 * values may introduce some further attenuation somewhere..
	 */
	write_max2820(dev, 5, 0x00f);

	/* baseband configuration */
	rtl8180_write_phy(dev, 0, 0x88); /* sys1       */
	rtl8180_write_phy(dev, 3, 0x08); /* txagc      */
	rtl8180_write_phy(dev, 4, 0xf8); /* lnadet     */
	rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit  */
	rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */
	rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet   */

	max2820_write_phy_antenna(dev, 1);

	rtl8180_write_phy(dev, 0x11, 0x88); /* trl */

	if (rtl818x_ioread8(priv, &priv->map->CONFIG2) &
	    RTL818X_CONFIG2_ANTENNA_DIV)
		rtl8180_write_phy(dev, 0x12, 0xc7);
	else
		rtl8180_write_phy(dev, 0x12, 0x47);

	rtl8180_write_phy(dev, 0x13, 0x9b);

	rtl8180_write_phy(dev, 0x19, 0x0);  /* CHESTLIM */
	rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM  */

	max2820_rf_set_channel(dev, NULL);
}

const struct rtl818x_rf_ops max2820_rf_ops = {
	.name		= "Maxim",
	.init		= max2820_rf_init,
	.stop		= max2820_rf_stop,
	.set_chan	= max2820_rf_set_channel,
	.calc_rssi	= max2820_rf_calc_rssi,
};
