mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
support other CI speeds
This commit is contained in:
parent
50fee67d49
commit
16c0834b78
@ -28,7 +28,7 @@ DEFINE_MUTEX(redirect_lock);
|
|||||||
|
|
||||||
static int ci_bitrate = 72000;
|
static int ci_bitrate = 72000;
|
||||||
module_param(ci_bitrate, int, 0444);
|
module_param(ci_bitrate, int, 0444);
|
||||||
MODULE_PARM_DESC(ci_bitrate, " Bitrate for output to CI.");
|
MODULE_PARM_DESC(ci_bitrate, " Bitrate in KHz for output to CI.");
|
||||||
|
|
||||||
static int ts_loop = -1;
|
static int ts_loop = -1;
|
||||||
module_param(ts_loop, int, 0444);
|
module_param(ts_loop, int, 0444);
|
||||||
@ -547,89 +547,74 @@ static void ddb_buffers_free(struct ddb *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void calc_speed(struct ddb_output *output, u32 *con, u32 *con2)
|
static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
||||||
{
|
{
|
||||||
struct ddb *dev = output->port->dev;
|
struct ddb *dev = output->port->dev;
|
||||||
u32 bitrate = output->port->obr;
|
u32 bitrate = output->port->obr, max_bitrate = 72000;
|
||||||
u32 flags = 0;//pdx->OutputStream[Stream].flags;
|
u32 gap = 4, nco = 0;
|
||||||
u32 gap = 6;
|
|
||||||
u32 NCOIncrement = 0;
|
|
||||||
u32 Control = 0x3C; /* Turn clock on, Enable GAP, Enable NP, Phase = 1 */
|
|
||||||
u32 Maxbitrate = 72000;
|
|
||||||
|
|
||||||
if (flags & 0x00000008) /* ts start */
|
*con = 0x1C;
|
||||||
Control |= 0x2000;
|
if (output->port->gap != 0xffffffff) {
|
||||||
|
flags |= 1;
|
||||||
|
gap = output->port->gap;
|
||||||
|
}
|
||||||
if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) {
|
if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) {
|
||||||
Control = 0x00;
|
*con = 0x10c;
|
||||||
if (flags & 0x00000004) { /* Override timing */
|
if (dev->link[0].ids.regmapid >= 0x10003 && !(flags & 1)) {
|
||||||
if (flags & 0x00000800)
|
if (!(flags & 2)) {
|
||||||
Control = 0x08; // Clock Edge
|
/* NCO */
|
||||||
Control |= (flags & 0x00000700); // Clock Delay
|
max_bitrate = 0;
|
||||||
} else
|
|
||||||
Control = 0x00000300; // Rising edge 21 ns setup time
|
|
||||||
if (dev->link[0].ids.regmapid >= 0x10003 &&
|
|
||||||
(flags & 0x00000001) == 0) {
|
|
||||||
if ((flags & 0x00000002) == 0) {
|
|
||||||
// NCO
|
|
||||||
Maxbitrate = 0;
|
|
||||||
gap = 0;
|
gap = 0;
|
||||||
if (bitrate == 72000)
|
if (bitrate != 72000) {
|
||||||
Control |= 0x24;
|
|
||||||
else
|
|
||||||
if (bitrate >= 96000)
|
if (bitrate >= 96000)
|
||||||
Control |= 0x824;
|
*con |= 0x800;
|
||||||
else {
|
else {
|
||||||
Control |= 0x1024;
|
*con |= 0x1000;
|
||||||
NCOIncrement = (bitrate * 8192 + 71999) / 72000;
|
nco = (bitrate * 8192 + 71999) / 72000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Divider
|
/* Divider and gap */
|
||||||
Control |= 0x1834;
|
*con |= 0x1810;
|
||||||
if (bitrate <= 64000) {
|
if (bitrate <= 64000) {
|
||||||
Maxbitrate = 64000;
|
max_bitrate = 64000;
|
||||||
NCOIncrement = 8;
|
nco = 8;
|
||||||
} else if( bitrate <= 72000) {
|
} else if( bitrate <= 72000) {
|
||||||
Maxbitrate = 72000;
|
max_bitrate = 72000;
|
||||||
NCOIncrement = 7;
|
nco = 7;
|
||||||
} else {
|
} else {
|
||||||
Maxbitrate = 96000;
|
max_bitrate = 96000;
|
||||||
NCOIncrement = 5;
|
nco = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bitrate > 72000) {
|
if (bitrate > 72000) {
|
||||||
Control |= 0x834; // Enable 96 MBit/s CI+ Speed
|
*con |= 0x810; /* 96 MBit/s and gap */
|
||||||
Maxbitrate = 96000;
|
max_bitrate = 96000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Maxbitrate > 0) {
|
if (max_bitrate > 0) {
|
||||||
if (bitrate > Maxbitrate)
|
if (bitrate > max_bitrate)
|
||||||
bitrate = Maxbitrate;
|
bitrate = max_bitrate;
|
||||||
if (bitrate < 31000)
|
if (bitrate < 31000)
|
||||||
bitrate = 31000;
|
bitrate = 31000;
|
||||||
gap = ((Maxbitrate - bitrate) * 94) / bitrate;
|
gap = ((max_bitrate - bitrate) * 94) / bitrate;
|
||||||
if (gap < 2)
|
if (gap < 2)
|
||||||
Control &= ~0x10; // Disable gap
|
*con &= ~0x10; /* Disable gap */
|
||||||
else
|
else
|
||||||
gap -= 2;
|
gap -= 2;
|
||||||
if (gap > 127)
|
if (gap > 127)
|
||||||
gap = 127;
|
gap = 127;
|
||||||
}
|
}
|
||||||
|
*con2 = (nco << 16) | gap;
|
||||||
*con = Control;
|
|
||||||
*con2 = (NCOIncrement << 16) | gap;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ddb_output_start(struct ddb_output *output)
|
static void ddb_output_start(struct ddb_output *output)
|
||||||
{
|
{
|
||||||
struct ddb *dev = output->port->dev;
|
struct ddb *dev = output->port->dev;
|
||||||
u32 con2;
|
u32 con = 0x11c, con2 = 0;
|
||||||
|
|
||||||
con2 = ((output->port->obr << 13) + 71999) / 72000;
|
|
||||||
con2 = (con2 << 16) | output->port->gap;
|
|
||||||
|
|
||||||
if (output->dma) {
|
if (output->dma) {
|
||||||
spin_lock_irq(&output->dma->lock);
|
spin_lock_irq(&output->dma->lock);
|
||||||
@ -641,10 +626,14 @@ static void ddb_output_start(struct ddb_output *output)
|
|||||||
if (output->port->class == DDB_PORT_MOD)
|
if (output->port->class == DDB_PORT_MOD)
|
||||||
ddbridge_mod_output_start(output);
|
ddbridge_mod_output_start(output);
|
||||||
else {
|
else {
|
||||||
|
if (output->port->input[0]->port->class == DDB_PORT_LOOP)
|
||||||
|
con = (1UL << 13) | 0x14;
|
||||||
|
else
|
||||||
|
calc_con(output, &con, &con2, 0);
|
||||||
ddbwritel(dev, 0, TS_CONTROL(output));
|
ddbwritel(dev, 0, TS_CONTROL(output));
|
||||||
ddbwritel(dev, 2, TS_CONTROL(output));
|
ddbwritel(dev, 2, TS_CONTROL(output));
|
||||||
ddbwritel(dev, 0, TS_CONTROL(output));
|
ddbwritel(dev, 0, TS_CONTROL(output));
|
||||||
ddbwritel(dev, 0x3c, TS_CONTROL(output));
|
ddbwritel(dev, con, TS_CONTROL(output));
|
||||||
ddbwritel(dev, con2, TS_CONTROL2(output));
|
ddbwritel(dev, con2, TS_CONTROL2(output));
|
||||||
}
|
}
|
||||||
if (output->dma) {
|
if (output->dma) {
|
||||||
@ -654,16 +643,8 @@ static void ddb_output_start(struct ddb_output *output)
|
|||||||
ddbwritel(dev, 1, DMA_BASE_READ);
|
ddbwritel(dev, 1, DMA_BASE_READ);
|
||||||
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma));
|
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma));
|
||||||
}
|
}
|
||||||
if (output->port->class != DDB_PORT_MOD) {
|
if (output->port->class != DDB_PORT_MOD)
|
||||||
if (output->port->input[0]->port->class == DDB_PORT_LOOP)
|
ddbwritel(dev, con | 1, TS_CONTROL(output));
|
||||||
/*ddbwritel(dev, 0x15, TS_CONTROL(output));
|
|
||||||
ddbwritel(dev, 0x45,
|
|
||||||
TS_CONTROL(output));*/
|
|
||||||
ddbwritel(dev, (1 << 13) | 0x15,
|
|
||||||
TS_CONTROL(output));
|
|
||||||
else
|
|
||||||
ddbwritel(dev, 0x11d, TS_CONTROL(output));
|
|
||||||
}
|
|
||||||
if (output->dma) {
|
if (output->dma) {
|
||||||
output->dma->running = 1;
|
output->dma->running = 1;
|
||||||
spin_unlock_irq(&output->dma->lock);
|
spin_unlock_irq(&output->dma->lock);
|
||||||
@ -3354,7 +3335,7 @@ static void ddb_ports_init(struct ddb *dev)
|
|||||||
port->nr = i;
|
port->nr = i;
|
||||||
port->lnr = l;
|
port->lnr = l;
|
||||||
port->pnr = p;
|
port->pnr = p;
|
||||||
port->gap = 4;
|
port->gap = 0xffffffff;
|
||||||
port->obr = ci_bitrate;
|
port->obr = ci_bitrate;
|
||||||
mutex_init(&port->i2c_gate_lock);
|
mutex_init(&port->i2c_gate_lock);
|
||||||
if (!ddb_port_match_i2c(port))
|
if (!ddb_port_match_i2c(port))
|
||||||
@ -4640,6 +4621,31 @@ static ssize_t gap_store(struct device *device, struct device_attribute *attr,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t obr_show(struct device *device,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct ddb *dev = dev_get_drvdata(device);
|
||||||
|
int num = attr->attr.name[3] - 0x30;
|
||||||
|
|
||||||
|
return sprintf(buf, "%d\n", dev->port[num].obr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t obr_store(struct device *device, struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct ddb *dev = dev_get_drvdata(device);
|
||||||
|
int num = attr->attr.name[3] - 0x30;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
if (sscanf(buf, "%u\n", &val) != 1)
|
||||||
|
return -EINVAL;
|
||||||
|
if (val > 96000)
|
||||||
|
return -EINVAL;
|
||||||
|
dev->port[num].obr = val;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t version_show(struct device *device,
|
static ssize_t version_show(struct device *device,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
@ -4732,6 +4738,10 @@ static struct device_attribute ddb_attrs[] = {
|
|||||||
__ATTR(gap1, 0664, gap_show, gap_store),
|
__ATTR(gap1, 0664, gap_show, gap_store),
|
||||||
__ATTR(gap2, 0664, gap_show, gap_store),
|
__ATTR(gap2, 0664, gap_show, gap_store),
|
||||||
__ATTR(gap3, 0664, gap_show, gap_store),
|
__ATTR(gap3, 0664, gap_show, gap_store),
|
||||||
|
__ATTR(obr0, 0664, obr_show, obr_store),
|
||||||
|
__ATTR(obr1, 0664, obr_show, obr_store),
|
||||||
|
__ATTR(obr2, 0664, obr_show, obr_store),
|
||||||
|
__ATTR(obr3, 0664, obr_show, obr_store),
|
||||||
__ATTR(vlan, 0664, vlan_show, vlan_store),
|
__ATTR(vlan, 0664, vlan_show, vlan_store),
|
||||||
__ATTR(fmode0, 0664, fmode_show, fmode_store),
|
__ATTR(fmode0, 0664, fmode_show, fmode_store),
|
||||||
__ATTR(fmode1, 0664, fmode_show, fmode_store),
|
__ATTR(fmode1, 0664, fmode_show, fmode_store),
|
||||||
|
Loading…
Reference in New Issue
Block a user