1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

Release 0.9.20

some CAMs are really slow, increase timeout for link init
  more I2C debugging
  added README.md
  store ids for all links in link structure and add devid attribute
  - fix dynamic fmode changes - 69Mhz no longer needed for MaxS8 on GT link - show state in GT link change
  do not reference eth_rebuild_header in newer kernels
  fix reference to struct
  inc copyright year
  inc version number
  added support for SPANSION flash
This commit is contained in:
mvoelkel 2015-09-17 11:42:01 +02:00
commit 411a142c21
11 changed files with 249 additions and 63 deletions

11
README.md Normal file
View File

@ -0,0 +1,11 @@
# DDBridge Driver
###Prepare for Building
TBD
###Building
TBD

View File

@ -61,6 +61,7 @@ struct ddflash {
uint32_t type;
uint32_t version;
uint32_t flash_type;
uint32_t sector_size;
uint32_t size;
@ -88,6 +89,8 @@ enum {
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
};
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
@ -131,6 +134,128 @@ void dump(const uint8_t *b, int l)
}
}
int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
uint8_t LockBits, uint32_t fw_off)
{
int err = 0;
uint8_t cmd[260];
int i, j;
uint32_t flen, blen;
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
if (blen % 0xff)
blen = (blen + 0xff) & 0xffffff00;
printf("blen = %u, flen = %u\n", blen, flen);
do {
cmd[0] = 0x50; // EWSR
err = flashio(ddf->fd, cmd, 1, NULL, 0);
if (err < 0)
break;
cmd[0] = 0x01; // WRSR
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(ddf->fd, cmd, 2, NULL, 0);
if (err < 0)
break;
for (i = 0; i < flen; i += 4096) {
if ((i & 0xFFFF) == 0)
printf(" Erase %08x\n", FlashOffset + i);
cmd[0] = 0x06; // WREN
err = flashio(ddf->fd, cmd, 1, NULL, 0);
if (err < 0)
break;
cmd[0] = 0x20; // Sector erase ( 4Kb)
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
cmd[3] = 0x00;
err = flashio(ddf->fd, cmd, 4, NULL, 0);
if (err < 0)
break;
while (1) {
cmd[0] = 0x05; // RDRS
err = flashio(ddf->fd, cmd, 1, &cmd[0], 1);
if (err < 0)
break;
if ((cmd[0] & 0x01) == 0)
break;
}
if (err < 0)
break;
}
if (err < 0)
break;
for (j = blen - 256; j >= 0; j -= 256 ) {
uint32_t len = 256;
ssize_t rlen;
if (lseek(dev, j + fw_off, SEEK_SET) < 0) {
printf("seek error\n");
return -1;
}
if (flen - j < 256) {
len = flen - j;
memset(ddf->buffer, 0xff, 256);
}
rlen = read(dev, ddf->buffer, len);
if (rlen < 0 || rlen != len) {
printf("file read error %d,%d at %u\n", rlen, errno, j);
return -1;
}
printf ("write %u bytes at %08x\n", len, j);
if ((j & 0xFFFF) == 0)
printf(" Programm %08x\n", FlashOffset + j);
cmd[0] = 0x06; // WREN
err = flashio(ddf->fd, cmd, 1, NULL, 0);
if (err < 0)
break;
cmd[0] = 0x02; // PP
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
cmd[3] = 0x00;
memcpy(&cmd[4], ddf->buffer, 256);
err = flashio(ddf->fd, cmd, 260, NULL, 0);
if (err < 0)
break;
while(1) {
cmd[0] = 0x05; // RDRS
err = flashio(ddf->fd, cmd,1, &cmd[0], 1);
if (err < 0)
break;
if ((cmd[0] & 0x01) == 0)
break;
}
if (err < 0)
break;
}
if (err < 0)
break;
cmd[0] = 0x50; // EWSR
err = flashio(ddf->fd, cmd, 1, NULL, 0);
if (err < 0)
break;
cmd[0] = 0x01; // WRSR
cmd[1] = LockBits; // BPx = 0, Lock all blocks
err = flashio(ddf->fd, cmd, 2, NULL, 0);
} while(0);
return err;
}
static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off)
{
int err = 0;
@ -261,7 +386,16 @@ static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, ui
static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
{
flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
switch (ddf->flash_type) {
case SSTI_SST25VF016B:
case SSTI_SST25VF032B:
return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
case SSTI_SST25VF064C:
return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off);
case SPANSION_S25FL116K:
return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off);
}
return -1;
}
static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
@ -314,29 +448,41 @@ static int flash_detect(struct ddflash *ddf)
return r;
if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) {
r = SSTI_SST25VF016B;
//printf("Flash: SSTI SST25VF016B 16 MBit\n");
ddf->flash_type = SSTI_SST25VF016B;
printf("Flash: SSTI SST25VF016B 16 MBit\n");
ddf->sector_size = 4096;
ddf->size = 0x200000;
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) {
r = SSTI_SST25VF032B;
//printf("Flash: SSTI SST25VF032B 32 MBit\n");
ddf->flash_type = SSTI_SST25VF032B;
printf("Flash: SSTI SST25VF032B 32 MBit\n");
ddf->sector_size = 4096;
ddf->size = 0x400000;
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) {
ddf->flash_type = SSTI_SST25VF064C;
printf("Flash: SSTI SST25VF064C 64 MBit\n");
ddf->sector_size = 4096;
ddf->size = 0x800000;
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) {
ddf->flash_type = SPANSION_S25FL116K;
printf("Flash: SPANSION S25FL116K 16 MBit\n");
ddf->sector_size = 4096;
ddf->size = 0x200000;
} else if (id[0] == 0x1F && id[1] == 0x28) {
r = ATMEL_AT45DB642D;
//printf("Flash: Atmel AT45DB642D 64 MBit\n");
ddf->flash_type = ATMEL_AT45DB642D;
printf("Flash: Atmel AT45DB642D 64 MBit\n");
ddf->sector_size = 1024;
ddf->size = 0x800000;
} else {
r = UNKNOWN_FLASH;
//printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
return -1;
}
if (ddf->sector_size) {
ddf->buffer = malloc(ddf->sector_size);
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
if (!ddf->buffer)
return -1;
}
return r;
return 0;
}
@ -777,6 +923,8 @@ int main(int argc, char **argv)
}
}
flash = flash_detect(&ddf);
if (flash < 0)
return -1;
get_id(&ddf);
res = update_flash(&ddf);

View File

@ -1292,6 +1292,8 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
break;
msleep(20);
}
if (c == 10)
pr_info("lnb_command lnb = %08x cmd = %08x\n", lnb, cmd);
return 0;
}
@ -1542,14 +1544,15 @@ static int mxl_fw_read(void *priv, u8 *buf, u32 len)
return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len);
}
static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fmode)
static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
{
u32 l = link->nr;
if (link->lnb.setmode == fmode)
if (link->lnb.fmode == fm)
return 0;
if (fmode == 2 || fmode == 1) {
mutex_lock(&link->lnb.lock);
pr_info("Set fmode link %u = %u\n", l, fm);
mutex_lock(&link->lnb.lock);
if (fm == 2 || fm == 1) {
lnb_set_tone(dev, l, 0, SEC_TONE_OFF);
if (old_quattro) {
lnb_set_tone(dev, l, 1, SEC_TONE_OFF);
@ -1559,9 +1562,9 @@ static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fmode)
lnb_set_tone(dev, l, 2, SEC_TONE_OFF);
}
lnb_set_tone(dev, l, 3, SEC_TONE_ON);
mutex_unlock(&link->lnb.lock);
}
link->lnb.setmode = fmode;
link->lnb.fmode = fm;
mutex_unlock(&link->lnb.lock);
return 0;
}
@ -1584,12 +1587,10 @@ static int fe_attach_mxl5xx(struct ddb_input *input)
struct mxl5xx_cfg cfg;
int demod, tuner;
link->lnb.fmode = fmode;
cfg = mxl5xx;
cfg.fw_priv = link;
if (dev->link[0].info->type == DDB_OCTONET)
cfg.ts_clk = 69;
;//cfg.ts_clk = 69;
demod = input->nr;
tuner = demod & 3;
@ -3660,10 +3661,10 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct ddb_id ddbid;
ddbid.vendor = dev->ids.vendor;
ddbid.device = dev->ids.device;
ddbid.subvendor = dev->ids.subvendor;
ddbid.subdevice = dev->ids.subdevice;
ddbid.vendor = dev->link[0].ids.vendor;
ddbid.device = dev->link[0].ids.device;
ddbid.subvendor = dev->link[0].ids.subvendor;
ddbid.subdevice = dev->link[0].ids.subdevice;
ddbid.hw = ddbreadl(dev, 0);
ddbid.regmap = ddbreadl(dev, 4);
if (copy_to_user(parg, &ddbid, sizeof(ddbid)))
@ -4164,7 +4165,7 @@ static ssize_t version_show(struct device *device,
struct ddb *dev = dev_get_drvdata(device);
return sprintf(buf, "%08x %08x\n",
dev->ids.hwid, dev->ids.regmapid);
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
}
static ssize_t hwid_show(struct device *device,
@ -4172,7 +4173,7 @@ static ssize_t hwid_show(struct device *device,
{
struct ddb *dev = dev_get_drvdata(device);
return sprintf(buf, "0x%08X\n", dev->ids.hwid);
return sprintf(buf, "0x%08X\n", dev->link[0].ids.hwid);
}
static ssize_t regmap_show(struct device *device,
@ -4180,7 +4181,7 @@ static ssize_t regmap_show(struct device *device,
{
struct ddb *dev = dev_get_drvdata(device);
return sprintf(buf, "0x%08X\n", dev->ids.regmapid);
return sprintf(buf, "0x%08X\n", dev->link[0].ids.regmapid);
}
static ssize_t vlan_show(struct device *device,
@ -4217,6 +4218,15 @@ static ssize_t fmode_show(struct device *device,
return sprintf(buf, "%u\n", dev->link[num].lnb.fmode);
}
static ssize_t devid_show(struct device *device,
struct device_attribute *attr, char *buf)
{
int num = attr->attr.name[5] - 0x30;
struct ddb *dev = dev_get_drvdata(device);
return sprintf(buf, "%08x\n", dev->link[num].ids.devid);
}
static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
const char *buf, size_t count)
{
@ -4228,8 +4238,7 @@ static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
return -EINVAL;
if (val > 3)
return -EINVAL;
dev->link[num].lnb.fmode = val;
lnb_init_fmode(dev, &dev->link[num], fmode);
lnb_init_fmode(dev, &dev->link[num], val);
return count;
}
@ -4247,6 +4256,10 @@ static struct device_attribute ddb_attrs[] = {
__ATTR(fmode1, 0664, fmode_show, fmode_store),
__ATTR(fmode2, 0664, fmode_show, fmode_store),
__ATTR(fmode3, 0664, fmode_show, fmode_store),
__ATTR_MRO(devid0, devid_show),
__ATTR_MRO(devid1, devid_show),
__ATTR_MRO(devid2, devid_show),
__ATTR_MRO(devid3, devid_show),
__ATTR_RO(hwid),
__ATTR_RO(regmap),
#if 0
@ -4421,7 +4434,11 @@ static void ddb_device_destroy(struct ddb *dev)
static void gtl_link_handler(unsigned long priv)
{
printk("GT link change\n");
struct ddb *dev = (struct ddb *) priv;
u32 regs = dev->link[0].info->regmap->gtl->base;
printk("GT link change: %u\n",
(1 & ddbreadl(dev, regs)));
}
static void link_tasklet(unsigned long data)
@ -4502,6 +4519,7 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
spin_lock_init(&link->lock);
mutex_init(&link->lnb.lock);
link->lnb.fmode = 0xffffffff;
mutex_init(&link->flash_mutex);
if (!(1 & ddbreadl(dev, regs))) {
@ -4531,6 +4549,7 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
id);
return -1;
}
link->ids.devid = id;
ddbwritel(dev, 1, 0x1a0);

View File

@ -113,20 +113,27 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND);
stat = wait_for_completion_timeout(&i2c->completion, HZ);
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
if (stat == 0) {
pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n",
dev->nr, i2c->nr, i2c->link);
#ifdef CONFIG_PCI_MSI
{ /* MSI debugging*/
#if 1
{
u32 istat = ddbreadl(dev, INTERRUPT_STATUS);
dev_err(dev->dev, "DDBridge IRS %08x\n", istat);
ddbwritel(dev, istat, INTERRUPT_ACK);
if (istat & 1) {
ddbwritel(dev, istat & 1, INTERRUPT_ACK);
} else {
u32 mon = ddbreadl(dev, i2c->regs + I2C_MONITOR);
dev_err(dev->dev, "I2C cmd=%08x mon=%08x\n",
val, mon);
}
}
#endif
return -EIO;
}
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
if (val & 0x70000)
return -EIO;
return 0;

View File

@ -102,7 +102,7 @@ static int ns_set_pids(struct dvbnss *nss)
struct ddb *dev = input->port->dev;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
if (dev->ids.devid == 0x0301dd01) {
if (dev->link[0].ids.devid == 0x0301dd01) {
u32 sys = 0;
int pid, j = 1;
@ -134,7 +134,7 @@ static int ns_set_pid(struct dvbnss *nss, u16 pid)
u32 off = STREAM_PIDS(dns->nr);
#if 1
if (dev->ids.devid == 0x0301dd01) {
if (dev->link[0].ids.devid == 0x0301dd01) {
if (pid & 0x2000) {
if (pid & 0x8000)
memset(nss->pids, 0xff, 0x400);

View File

@ -112,10 +112,10 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->dev = &pdev->dev;
pci_set_drvdata(pdev, dev);
dev->ids.vendor = id->vendor;
dev->ids.device = id->device;
dev->ids.subvendor = id->subvendor;
dev->ids.subdevice = id->subdevice;
dev->link[0].ids.vendor = id->vendor;
dev->link[0].ids.device = id->device;
dev->link[0].ids.subvendor = id->subvendor;
dev->link[0].ids.subdevice = id->subdevice;
dev->link[0].dev = dev;
dev->link[0].info = (struct ddb_info *) id->driver_data;
@ -136,11 +136,11 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
goto fail;
}
dev->ids.hwid = ddbreadl(dev, 0);
dev->ids.regmapid = ddbreadl(dev, 4);
dev->link[0].ids.hwid = ddbreadl(dev, 0);
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
pr_info("DDBridge: HW %08x REGMAP %08x\n",
dev->ids.hwid, dev->ids.regmapid);
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
if (dev->link[0].info->ns_num) {
int i;

View File

@ -371,7 +371,6 @@ struct ddb_lnb {
u32 voltage[4];
u32 voltages;
u32 fmode;
u32 setmode;
};
struct ddb_link {
@ -383,13 +382,13 @@ struct ddb_link {
struct mutex flash_mutex;
struct ddb_lnb lnb;
struct tasklet_struct tasklet;
struct ddb_ids ids;
};
struct ddb {
struct pci_dev *pdev;
struct platform_device *pfdev;
struct device *dev;
struct ddb_ids ids;
int msi;
struct workqueue_struct *wq;
@ -706,6 +705,6 @@ void ddbridge_mod_rate_handler(unsigned long data);
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
#define DDBRIDGE_VERSION "0.9.19"
#define DDBRIDGE_VERSION "0.9.20"
#endif

View File

@ -156,28 +156,28 @@ static int __init octonet_probe(struct platform_device *pdev)
return -ENOMEM;
}
dev->ids.hwid = ddbreadl(dev, 0);
dev->ids.regmapid = ddbreadl(dev, 4);
dev->ids.devid = ddbreadl(dev, 8);
dev->ids.mac = ddbreadl(dev, 12);
dev->link[0].ids.hwid = ddbreadl(dev, 0);
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
dev->link[0].ids.devid = ddbreadl(dev, 8);
dev->link[0].ids.mac = ddbreadl(dev, 12);
dev->ids.vendor = dev->ids.devid & 0xffff;
dev->ids.device = dev->ids.devid >> 16;
dev->ids.subvendor = dev->ids.devid & 0xffff;
dev->ids.subdevice = dev->ids.devid >> 16;
dev->link[0].ids.vendor = dev->link[0].ids.devid & 0xffff;
dev->link[0].ids.device = dev->link[0].ids.devid >> 16;
dev->link[0].ids.subvendor = dev->link[0].ids.devid & 0xffff;
dev->link[0].ids.subdevice = dev->link[0].ids.devid >> 16;
dev->link[0].dev = dev;
if (dev->ids.devid == 0x0300dd01)
if (dev->link[0].ids.devid == 0x0300dd01)
dev->link[0].info = &ddb_octonet;
else if (dev->ids.devid == 0x0301dd01)
else if (dev->link[0].ids.devid == 0x0301dd01)
dev->link[0].info = &ddb_octonet_jse;
else if (dev->ids.devid == 0x0307dd01)
else if (dev->link[0].ids.devid == 0x0307dd01)
dev->link[0].info = &ddb_octonet_gtl;
else
dev->link[0].info = &ddb_octonet_tbd;
pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid);
pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid);
pr_info("HW %08x REGMAP %08x\n", dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
pr_info("MAC %08x DEVID %08x\n", dev->link[0].ids.mac, dev->link[0].ids.devid);
ddbwritel(dev, 0, ETHER_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
@ -233,7 +233,7 @@ static __init int init_octonet(void)
int res;
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
", Copyright (C) 2010-14 Digital Devices GmbH\n");
", Copyright (C) 2010-15 Digital Devices GmbH\n");
res = ddb_class_create();
if (res)
return res;

View File

@ -315,7 +315,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
/* read the buffer size from the CAM */
if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
return ret;
if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ)) != 0)
return ret;
if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
return -EIO;

View File

@ -1227,7 +1227,9 @@ static int dvb_net_stop(struct net_device *dev)
static const struct header_ops dvb_header_ops = {
.create = eth_header,
.parse = eth_header_parse,
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 2)
.rebuild = eth_rebuild_header,
#endif
};

View File

@ -585,7 +585,7 @@ static int sleep(struct dvb_frontend *fe)
if (p->tuner_in_use == state->tuner)
break;
}
if (p == &state->base->mxls)
if (&p->mxl == &state->base->mxls)
enable_tuner(state, state->tuner, 0);
mutex_unlock(&state->base->tune_lock);
}