Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02ebf23b authored by Alan Nisota's avatar Alan Nisota Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (9928): Convert GP8PSK module to use S2API



This patch converts the gp8psk module to use the S2API.
It pretends to be  DVB-S2 capable in order to allow the various
supported modulations (8PSK, QPSK-Turbo, etc), and keep software
compatibility with the S2API patches for Mythtv and VDR.

Signed-off by: Alan Nisota <alannisota@gmail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent bddcf633
Loading
Loading
Loading
Loading
+114 −26
Original line number Original line Diff line number Diff line
@@ -25,6 +25,20 @@ struct gp8psk_fe_state {
	unsigned long status_check_interval;
	unsigned long status_check_interval;
};
};


static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
{
	struct gp8psk_fe_state *st = fe->demodulator_priv;
	u8 status;
	gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
	return status & bmDCtuned;
}

static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
{
	struct gp8psk_fe_state *state = fe->demodulator_priv;
	return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
}

static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
{
{
	u8 buf[6];
	u8 buf[6];
@@ -99,38 +113,113 @@ static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_front
	return 0;
	return 0;
}
}


static int gp8psk_fe_set_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
{
	deb_fe("%s(..)\n", __func__);
	return 0;
}

static int gp8psk_fe_get_property(struct dvb_frontend *fe,
	struct dtv_property *tvp)
{
	deb_fe("%s(..)\n", __func__);
	return 0;
}


static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
				  struct dvb_frontend_parameters *fep)
				  struct dvb_frontend_parameters *fep)
{
{
	struct gp8psk_fe_state *state = fe->demodulator_priv;
	struct gp8psk_fe_state *state = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	u8 cmd[10];
	u8 cmd[10];
	u32 freq = fep->frequency * 1000;
	u32 freq = fep->frequency * 1000;
	int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);

	deb_fe("%s()\n", __func__);


	cmd[4] = freq         & 0xff;
	cmd[4] = freq         & 0xff;
	cmd[5] = (freq >> 8)  & 0xff;
	cmd[5] = (freq >> 8)  & 0xff;
	cmd[6] = (freq >> 16) & 0xff;
	cmd[6] = (freq >> 16) & 0xff;
	cmd[7] = (freq >> 24) & 0xff;
	cmd[7] = (freq >> 24) & 0xff;


	switch(fe->ops.info.type) {
	switch (c->delivery_system) {
	case FE_QPSK:
	case SYS_DVBS:
		cmd[0] =  fep->u.qpsk.symbol_rate        & 0xff;
		/* Only QPSK is supported for DVB-S */
		cmd[1] = (fep->u.qpsk.symbol_rate >>  8) & 0xff;
		if (c->modulation != QPSK) {
		cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
			deb_fe("%s: unsupported modulation selected (%d)\n",
		cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
				__func__, c->modulation);
			return -EOPNOTSUPP;
		}
		c->fec_inner = FEC_AUTO;
		break;
	case SYS_DVBS2:
		deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
		break;

	default:
		deb_fe("%s: unsupported delivery system selected (%d)\n",
			__func__, c->delivery_system);
		return -EOPNOTSUPP;
	}

	cmd[0] =  c->symbol_rate        & 0xff;
	cmd[1] = (c->symbol_rate >>  8) & 0xff;
	cmd[2] = (c->symbol_rate >> 16) & 0xff;
	cmd[3] = (c->symbol_rate >> 24) & 0xff;
	switch (c->modulation) {
	case QPSK:
		if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
			if (gp8psk_tuned_to_DCII(fe))
				gp8psk_bcm4500_reload(state->d);
		switch (c->fec_inner) {
		case FEC_1_2:
			cmd[9] = 0; break;
		case FEC_2_3:
			cmd[9] = 1; break;
		case FEC_3_4:
			cmd[9] = 2; break;
		case FEC_5_6:
			cmd[9] = 3; break;
		case FEC_7_8:
			cmd[9] = 4; break;
		case FEC_AUTO:
			cmd[9] = 5; break;
		default:
			cmd[9] = 5; break;
		}
		cmd[8] = ADV_MOD_DVB_QPSK;
		cmd[8] = ADV_MOD_DVB_QPSK;
		cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
		break;
		break;
	case PSK_8: /* PSK_8 is for compatibility with DN */
		cmd[8] = ADV_MOD_TURBO_8PSK;
		switch (c->fec_inner) {
		case FEC_2_3:
			cmd[9] = 0; break;
		case FEC_3_4:
			cmd[9] = 1; break;
		case FEC_3_5:
			cmd[9] = 2; break;
		case FEC_5_6:
			cmd[9] = 3; break;
		case FEC_8_9:
			cmd[9] = 4; break;
		default:
		default:
		// other modes are unsuported right now
			cmd[9] = 0; break;
		cmd[0] = 0;
		}
		cmd[1] = 0;
		break;
		cmd[2] = 0;
	case QAM_16: /* QAM_16 is for compatibility with DN */
		cmd[3] = 0;
		cmd[8] = ADV_MOD_TURBO_16QAM;
		cmd[8] = 0;
		cmd[9] = 0;
		cmd[9] = 0;
		break;
		break;
	default: /* Unknown modulation */
		deb_fe("%s: unsupported modulation selected (%d)\n",
			__func__, c->modulation);
		return -EOPNOTSUPP;
	}
	}


	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
		gp8psk_set_tuner_mode(fe, 0);
	gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
	gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);


	state->lock = 0;
	state->lock = 0;
@@ -140,13 +229,6 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
	return 0;
	return 0;
}
}


static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
				  struct dvb_frontend_parameters *fep)
{
	return 0;
}


static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
				    struct dvb_diseqc_master_cmd *m)
				    struct dvb_diseqc_master_cmd *m)
{
{
@@ -263,7 +345,11 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
		.caps = FE_CAN_INVERSION_AUTO |
		.caps = FE_CAN_INVERSION_AUTO |
			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
				FE_CAN_QPSK
			/*
			 * FE_CAN_QAM_16 is for compatibility
			 * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
			 */
			FE_CAN_QPSK | FE_CAN_QAM_16
	},
	},


	.release = gp8psk_fe_release,
	.release = gp8psk_fe_release,
@@ -271,8 +357,10 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
	.init = NULL,
	.init = NULL,
	.sleep = NULL,
	.sleep = NULL,


	.set_property = gp8psk_fe_set_property,
	.get_property = gp8psk_fe_get_property,
	.set_frontend = gp8psk_fe_set_frontend,
	.set_frontend = gp8psk_fe_set_frontend,
	.get_frontend = gp8psk_fe_get_frontend,

	.get_tune_settings = gp8psk_fe_get_tune_settings,
	.get_tune_settings = gp8psk_fe_get_tune_settings,


	.read_status = gp8psk_fe_read_status,
	.read_status = gp8psk_fe_read_status,
+16 −0
Original line number Original line Diff line number Diff line
@@ -174,6 +174,22 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
	return 0;
	return 0;
}
}


int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
{
	u8 buf;
	int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
	/* Turn off 8psk power */
	if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
		return -EINVAL;
	/* Turn On 8psk power */
	if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
		return -EINVAL;
	/* load BCM4500 firmware */
	if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
		if (gp8psk_load_bcm4500fw(d))
			return EINVAL;
	return 0;
}


static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
{
+1 −0
Original line number Original line Diff line number Diff line
@@ -92,5 +92,6 @@ extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
			     u16 index, u8 *b, int blen);
			     u16 index, u8 *b, int blen);
extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);


#endif
#endif