diff -r 4df151d5b3fe linux/drivers/media/dvb/cinergyT2/cinergyT2.c --- a/linux/drivers/media/dvb/cinergyT2/cinergyT2.c Sat Dec 01 01:50:24 2007 +0400 +++ b/linux/drivers/media/dvb/cinergyT2/cinergyT2.c Sat Jan 12 22:45:29 2008 +0100 @@ -1,5 +1,5 @@ /* - * TerraTec Cinergy T²/qanu USB2 DVB-T adapter. + * TerraTec Cinergy T²/qanu USB2 DVB-T adapter. * * Copyright (C) 2004 Daniel Mack and * Holger Waechtler @@ -511,6 +511,106 @@ static uint16_t compute_tps (struct dvb_ return tps; } +static uint16_t compute_newtps (struct dvbfe_params *fep) +{ + uint16_t tps = 0; + + switch (fep->delsys.dvbt.code_rate_HP) { + case DVBFE_FEC_2_3: + tps |= (1 << 7); + break; + case DVBFE_FEC_3_4: + tps |= (2 << 7); + break; + case DVBFE_FEC_5_6: + tps |= (3 << 7); + break; + case DVBFE_FEC_7_8: + tps |= (4 << 7); + break; + case DVBFE_FEC_1_2: + case DVBFE_FEC_AUTO: + default: + /* tps |= (0 << 7) */; + } + + switch (fep->delsys.dvbt.code_rate_LP) { + case DVBFE_FEC_2_3: + tps |= (1 << 4); + break; + case DVBFE_FEC_3_4: + tps |= (2 << 4); + break; + case DVBFE_FEC_5_6: + tps |= (3 << 4); + break; + case DVBFE_FEC_7_8: + tps |= (4 << 4); + break; + case DVBFE_FEC_1_2: + case DVBFE_FEC_AUTO: + default: + /* tps |= (0 << 4) */; + } + + switch (fep->delsys.dvbt.constellation) { + case DVBFE_MOD_QAM16: + tps |= (1 << 13); + break; + case DVBFE_MOD_QAM64: + tps |= (2 << 13); + break; + case DVBFE_MOD_QPSK: + default: + /* tps |= (0 << 13) */; + } + + switch (fep->delsys.dvbt.transmission_mode) { + case DVBFE_TRANSMISSION_MODE_8K: + tps |= (1 << 0); + break; + case DVBFE_TRANSMISSION_MODE_2K: + default: + /* tps |= (0 << 0) */; + } + + switch (fep->delsys.dvbt.guard_interval) { + case DVBFE_GUARD_INTERVAL_1_16: + tps |= (1 << 2); + break; + case DVBFE_GUARD_INTERVAL_1_8: + tps |= (2 << 2); + break; + case DVBFE_GUARD_INTERVAL_1_4: + tps |= (3 << 2); + break; + case DVBFE_GUARD_INTERVAL_1_32: + default: + /* tps |= (0 << 2) */; + } + + switch (fep->delsys.dvbt.hierarchy) { + case DVBFE_HIERARCHY_ON: + switch (fep->delsys.dvbt.alpha) { + case DVBFE_ALPHA_1: + tps |= (1 << 10); + break; + case DVBFE_ALPHA_2: + tps |= (2 << 10); + break; + case DVBFE_ALPHA_4: + tps |= (3 << 10); + break; + } + break; + case DVBFE_HIERARCHY_OFF: + default: + /* tps |= (0 << 10) */; + } + + return tps; +} + static int cinergyt2_open (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; @@ -597,6 +697,22 @@ static unsigned int cinergyt2_poll (stru return mask; } +static int newbw2old (struct dvbt_params *dvbt) +{ + switch (dvbt->bandwidth) { + case DVBFE_BANDWIDTH_8_MHZ: + return BANDWIDTH_8_MHZ; + case DVBFE_BANDWIDTH_7_MHZ: + return BANDWIDTH_7_MHZ; + case DVBFE_BANDWIDTH_6_MHZ: + return BANDWIDTH_6_MHZ; + case DVBFE_BANDWIDTH_AUTO: + return BANDWIDTH_AUTO; + default: + printk("%s: Unsupported bandwidth %x\n", __func__, dvbt->bandwidth); + return BANDWIDTH_AUTO; + } +} static int cinergyt2_ioctl (struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) @@ -708,8 +824,63 @@ static int cinergyt2_ioctl (struct inode (unsigned long) &e->status); } + case DVBFE_GET_EVENT: + { + printk("%s: DVBFE_GET_EVENT\n", __func__); + return -EINVAL; + } + case DVBFE_GET_PARAMS: + { + printk("%s: DVBFE_GET_PARAMS\n", __func__); + return -EINVAL; + } + case DVBFE_GET_DELSYS: + { + printk("%s: DVBFE_GET_DELSYS\n", __func__); + *((enum dvbfe_delsys *) arg) = DVBFE_DELSYS_DVBT; + return 0; + } + case DVBFE_GET_INFO: + { + printk("%s: DVBFE_GET_INFO\n", __func__); + return -EINVAL; + } + case DVBFE_SET_PARAMS: + { + struct dvbt_set_parameters_msg *param = &cinergyt2->param; + struct dvbfe_params fep; + int err; + + printk("%s: DVBFE_SET_PARAMS\n", __func__); + + if ((file->f_flags & O_ACCMODE) == O_RDONLY) + return -EPERM; + + if (copy_from_user(&fep, (void __user*) arg, sizeof(fep))) + return -EFAULT; + + if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; + + param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; + param->tps = cpu_to_le16(compute_newtps(&fep)); + param->freq = cpu_to_le32(fep.frequency / 1000); + param->bandwidth = 8 - newbw2old (&fep.delsys.dvbt) - BANDWIDTH_8_MHZ; + + stat->lock_bits = 0; + cinergyt2->pending_fe_events++; + wake_up_interruptible(&cinergyt2->poll_wq); + + err = cinergyt2_command(cinergyt2, + (char *) param, sizeof(*param), + NULL, 0); + + mutex_unlock(&cinergyt2->sem); + + return (err < 0) ? err : 0; + } default: - ; + printk("%s: ERROR unsupported ioctl %d\n", __func__, cmd); } return -EINVAL;