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

- add support for new Max S8/A8 with temperature monitor

- move temperature monitor code from mod to core and cleanup modulator ioctls
This commit is contained in:
Ralph Metzler 2016-08-29 18:44:53 +02:00
parent 2ec7863b04
commit 1f4ae2bd51
5 changed files with 340 additions and 204 deletions

View File

@ -285,7 +285,6 @@ static struct ddb_regmap octopus_mod_map = {
.channel = &octopus_mod_channel, .channel = &octopus_mod_channel,
}; };
static struct ddb_regmap octopus_mod_2_map = { static struct ddb_regmap octopus_mod_2_map = {
.irq_version = 2, .irq_version = 2,
.irq_base_odma = 64, .irq_base_odma = 64,
@ -306,17 +305,67 @@ static struct ddb_info ddb_s2_48 = {
.port_num = 4, .port_num = 4,
.i2c_mask = 0x01, .i2c_mask = 0x01,
.board_control = 1, .board_control = 1,
.tempmon_irq = 24,
}; };
static struct ddb_info ddb_ct_8 = { static struct ddb_info ddb_ct2_8 = {
.type = DDB_OCTOPUS_MAX_CT, .type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX CT8", .name = "Digital Devices MAX A8 CT2",
.regmap = &octopus_map, .regmap = &octopus_map,
.port_num = 4, .port_num = 4,
.i2c_mask = 0x0f, .i2c_mask = 0x0f,
.board_control = 0x0ff, .board_control = 0x0ff,
.board_control_2 = 0xf00, .board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL, .ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_isdbt_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 ISDBT",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_v0_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I V0",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
}; };
@ -2601,6 +2650,11 @@ static void ddb_port_probe(struct ddb_port *port)
port->type = DDB_TUNER_ISDBT_SONY_P; port->type = DDB_TUNER_ISDBT_SONY_P;
port->type_name = "ISDBT_SONY"; port->type_name = "ISDBT_SONY";
break; break;
case 0xc1:
port->name = "DUAL DVB-C2T2 ISDB-T CXD2854";
port->type = DDB_TUNER_DVBC2T2_SONY_P;
port->type_name = "DVBC2T2_ISDBT_SONY";
break;
default: default:
return; return;
} }
@ -4359,10 +4413,23 @@ static ssize_t fan_store(struct device *device, struct device_attribute *d,
return count; return count;
} }
static ssize_t fanspeed_show(struct device *device,
struct device_attribute *attr, char *buf)
{
struct ddb *dev = dev_get_drvdata(device);
int num = attr->attr.name[8] - 0x30;
struct ddb_link *link = &dev->link[num];
u32 spd;
spd = ddblreadl(link, TEMPMON_FANCONTROL) & 0xff;
return sprintf(buf, "%u\n", spd * 100);
}
static ssize_t temp_show(struct device *device, static ssize_t temp_show(struct device *device,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct ddb *dev = dev_get_drvdata(device); struct ddb *dev = dev_get_drvdata(device);
struct ddb_link *link = &dev->link[0];
struct i2c_adapter *adap; struct i2c_adapter *adap;
s32 temp, temp2, temp3; s32 temp, temp2, temp3;
int i; int i;
@ -4849,6 +4916,13 @@ static struct device_attribute ddb_attrs_led[] = {
__ATTR(led3, 0664, led_show, led_store), __ATTR(led3, 0664, led_show, led_store),
}; };
static struct device_attribute ddb_attrs_fanspeed[] = {
__ATTR_MRO(fanspeed0, fanspeed_show),
__ATTR_MRO(fanspeed1, fanspeed_show),
__ATTR_MRO(fanspeed2, fanspeed_show),
__ATTR_MRO(fanspeed3, fanspeed_show),
};
static struct class ddb_class = { static struct class ddb_class = {
.name = "ddbridge", .name = "ddbridge",
.owner = THIS_MODULE, .owner = THIS_MODULE,
@ -4878,6 +4952,9 @@ static void ddb_device_attrs_del(struct ddb *dev)
{ {
int i; int i;
for (i = 0; i < 4; i++)
if (dev->link[i].info->tempmon_irq)
device_remove_file(dev->ddb_dev, &ddb_attrs_fanspeed[i]);
for (i = 0; i < dev->link[0].info->temp_num; i++) for (i = 0; i < dev->link[0].info->temp_num; i++)
device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]); device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]);
for (i = 0; i < dev->link[0].info->port_num; i++) for (i = 0; i < dev->link[0].info->port_num; i++)
@ -4920,6 +4997,12 @@ static int ddb_device_attrs_add(struct ddb *dev)
&ddb_attrs_led[i])) &ddb_attrs_led[i]))
goto fail; goto fail;
} }
for (i = 0; i < 4; i++)
if (dev->link[i].info &&
dev->link[i].info->tempmon_irq)
if (device_create_file(dev->ddb_dev,
&ddb_attrs_fanspeed[i]))
goto fail;
return 0; return 0;
fail: fail:
return -1; return -1;
@ -4994,6 +5077,7 @@ static void link_tasklet(unsigned long data)
LINK_IRQ_HANDLE(l, 1); LINK_IRQ_HANDLE(l, 1);
LINK_IRQ_HANDLE(l, 2); LINK_IRQ_HANDLE(l, 2);
LINK_IRQ_HANDLE(l, 3); LINK_IRQ_HANDLE(l, 3);
LINK_IRQ_HANDLE(l, 24);
} }
static void gtl_irq_handler(unsigned long priv) static void gtl_irq_handler(unsigned long priv)
@ -5010,6 +5094,7 @@ static void gtl_irq_handler(unsigned long priv)
LINK_IRQ_HANDLE(l, 1); LINK_IRQ_HANDLE(l, 1);
LINK_IRQ_HANDLE(l, 2); LINK_IRQ_HANDLE(l, 2);
LINK_IRQ_HANDLE(l, 3); LINK_IRQ_HANDLE(l, 3);
LINK_IRQ_HANDLE(l, 24);
} }
#else #else
tasklet_schedule(&link->tasklet); tasklet_schedule(&link->tasklet);
@ -5054,7 +5139,7 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
link->info = &ddb_s2_48; link->info = &ddb_s2_48;
break; break;
case 0x0008dd01: case 0x0008dd01:
link->info = &ddb_ct_8; link->info = &ddb_c2t2_8;
break; break;
default: default:
pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.", pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.",
@ -5068,16 +5153,24 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
dev->handler_data[0][base + l] = (unsigned long) link; dev->handler_data[0][base + l] = (unsigned long) link;
dev->handler[0][base + l] = gtl_irq_handler; dev->handler[0][base + l] = gtl_irq_handler;
dev->link[l].ids.hwid = ddbreadl(dev, DDB_LINK_TAG(l) | 0);
dev->link[l].ids.regmapid = ddbreadl(dev, DDB_LINK_TAG(l) | 4);
dev->link[l].ids.vendor = id >> 16;;
dev->link[l].ids.device = id & 0xffff;;
//dev->link[l].ids.subvendor = id->subvendor;
//dev->link[l].ids.subdevice = id->subdevice;
pr_info("GTL %s\n", dev->link[l].info->name); pr_info("GTL %s\n", dev->link[l].info->name);
pr_info("GTL HW %08x REGMAP %08x\n", pr_info("GTL HW %08x REGMAP %08x\n",
ddbreadl(dev, DDB_LINK_TAG(l) | 0), dev->link[l].ids.hwid,
ddbreadl(dev, DDB_LINK_TAG(l) | 4)); dev->link[l].ids.regmapid);
pr_info("GTL ID %08x\n", pr_info("GTL ID %08x\n",
ddbreadl(dev, DDB_LINK_TAG(l) | 8)); ddbreadl(dev, DDB_LINK_TAG(l) | 8));
tasklet_init(&link->tasklet, link_tasklet, (unsigned long) link); tasklet_init(&link->tasklet, link_tasklet, (unsigned long) link);
ddbwritel(dev, 0xffffffff, DDB_LINK_TAG(l) | INTERRUPT_ACK); ddbwritel(dev, 0xffffffff, DDB_LINK_TAG(l) | INTERRUPT_ACK);
ddbwritel(dev, 0xf, DDB_LINK_TAG(l) | INTERRUPT_ENABLE); ddbwritel(dev, 0x0100000f, DDB_LINK_TAG(l) | INTERRUPT_ENABLE);
return 0; return 0;
} }
@ -5093,13 +5186,110 @@ static int ddb_gtl_init(struct ddb *dev)
return 0; return 0;
} }
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void tempmon_setfan(struct ddb_link *link)
{
u32 temp, temp2, pwm;
if ((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) {
pr_info("Over temperature condition\n");
link->OverTemperatureError = 1;
}
temp = (ddblreadl(link, TEMPMON_SENSOR0) >> 8) & 0xFF;
if (temp & 0x80)
temp = 0;
temp2 = (ddblreadl(link, TEMPMON_SENSOR1) >> 8) & 0xFF;
if (temp2 & 0x80)
temp2 = 0;
if (temp2 > temp)
temp = temp2;
pwm = (ddblreadl(link, TEMPMON_FANCONTROL) >> 8) & 0x0F;
if (pwm > 10)
pwm = 10;
if (temp >= link->temp_tab[pwm]) {
while( pwm < 10 && temp >= link->temp_tab[pwm + 1])
pwm += 1;
} else {
while( pwm > 1 && temp < link->temp_tab[pwm - 2])
pwm -= 1;
}
ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL);
}
static void temp_handler(unsigned long data)
{
struct ddb_link *link = (struct ddb_link *) data;
spin_lock(&link->temp_lock);
tempmon_setfan(link);
spin_unlock(&link->temp_lock);
}
static int tempmon_init(struct ddb_link *link, int FirstTime)
{
struct ddb *dev = link->dev;
int status = 0;
u32 l = link->nr;
spin_lock_irq(&link->temp_lock);
if (FirstTime) {
static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80};
memcpy(link->temp_tab, TemperatureTable, sizeof(TemperatureTable));
}
dev->handler[l][link->info->tempmon_irq] = temp_handler;
dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link;
ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
TEMPMON_CONTROL_INTENABLE),
TEMPMON_CONTROL);
ddblwritel(link, (3 << 8), TEMPMON_FANCONTROL);
link->OverTemperatureError =
((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0);
if (link->OverTemperatureError) {
pr_info("Over temperature condition\n");
status = -1;
}
tempmon_setfan(link);
spin_unlock_irq(&link->temp_lock);
return status;
}
static int ddb_init_tempmon(struct ddb_link *link)
{
struct ddb *dev = link->dev;
struct ddb_info *info = link->info;
if (!info->tempmon_irq)
return;
if (info->type == DDB_OCTOPUS_MAX ||
info->type == DDB_OCTOPUS_MAX_CT)
if (link->ids.regmapid < 0x00010002)
return;
spin_lock_init(&link->temp_lock);
printk("init_tempmon\n");
tempmon_init(link, 1);
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static int ddb_init_boards(struct ddb *dev) static int ddb_init_boards(struct ddb *dev)
{ {
struct ddb_info *info; struct ddb_info *info;
struct ddb_link *link;
u32 l; u32 l;
for (l = 0; l < DDB_MAX_LINK; l++) { for (l = 0; l < DDB_MAX_LINK; l++) {
info = dev->link[l].info; link = &dev->link[l];
info = link->info;
if (!info) if (!info)
continue; continue;
if (info->board_control) { if (info->board_control) {
@ -5113,6 +5303,7 @@ static int ddb_init_boards(struct ddb *dev)
DDB_LINK_TAG(l) | BOARD_CONTROL); DDB_LINK_TAG(l) | BOARD_CONTROL);
usleep_range(2000, 3000); usleep_range(2000, 3000);
} }
ddb_init_tempmon(link);
} }
return 0; return 0;
} }

View File

@ -215,12 +215,12 @@ static void mod_set_rateinc(struct ddb *dev, u32 chan)
static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 }; static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 };
void ddbridge_mod_output_start(struct ddb_output *output) int ddbridge_mod_output_start(struct ddb_output *output)
{ {
struct ddb *dev = output->port->dev; struct ddb *dev = output->port->dev;
u32 Channel = output->nr; u32 Channel = output->nr;
struct ddb_mod *mod = &dev->mod[output->nr]; struct ddb_mod *mod = &dev->mod[output->nr];
u32 Symbolrate = 6900000; u32 Symbolrate = mod->symbolrate;
/*PCRIncrement = RoundPCR(PCRIncrement);*/ /*PCRIncrement = RoundPCR(PCRIncrement);*/
/*PCRDecrement = RoundPCR(PCRDecrement);*/ /*PCRDecrement = RoundPCR(PCRDecrement);*/
@ -256,8 +256,7 @@ void ddbridge_mod_output_start(struct ddb_output *output)
u32 d = gcd(KF,LF); u32 d = gcd(KF,LF);
u32 checkLF; u32 checkLF;
mod->modulation = QAM_256 - 1; ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel));
ddbwritel(dev, mod->modulation, CHANNEL_SETTINGS(Channel));
ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel)); ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel));
KF = KF / d; KF = KF / d;
@ -297,6 +296,7 @@ void ddbridge_mod_output_start(struct ddb_output *output)
if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_UNMUTE)) if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_UNMUTE))
return -EINVAL; return -EINVAL;
pr_info("mod_output_start %d.%d\n", dev->nr, output->nr); pr_info("mod_output_start %d.%d\n", dev->nr, output->nr);
return 0;
} }
/****************************************************************************/ /****************************************************************************/
@ -422,14 +422,14 @@ static int mod_get_vga(struct ddb *dev, u32 *pGain)
*pGain = ddbreadl(dev, RF_VGA); *pGain = ddbreadl(dev, RF_VGA);
return 0; return 0;
} }
#if 0
static void mod_TemperatureMonitorSetFan(struct ddb *dev) static void TemperatureMonitorSetFan(struct ddb *dev)
{ {
u32 tqam, pwm; u32 tqam, pwm;
if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) { if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) {
pr_info("Over temperature condition\n"); pr_info("Over temperature condition\n");
dev->mod_base.OverTemperatureError = 1; dev->OverTemperatureError = 1;
} }
tqam = (ddbreadl(dev, TEMPMON2_QAMCORE) >> 8) & 0xFF; tqam = (ddbreadl(dev, TEMPMON2_QAMCORE) >> 8) & 0xFF;
if (tqam & 0x80) if (tqam & 0x80)
@ -439,55 +439,55 @@ static void mod_TemperatureMonitorSetFan(struct ddb *dev)
if (pwm > 10) if (pwm > 10)
pwm = 10; pwm = 10;
if (tqam >= dev->mod_base.temp_tab[pwm]) { if (tqam >= dev->temp_tab[pwm]) {
while( pwm < 10 && tqam >= dev->mod_base.temp_tab[pwm + 1]) while( pwm < 10 && tqam >= dev->temp_tab[pwm + 1])
pwm += 1; pwm += 1;
} else { } else {
while( pwm > 1 && tqam < dev->mod_base.temp_tab[pwm - 2]) while( pwm > 1 && tqam < dev->temp_tab[pwm - 2])
pwm -= 1; pwm -= 1;
} }
ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL); ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL);
} }
static void mod_temp_handler(unsigned long data) static void temp_handler(unsigned long data)
{ {
struct ddb *dev = (struct ddb *) data; struct ddb *dev = (struct ddb *) data;
pr_info("mod_temp_handler\n"); pr_info("temp_handler\n");
spin_lock(&dev->mod_base.temp_lock); spin_lock(&dev->temp_lock);
mod_TemperatureMonitorSetFan(dev); TemperatureMonitorSetFan(dev);
spin_unlock(&dev->mod_base.temp_lock); spin_unlock(&dev->temp_lock);
} }
static int mod_TemperatureMonitorInit(struct ddb *dev, int FirstTime) { static int TemperatureMonitorInit(struct ddb *dev, int FirstTime) {
int status = 0; int status = 0;
spin_lock_irq(&dev->mod_base.temp_lock); spin_lock_irq(&dev->temp_lock);
if (FirstTime) { if (FirstTime) {
static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80}; static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80};
memcpy(dev->mod_base.temp_tab, TemperatureTable, sizeof(TemperatureTable)); memcpy(dev->temp_tab, TemperatureTable, sizeof(TemperatureTable));
} }
dev->handler[0][8] = mod_temp_handler; dev->handler[0][8] = temp_handler;
dev->handler_data[0][8] = (unsigned long) dev; dev->handler_data[0][8] = (unsigned long) dev;
ddbwritel(dev, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN | ddbwritel(dev, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
TEMPMON_CONTROL_INTENABLE), TEMPMON_CONTROL_INTENABLE),
TEMPMON_CONTROL); TEMPMON_CONTROL);
ddbwritel(dev, (3 << 8), TEMPMON_FANCONTROL); ddbwritel(dev, (3 << 8), TEMPMON_FANCONTROL);
dev->mod_base.OverTemperatureError = dev->OverTemperatureError =
((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0); ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0);
if (dev->mod_base.OverTemperatureError) { if (dev->OverTemperatureError) {
pr_info("Over temperature condition\n"); pr_info("Over temperature condition\n");
status = -1; status = -1;
} }
mod_TemperatureMonitorSetFan(dev); TemperatureMonitorSetFan(dev);
spin_unlock_irq(&dev->mod_base.temp_lock); spin_unlock_irq(&dev->temp_lock);
return status; return status;
} }
#endif
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
@ -1063,12 +1063,24 @@ u32 eqtab[] = {
0x00001B23, 0x0000EEB7, 0x00006A28 0x00001B23, 0x0000EEB7, 0x00006A28
}; };
static int mod_set_modulation(struct ddb *dev, int chan, enum fe_modulation mod) static int mod_set_modrate(struct ddb *dev, int chan,
enum fe_modulation mod, u32 srate)
{ {
u64 ofac;
if (mod > QAM_256 || mod < QAM_16) if (mod > QAM_256 || mod < QAM_16)
return -EINVAL; return -EINVAL;
if (dev->link[0].info->version < 2) {
if (srate != 6900000)
return -EINVAL;
} else {
if (srate > 7100000)
return -EINVAL;
}
dev->mod[chan].symbolrate = srate;
dev->mod[chan].modulation = mod; dev->mod[chan].modulation = mod;
dev->mod[chan].obitrate = 0x0061072787900000ULL * (mod + 3); ofac = ((((u64) srate) << 32) * 188 ) / 204;
dev->mod[chan].obitrate = ofac * (mod + 3);
dev->mod[chan].ibitrate = dev->mod[chan].obitrate; dev->mod[chan].ibitrate = dev->mod[chan].obitrate;
if (dev->link[0].info->version < 2) if (dev->link[0].info->version < 2)
ddbwritel(dev, qamtab[mod], CHANNEL_SETTINGS(chan)); ddbwritel(dev, qamtab[mod], CHANNEL_SETTINGS(chan));
@ -1180,9 +1192,10 @@ static int mod_init_1(struct ddb *dev, u32 Frequency)
iqfreq = flash->DataSet[0].FrequencyFactor * iqfreq = flash->DataSet[0].FrequencyFactor *
(FrequencyCH10 + (9 - i) * 8); (FrequencyCH10 + (9 - i) * 8);
iqfreq += (dev->link[0].ids.hwid == 0x0203dd01) ? 22 : 0 ;
iqsteps = flash->DataSet[0].IQTableLength; iqsteps = flash->DataSet[0].IQTableLength;
mod_set_iq(dev, iqsteps, i, iqfreq); mod_set_iq(dev, iqsteps, i, iqfreq);
mod_set_modulation(dev, i, QAM_256); mod_set_modrate(dev, i, QAM_256, 6900000);
} }
mod_bypass_equalizer(dev, 1); mod_bypass_equalizer(dev, 1);
@ -1391,7 +1404,29 @@ void ddbridge_mod_rate_handler(unsigned long data)
PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement); PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement);
} }
static int mod_ioctl_1(struct file *file, unsigned int cmd, void *parg) static void mod_calc_rateinc(struct ddb_mod *mod)
{
u32 ri;
pr_info("ibitrate %llu\n", mod->ibitrate);
pr_info("obitrate %llu\n", mod->obitrate);
if (mod->ibitrate != 0) {
u64 d = mod->obitrate - mod->ibitrate;
d = div64_u64(d, mod->obitrate >> 24);
if (d > 0xfffffe)
ri = 0xfffffe;
else
ri = d;
} else
ri = 0;
mod->rate_inc = ri;
pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n",
mod->ibitrate >> 32, mod->obitrate >> 32, ri);
}
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
{ {
struct dvb_device *dvbdev = file->private_data; struct dvb_device *dvbdev = file->private_data;
struct ddb_output *output = dvbdev->priv; struct ddb_output *output = dvbdev->priv;
@ -1405,79 +1440,13 @@ static int mod_ioctl_1(struct file *file, unsigned int cmd, void *parg)
{ {
struct dvb_mod_params *mp = parg; struct dvb_mod_params *mp = parg;
pr_info("set base freq\n"); if (dev->link[0].info->version < 2) {
if (mp->base_frequency != dev->mod_base.frequency) if (mp->base_frequency != dev->mod_base.frequency)
if (set_base_frequency(dev, mp->base_frequency)) if (set_base_frequency(dev, mp->base_frequency))
return -EINVAL; return -EINVAL;
pr_info("set attenuator\n"); } else {
mod_set_attenuator(dev, mp->attenuator);
break;
}
case DVB_MOD_CHANNEL_SET:
{
struct dvb_mod_channel_params *cp = parg;
int res;
u32 ri;
pr_info("set modulation\n");
res = mod_set_modulation(dev, output->nr, cp->modulation);
if (res)
return res;
if (cp->input_bitrate > dev->mod[output->nr].obitrate)
return -EINVAL;
dev->mod[output->nr].ibitrate = cp->input_bitrate;
dev->mod[output->nr].pcr_correction = cp->pcr_correction;
pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate);
pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate);
if (cp->input_bitrate != 0) {
u64 d = dev->mod[output->nr].obitrate -
dev->mod[output->nr].ibitrate;
d = div64_u64(d, dev->mod[output->nr].obitrate >> 24);
if (d > 0xfffffe)
ri = 0xfffffe;
else
ri = d;
} else
ri = 0;
dev->mod[output->nr].rate_inc = ri;
pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n",
dev->mod[output->nr].ibitrate >> 32,
dev->mod[output->nr].obitrate >> 32,
ri);
break;
}
default:
ret = -EINVAL;
break;
}
return ret;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct ddb_output *output = dvbdev->priv;
struct ddb *dev = output->port->dev;
/* unsigned long arg = (unsigned long) parg; */
int ret = 0;
switch (cmd) {
case DVB_MOD_SET:
{
struct dvb_mod_params *mp = parg;
pr_info("set base freq\n");
dev->mod_base.frequency = mp->base_frequency; dev->mod_base.frequency = mp->base_frequency;
pr_info("set attenuator\n"); }
mod_set_attenuator(dev, mp->attenuator); mod_set_attenuator(dev, mp->attenuator);
break; break;
} }
@ -1485,9 +1454,8 @@ static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg)
{ {
struct dvb_mod_channel_params *cp = parg; struct dvb_mod_channel_params *cp = parg;
int res; int res;
u32 ri;
res = mod_set_modulation(dev, output->nr, cp->modulation); res = mod_set_modrate(dev, output->nr, cp->modulation, 6900000);
if (res) if (res)
return res; return res;
@ -1496,24 +1464,7 @@ static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg)
dev->mod[output->nr].ibitrate = cp->input_bitrate; dev->mod[output->nr].ibitrate = cp->input_bitrate;
dev->mod[output->nr].pcr_correction = cp->pcr_correction; dev->mod[output->nr].pcr_correction = cp->pcr_correction;
pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate); mod_calc_rateinc(&dev->mod[output->nr]);
pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate);
if (cp->input_bitrate != 0) {
u64 d = dev->mod[output->nr].obitrate -
dev->mod[output->nr].ibitrate;
d = div64_u64(d, dev->mod[output->nr].obitrate >> 24);
if (d > 0xfffffe)
ri = 0xfffffe;
else
ri = d;
} else
ri = 0;
dev->mod[output->nr].rate_inc = ri;
pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n",
dev->mod[output->nr].ibitrate >> 32,
dev->mod[output->nr].obitrate >> 32,
ri);
break; break;
} }
default: default:
@ -1523,16 +1474,17 @@ static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg)
return ret; return ret;
} }
static int mod_init_2(struct ddb *dev, u32 Frequency) static int mod_init_2(struct ddb *dev, u32 Frequency)
{ {
int status; int status, i;
int streams = dev->link[0].info->port_num; int streams = dev->link[0].info->port_num;
dev->mod_base.frequency = Frequency; dev->mod_base.frequency = Frequency;
mod_TemperatureMonitorInit(dev, 1);
status = mod_fsm_setup(dev, 0, 0); status = mod_fsm_setup(dev, 0, 0);
for (i = 0; i < streams; i++)
mod_set_modrate(dev, i, QAM_256, 6900000);
if (streams <= 8) if (streams <= 8)
mod_set_vga(dev, RF_VGA_GAIN_N8); mod_set_vga(dev, RF_VGA_GAIN_N8);
else if (streams <= 16) else if (streams <= 16)
@ -1544,22 +1496,8 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
return 0; return 0;
} }
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct ddb_output *output = dvbdev->priv;
struct ddb *dev = output->port->dev;
if (dev->link[0].info->version <= 0)
return mod_ioctl_1(file, cmd, parg);
if (dev->link[0].info->version == 2)
return mod_ioctl_2(file, cmd, parg);
return -1;
}
int ddbridge_mod_init(struct ddb *dev) int ddbridge_mod_init(struct ddb *dev)
{ {
spin_lock_init(&dev->mod_base.temp_lock);
if (dev->link[0].info->version <= 1) if (dev->link[0].info->version <= 1)
return mod_init_1(dev, 722000000); return mod_init_1(dev, 722000000);
if (dev->link[0].info->version == 2) if (dev->link[0].info->version == 2)

View File

@ -147,7 +147,7 @@
#define DAC_CONTROL_RESET (0x200) #define DAC_CONTROL_RESET (0x200)
/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ /* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */
#define TEMPMON_BASE (0xA0) #define TEMPMON_BASE (0x1c0)
#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00) #define TEMPMON_CONTROL (TEMPMON_BASE + 0x00)
#define TEMPMON_CONTROL_SCAN (0x00000001) #define TEMPMON_CONTROL_SCAN (0x00000001)

View File

@ -475,6 +475,7 @@ static struct ddb_info ddb_mod_fsm_24 = {
.regmap = &octopus_mod_2_map, .regmap = &octopus_mod_2_map,
.port_num = 24, .port_num = 24,
.temp_num = 1, .temp_num = 1,
.tempmon_irq = 8,
}; };
static struct ddb_info ddb_mod_fsm_16 = { static struct ddb_info ddb_mod_fsm_16 = {
@ -484,6 +485,7 @@ static struct ddb_info ddb_mod_fsm_16 = {
.regmap = &octopus_mod_2_map, .regmap = &octopus_mod_2_map,
.port_num = 16, .port_num = 16,
.temp_num = 1, .temp_num = 1,
.tempmon_irq = 8,
}; };
static struct ddb_info ddb_mod_fsm_8 = { static struct ddb_info ddb_mod_fsm_8 = {
@ -493,6 +495,7 @@ static struct ddb_info ddb_mod_fsm_8 = {
.regmap = &octopus_mod_2_map, .regmap = &octopus_mod_2_map,
.port_num = 8, .port_num = 8,
.temp_num = 1, .temp_num = 1,
.tempmon_irq = 8,
}; };
static struct ddb_info ddb_octopro_hdin = { static struct ddb_info ddb_octopro_hdin = {
@ -541,15 +544,18 @@ static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct_8), DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_ct_8), DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_ct_8), DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8),
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci), DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro), DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod), DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
DDB_ID(DDVID, 0x0203, DDVID, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24), DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24),
DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16), DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16),
DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8), DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8),

View File

@ -172,6 +172,7 @@ struct ddb_info {
#define TS_QUIRK_SERIAL 1 #define TS_QUIRK_SERIAL 1
#define TS_QUIRK_REVERSED 2 #define TS_QUIRK_REVERSED 2
#define TS_QUIRK_NO_OUTPUT 4 #define TS_QUIRK_NO_OUTPUT 4
u32 tempmon_irq;
struct ddb_regmap *regmap; struct ddb_regmap *regmap;
}; };
@ -338,10 +339,6 @@ struct mod_base {
u32 frequency; u32 frequency;
u32 flat_start; u32 flat_start;
u32 flat_end; u32 flat_end;
spinlock_t temp_lock;
int OverTemperatureError;
u8 temp_tab[11];
}; };
struct ddb_mod { struct ddb_mod {
@ -424,6 +421,10 @@ struct ddb_link {
struct ddb_lnb lnb; struct ddb_lnb lnb;
struct tasklet_struct tasklet; struct tasklet_struct tasklet;
struct ddb_ids ids; struct ddb_ids ids;
spinlock_t temp_lock;
int OverTemperatureError;
u8 temp_tab[11];
}; };
struct ddb { struct ddb {
@ -471,6 +472,7 @@ struct ddb {
struct mod_base mod_base; struct mod_base mod_base;
struct ddb_mod mod[24]; struct ddb_mod mod[24];
}; };
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
@ -520,7 +522,7 @@ static inline void gtlw(struct ddb_link *link)
} }
#endif #endif
#if 0
static u32 ddblreadl(struct ddb_link *link, u32 adr) static u32 ddblreadl(struct ddb_link *link, u32 adr)
{ {
if (unlikely(link->nr)) { if (unlikely(link->nr)) {
@ -554,7 +556,6 @@ static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
} }
writel(val, (char *) (link->dev->regs + (adr))); writel(val, (char *) (link->dev->regs + (adr)));
} }
#endif
static u32 ddbreadl(struct ddb *dev, u32 adr) static u32 ddbreadl(struct ddb *dev, u32 adr)
{ {
@ -744,7 +745,7 @@ struct DDMOD_FLASH {
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg); int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg);
int ddbridge_mod_init(struct ddb *dev); int ddbridge_mod_init(struct ddb *dev);
void ddbridge_mod_output_stop(struct ddb_output *output); void ddbridge_mod_output_stop(struct ddb_output *output);
void ddbridge_mod_output_start(struct ddb_output *output); int ddbridge_mod_output_start(struct ddb_output *output);
void ddbridge_mod_rate_handler(unsigned long data); void ddbridge_mod_rate_handler(unsigned long data);