예제 #1
0
static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
{
	int ret;
	struct dvb_usb_device *d = adap_to_d(adap);
	struct rtl28xxu_priv *priv = d_to_priv(d);
	const struct rtl2832_config *rtl2832_config;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	switch (priv->tuner) {
	case TUNER_RTL2832_FC0012:
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_FC0013:
		rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
		break;
	case TUNER_RTL2832_FC2580:
		/* FIXME: do not abuse fc0012 settings */
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_TUA9001:
		rtl2832_config = &rtl28xxu_rtl2832_tua9001_config;
		break;
	case TUNER_RTL2832_E4000:
		rtl2832_config = &rtl28xxu_rtl2832_e4000_config;
		break;
	case TUNER_RTL2832_R820T:
	case TUNER_RTL2832_R828D:
		rtl2832_config = &rtl28xxu_rtl2832_r820t_config;
		break;
	default:
		dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
				KBUILD_MODNAME, priv->tuner_name);
		ret = -ENODEV;
		goto err;
	}

	/* attach demodulator */
	adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config, &d->i2c_adap);
	if (!adap->fe[0]) {
		ret = -ENODEV;
		goto err;
	}

	/* RTL2832 I2C repeater */
	priv->demod_i2c_adapter = rtl2832_get_i2c_adapter(adap->fe[0]);

	/* set fe callback */
	adap->fe[0]->callback = rtl2832u_frontend_callback;

	return 0;
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
예제 #2
0
static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
{
	int ret;
	struct dvb_usb_device *d = adap_to_d(adap);
	struct rtl28xxu_priv *priv = d_to_priv(d);
	struct rtl2832_platform_data platform_data;
	const struct rtl2832_config *rtl2832_config;
	struct i2c_board_info board_info = {};
	struct i2c_client *client;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	switch (priv->tuner) {
	case TUNER_RTL2832_FC0012:
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_FC0013:
		rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
		break;
	case TUNER_RTL2832_FC2580:
		/* FIXME: do not abuse fc0012 settings */
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_TUA9001:
		rtl2832_config = &rtl28xxu_rtl2832_tua9001_config;
		break;
	case TUNER_RTL2832_E4000:
		rtl2832_config = &rtl28xxu_rtl2832_e4000_config;
		break;
	case TUNER_RTL2832_R820T:
	case TUNER_RTL2832_R828D:
		rtl2832_config = &rtl28xxu_rtl2832_r820t_config;
		break;
	default:
		dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
				KBUILD_MODNAME, priv->tuner_name);
		ret = -ENODEV;
		goto err;
	}

	/* attach demodulator */
	platform_data.config = rtl2832_config;
	platform_data.dvb_frontend = &adap->fe[0];
	strlcpy(board_info.type, "rtl2832", I2C_NAME_SIZE);
	board_info.addr = 0x10;
	board_info.platform_data = &platform_data;
	request_module("%s", board_info.type);
	client = i2c_new_device(&d->i2c_adap, &board_info);
	if (client == NULL || client->dev.driver == NULL) {
		ret = -ENODEV;
		goto err;
	}

	if (!try_module_get(client->dev.driver->owner)) {
		i2c_unregister_device(client);
		ret = -ENODEV;
		goto err;
	}

	priv->i2c_client_demod = client;

	/* RTL2832 I2C repeater */
	priv->demod_i2c_adapter = rtl2832_get_i2c_adapter(adap->fe[0]);

	/* set fe callback */
	adap->fe[0]->callback = rtl2832u_frontend_callback;

	if (priv->slave_demod) {
		struct i2c_board_info info = {};

		/*
		 * We continue on reduced mode, without DVB-T2/C, using master
		 * demod, when slave demod fails.
		 */
		ret = 0;

		/* attach slave demodulator */
		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
			struct mn88472_config mn88472_config = {};

			mn88472_config.fe = &adap->fe[1];
			mn88472_config.i2c_wr_max = 22,
			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
			mn88472_config.xtal = 20500000;
			info.addr = 0x18;
			info.platform_data = &mn88472_config;
			request_module(info.type);
			client = i2c_new_device(priv->demod_i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			priv->i2c_client_slave_demod = client;
		} else {
			struct mn88473_config mn88473_config = {};

			mn88473_config.fe = &adap->fe[1];
			mn88473_config.i2c_wr_max = 22,
			strlcpy(info.type, "mn88473", I2C_NAME_SIZE);
			info.addr = 0x18;
			info.platform_data = &mn88473_config;
			request_module(info.type);
			client = i2c_new_device(priv->demod_i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			priv->i2c_client_slave_demod = client;
		}
	}

	return 0;
err_slave_demod_failed:
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}