public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod
@ 2008-04-12 15:04 Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 1/5] mt312: Cleanup buffer variables of read/write functions Matthias Schwarzott
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

mt312: Cleanup driver and add support for zl10313.

These patches add support for the Zarlink zl10313 demod to mt312 driver.
This chip is used at least on Avermedia A700 DVB-S and
Compro VideoMate S300/S350 DVB-S cards.

Regards
Matthias

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [linux-dvb] [patch 1/5] mt312: Cleanup buffer variables of read/write functions
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
@ 2008-04-12 15:04 ` Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 2/5] mt312: Fix diseqc Matthias Schwarzott
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

[-- Attachment #1: 01_mt312-var-types.diff --]
[-- Type: text/plain, Size: 1996 bytes --]

Change type of buffer variables from void* to u8* to save some casts.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.c
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
@@ -58,7 +58,7 @@ static int debug;
 #define MT312_PLL_CLK		10000000UL	/* 10 MHz */
 
 static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
-		      void *buf, const size_t count)
+		      u8 *buf, const size_t count)
 {
 	int ret;
 	struct i2c_msg msg[2];
@@ -84,7 +84,7 @@ static int mt312_read(struct mt312_state
 		int i;
 		dprintk("R(%d):", reg & 0x7f);
 		for (i = 0; i < count; i++)
-			printk(" %02x", ((const u8 *) buf)[i]);
+			printk(" %02x", buf[i]);
 		printk("\n");
 	}
 
@@ -92,7 +92,7 @@ static int mt312_read(struct mt312_state
 }
 
 static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
-		       const void *src, const size_t count)
+		       const u8 *src, const size_t count)
 {
 	int ret;
 	u8 buf[count + 1];
@@ -102,7 +102,7 @@ static int mt312_write(struct mt312_stat
 		int i;
 		dprintk("W(%d):", reg & 0x7f);
 		for (i = 0; i < count; i++)
-			printk(" %02x", ((const u8 *) src)[i]);
+			printk(" %02x", src[i]);
 		printk("\n");
 	}
 
@@ -463,7 +463,7 @@ static int mt312_read_snr(struct dvb_fro
 	int ret;
 	u8 buf[2];
 
-	ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf));
+	ret = mt312_read(state, M_SNR_H, buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 
@@ -478,7 +478,7 @@ static int mt312_read_ucblocks(struct dv
 	int ret;
 	u8 buf[2];
 
-	ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf));
+	ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf));
 	if (ret < 0)
 		return ret;
 

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [linux-dvb] [patch 2/5] mt312: Fix diseqc
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 1/5] mt312: Cleanup buffer variables of read/write functions Matthias Schwarzott
@ 2008-04-12 15:04 ` Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 3/5] mt312: Supports different xtal frequencies Matthias Schwarzott
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

[-- Attachment #1: 02_mt312-fix-diseqc.diff --]
[-- Type: text/plain, Size: 1308 bytes --]

Correct the frequency of the emitted diseqc signal to 22kHz.
Adds sleep(100) to wait for message to be transmitted.

For now the only user of mt312 is b2c2-flexcop, and it
does overwrite all diseqc related functions with own code.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>

Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.c
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
@@ -270,7 +270,7 @@ static int mt312_initfe(struct dvb_front
 				MT312_SYS_CLK) * 2, 1000000);
 
 	/* DISEQC_RATIO */
-	buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
+	buf[1] = mt312_div(MT312_PLL_CLK, 22000 * 4);
 
 	ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
 	if (ret < 0)
@@ -323,6 +323,9 @@ static int mt312_send_master_cmd(struct 
 	if (ret < 0)
 		return ret;
 
+	/* is there a better way to wait for message to be transmitted */
+	msleep(100);
+
 	/* set DISEQC_MODE[2:0] to zero if a return message is expected */
 	if (c->msg[0] & 0x02) {
 		ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [linux-dvb] [patch 3/5] mt312: Supports different xtal frequencies
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 1/5] mt312: Cleanup buffer variables of read/write functions Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 2/5] mt312: Fix diseqc Matthias Schwarzott
@ 2008-04-12 15:04 ` Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 4/5] mt312: Add support for zl10313 demod Matthias Schwarzott
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

[-- Attachment #1: 03_mt312-changable-xtal.diff --]
[-- Type: text/plain, Size: 3840 bytes --]

Do not hardcode xtal frequency but allow different values
for future zl10313 support.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.c
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
@@ -43,7 +43,8 @@ struct mt312_state {
 	struct dvb_frontend frontend;
 
 	u8 id;
-	u8 frequency;
+	unsigned long xtal;
+	u8 freq_mult;
 };
 
 static int debug;
@@ -53,8 +54,6 @@ static int debug;
 			printk(KERN_DEBUG "mt312: " args); \
 	} while (0)
 
-#define MT312_SYS_CLK		90000000UL	/* 90 MHz */
-#define MT312_LPOWER_SYS_CLK	60000000UL	/* 60 MHz */
 #define MT312_PLL_CLK		10000000UL	/* 10 MHz */
 
 static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
@@ -209,7 +208,7 @@ static int mt312_get_symbol_rate(struct 
 		dprintk("sym_rat_op=%d dec_ratio=%d\n",
 		       sym_rat_op, dec_ratio);
 		dprintk("*sr(manual) = %lu\n",
-		       (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
+		       (((state->xtal * 8192) / (sym_rat_op + 8192)) *
 			2) - dec_ratio);
 	}
 
@@ -242,7 +241,7 @@ static int mt312_initfe(struct dvb_front
 
 	/* wake up */
 	ret = mt312_writereg(state, CONFIG,
-			(state->frequency == 60 ? 0x88 : 0x8c));
+			(state->freq_mult == 6 ? 0x88 : 0x8c));
 	if (ret < 0)
 		return ret;
 
@@ -266,11 +265,10 @@ static int mt312_initfe(struct dvb_front
 	}
 
 	/* SYS_CLK */
-	buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK :
-				MT312_SYS_CLK) * 2, 1000000);
+	buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
 
 	/* DISEQC_RATIO */
-	buf[1] = mt312_div(MT312_PLL_CLK, 22000 * 4);
+	buf[1] = mt312_div(state->xtal, 22000 * 4);
 
 	ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
 	if (ret < 0)
@@ -535,17 +533,17 @@ static int mt312_set_frontend(struct dvb
 			return ret;
 		if (p->u.qpsk.symbol_rate >= 30000000) {
 			/* Note that 30MS/s should use 90MHz */
-			if ((config_val & 0x0c) == 0x08) {
+			if (state->freq_mult == 6) {
 				/* We are running 60MHz */
-				state->frequency = 90;
+				state->freq_mult = 9;
 				ret = mt312_initfe(fe);
 				if (ret < 0)
 					return ret;
 			}
 		} else {
-			if ((config_val & 0x0c) == 0x0C) {
+			if (state->freq_mult == 9) {
 				/* We are running 90MHz */
-				state->frequency = 60;
+				state->freq_mult = 6;
 				ret = mt312_initfe(fe);
 				if (ret < 0)
 					return ret;
@@ -664,6 +662,7 @@ static void mt312_release(struct dvb_fro
 	kfree(state);
 }
 
+#define MT312_SYS_CLK		90000000UL	/* 90 MHz */
 static struct dvb_frontend_ops vp310_mt312_ops = {
 
 	.info = {
@@ -671,8 +670,8 @@ static struct dvb_frontend_ops vp310_mt3
 		.type = FE_QPSK,
 		.frequency_min = 950000,
 		.frequency_max = 2150000,
-		.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
-		.symbol_rate_min = MT312_SYS_CLK / 128,
+		.frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */
+		.symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
 		.symbol_rate_max = MT312_SYS_CLK / 2,
 		.caps =
 		    FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
@@ -729,11 +728,13 @@ struct dvb_frontend *vp310_mt312_attach(
 	switch (state->id) {
 	case ID_VP310:
 		strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
-		state->frequency = 90;
+		state->xtal = MT312_PLL_CLK;
+		state->freq_mult = 9;
 		break;
 	case ID_MT312:
 		strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
-		state->frequency = 60;
+		state->xtal = MT312_PLL_CLK;
+		state->freq_mult = 6;
 		break;
 	default:
 		printk(KERN_WARNING "Only Zarlink VP310/MT312"

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [linux-dvb] [patch 4/5] mt312: Add support for zl10313 demod
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
                   ` (2 preceding siblings ...)
  2008-04-12 15:04 ` [linux-dvb] [patch 3/5] mt312: Supports different xtal frequencies Matthias Schwarzott
@ 2008-04-12 15:04 ` Matthias Schwarzott
  2008-04-12 15:04 ` [linux-dvb] [patch 5/5] mt312: add attach-time setting to invert lnb-voltage Matthias Schwarzott
  2008-04-12 15:37 ` [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
  5 siblings, 0 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

[-- Attachment #1: 04_mt312-add-zl10313-support.diff --]
[-- Type: text/plain, Size: 5045 bytes --]

Add zl10313 support to mt312 driver.
zl10313 uses 10.111MHz xtal.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.c
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
@@ -1,7 +1,8 @@
 /*
-    Driver for Zarlink VP310/MT312 Satellite Channel Decoder
+    Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder
 
     Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
+    Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org>
 
     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
@@ -55,6 +56,7 @@ static int debug;
 	} while (0)
 
 #define MT312_PLL_CLK		10000000UL	/* 10 MHz */
+#define MT312_PLL_CLK_10_111	10111000UL	/* 10.111 MHz */
 
 static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
 		      u8 *buf, const size_t count)
@@ -264,6 +266,32 @@ static int mt312_initfe(struct dvb_front
 			return ret;
 	}
 
+	switch (state->id) {
+	case ID_ZL10313:
+		/* enable ADC */
+		ret = mt312_writereg(state, GPP_CTRL, 0x80);
+		if (ret < 0)
+			return ret;
+
+		/* configure ZL10313 for optimal ADC performance */
+		buf[0] = 0x80;
+		buf[1] = 0xB0;
+		ret = mt312_write(state, HW_CTRL, buf, 2);
+		if (ret < 0)
+			return ret;
+
+		/* enable MPEG output and ADCs */
+		ret = mt312_writereg(state, HW_CTRL, 0x00);
+		if (ret < 0)
+			return ret;
+
+		ret = mt312_writereg(state, MPEG_CTRL, 0x00);
+		if (ret < 0)
+			return ret;
+
+		break;
+	}
+
 	/* SYS_CLK */
 	buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
 
@@ -278,7 +306,17 @@ static int mt312_initfe(struct dvb_front
 	if (ret < 0)
 		return ret;
 
-	ret = mt312_writereg(state, OP_CTRL, 0x53);
+	/* different MOCLK polarity */
+	switch (state->id) {
+	case ID_ZL10313:
+		buf[0] = 0x33;
+		break;
+	default:
+		buf[0] = 0x53;
+		break;
+	}
+
+	ret = mt312_writereg(state, OP_CTRL, buf[0]);
 	if (ret < 0)
 		return ret;
 
@@ -552,6 +590,7 @@ static int mt312_set_frontend(struct dvb
 		break;
 
 	case ID_MT312:
+	case ID_ZL10313:
 		break;
 
 	default:
@@ -617,11 +656,29 @@ static int mt312_i2c_gate_ctrl(struct dv
 {
 	struct mt312_state *state = fe->demodulator_priv;
 
-	if (enable) {
-		return mt312_writereg(state, GPP_CTRL, 0x40);
-	} else {
-		return mt312_writereg(state, GPP_CTRL, 0x00);
+	u8 val = 0x00;
+	int ret;
+
+	switch (state->id) {
+	case ID_ZL10313:
+		ret = mt312_readreg(state, GPP_CTRL, &val);
+		if (ret < 0)
+			goto error;
+
+		/* preserve this bit to not accidently shutdown ADC */
+		val &= 0x80;
+		break;
 	}
+
+	if (enable)
+		val |= 0x40;
+	else
+		val &= ~0x40;
+
+	ret = mt312_writereg(state, GPP_CTRL, val);
+
+error:
+	return ret;
 }
 
 static int mt312_sleep(struct dvb_frontend *fe)
@@ -635,6 +692,18 @@ static int mt312_sleep(struct dvb_fronte
 	if (ret < 0)
 		return ret;
 
+	if (state->id == ID_ZL10313) {
+		/* reset ADC */
+		ret = mt312_writereg(state, GPP_CTRL, 0x00);
+		if (ret < 0)
+			return ret;
+
+		/* full shutdown of ADCs, mpeg bus tristated */
+		ret = mt312_writereg(state, HW_CTRL, 0x0d);
+		if (ret < 0)
+			return ret;
+	}
+
 	ret = mt312_readreg(state, CONFIG, &config);
 	if (ret < 0)
 		return ret;
@@ -736,8 +805,13 @@ struct dvb_frontend *vp310_mt312_attach(
 		state->xtal = MT312_PLL_CLK;
 		state->freq_mult = 6;
 		break;
+	case ID_ZL10313:
+		strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
+		state->xtal = MT312_PLL_CLK_10_111;
+		state->freq_mult = 9;
+		break;
 	default:
-		printk(KERN_WARNING "Only Zarlink VP310/MT312"
+		printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313"
 			" are supported chips.\n");
 		goto error;
 	}
@@ -753,7 +827,7 @@ EXPORT_SYMBOL(vp310_mt312_attach);
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 
-MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
+MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
 MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
 MODULE_LICENSE("GPL");
 
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312_priv.h
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312_priv.h
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312_priv.h
@@ -110,6 +110,8 @@ enum mt312_reg_addr {
 	VIT_ERRPER_H = 83,
 	VIT_ERRPER_M = 84,
 	VIT_ERRPER_L = 85,
+	HW_CTRL = 84,	/* ZL10313 only */
+	MPEG_CTRL = 85,	/* ZL10313 only */
 	VIT_SETUP = 86,
 	VIT_REF0 = 87,
 	VIT_REF1 = 88,
@@ -156,7 +158,8 @@ enum mt312_reg_addr {
 
 enum mt312_model_id {
 	ID_VP310 = 1,
-	ID_MT312 = 3
+	ID_MT312 = 3,
+	ID_ZL10313 = 5,
 };
 
 #endif				/* DVB_FRONTENDS_MT312_PRIV */

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [linux-dvb] [patch 5/5] mt312: add attach-time setting to invert lnb-voltage
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
                   ` (3 preceding siblings ...)
  2008-04-12 15:04 ` [linux-dvb] [patch 4/5] mt312: Add support for zl10313 demod Matthias Schwarzott
@ 2008-04-12 15:04 ` Matthias Schwarzott
  2008-04-12 15:37 ` [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
  5 siblings, 0 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:04 UTC (permalink / raw)
  To: linux-dvb

[-- Attachment #1: 05_mt312-invertable-lnb-voltage.diff --]
[-- Type: text/plain, Size: 1533 bytes --]

Add a setting to config struct for inversion of lnb-voltage.
Needed for support of Avermedia A700 cards.

Signed-off-by: Matthias Schwarzott <zzam@gentoo.org>
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.c
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.c
@@ -422,11 +422,16 @@ static int mt312_set_voltage(struct dvb_
 {
 	struct mt312_state *state = fe->demodulator_priv;
 	const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
+	u8 val;
 
 	if (v > SEC_VOLTAGE_OFF)
 		return -EINVAL;
 
-	return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
+	val = volt_tab[v];
+	if (state->config->voltage_inverted)
+		val ^= 0x40;
+
+	return mt312_writereg(state, DISEQC_MODE, val);
 }
 
 static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
Index: v4l-dvb/linux/drivers/media/dvb/frontends/mt312.h
===================================================================
--- v4l-dvb.orig/linux/drivers/media/dvb/frontends/mt312.h
+++ v4l-dvb/linux/drivers/media/dvb/frontends/mt312.h
@@ -31,6 +31,9 @@
 struct mt312_config {
 	/* the demodulator's i2c address */
 	u8 demod_address;
+
+	/* inverted voltage setting */
+	int voltage_inverted:1;
 };
 
 #if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))

-- 

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod
  2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
                   ` (4 preceding siblings ...)
  2008-04-12 15:04 ` [linux-dvb] [patch 5/5] mt312: add attach-time setting to invert lnb-voltage Matthias Schwarzott
@ 2008-04-12 15:37 ` Matthias Schwarzott
  2008-04-26 16:39   ` Jan Louw
       [not found]   ` <000a01c8a7b7$5cc2c060$0500000a@Core2Duo>
  5 siblings, 2 replies; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-12 15:37 UTC (permalink / raw)
  To: Jan D. Louw; +Cc: linux-dvb

On Samstag, 12. April 2008, Matthias Schwarzott wrote:
> mt312: Cleanup driver and add support for zl10313.
>
> These patches add support for the Zarlink zl10313 demod to mt312 driver.
> This chip is used at least on Avermedia A700 DVB-S and
> Compro VideoMate S300/S350 DVB-S cards.
>
Hi Jan!

Could you please try to use this driver with your Compro card.

Regards
Matthias

-- 
Matthias Schwarzott (zzam)

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod
  2008-04-12 15:37 ` [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
@ 2008-04-26 16:39   ` Jan Louw
       [not found]   ` <000a01c8a7b7$5cc2c060$0500000a@Core2Duo>
  1 sibling, 0 replies; 10+ messages in thread
From: Jan Louw @ 2008-04-26 16:39 UTC (permalink / raw)
  To: linux-dvb

Hi Matthias,

It still works. I combined your zl10313 modulator patch  with my earlier 
zl10039 frontend patch. The additional modifications necesary are in (see 
previous patch):

~/schwarzottv4l/v4l-dvb $ hg status
M linux/drivers/media/dvb/frontends/Kconfig
M linux/drivers/media/dvb/frontends/Makefile
M linux/drivers/media/video/saa7134/Kconfig
M linux/drivers/media/video/saa7134/saa7134-cards.c
M linux/drivers/media/video/saa7134/saa7134-dvb.c
M linux/drivers/media/video/saa7134/saa7134.h
A linux/drivers/media/dvb/frontends/zl10039.c
A linux/drivers/media/dvb/frontends/zl10039.h
A linux/drivers/media/dvb/frontends/zl10039_priv.h

To keep it simple I omitted the previous remote control code.

Regards
JD

----- Original Message ----- 
From: "Matthias Schwarzott" <zzam@gentoo.org>
To: "Jan D. Louw" <myvonkpos@mweb.co.za>
Cc: <linux-dvb@linuxtv.org>
Sent: Saturday, April 12, 2008 5:37 PM
Subject: Re: [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod


> On Samstag, 12. April 2008, Matthias Schwarzott wrote:
>> mt312: Cleanup driver and add support for zl10313.
>>
>> These patches add support for the Zarlink zl10313 demod to mt312 driver.
>> This chip is used at least on Avermedia A700 DVB-S and
>> Compro VideoMate S300/S350 DVB-S cards.
>>
> Hi Jan!
> 
> Could you please try to use this driver with your Compro card.
> 
> Regards
> Matthias
> 
> -- 
> Matthias Schwarzott (zzam)

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod
       [not found]   ` <000a01c8a7b7$5cc2c060$0500000a@Core2Duo>
@ 2008-04-27  3:51     ` Matthias Schwarzott
  2008-04-27  8:57       ` Jan D. Louw
  0 siblings, 1 reply; 10+ messages in thread
From: Matthias Schwarzott @ 2008-04-27  3:51 UTC (permalink / raw)
  To: Jan Louw; +Cc: linux-dvb

On Samstag, 26. April 2008, Jan Louw wrote:
> Hi Matthias,
>
> It still works. I combined your zl10313 modulator patch  with my earlier
> zl10039 frontend patch. The additional modifications necesary are in (see
> previous patch):
>
> ~/schwarzottv4l/v4l-dvb $ hg status
> M linux/drivers/media/dvb/frontends/Kconfig
> M linux/drivers/media/dvb/frontends/Makefile
> M linux/drivers/media/video/saa7134/Kconfig
> M linux/drivers/media/video/saa7134/saa7134-cards.c
> M linux/drivers/media/video/saa7134/saa7134-dvb.c
> M linux/drivers/media/video/saa7134/saa7134.h
> A linux/drivers/media/dvb/frontends/zl10039.c
> A linux/drivers/media/dvb/frontends/zl10039.h
> A linux/drivers/media/dvb/frontends/zl10039_priv.h
>
> To keep it simple I omitted the previous remote control code.
>

As you see here my zl10036 driver seems to work to some point:
http://thread.gmane.org/gmane.linux.drivers.dvb/41015/focus=41303

Could you please mail your current driver for zl10039.
Maybe it is worth merging both.

Regards
Matthias

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod
  2008-04-27  3:51     ` Matthias Schwarzott
@ 2008-04-27  8:57       ` Jan D. Louw
  0 siblings, 0 replies; 10+ messages in thread
From: Jan D. Louw @ 2008-04-27  8:57 UTC (permalink / raw)
  To: Matthias Schwarzott; +Cc: linux-dvb

[-- Attachment #1: Type: text/plain, Size: 1396 bytes --]

On Sunday 27 April 2008 05:51:30 Matthias Schwarzott wrote:
> On Samstag, 26. April 2008, Jan Louw wrote:
> > Hi Matthias,
> >
> > It still works. I combined your zl10313 modulator patch  with my earlier
> > zl10039 frontend patch. The additional modifications necesary are in (see
> > previous patch):
> >
> > ~/schwarzottv4l/v4l-dvb $ hg status
> > M linux/drivers/media/dvb/frontends/Kconfig
> > M linux/drivers/media/dvb/frontends/Makefile
> > M linux/drivers/media/video/saa7134/Kconfig
> > M linux/drivers/media/video/saa7134/saa7134-cards.c
> > M linux/drivers/media/video/saa7134/saa7134-dvb.c
> > M linux/drivers/media/video/saa7134/saa7134.h
> > A linux/drivers/media/dvb/frontends/zl10039.c
> > A linux/drivers/media/dvb/frontends/zl10039.h
> > A linux/drivers/media/dvb/frontends/zl10039_priv.h
> >
> > To keep it simple I omitted the previous remote control code.
>
> As you see here my zl10036 driver seems to work to some point:
> http://thread.gmane.org/gmane.linux.drivers.dvb/41015/focus=41303
>
> Could you please mail your current driver for zl10039.
> Maybe it is worth merging both.
>
> Regards
> Matthias

Hi Matthias,

Here's the zl10039 driver. With the zl10039 I did not bother with offsets or 
gains - even the weak channels lock stable :-)

I used a constant bandwidth resolution of 200KHz (reference divider of 10) and 
a PLL frequency divider of 80.

Regards
JD





[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: zl10039.c --]
[-- Type: text/x-csrc; charset="utf-8"; name="zl10039.c", Size: 7210 bytes --]

/*
 *  Driver for Zarlink ZL10039 DVB-S tuner
 *
 *  Copyright 2007 Jan Daniël Louw <jd.louw@mweb.co.za>
 *
 *  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 <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/dvb/frontend.h>

#include "dvb_frontend.h"
#include "zl10039.h"
#include "zl10039_priv.h"


static int zl10039_read(const struct zl10039_state *state,
			const enum zl10039_reg_addr reg, u8 *buf,
			const size_t count)
{
	struct i2c_msg msg[2];
	u8 regbuf[1] = { reg };
	int i;

	io_printk("%s\n", __FUNCTION__);
	/* Write register address */
	msg[0].addr = state->config.tuner_address;
	msg[0].flags = 0;
	msg[0].buf = regbuf;
	msg[0].len = 1;
	/* Read count bytes */
	msg[1].addr = state->config.tuner_address;
	msg[1].flags = I2C_M_RD;
	msg[1].buf = buf;
	msg[1].len = count;
	if (i2c_transfer(state->i2c, msg, 2) != 2) {
		eprintk("%s: i2c read error\n", __FUNCTION__);
		return -EREMOTEIO;
	}
	for (i = 0; i < count; i++) {
		io_printk("R[%s] = 0x%x\n", zl10039_reg_names[reg + i], buf[i]);
	}
	return 0; /* Success */
}

static int zl10039_write(struct zl10039_state *state,
			const enum zl10039_reg_addr reg, const u8 *src,
			const size_t count)
{
	u8 buf[count + 1];
	struct i2c_msg msg;
	int i;

	io_printk("%s\n", __FUNCTION__);
	for (i = 0; i < count; i++) {
		io_printk("W[%s] = 0x%x\n", zl10039_reg_names[reg + i], src[i]);
	}
	/* Write register address and data in one go */
	buf[0] = reg;
	memcpy(&buf[1], src, count);
	msg.addr = state->config.tuner_address;
	msg.flags = 0;
	msg.buf = buf;
	msg.len = count + 1;
	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
		eprintk("%s: i2c write error\n", __FUNCTION__);
		return -EREMOTEIO;
	}
	return 0; /* Success */
}

static inline int zl10039_readreg(struct zl10039_state *state,
				const enum zl10039_reg_addr reg, u8 *val)
{
	return zl10039_read(state, reg, val, 1);
}

static inline int zl10039_writereg(struct zl10039_state *state,
				const enum zl10039_reg_addr reg,
				const u8 val)
{
	return zl10039_write(state, reg, &val, 1);
}

static int zl10039_init(struct dvb_frontend *fe)
{
	struct zl10039_state *state = fe->tuner_priv;
	int ret;

	trace_printk("%s\n", __FUNCTION__);
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
	/* Reset logic */
	ret = zl10039_writereg(state, GENERAL, 0x40);
	if (ret < 0) {
		eprintk("Note: i2c write error normal when resetting the "
			"tuner\n");
	}
	/* Wake up */
	ret = zl10039_writereg(state, GENERAL, 0x01);
	if (ret < 0) {
		eprintk("Tuner power up failed\n");
		return ret;
	}
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	return 0;
}

static int zl10039_sleep(struct dvb_frontend *fe)
{
	struct zl10039_state *state = fe->tuner_priv;
	int ret;

	trace_printk("%s\n", __FUNCTION__);
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
	ret = zl10039_writereg(state, GENERAL, 0x80);
	if (ret < 0) {
		eprintk("Tuner sleep failed\n");
		return ret;
	}
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	return 0;
}

static int zl10039_set_params(struct dvb_frontend *fe,
			struct dvb_frontend_parameters *params)
{
	struct zl10039_state *state = fe->tuner_priv;
	u8 buf[6];
	u8 bf;
	u32 fbw;
	u32 div;
	int ret;

	trace_printk("%s\n", __FUNCTION__);
	params_printk("Set frequency = %d, symbol rate = %d\n",
			params->frequency, params->u.qpsk.symbol_rate);

	/* Assumed 10.111 MHz crystal oscillator */
	/* Cancelled num/den 80 to prevent overflow */
	div = (params->frequency * 1000) / 126387;
	fbw = (params->u.qpsk.symbol_rate * 27) / 32000;
	/* Cancelled num/den 10 to prevent overflow */
	bf = ((fbw * 5088) / 1011100) - 1;

	/*PLL divider*/
	buf[0] = (div >> 8) & 0x7f;
	buf[1] = (div >> 0) & 0xff;
	/*Reference divider*/
	/* Select reference ratio of 80 */
	buf[2] = 0x1D;
	/*PLL test modes*/
	buf[3] = 0x40;
	/*RF Control register*/
	buf[4] = 0x6E; /* Bypass enable */
	/*Baseband filter cutoff */
	buf[5] = bf;

	/* Open i2c gate */
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
	/* BR = 10, Enable filter adjustment */
	ret = zl10039_writereg(state, BASE1, 0x0A);
	if (ret < 0) goto error;
	/* Write new config values */
	ret = zl10039_write(state, PLL0, buf, sizeof(buf));
	if (ret < 0) goto error;
	/* BR = 10, Disable filter adjustment */
	ret = zl10039_writereg(state, BASE1, 0x6A);
	if (ret < 0) goto error;

	zl10039_dump_registers(state);
	/* Close i2c gate */
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	return 0;
error:
	eprintk("Error setting tuner\n");
	return ret;
}

static struct dvb_tuner_ops zl10039_ops;

struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe,
		const struct zl10039_config *config, struct i2c_adapter *i2c)
{
	struct zl10039_state *state = NULL;

	trace_printk("%s\n", __FUNCTION__);
	state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
	if (state == NULL) goto error;

	state->i2c = i2c;
	state->config.tuner_address = config->tuner_address;

	/* Open i2c gate */
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
	/* check if this is a valid tuner */
	if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
		/* Close i2c gate */
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
		goto error;
	}
	/* Close i2c gate */
	if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);

	state->id = state->id & 0x0F;
	switch (state->id) {
	case ID_ZL10039:
		strcpy(fe->ops.tuner_ops.info.name,
			"Zarlink ZL10039 DVB-S tuner");
		break;
	default:
		eprintk("Chip ID does not match a known type\n");
		goto error;
	}
	memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
	fe->tuner_priv = state;
	iprintk("Tuner attached @ i2c address 0x%02x\n", config->tuner_address);
	return fe;
error:
	kfree(state);
	return NULL;
}

static int zl10039_release(struct dvb_frontend *fe)
{
	struct zl10039_state *state = fe->tuner_priv;

	trace_printk("%s\n", __FUNCTION__);
	kfree(state);
	fe->tuner_priv = NULL;
	return 0;
}

static struct dvb_tuner_ops zl10039_ops = {
	.release = zl10039_release,
	.init = zl10039_init,
	.sleep = zl10039_sleep,
	.set_params = zl10039_set_params,
};

EXPORT_SYMBOL(zl10039_attach);

MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
MODULE_AUTHOR("Jan Daniël Louw <jd.louw@mweb.co.za>");
MODULE_LICENSE("GPL");

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: zl10039.h --]
[-- Type: text/x-chdr; charset="utf-8"; name="zl10039.h", Size: 1507 bytes --]

/*
    Driver for Zarlink ZL10039 DVB-S tuner

    Copyright (C) 2007 Jan Daniël Louw <jd.louw@mweb.co.za>

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

#ifndef ZL10039_H
#define ZL10039_H

struct zl10039_config
{
	/* tuner's i2c address */
	u8 tuner_address;
};

#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
	    && defined(MODULE))
struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe,
					const struct zl10039_config *config,
					struct i2c_adapter *i2c);
#else
static inline struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe,
					const struct zl10039_config *config,
					struct i2c_adapter *i2c)
{
	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
	return NULL;
}
#endif /* CONFIG_DVB_ZL10039 */

#endif /* ZL10039_H */

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: zl10039_priv.h --]
[-- Type: text/x-chdr; charset="utf-8"; name="zl10039_priv.h", Size: 3295 bytes --]

/*
 *  Driver for Zarlink ZL10039 DVB-S tuner
 *
 *  Copyright 2007 Jan Daniël Louw <jd.louw@mweb.co.za>
 *
 *  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.=
 */

#ifndef DVB_FRONTENDS_ZL10039_PRIV
#define DVB_FRONTENDS_ZL10039_PRIV

/* Trace function calls */
#define DEBUG_CALL_TRACE	0
/* Trace read/write function calls - information overload */
#define DEBUG_IO_TRACE		0
/* Print register values at critical points */
#define DEBUG_DUMP_REGISTERS	0
/* Print important params passed to functions */
#define DEBUG_PRINT_PARAMS	0

#if DEBUG_CALL_TRACE
	#define trace_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " args)
#else
	#define trace_printk(args...)
#endif

#if DEBUG_IO_TRACE
	#define io_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " args)
#else
	#define io_printk(args...)
#endif

#if DEBUG_PRINT_PARAMS
	#define params_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " \
						args)
#else
	#define params_printk(args...)
#endif

#define eprintk(args...) printk(KERN_ERR "tuner: zl10039: " args)
#define iprintk(args...) printk(KERN_INFO "tuner: zl10039: " args)

enum zl10039_model_id {
	ID_ZL10039 = 1
};

struct zl10039_state {
	struct i2c_adapter *i2c;
	struct zl10039_config config;
	u8 id;
};

enum zl10039_reg_addr {
	PLL0 = 0,
	PLL1,
	PLL2,
	PLL3,
	RFFE,
	BASE0,
	BASE1,
	BASE2,
	LO0,
	LO1,
	LO2,
	LO3,
	LO4,
	LO5,
	LO6,
	GENERAL
};

#if DEBUG_DUMP_REGISTERS || DEBUG_IO_TRACE
static const char *zl10039_reg_names[] = {
	"PLL_0", "PLL_1", "PLL_2", "PLL_3",
	"RF_FRONT_END", "BASE_BAND_0", "BASE_BAND_1", "BASE_BAND_2",
	"LOCAL_OSC_0", "LOCAL_OSC_1", "LOCAL_OSC_2", "LOCAL_OSC_3",
	"LOCAL_OSC_4", "LOCAL_OSC_5", "LOCAL_OSC_6", "GENERAL"
};
#endif

#if DEBUG_DUMP_REGISTERS
static int zl10039_read(const struct zl10039_state *state,
			const enum zl10039_reg_addr reg, u8 *buf,
			const size_t count);

static void zl10039_dump_registers(const struct zl10039_state *state)
{
	u8 buf[16];
	int ret;
	u8 reg;

	trace_printk("%s\n", __FUNCTION__);
	ret = zl10039_read(state, PLL0, buf, sizeof(buf));
	if (ret < 0) return;
	for (reg = PLL0; reg <= GENERAL; reg += 4) {
		printk(KERN_DEBUG "%03x: [%02x %13s] [%02x %13s] [%02x %13s] "
			"[%02x %13s]\n", reg, buf[reg], zl10039_reg_names[reg],
			buf[reg+1], zl10039_reg_names[reg+1], buf[reg+2],
			zl10039_reg_names[reg+2], buf[reg+3],
			zl10039_reg_names[reg+3]);
	}
}
#else
static inline void zl10039_dump_registers(const struct zl10039_state *state) {}
#endif /* DEBUG_DUMP_REGISTERS */

#endif /* DVB_FRONTENDS_ZL10039_PRIV */


[-- Attachment #5: Type: text/plain, Size: 150 bytes --]

_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2008-04-27  8:58 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-04-12 15:04 [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
2008-04-12 15:04 ` [linux-dvb] [patch 1/5] mt312: Cleanup buffer variables of read/write functions Matthias Schwarzott
2008-04-12 15:04 ` [linux-dvb] [patch 2/5] mt312: Fix diseqc Matthias Schwarzott
2008-04-12 15:04 ` [linux-dvb] [patch 3/5] mt312: Supports different xtal frequencies Matthias Schwarzott
2008-04-12 15:04 ` [linux-dvb] [patch 4/5] mt312: Add support for zl10313 demod Matthias Schwarzott
2008-04-12 15:04 ` [linux-dvb] [patch 5/5] mt312: add attach-time setting to invert lnb-voltage Matthias Schwarzott
2008-04-12 15:37 ` [linux-dvb] [patch 0/5] mt312: Add support for zl10313 demod Matthias Schwarzott
2008-04-26 16:39   ` Jan Louw
     [not found]   ` <000a01c8a7b7$5cc2c060$0500000a@Core2Duo>
2008-04-27  3:51     ` Matthias Schwarzott
2008-04-27  8:57       ` Jan D. Louw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox