From 6830f4df0824280542fc690a61b2f030fb132d3d Mon Sep 17 00:00:00 2001 From: Ralph Metzler Date: Fri, 7 Apr 2017 22:21:06 +0200 Subject: [PATCH] add sat selection for fmode 1 and 2 --- ddbridge/ddbridge-core.c | 110 ++++++++++++++++++++++----------------- ddbridge/ddbridge-i2c.c | 60 +++++++++++---------- ddbridge/ddbridge.h | 23 ++++---- 3 files changed, 107 insertions(+), 86 deletions(-) diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 9ccc2aa..c24f53e 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -46,6 +46,10 @@ static int fmode; module_param(fmode, int, 0444); MODULE_PARM_DESC(fmode, "frontend emulation mode"); +static int fmode_sat = -1; +module_param(fmode_sat, int, 0444); +MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat"); + static int old_quattro; module_param(old_quattro, int, 0444); MODULE_PARM_DESC(old_quattro, "old quattro LNB input order "); @@ -1681,6 +1685,29 @@ static int max_send_master_cmd(struct dvb_frontend *fe, return 0; } +static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input, + struct dvb_diseqc_master_cmd *cmd) +{ + u32 tag = DDB_LINK_TAG(link); + int i; + + ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input)); + for (i = 0; i < cmd->msg_len; i++) + ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input)); + lnb_command(dev, link, input, LNB_CMD_DISEQC); + return 0; +} + +static int lnb_set_sat(struct ddb *dev, u32 link, u32 input, u32 sat, u32 band, u32 hor) +{ + struct dvb_diseqc_master_cmd cmd = { + .msg = {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, + .msg_len = 4 + }; + cmd.msg[3] = 0xf0 | ( ((sat << 2) & 0x0c) | (band ? 1 : 0) | (hor ? 2 : 0)); + return lnb_send_diseqc(dev, link, input, &cmd); +} + static int lnb_set_tone(struct ddb *dev, u32 link, u32 input, fe_sec_tone_mode_t tone) { @@ -1933,6 +1960,17 @@ static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm) pr_info("DDBridge: Set fmode link %u = %u\n", l, fm); mutex_lock(&link->lnb.lock); if (fm == 2 || fm == 1) { + if (fmode_sat >= 0) { + lnb_set_sat(dev, l, 0, fmode_sat, 0, 0); + if (old_quattro) { + lnb_set_sat(dev, l, 1, fmode_sat, 0, 1); + lnb_set_sat(dev, l, 2, fmode_sat, 1, 0); + } else { + lnb_set_sat(dev, l, 1, fmode_sat, 1, 0); + lnb_set_sat(dev, l, 2, fmode_sat, 0, 1); + } + lnb_set_sat(dev, l, 3, fmode_sat, 1, 1); + } lnb_set_tone(dev, l, 0, SEC_TONE_OFF); if (old_quattro) { lnb_set_tone(dev, l, 1, SEC_TONE_OFF); @@ -2000,46 +2038,6 @@ static int fe_attach_mxl5xx(struct ddb_input *input) return 0; } -static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, - int (*start_feed)(struct dvb_demux_feed *), - int (*stop_feed)(struct dvb_demux_feed *), - void *priv) -{ - dvbdemux->priv = priv; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = start_feed; - dvbdemux->stop_feed = stop_feed; - dvbdemux->write_to_decoder = NULL; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - return dvb_dmx_init(dvbdemux); -} - -static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, - struct dvb_demux *dvbdemux, - struct dmx_frontend *hw_frontend, - struct dmx_frontend *mem_frontend, - struct dvb_adapter *dvb_adapter) -{ - int ret; - - dmxdev->filternum = 256; - dmxdev->demux = &dvbdemux->dmx; - dmxdev->capabilities = 0; - ret = dvb_dmxdev_init(dmxdev, dvb_adapter); - if (ret < 0) - return ret; - - hw_frontend->source = DMX_FRONTEND_0; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); - mem_frontend->source = DMX_MEMORY_FE; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); - return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); -} - #if 0 static int start_input(struct ddb_input *input) { @@ -2111,12 +2109,13 @@ static void dvb_input_detach(struct ddb_input *input) case 0x20: dvb_net_release(&dvb->dvbnet); /* fallthrough */ - case 0x11: - dvbdemux->dmx.close(&dvbdemux->dmx); + case 0x12: dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &dvb->hw_frontend); dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &dvb->mem_frontend); + /* fallthrough */ + case 0x11: dvb_dmxdev_release(&dvb->dmxdev); /* fallthrough */ case 0x10: @@ -2239,21 +2238,33 @@ static int dvb_input_attach(struct ddb_input *input) dvb->attached = 0x01; - ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", - start_feed, - stop_feed, input); + dvbdemux->priv = input; + dvbdemux->dmx.capabilities = DMX_TS_FILTERING | + DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; + dvbdemux->start_feed = start_feed; + dvbdemux->stop_feed = stop_feed; + dvbdemux->filternum = dvbdemux->feednum = 256; + ret = dvb_dmx_init(dvbdemux); if (ret < 0) return ret; dvb->attached = 0x10; - ret = my_dvb_dmxdev_ts_card_init(&dvb->dmxdev, - &dvb->demux, - &dvb->hw_frontend, - &dvb->mem_frontend, adap); + dvb->dmxdev.filternum = 256; + dvb->dmxdev.demux = &dvbdemux->dmx; + ret = dvb_dmxdev_init(&dvb->dmxdev, adap); if (ret < 0) return ret; dvb->attached = 0x11; + dvb->mem_frontend.source = DMX_MEMORY_FE; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->mem_frontend); + dvb->hw_frontend.source = DMX_FRONTEND_0; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend); + ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend); + if (ret < 0) + return ret; + dvb->attached = 0x12; + ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); if (ret < 0) return ret; @@ -2348,6 +2359,7 @@ static int dvb_input_attach(struct ddb_input *input) return 0; } dvb->attached = 0x30; + if (dvb->fe) { if (dvb_register_frontend(adap, dvb->fe) < 0) return -ENODEV; diff --git a/ddbridge/ddbridge-i2c.c b/ddbridge/ddbridge-i2c.c index f8b4fe8..6fc63d5 100644 --- a/ddbridge/ddbridge-i2c.c +++ b/ddbridge/ddbridge-i2c.c @@ -156,38 +156,43 @@ static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, struct ddb *dev = i2c->dev; u8 addr = 0; - if (num != 1 && num != 2) - return -EIO; addr = msg[0].addr; if (msg[0].len > i2c->bsize) return -EIO; - if (num == 2 && msg[1].flags & I2C_M_RD && - !(msg[0].flags & I2C_M_RD)) { - if (msg[1].len > i2c->bsize) - return -EIO; - ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(dev, msg[0].len | (msg[1].len << 16), - i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 1)) { - ddbcpyfrom(dev, msg[1].buf, - i2c->rbuf, - msg[1].len); - return num; - } - } - if (num == 1 && !(msg[0].flags & I2C_M_RD)) { - ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 2)) - return num; - } - if (num == 1 && (msg[0].flags & I2C_M_RD)) { - ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 3)) { + switch (num) { + case 1: + if (msg[0].flags & I2C_M_RD) { + ddbwritel(dev, msg[0].len << 16, + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 3)) + break; ddbcpyfrom(dev, msg[0].buf, i2c->rbuf, msg[0].len); return num; - } + } + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 2)) + break; + return num; + case 2: + if ((msg[0].flags & I2C_M_RD) == I2C_M_RD) + break; + if ((msg[1].flags & I2C_M_RD) != I2C_M_RD) + break; + if (msg[1].len > i2c->bsize) + break; + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len | (msg[1].len << 16), + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 1)) + break; + ddbcpyfrom(dev, msg[1].buf, + i2c->rbuf, + msg[1].len); + return num; + default: + break; } return -EIO; } @@ -247,11 +252,10 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, adap->class = I2C_CLASS_TV_ANALOG; #endif #endif - /*strcpy(adap->name, "ddbridge");*/ snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x", dev->nr, i2c->link, i); adap->algo = &ddb_i2c_algo; - adap->algo_data = (void *)i2c; + adap->algo_data = (void *) i2c; adap->dev.parent = dev->dev; return i2c_add_adapter(adap); } diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index 0c324d5..e3b1c29 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -144,6 +144,19 @@ struct ddb_ids { u32 mac; }; +#if 0 +struct ddb_ddata { + u32 id; +#define DDB_NONE 0 +#define DDB_OCTOPUS 1 +#define DDB_OCTOPUS_CI 2 +#define DDB_MODULATOR 3 +#define DDB_OCTONET 4 +#define DDB_OCTOPUS_MAX 5 +#define DDB_OCTOPUS_MAX_CT 6 +#define DDB_OCTOPRO 7 +#define DDB_OCTOPRO_HDIN 8 +#else struct ddb_info { u32 type; #define DDB_NONE 0 @@ -155,6 +168,7 @@ struct ddb_info { #define DDB_OCTOPUS_MAX_CT 6 #define DDB_OCTOPRO 7 #define DDB_OCTOPRO_HDIN 8 +#endif u32 version; char *name; u32 i2c_mask; @@ -682,15 +696,6 @@ static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) return memcpy_fromio(dst, (char *) (dev->regs + adr), count); } -#if 0 - -#define ddbcpyto(_dev, _adr, _src, _count) \ - memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count)) - -#define ddbcpyfrom(_dev, _dst, _adr, _count) \ - memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count)) -#endif - #define ddbmemset(_dev, _adr, _val, _count) \ memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))