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

Commit ecb71d26 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[media] saa7134: Kworld SBTVD: make both analog and digital to work



There are some weird bugs at tda8290/tda18271 initialization, as it
insits do do analog initialization during DVB frontend attach:

DVB: registering new adapter (saa7133[0])
DVB: registering adapter 0 frontend 0 (Fujitsu mb86A20s)...
mb86a20s: mb86a20s_initfe
tda18271_write_regs: [2-0060|M] ERROR: idx = 0x5, len = 1, i2c_transfer returned: -5
tda18271_init: [2-0060|M] error -5 on line 830
tda18271_tune: [2-0060|M] error -5 on line 908
tda18271_write_regs
tda18271_write_regs: [2-0060|M] ERROR: idx = 0x5, len = 1, i2c_transfer returned: -5
tda18271c2_rf_tracking_filters_correction: [2-0060|M] error -5 on line 265
tda18271_write_regs
tda18271_write_regs: [2-0060|M] ERROR: idx = 0x25, len = 1, i2c_transfer returned: -5
tda18271_channel_configuration: [2-0060|M] error -5 on line 119
tda18271_set_analog_params: [2-0060|M] error -5 on line 1045
tda18271_set_analog_params: [2-0060|M] error -5 on line 1045
tda829x 2-004b: tda8295 not locked, no signal?
tda829x 2-004b: tda8295_i2c_bridge: disable i2c gate
tda829x 2-004b: tda8295 not locked, no signal?
tda829x 2-004b: tda8295_i2c_bridge: disable i2c gate
mb86a20s_i2c_writereg: writereg error (rc == -5, reg == 0x29, data == 0x33)
mb86a20s: Init failed. Will try again later

The problem is that mb86a20s is only visible if the analog part is disabled.

However, due to a trick at mb86a20s, it will later initialize properly:

mb86a20s: mb86a20s_initfe: Initialization succeded.

This is hacky and ugly. However, I coldn't find any easy way to fix it.
A proper fix would be to have a resource locking schema, used by both
V4L and DVB parts that would block access to analog registers while
digital registers are in use, but this will probably put tda829x into
a dead lock.

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 6a58bc0f
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -232,6 +232,7 @@ static void tda8290_set_params(struct dvb_frontend *fe,
		tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
		tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
	}
	}



	tda8290_i2c_bridge(fe, 1);
	tda8290_i2c_bridge(fe, 1);


	if (fe->ops.tuner_ops.set_analog_params)
	if (fe->ops.tuner_ops.set_analog_params)
+10 −6
Original line number Original line Diff line number Diff line
@@ -5179,11 +5179,7 @@ struct saa7134_board saa7134_boards[] = {
	[SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
	[SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG] = {
		.name           = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
		.name           = "Kworld PCI SBTVD/ISDB-T Full-Seg Hybrid",
		.audio_clock    = 0x00187de7,
		.audio_clock    = 0x00187de7,
#if 0
		.tuner_type     = TUNER_PHILIPS_TDA8290,
		.tuner_type     = TUNER_PHILIPS_TDA8290,
#else
		.tuner_type	= UNSET,
#endif
		.tuner_addr     = ADDR_UNSET,
		.tuner_addr     = ADDR_UNSET,
		.radio_type     = UNSET,
		.radio_type     = UNSET,
		.radio_addr	= ADDR_UNSET,
		.radio_addr	= ADDR_UNSET,
@@ -6926,10 +6922,17 @@ static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
	/* toggle AGC switch through GPIO 27 */
	/* toggle AGC switch through GPIO 27 */
	switch (mode) {
	switch (mode) {
	case TDA18271_ANALOG:
	case TDA18271_ANALOG:
		saa7134_set_gpio(dev, 27, 0);
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x4000);
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x4000);
		msleep(20);
		break;
		break;
	case TDA18271_DIGITAL:
	case TDA18271_DIGITAL:
		saa7134_set_gpio(dev, 27, 1);
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
		msleep(20);
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
		msleep(30);
		break;
		break;
	default:
	default:
		return -EINVAL;
		return -EINVAL;
@@ -6987,6 +6990,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
int saa7134_tuner_callback(void *priv, int component, int command, int arg)
int saa7134_tuner_callback(void *priv, int component, int command, int arg)
{
{
	struct saa7134_dev *dev = priv;
	struct saa7134_dev *dev = priv;

	if (dev != NULL) {
	if (dev != NULL) {
		switch (dev->tuner_type) {
		switch (dev->tuner_type) {
		case TUNER_PHILIPS_TDA8290:
		case TUNER_PHILIPS_TDA8290:
+5 −11
Original line number Original line Diff line number Diff line
@@ -237,6 +237,8 @@ static struct tda18271_std_map mb86a20s_tda18271_std_map = {
static struct tda18271_config kworld_tda18271_config = {
static struct tda18271_config kworld_tda18271_config = {
	.std_map = &mb86a20s_tda18271_std_map,
	.std_map = &mb86a20s_tda18271_std_map,
	.gate    = TDA18271_GATE_DIGITAL,
	.gate    = TDA18271_GATE_DIGITAL,
	.config  = 3,	/* Use tuner callback for AGC */

};
};


static const struct mb86a20s_config kworld_mb86a20s_config = {
static const struct mb86a20s_config kworld_mb86a20s_config = {
@@ -1654,24 +1656,16 @@ static int dvb_init(struct saa7134_dev *dev)
		}
		}
		break;
		break;
	case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
	case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x14000);
		/* Switch to digital mode */
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x14000);
		saa7134_tuner_callback(dev, 0,
		msleep(20);
				       TDA18271_CALLBACK_CMD_AGC_ENABLE, 1);
		saa_writel(SAA7134_GPIO_GPMODE0 >> 2, 0x54000);
		saa_writel(SAA7134_GPIO_GPSTATUS0 >> 2, 0x54000);
		msleep(20);
		fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
		fe0->dvb.frontend = dvb_attach(mb86a20s_attach,
					       &kworld_mb86a20s_config,
					       &kworld_mb86a20s_config,
					       &dev->i2c_adap);
					       &dev->i2c_adap);
		if (fe0->dvb.frontend != NULL) {
		if (fe0->dvb.frontend != NULL) {
#if 0
			dvb_attach(tda829x_attach, fe0->dvb.frontend,
			dvb_attach(tda829x_attach, fe0->dvb.frontend,
				   &dev->i2c_adap, 0x4b,
				   &dev->i2c_adap, 0x4b,
				   &tda829x_no_probe);
				   &tda829x_no_probe);
#else
			dvb_attach(tda829x_attach, fe0->dvb.frontend,
				   &dev->i2c_adap, 0x4b, NULL);
#endif
			dvb_attach(tda18271_attach, fe0->dvb.frontend,
			dvb_attach(tda18271_attach, fe0->dvb.frontend,
				   0x60, &dev->i2c_adap,
				   0x60, &dev->i2c_adap,
				   &kworld_tda18271_config);
				   &kworld_tda18271_config);