if (one_adapter) {
pt3 = fe->dvb->priv; for (i = 0; i < PT3_NUM_FE; i++) if (pt3->adaps[i]->fe == fe) return pt3->adaps[i];
} return container_of(fe->dvb, struct pt3_adapter, dvb_adap);
}
/* * all 4 tuners in PT3 are packaged in a can module (Sharp VA4M6JC2103). * it seems that they share the power lines and Amp power line and * adaps[3] controls those powers.
*/ staticint
pt3_set_tuner_power(struct pt3_board *pt3, bool tuner_on, bool amp_on)
{ struct reg_val rv = { 0x1e, 0x99 };
if (tuner_on)
rv.val |= 0x40; if (amp_on)
rv.val |= 0x04; return pt3_demod_write(pt3->adaps[PT3_NUM_FE - 1], &rv, 1);
}
/* * pt3_fe_init: initialize demod sub modules and ISDB-T tuners all at once. * * As for demod IC (TC90522) and ISDB-T tuners (MxL301RF), * the i2c sequences for init'ing them are not public and hidden in a ROM, * and include the board specific configurations as well. * They are stored in a lump and cannot be taken out / accessed separately, * thus cannot be moved to the FE/tuner driver.
*/ staticint pt3_fe_init(struct pt3_board *pt3)
{ int i, ret; struct dvb_frontend *fe;
pt3_i2c_reset(pt3);
ret = pt3_init_all_demods(pt3); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed to init demod chips\n"); return ret;
}
/* additional config? */ for (i = 0; i < PT3_NUM_FE; i++) {
fe = pt3->adaps[i]->fe;
if (fe->ops.delsys[0] == SYS_ISDBS)
ret = pt3_demod_write(pt3->adaps[i],
init0_sat, ARRAY_SIZE(init0_sat)); else
ret = pt3_demod_write(pt3->adaps[i],
init0_ter, ARRAY_SIZE(init0_ter)); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "demod[%d] failed in init sequence0\n", i); return ret;
}
ret = fe->ops.init(fe); if (ret < 0) return ret;
}
usleep_range(2000, 4000);
ret = pt3_set_tuner_power(pt3, true, false); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed to control tuner module\n"); return ret;
}
/* output pin configuration */ for (i = 0; i < PT3_NUM_FE; i++) {
fe = pt3->adaps[i]->fe; if (fe->ops.delsys[0] == SYS_ISDBS)
ret = pt3_demod_write(pt3->adaps[i],
cfg_sat, ARRAY_SIZE(cfg_sat)); else
ret = pt3_demod_write(pt3->adaps[i],
cfg_ter, ARRAY_SIZE(cfg_ter)); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "demod[%d] failed in init sequence1\n", i); return ret;
}
}
usleep_range(4000, 6000);
for (i = 0; i < PT3_NUM_FE; i++) {
fe = pt3->adaps[i]->fe; if (fe->ops.delsys[0] != SYS_ISDBS) continue; /* init and wake-up ISDB-S tuners */
ret = fe->ops.tuner_ops.init(fe); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed to init SAT-tuner[%d]\n", i); return ret;
}
}
ret = pt3_init_all_mxl301rf(pt3); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed to init TERR-tuners\n"); return ret;
}
ret = pt3_set_tuner_power(pt3, true, true); if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed to control tuner module\n"); return ret;
}
/* Wake up all tuners and make an initial tuning, * in order to avoid interference among the tuners in the module, * according to the doc from the manufacturer.
*/ for (i = 0; i < PT3_NUM_FE; i++) {
fe = pt3->adaps[i]->fe;
ret = 0; if (fe->ops.delsys[0] == SYS_ISDBT)
ret = fe->ops.tuner_ops.init(fe); /* set only when called from pt3_probe(), not resume() */ if (ret == 0 && fe->dtv_property_cache.frequency == 0) {
fe->dtv_property_cache.frequency =
adap_conf[i].init_freq;
ret = fe->ops.tuner_ops.set_params(fe);
} if (ret < 0) {
dev_warn(&pt3->pdev->dev, "Failed in initial tuning of tuner[%d]\n", i); return ret;
}
}
/* and sleep again, waiting to be opened by users. */ for (i = 0; i < PT3_NUM_FE; i++) {
fe = pt3->adaps[i]->fe; if (fe->ops.tuner_ops.sleep)
ret = fe->ops.tuner_ops.sleep(fe); if (ret < 0) break; if (fe->ops.sleep)
ret = fe->ops.sleep(fe); if (ret < 0) break; if (fe->ops.delsys[0] == SYS_ISDBS)
fe->ops.set_voltage = &pt3_set_voltage; else
fe->ops.set_lna = &pt3_set_lna;
} if (i < PT3_NUM_FE) {
dev_warn(&pt3->pdev->dev, "FE[%d] failed to standby\n", i); return ret;
} return 0;
}
staticint pt3_stop_streaming(struct pt3_adapter *adap)
{ int ret;
ret = pt3_stop_dma(adap); if (ret)
dev_warn(adap->dvb_adap.device, "PT3: failed to stop streaming of adap:%d/FE:%d\n",
adap->dvb_adap.num, adap->fe->id);
/* kill the fetching thread */
ret = kthread_stop(adap->thread);
adap->thread = NULL; return ret;
}
for (i = 0; i < PT3_NUM_FE; i++) {
adap = pt3->adaps[i]; if (adap->num_feeds > 0)
pt3_stop_dma(adap);
dvb_frontend_suspend(adap->fe);
pt3_free_dmabuf(adap);
}
staticint pt3_resume(struct device *dev)
{ struct pt3_board *pt3 = dev_get_drvdata(dev); int i, ret; struct pt3_adapter *adap;
ret = pt3_fe_init(pt3); if (ret) return ret;
if (pt3->lna_on_cnt > 0)
pt3_set_tuner_power(pt3, true, true); if (pt3->lnb_on_cnt > 0)
pt3_lnb_ctrl(pt3, true);
for (i = 0; i < PT3_NUM_FE; i++) {
adap = pt3->adaps[i];
dvb_frontend_resume(adap->fe);
ret = pt3_alloc_dmabuf(adap); if (ret) {
dev_err(&pt3->pdev->dev, "failed to alloc DMA bufs\n"); continue;
} if (adap->num_feeds > 0)
pt3_start_dma(adap);
}
return 0;
}
#endif/* CONFIG_PM_SLEEP */
staticvoid pt3_remove(struct pci_dev *pdev)
{ struct pt3_board *pt3; int i;
pt3 = pci_get_drvdata(pdev); for (i = PT3_NUM_FE - 1; i >= 0; i--)
pt3_cleanup_adapter(pt3, i);
i2c_del_adapter(&pt3->i2c_adap);
}
for (i = 0; i < PT3_NUM_FE; i++) {
ret = pt3_alloc_adapter(pt3, i); if (ret < 0) break;
ret = pt3_attach_fe(pt3, i); if (ret < 0) break;
} if (i < PT3_NUM_FE) {
dev_err(&pdev->dev, "Failed to create FE%d\n", i); goto err_cleanup_adapters;
}
ret = pt3_fe_init(pt3); if (ret < 0) {
dev_err(&pdev->dev, "Failed to init frontends\n");
i = PT3_NUM_FE - 1; goto err_cleanup_adapters;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.