[PATCH] STB0899 API Intreface -- [Multi protocol support]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Johannes,


The STB0899's interface to the API, this is only the API interface and not the complete driver.


Thanks,
Manu






/*
	STB0899 Multistandard Frontend driver
	Copyright (C) 2006 Manu Abraham (abraham.manu@xxxxxxxxx)

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "stb0899_com.h"
#include "stb0899_hla.h"

static unsigned int verbose;
module_param(verbose, int, 0644);

struct stb0899_tab stb0899_cn_tab[] = {
	{ 15,	9600 },
	{ 20,	9450 },
	{ 30,	9000 },
	{ 40,	8250 },
	{ 50,	7970 },
	{ 60,	7360 },
	{ 70,	6770 },
	{ 80,	6200 },
	{ 90,	5670 },
	{ 100,	5190 },
	{ 110,	4740 },
	{ 120,	4360 },
	{ 130,	4010 },
	{ 140,	3710 },
	{ 150,	3440 },
	{ 160,	3210 },
	{ 170,	3020 },
	{ 180,	2860 },
	{ 190,	2700 },
	{ 200,	2600 }
};

struct stb0899_tab stb0899_dvbsrf_tab[] = {
	{ -5,	79   },
	{ -10,	73   },
	{ -15,	67   },
	{ -20,	62   },
	{ -25,	56   },
	{ -30,	49   },
	{ -33,	44   },
	{ -35,	40   },
	{ -37,	36   },
	{ -38,	33   },
	{ -40,	27   },
	{ -45,	4    },
	{ -47,	-11  },
	{ -48,	-19  },
	{ -50,	-29  },
	{ -55,	-43  },
	{ -60,	-52  },
	{ -65,	-61  },
	{ -67,	-65  },
	{ -70,	-128 }
};

struct stb0899_tab stb0899_dvbs2rf_tab[] = {
	{ -5,	2899 },
	{ -10,	3330 },
	{ -15,	3123 },
	{ -20,	3577 },
	{ -25,	4004 },
	{ -30,	4417 },
	{ -35,	4841 },
	{ -40,	5300 },
	{ -45,	5822 },
	{ -50,	6491 },
	{ -55,	7516 },
	{ -60,	9235 },
	{ -65,	11374},
	{ -70,	12364},
	{ -75,	13063}
};

/**
 *	bfloatdiv(), float division with int
 */
u32 bfloatdiv(long n1, long n2, int precision)
{
	int i = 0;
	u32 result = 0;

	while (i <= precision) {	/*	N1 < N2		*/
		if (n1 < n2) {
			result *= 2;
			n1 *= 2;
		} else {
			result = result * 2 + 1;
			n1 = (n1 - n2) * 2;
		}
		i++;
	}

	return result;
}

static int stb0899_scan_frequency(struct dvb_frontend *fe,
			struct dvb_frontend_params *params,
			unsigned int mode_flags,
			int *delay,
			fe_status_t *status)
{
//	struct stb0899_state *state = fe->demodulator_priv;

//	state->params.modulation =
//	state->params.inversion  =

	stb0899_search(fe, params);

	return 0;
}

static void stb0899_release(struct dvb_frontend *fe)
{
	struct stb0899_state *state = fe->demodulator_priv;

	dprintk(verbose, FE_DEBUG, 1, "Release Frontend");
	kfree(state);
}

static int stb0899_init(struct dvb_frontend *fe)
{
	struct stb0899_state *state = fe->demodulator_priv;

	dprintk(verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
	stb0899_tsintf_init(state);
	stb0899_diseqc_init(state);

	return 0;
}

static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	int i, min, max, quant, val;
	u8 val_msb, val_lsb, carrier_stat;
	struct stb0899_state *state = fe->demodulator_priv;
	struct stb0899_tab *cntab = stb0899_cn_tab;

	switch (state->delsys) {
	case STB0899_DELSYS_DVBS:
	case STB0899_DELSYS_DSS:
		carrier_stat = STB0899_GETFIELD(stb0899_read_reg(state,
						 STB0899_DSTATUS),
						 STB0899_WIDTH_CARRIER_FOUND,
						 STB0899_OFFST_CARRIER_FOUND);

		if (carrier_stat) {
			val_lsb = STB0899_GETFIELD(stb0899_read_reg(state,
						    STB0899_NIRL),
						    STB0899_WIDTH_NIRL,
						    STB0899_OFFST_NIRL);

			val_msb = STB0899_GETFIELD(stb0899_read_reg(state,
						    STB0899_NIRM),
						    STB0899_WIDTH_NIRM,
						    STB0899_OFFST_NIRM);

			val = MAKEWORD16(val_msb, val_lsb);
			min = 0;
			max = ARRAY_SIZE(stb0899_cn_tab) - 1;
			if (INRANGE(val, cntab[min].read, cntab[max].read)) {
				while ((max - min) > 1) {
					i = (max + min) / 2;
					if (INRANGE(val, cntab[min].read, cntab[i].read))
						max = i;
					else
						min = i;
					*snr = ((val - cntab[min].read) *
							(cntab[max].real - cntab[min].real) /
							(cntab[max].read - cntab[min].read)) +
							 cntab[min].real;
				}
			} else if (val < cntab[min].read)
				*snr = 100;
		}
		break;
	case STB0899_DELSYS_DVBS2:
		quant = STB0899_GETFIELD(stb0899_read_s2reg(state,
							     STB0899_S2DEMOD,
							     STB0899_BASE_UWP_CNTRL1,
							     STB0899_OFF0_UWP_CNTRL1),
					  STB0899_WIDTH_UWP_ESN0_QUANT,
					  STB0899_OFFST_UWP_ESN0_QUANT);

		*snr = STB0899_GETFIELD(stb0899_read_s2reg(state,
							    STB0899_S2DEMOD,
							    STB0899_BASE_UWP_STAT2,
							    STB0899_OFF0_UWP_STAT2),
					STB0899_WIDTH_UWP_ESN0_EST,
					STB0899_OFFST_UWP_ESN0_EST);

		break;
	case FE_DELSYS_IGNORE:
	default:
		break;
	}

	return 0;
}

static s32 stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
	s32 min, max = 0, i, val = 0;
	struct stb0899_state *state = fe->demodulator_priv;
	struct stb0899_tab *rftab = NULL;

	min = 0;

	switch (state->delsys) {
	case STB0899_DELSYS_DVBS:
	case STB0899_DELSYS_DSS:
		rftab = stb0899_dvbsrf_tab;
		max = ARRAY_SIZE(stb0899_dvbsrf_tab) - 1;
		val = STB0899_GETFIELD(stb0899_read_reg(state, STB0899_AGCIQIN),
					STB0899_WIDTH_AGCIQVALUE,
					STB0899_OFFST_AGCIQVALUE);

		break;
	case STB0899_DELSYS_DVBS2:
		rftab = stb0899_dvbs2rf_tab;
		max = ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1;
//		val = STB0899_GETFIELD(stb0899_read_s2reg(state,STB0899_S2DEMOD,
//							  STB0899_BASE_IF_AGC_GAIN,
//							  STB0899_OFF0_IF_AGC_GAIN),
//					STB0899_WIDTH_IF_AGC_GAIN,
//					STB0899_OFFST_IF_AGC_GAIN);
		break;
	case FE_DELSYS_IGNORE:
	default:
		break;
	}
	if (INRANGE(val, rftab[min].read, rftab[max].read)) {
		while ((max - min) > 1) {
			i = (max + min) / 2;
			if (INRANGE(val, rftab[min].read, rftab[i].read))
				max = i;
			else
				min = i;
			*strength = ((val - rftab[min].read) *
					(rftab[max].real - rftab[min].real) /
					(rftab[max].read - rftab[min].read)) +
					 rftab[min].real;
		}
	} else
		*strength = -100;

	*strength *= 10;

	return 0;
}

static const struct dvb_frontend_cap stb0899_dvbs_caps = {
	.name			= "STB0899 Multi-standard (DVB-S Mode)",
	.frequency_min		= 950000,
	.frequency_max		= 2150000,
	.symbol_rate_min	= 1000000,
	.symbol_rate_max	= 45000000,

	.inversion		= FE_INVERSION_IGNORE	| FE_INVERSION_OFF |
				  FE_INVERSION_ON	| FE_INVERSION_AUTO,

	.delsys.dvbs.modulation	= FE_MOD_QPSK,

	.delsys.dvbs.coderate	= FE_CODERATE_1_2 | FE_CODERATE_2_3 |
				  FE_CODERATE_3_4 | FE_CODERATE_5_6 |
				  FE_CODERATE_6_7
};

static const struct dvb_frontend_cap stb0899_dss_caps = {
	.name			= "STB0899 Multi-standard (DSS Mode)",
	.frequency_min		= 950000,
	.frequency_max		= 2150000,
	.symbol_rate_min	= 1000000,
	.symbol_rate_max	= 45000000,

	.inversion		= FE_INVERSION_IGNORE	| FE_INVERSION_OFF |
				  FE_INVERSION_ON	| FE_INVERSION_AUTO,

	.delsys.dvbs.modulation	= FE_MOD_QPSK,

	.delsys.dvbs.coderate	= FE_CODERATE_1_2 | FE_CODERATE_2_3 |
				  FE_CODERATE_3_4 | FE_CODERATE_5_6 |
				  FE_CODERATE_6_7
};

static const struct dvb_frontend_cap stb0899_dvbs2_caps = {
	.name			= "STB0899 Multi-standard (DVB-S2 Mode)",
	.frequency_min		= 950000,
	.frequency_max		= 2150000,
	.symbol_rate_min	= 1000000,
	.symbol_rate_max	= 45000000,

	.inversion		= FE_INVERSION_IGNORE	| FE_INVERSION_OFF |
				  FE_INVERSION_ON	| FE_INVERSION_AUTO,

	.delsys.dvbs.modulation	= FE_MOD_QPSK | FE_MOD_8PSK | FE_MOD_16APSK,

	.delsys.dvbs.coderate	= FE_CODERATE_1_4 | FE_CODERATE_1_3 |
				  FE_CODERATE_2_5 | FE_CODERATE_1_2 |
				  FE_CODERATE_3_5 | FE_CODERATE_2_3 |
				  FE_CODERATE_3_4 | FE_CODERATE_4_5 |
				  FE_CODERATE_5_6 | FE_CODERATE_8_9 |
				  FE_CODERATE_9_10
};


static int stb0899_get_caps(struct dvb_frontend *fe,
			    struct dvb_frontend_cap *caps)
{
	struct stb0899_state *state = fe->demodulator_priv;
	state->delsys = caps->delivery;

	switch (caps->delivery) {
	case STB0899_DELSYS_DVBS:
		memcpy(caps, &stb0899_dvbs_caps, sizeof (stb0899_dvbs_caps));
		break;
	case STB0899_DELSYS_DSS:
		memcpy(caps, &stb0899_dss_caps, sizeof (stb0899_dss_caps));
		break;
	case STB0899_DELSYS_DVBS2:
		memcpy(caps, &stb0899_dvbs2_caps, sizeof (stb0899_dvbs2_caps));
		break;
	case STB0899_DELSYS_IGNORE:
	default:
		break;
	}

	return 0;
}

static int stb0899_set_params(struct dvb_frontend *fe,
			      struct dvb_frontend_params *params)
{

	return 0;
}

static int stb0899_get_params(struct dvb_frontend *fe,
			      struct dvb_frontend_params *params)
{

	return 0;
}

static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
	switch (voltage) {
	case SEC_VOLTAGE_13:

		break;
	case SEC_VOLTAGE_18:

		break;
	default:
		break;
	}

	return 0;
}

static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
	switch (tone) {
	case SEC_TONE_ON:

		break;
	case SEC_TONE_OFF:

		break;
	default:
		break;
	}
	return 0;
}

static struct dvb_frontend_ops stb0899_ops = {
	.release		= stb0899_release,
	.init			= stb0899_init,
	.read_signal_strength	= stb0899_read_signal_strength,
	.read_snr		= stb0899_read_snr,
	.tune			= stb0899_scan_frequency,
	.get_caps		= stb0899_get_caps,
	.set_params		= stb0899_set_params,
	.get_params		= stb0899_get_params,
	.set_voltage		= stb0899_set_voltage,
	.set_tone		= stb0899_set_tone
};

struct dvb_frontend *stb0899_attach(const struct stb0899_config *config,
				    struct i2c_adapter *i2c)
{
	struct stb0899_state *state = NULL;

	state = kmalloc(sizeof (struct stb0899_state), GFP_KERNEL);
	if (state == NULL)
		goto error;

	state->verbose = verbose;
	state->config = config;
	state->i2c = i2c;
	memcpy(&state->ops, &stb0899_ops, sizeof (struct dvb_frontend_ops));

	state->frontend.ops = &state->ops;
	state->frontend.demodulator_priv = state;

	if (stb0899_get_dev_id(state) == -ENODEV) {
		printk("%s: Exitting .. !\n", __func__);
		goto error;
	}

	printk("%s: Attaching STB0899 \n", __func__);
	return &state->frontend;

error:
	kfree(state);
	return NULL;
}
EXPORT_SYMBOL(stb0899_attach);

MODULE_PARM_DESC(verbose, "Set Verbosity level");

MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
MODULE_LICENSE("GPL");
_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux