mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
- add lock loss irq handler
- add modulator ioctl mutex - some more documentation about modulator properties
This commit is contained in:
parent
4a93f79093
commit
0f05b1988a
@ -63,12 +63,18 @@ int main()
|
||||
/* gain 0-255 */
|
||||
get_property(fd, MODULATOR_GAIN, &data);
|
||||
printf("Modulator gain = %u\n", data);
|
||||
set_property(fd, MODULATOR_GAIN, 120);
|
||||
set_property(fd, MODULATOR_GAIN, 100);
|
||||
|
||||
get_property(fd, MODULATOR_GAIN, &data);
|
||||
printf("Modulator gain = %u\n", data);
|
||||
|
||||
get_property(fd, MODULATOR_ATTENUATOR, &data);
|
||||
printf("Modulator attenuator = %u\n", data);
|
||||
|
||||
|
||||
get_property(fd, MODULATOR_STATUS, &data);
|
||||
printf("Modulator status = %u\n", data);
|
||||
set_property(fd, MODULATOR_STATUS, 2);
|
||||
|
||||
|
||||
//set_property(fd, MODULATOR_RESET, 0);
|
||||
|
@ -4341,6 +4341,7 @@ static int ddb_init_boards(struct ddb *dev)
|
||||
int ddb_init(struct ddb *dev)
|
||||
{
|
||||
mutex_init(&dev->link[0].flash_mutex);
|
||||
mutex_init(&dev->ioctl_mutex);
|
||||
if (no_init) {
|
||||
ddb_device_create(dev);
|
||||
return 0;
|
||||
|
@ -437,6 +437,7 @@ static const struct ddb_info ddb_mod_fsm_24 = {
|
||||
.port_num = 24,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
.lostlock_irq = 9,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_mod_fsm_16 = {
|
||||
@ -447,6 +448,7 @@ static const struct ddb_info ddb_mod_fsm_16 = {
|
||||
.port_num = 16,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
.lostlock_irq = 9,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_mod_fsm_8 = {
|
||||
@ -457,6 +459,7 @@ static const struct ddb_info ddb_mod_fsm_8 = {
|
||||
.port_num = 8,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
.lostlock_irq = 9,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_mod_fsm_4 = {
|
||||
@ -467,6 +470,7 @@ static const struct ddb_info ddb_mod_fsm_4 = {
|
||||
.port_num = 4,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
.lostlock_irq = 9,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_sdr = {
|
||||
|
@ -434,6 +434,16 @@ static u32 max2871_sdr[6] = {
|
||||
0x007A8098, 0x600080C9, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005
|
||||
};
|
||||
|
||||
static void lostlock_handler(unsigned long data)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *)data;
|
||||
|
||||
dev_err(dev->dev, "Lost PLL lock!\n");
|
||||
ddbwritel(dev, 0, RF_VGA);
|
||||
udelay(10);
|
||||
ddbwritel(dev, 31, RF_ATTENUATOR);
|
||||
}
|
||||
|
||||
static int mod_setup_max2871(struct ddb *dev, u32 *reg)
|
||||
{
|
||||
int status = 0;
|
||||
@ -467,6 +477,12 @@ static int mod_setup_max2871(struct ddb *dev, u32 *reg)
|
||||
ddbwritel(dev,
|
||||
MAX2871_CONTROL_CE | MAX2871_CONTROL_LOSTLOCK,
|
||||
MAX2871_CONTROL);
|
||||
if (dev->link[0].info->lostlock_irq) {
|
||||
dev->handler_data[0][dev->link[0].info->lostlock_irq] =
|
||||
(unsigned long)dev;
|
||||
dev->handler[0][dev->link[0].info->lostlock_irq] =
|
||||
lostlock_handler;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -1536,6 +1552,17 @@ static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||
if (mod->port->dev->link[0].info->version == 2)
|
||||
return mod_fsm_setup(mod->port->dev,0 );
|
||||
return -EINVAL;
|
||||
|
||||
case MODULATOR_STATUS:
|
||||
if (mod->port->dev->link[0].info->version != 2)
|
||||
return -EINVAL;
|
||||
if (tvp->u.data & 2)
|
||||
ddbwritel(mod->port->dev,
|
||||
MAX2871_CONTROL_CE |
|
||||
MAX2871_CONTROL_LOSTLOCK |
|
||||
MAX2871_CONTROL_ENABLE_LOSTLOCK_EVENT,
|
||||
MAX2871_CONTROL);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1560,8 +1587,6 @@ static int mod_prop_get(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||
u32 status = 0, val;
|
||||
|
||||
val = ddbreadl(dev, MAX2871_CONTROL);
|
||||
if (!(val & MAX2871_CONTROL_LOCK))
|
||||
status |= 1;
|
||||
if (!(val & MAX2871_CONTROL_LOCK))
|
||||
status |= 1;
|
||||
if (val & MAX2871_CONTROL_LOSTLOCK)
|
||||
@ -1571,6 +1596,9 @@ static int mod_prop_get(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||
val = ddbreadl(dev, TEMPMON_CONTROL);
|
||||
if (val & TEMPMON_CONTROL_OVERTEMP)
|
||||
status |= 4;
|
||||
val = ddbreadl(dev, HARDWARE_VERSION);
|
||||
if (val == 0xffffffff)
|
||||
status |= 8;
|
||||
tvp->u.data = status;
|
||||
return 0;
|
||||
}
|
||||
@ -1592,13 +1620,18 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
|
||||
if (dev->link[0].info->version == 3 && cmd != FE_SET_PROPERTY)
|
||||
return -EINVAL;
|
||||
mutex_lock(&dev->ioctl_mutex);
|
||||
switch (cmd) {
|
||||
case FE_SET_PROPERTY:
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||
return -EINVAL;
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
if (IS_ERR(tvp)) {
|
||||
ret = PTR_ERR(tvp);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
ret = mod_prop_proc(mod, tvp + i);
|
||||
if (ret < 0)
|
||||
@ -1606,14 +1639,18 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
(tvp + i)->result = ret;
|
||||
}
|
||||
kfree(tvp);
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case FE_GET_PROPERTY:
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||
return -EINVAL;
|
||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||
if (IS_ERR(tvp))
|
||||
return PTR_ERR(tvp);
|
||||
if (IS_ERR(tvp)) {
|
||||
ret = PTR_ERR(tvp);
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < tvps->num; i++) {
|
||||
ret = mod_prop_get(mod, tvp + i);
|
||||
if (ret < 0)
|
||||
@ -1625,7 +1662,7 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
tvps->num * sizeof(struct dtv_property)))
|
||||
ret = -EFAULT;
|
||||
kfree(tvp);
|
||||
return ret;
|
||||
break;
|
||||
|
||||
case DVB_MOD_SET:
|
||||
{
|
||||
@ -1633,8 +1670,10 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
|
||||
if (dev->link[0].info->version < 2) {
|
||||
if (mp->base_frequency != dev->mod_base.frequency)
|
||||
if (set_base_frequency(dev, mp->base_frequency))
|
||||
return -EINVAL;
|
||||
if (set_base_frequency(dev, mp->base_frequency)) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
int i, streams = dev->link[0].info->port_num;
|
||||
|
||||
@ -1659,11 +1698,15 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
int res;
|
||||
|
||||
res = mod_set_modulation(mod, cp->modulation);
|
||||
if (res)
|
||||
return res;
|
||||
if (res) {
|
||||
ret = res;
|
||||
break;
|
||||
}
|
||||
res = mod_set_ibitrate(mod, cp->input_bitrate);
|
||||
if (res)
|
||||
return res;
|
||||
if (res) {
|
||||
ret = res;
|
||||
break;
|
||||
}
|
||||
mod->pcr_correction = cp->pcr_correction;
|
||||
break;
|
||||
}
|
||||
@ -1671,6 +1714,7 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&dev->ioctl_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1699,7 +1743,8 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
|
||||
mod_set_vga(dev, RF_VGA_GAIN_N16);
|
||||
else
|
||||
mod_set_vga(dev, RF_VGA_GAIN_N24);
|
||||
|
||||
|
||||
udelay(10);
|
||||
mod_set_attenuator(dev, 0);
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,7 +171,8 @@ struct ddb_info {
|
||||
#define TS_QUIRK_REVERSED 2
|
||||
#define TS_QUIRK_NO_OUTPUT 4
|
||||
#define TS_QUIRK_ALT_OSC 8
|
||||
u32 tempmon_irq;
|
||||
u32 tempmon_irq;
|
||||
u32 lostlock_irq;
|
||||
const struct ddb_regmap *regmap;
|
||||
};
|
||||
|
||||
@ -474,7 +475,7 @@ struct ddb {
|
||||
|
||||
struct mod_base mod_base;
|
||||
struct ddb_mod mod[24];
|
||||
|
||||
struct mutex ioctl_mutex; /* lock extra ioctls */
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -102,7 +102,7 @@ MODULATOR_STATUS and MODULATOR_RESET have been added to debug
|
||||
possible problems with too high temperatures (overtemperature)
|
||||
or PLL lock loss on FSM type cards.
|
||||
|
||||
The MODUALTOR_STATUS property returns a __u32 with the following status bits:
|
||||
The MODULATOR_STATUS property returns a __u32 with the following status bits:
|
||||
|
||||
- bit 0 : Lock status 1=lock OK, 0 = lock lost
|
||||
|
||||
@ -113,8 +113,18 @@ The MODUALTOR_STATUS property returns a __u32 with the following status bits:
|
||||
- bit 2 : 0 = no overtemperature
|
||||
1 = overtemperature detected
|
||||
|
||||
- bit 4 : 0 = PCIe link OK
|
||||
1 = PCIe link lost
|
||||
|
||||
In case of overtemperratur or PCIe link loss you will have to reboot the PC.
|
||||
|
||||
|
||||
Putting a MODULATOR_STATUS property with value 2 will enable the lost lock
|
||||
interrupt. This will set the gain to 0 and the attenuation to 31 in case
|
||||
of a lost PLL lock.
|
||||
|
||||
|
||||
The MODULATOR_RESET property can be used to reset the modulator without
|
||||
needing to reload the driver or rebooting.
|
||||
needing to reload the driver or rebooting in case of PLL lock loss.
|
||||
All channels should be stopped before using it and restarted after using it.
|
||||
Otherwise, results are unpredictable.
|
||||
|
Loading…
Reference in New Issue
Block a user