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 */
|
/* gain 0-255 */
|
||||||
get_property(fd, MODULATOR_GAIN, &data);
|
get_property(fd, MODULATOR_GAIN, &data);
|
||||||
printf("Modulator gain = %u\n", 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);
|
get_property(fd, MODULATOR_GAIN, &data);
|
||||||
printf("Modulator gain = %u\n", 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);
|
get_property(fd, MODULATOR_STATUS, &data);
|
||||||
printf("Modulator status = %u\n", data);
|
printf("Modulator status = %u\n", data);
|
||||||
|
set_property(fd, MODULATOR_STATUS, 2);
|
||||||
|
|
||||||
|
|
||||||
//set_property(fd, MODULATOR_RESET, 0);
|
//set_property(fd, MODULATOR_RESET, 0);
|
||||||
|
@ -4341,6 +4341,7 @@ static int ddb_init_boards(struct ddb *dev)
|
|||||||
int ddb_init(struct ddb *dev)
|
int ddb_init(struct ddb *dev)
|
||||||
{
|
{
|
||||||
mutex_init(&dev->link[0].flash_mutex);
|
mutex_init(&dev->link[0].flash_mutex);
|
||||||
|
mutex_init(&dev->ioctl_mutex);
|
||||||
if (no_init) {
|
if (no_init) {
|
||||||
ddb_device_create(dev);
|
ddb_device_create(dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -437,6 +437,7 @@ static const struct ddb_info ddb_mod_fsm_24 = {
|
|||||||
.port_num = 24,
|
.port_num = 24,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
|
.lostlock_irq = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_mod_fsm_16 = {
|
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,
|
.port_num = 16,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
|
.lostlock_irq = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_mod_fsm_8 = {
|
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,
|
.port_num = 8,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
|
.lostlock_irq = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_mod_fsm_4 = {
|
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,
|
.port_num = 4,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
|
.lostlock_irq = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_sdr = {
|
static const struct ddb_info ddb_sdr = {
|
||||||
|
@ -434,6 +434,16 @@ static u32 max2871_sdr[6] = {
|
|||||||
0x007A8098, 0x600080C9, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005
|
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)
|
static int mod_setup_max2871(struct ddb *dev, u32 *reg)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -467,6 +477,12 @@ static int mod_setup_max2871(struct ddb *dev, u32 *reg)
|
|||||||
ddbwritel(dev,
|
ddbwritel(dev,
|
||||||
MAX2871_CONTROL_CE | MAX2871_CONTROL_LOSTLOCK,
|
MAX2871_CONTROL_CE | MAX2871_CONTROL_LOSTLOCK,
|
||||||
MAX2871_CONTROL);
|
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;
|
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)
|
if (mod->port->dev->link[0].info->version == 2)
|
||||||
return mod_fsm_setup(mod->port->dev,0 );
|
return mod_fsm_setup(mod->port->dev,0 );
|
||||||
return -EINVAL;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1560,8 +1587,6 @@ static int mod_prop_get(struct ddb_mod *mod, struct dtv_property *tvp)
|
|||||||
u32 status = 0, val;
|
u32 status = 0, val;
|
||||||
|
|
||||||
val = ddbreadl(dev, MAX2871_CONTROL);
|
val = ddbreadl(dev, MAX2871_CONTROL);
|
||||||
if (!(val & MAX2871_CONTROL_LOCK))
|
|
||||||
status |= 1;
|
|
||||||
if (!(val & MAX2871_CONTROL_LOCK))
|
if (!(val & MAX2871_CONTROL_LOCK))
|
||||||
status |= 1;
|
status |= 1;
|
||||||
if (val & MAX2871_CONTROL_LOSTLOCK)
|
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);
|
val = ddbreadl(dev, TEMPMON_CONTROL);
|
||||||
if (val & TEMPMON_CONTROL_OVERTEMP)
|
if (val & TEMPMON_CONTROL_OVERTEMP)
|
||||||
status |= 4;
|
status |= 4;
|
||||||
|
val = ddbreadl(dev, HARDWARE_VERSION);
|
||||||
|
if (val == 0xffffffff)
|
||||||
|
status |= 8;
|
||||||
tvp->u.data = status;
|
tvp->u.data = status;
|
||||||
return 0;
|
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)
|
if (dev->link[0].info->version == 3 && cmd != FE_SET_PROPERTY)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
mutex_lock(&dev->ioctl_mutex);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case FE_SET_PROPERTY:
|
case FE_SET_PROPERTY:
|
||||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||||
if (IS_ERR(tvp))
|
if (IS_ERR(tvp)) {
|
||||||
return PTR_ERR(tvp);
|
ret = PTR_ERR(tvp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < tvps->num; i++) {
|
for (i = 0; i < tvps->num; i++) {
|
||||||
ret = mod_prop_proc(mod, tvp + i);
|
ret = mod_prop_proc(mod, tvp + i);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1606,14 +1639,18 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
(tvp + i)->result = ret;
|
(tvp + i)->result = ret;
|
||||||
}
|
}
|
||||||
kfree(tvp);
|
kfree(tvp);
|
||||||
return ret;
|
break;
|
||||||
|
|
||||||
case FE_GET_PROPERTY:
|
case FE_GET_PROPERTY:
|
||||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
tvp = memdup_user(tvps->props, tvps->num * sizeof(*tvp));
|
||||||
if (IS_ERR(tvp))
|
if (IS_ERR(tvp)) {
|
||||||
return PTR_ERR(tvp);
|
ret = PTR_ERR(tvp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < tvps->num; i++) {
|
for (i = 0; i < tvps->num; i++) {
|
||||||
ret = mod_prop_get(mod, tvp + i);
|
ret = mod_prop_get(mod, tvp + i);
|
||||||
if (ret < 0)
|
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)))
|
tvps->num * sizeof(struct dtv_property)))
|
||||||
ret = -EFAULT;
|
ret = -EFAULT;
|
||||||
kfree(tvp);
|
kfree(tvp);
|
||||||
return ret;
|
break;
|
||||||
|
|
||||||
case DVB_MOD_SET:
|
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 (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;
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int i, streams = dev->link[0].info->port_num;
|
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;
|
int res;
|
||||||
|
|
||||||
res = mod_set_modulation(mod, cp->modulation);
|
res = mod_set_modulation(mod, cp->modulation);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
ret = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
res = mod_set_ibitrate(mod, cp->input_bitrate);
|
res = mod_set_ibitrate(mod, cp->input_bitrate);
|
||||||
if (res)
|
if (res) {
|
||||||
return res;
|
ret = res;
|
||||||
|
break;
|
||||||
|
}
|
||||||
mod->pcr_correction = cp->pcr_correction;
|
mod->pcr_correction = cp->pcr_correction;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1671,6 +1714,7 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&dev->ioctl_mutex);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1699,7 +1743,8 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
|
|||||||
mod_set_vga(dev, RF_VGA_GAIN_N16);
|
mod_set_vga(dev, RF_VGA_GAIN_N16);
|
||||||
else
|
else
|
||||||
mod_set_vga(dev, RF_VGA_GAIN_N24);
|
mod_set_vga(dev, RF_VGA_GAIN_N24);
|
||||||
|
|
||||||
|
udelay(10);
|
||||||
mod_set_attenuator(dev, 0);
|
mod_set_attenuator(dev, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,8 @@ struct ddb_info {
|
|||||||
#define TS_QUIRK_REVERSED 2
|
#define TS_QUIRK_REVERSED 2
|
||||||
#define TS_QUIRK_NO_OUTPUT 4
|
#define TS_QUIRK_NO_OUTPUT 4
|
||||||
#define TS_QUIRK_ALT_OSC 8
|
#define TS_QUIRK_ALT_OSC 8
|
||||||
u32 tempmon_irq;
|
u32 tempmon_irq;
|
||||||
|
u32 lostlock_irq;
|
||||||
const struct ddb_regmap *regmap;
|
const struct ddb_regmap *regmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -474,7 +475,7 @@ struct ddb {
|
|||||||
|
|
||||||
struct mod_base mod_base;
|
struct mod_base mod_base;
|
||||||
struct ddb_mod mod[24];
|
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)
|
possible problems with too high temperatures (overtemperature)
|
||||||
or PLL lock loss on FSM type cards.
|
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
|
- 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
|
- bit 2 : 0 = no overtemperature
|
||||||
1 = overtemperature detected
|
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
|
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.
|
All channels should be stopped before using it and restarted after using it.
|
||||||
Otherwise, results are unpredictable.
|
Otherwise, results are unpredictable.
|
||||||
|
Loading…
Reference in New Issue
Block a user