diff options
Diffstat (limited to 'drivers/media/dvb')
53 files changed, 3038 insertions, 988 deletions
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index 79875958930e..a0dcd59da76e 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
@@ -9,7 +9,6 @@ config DVB_B2C2_FLEXCOP | |||
9 | select DVB_STV0297 if !DVB_FE_CUSTOMISE | 9 | select DVB_STV0297 if !DVB_FE_CUSTOMISE |
10 | select DVB_BCM3510 if !DVB_FE_CUSTOMISE | 10 | select DVB_BCM3510 if !DVB_FE_CUSTOMISE |
11 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 11 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
12 | select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE | ||
13 | help | 12 | help |
14 | Support for the digital TV receiver chip made by B2C2 Inc. included in | 13 | Support for the digital TV receiver chip made by B2C2 Inc. included in |
15 | Technisats PCI cards and USB boxes. | 14 | Technisats PCI cards and USB boxes. |
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 752cf79c532f..b02c2fd65baa 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
15 | #include "mt312.h" | 15 | #include "mt312.h" |
16 | #include "lgdt330x.h" | 16 | #include "lgdt330x.h" |
17 | #include "lgh06xf.h" | ||
18 | #include "dvb-pll.h" | 17 | #include "dvb-pll.h" |
19 | 18 | ||
20 | /* lnb control */ | 19 | /* lnb control */ |
@@ -507,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
507 | /* try the air atsc 3nd generation (lgdt3303) */ | 506 | /* try the air atsc 3nd generation (lgdt3303) */ |
508 | if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { | 507 | if ((fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, &fc->i2c_adap)) != NULL) { |
509 | fc->dev_type = FC_AIR_ATSC3; | 508 | fc->dev_type = FC_AIR_ATSC3; |
510 | dvb_attach(lgh06xf_attach, fc->fe, &fc->i2c_adap); | 509 | dvb_attach(dvb_pll_attach, fc->fe, 0x61, &fc->i2c_adap, &dvb_pll_lg_tdvs_h06xf); |
511 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); | 510 | info("found the lgdt3303 at i2c address: 0x%02x",air2pc_atsc_hd5000_config.demod_address); |
512 | } else | 511 | } else |
513 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ | 512 | /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 6e166801505d..01af4d237eb1 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -127,10 +127,11 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) | |||
127 | { | 127 | { |
128 | struct flexcop_pci *fc_pci = dev_id; | 128 | struct flexcop_pci *fc_pci = dev_id; |
129 | struct flexcop_device *fc = fc_pci->fc_dev; | 129 | struct flexcop_device *fc = fc_pci->fc_dev; |
130 | unsigned long flags; | ||
130 | flexcop_ibi_value v; | 131 | flexcop_ibi_value v; |
131 | irqreturn_t ret = IRQ_HANDLED; | 132 | irqreturn_t ret = IRQ_HANDLED; |
132 | 133 | ||
133 | spin_lock_irq(&fc_pci->irq_lock); | 134 | spin_lock_irqsave(&fc_pci->irq_lock,flags); |
134 | 135 | ||
135 | v = fc->read_ibi_reg(fc,irq_20c); | 136 | v = fc->read_ibi_reg(fc,irq_20c); |
136 | 137 | ||
@@ -194,7 +195,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) | |||
194 | ret = IRQ_NONE; | 195 | ret = IRQ_NONE; |
195 | } | 196 | } |
196 | 197 | ||
197 | spin_unlock_irq(&fc_pci->irq_lock); | 198 | spin_unlock_irqrestore(&fc_pci->irq_lock,flags); |
198 | 199 | ||
199 | return ret; | 200 | return ret; |
200 | } | 201 | } |
@@ -293,12 +294,12 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci) | |||
293 | } | 294 | } |
294 | 295 | ||
295 | pci_set_drvdata(fc_pci->pdev, fc_pci); | 296 | pci_set_drvdata(fc_pci->pdev, fc_pci); |
296 | 297 | spin_lock_init(&fc_pci->irq_lock); | |
297 | if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr, | 298 | if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr, |
298 | IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) | 299 | IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) |
299 | goto err_pci_iounmap; | 300 | goto err_pci_iounmap; |
300 | 301 | ||
301 | spin_lock_init(&fc_pci->irq_lock); | 302 | |
302 | 303 | ||
303 | fc_pci->init_state |= FC_PCI_INIT; | 304 | fc_pci->init_state |= FC_PCI_INIT; |
304 | return ret; | 305 | return ret; |
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index dd66b60fbc98..cfd6fb729a61 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig | |||
@@ -7,7 +7,7 @@ config DVB_BT8XX | |||
7 | select DVB_CX24110 if !DVB_FE_CUSTOMISE | 7 | select DVB_CX24110 if !DVB_FE_CUSTOMISE |
8 | select DVB_OR51211 if !DVB_FE_CUSTOMISE | 8 | select DVB_OR51211 if !DVB_FE_CUSTOMISE |
9 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 9 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
10 | select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE | 10 | select DVB_PLL |
11 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 11 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
12 | select FW_LOADER | 12 | select FW_LOADER |
13 | help | 13 | help |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 83b090ef2445..df72b4b8ee10 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -393,9 +393,7 @@ static struct cards card_list[] __devinitdata = { | |||
393 | { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, | 393 | { 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" }, |
394 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | 394 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, |
395 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, | 395 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, |
396 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, | 396 | { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" } |
397 | |||
398 | { 0, -1, NULL } | ||
399 | }; | 397 | }; |
400 | 398 | ||
401 | 399 | ||
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 58f69f6ae391..4f1c09bee538 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -610,7 +610,8 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
610 | lgdt330x_reset(card); | 610 | lgdt330x_reset(card); |
611 | card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); | 611 | card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); |
612 | if (card->fe != NULL) { | 612 | if (card->fe != NULL) { |
613 | dvb_attach(lgh06xf_attach, card->fe, card->i2c_adapter); | 613 | dvb_attach(dvb_pll_attach, card->fe, 0x61, |
614 | card->i2c_adapter, &dvb_pll_lg_tdvs_h06xf); | ||
614 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); | 615 | dprintk ("dvb_bt8xx: lgdt330x detected\n"); |
615 | } | 616 | } |
616 | break; | 617 | break; |
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index e75f4173c059..436880e68672 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -37,8 +37,8 @@ | |||
37 | #include "cx24110.h" | 37 | #include "cx24110.h" |
38 | #include "or51211.h" | 38 | #include "or51211.h" |
39 | #include "lgdt330x.h" | 39 | #include "lgdt330x.h" |
40 | #include "lgh06xf.h" | ||
41 | #include "zl10353.h" | 40 | #include "zl10353.h" |
41 | #include "dvb-pll.h" | ||
42 | 42 | ||
43 | struct dvb_bt8xx_card { | 43 | struct dvb_bt8xx_card { |
44 | struct mutex lock; | 44 | struct mutex lock; |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index a5c0e1a3e6d1..275df65fde99 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) | |||
132 | if (mutex_lock_interruptible(&dmxdev->mutex)) | 132 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
133 | return -ERESTARTSYS; | 133 | return -ERESTARTSYS; |
134 | 134 | ||
135 | if (dmxdev->exit) { | ||
136 | mutex_unlock(&dmxdev->mutex); | ||
137 | return -ENODEV; | ||
138 | } | ||
139 | |||
135 | if ((file->f_flags & O_ACCMODE) == O_RDWR) { | 140 | if ((file->f_flags & O_ACCMODE) == O_RDWR) { |
136 | if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { | 141 | if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { |
137 | mutex_unlock(&dmxdev->mutex); | 142 | mutex_unlock(&dmxdev->mutex); |
@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) | |||
171 | dmxdev->demux->disconnect_frontend(dmxdev->demux); | 176 | dmxdev->demux->disconnect_frontend(dmxdev->demux); |
172 | dmxdev->demux->connect_frontend(dmxdev->demux, front); | 177 | dmxdev->demux->connect_frontend(dmxdev->demux, front); |
173 | } | 178 | } |
179 | dvbdev->users++; | ||
174 | mutex_unlock(&dmxdev->mutex); | 180 | mutex_unlock(&dmxdev->mutex); |
175 | return 0; | 181 | return 0; |
176 | } | 182 | } |
@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) | |||
198 | vfree(mem); | 204 | vfree(mem); |
199 | } | 205 | } |
200 | } | 206 | } |
201 | mutex_unlock(&dmxdev->mutex); | 207 | /* TODO */ |
208 | dvbdev->users--; | ||
209 | if(dvbdev->users==-1 && dmxdev->exit==1) { | ||
210 | fops_put(file->f_op); | ||
211 | file->f_op = NULL; | ||
212 | mutex_unlock(&dmxdev->mutex); | ||
213 | wake_up(&dvbdev->wait_queue); | ||
214 | } else | ||
215 | mutex_unlock(&dmxdev->mutex); | ||
216 | |||
202 | return 0; | 217 | return 0; |
203 | } | 218 | } |
204 | 219 | ||
@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, | |||
215 | return -EINVAL; | 230 | return -EINVAL; |
216 | if (mutex_lock_interruptible(&dmxdev->mutex)) | 231 | if (mutex_lock_interruptible(&dmxdev->mutex)) |
217 | return -ERESTARTSYS; | 232 | return -ERESTARTSYS; |
233 | |||
234 | if (dmxdev->exit) { | ||
235 | mutex_unlock(&dmxdev->mutex); | ||
236 | return -ENODEV; | ||
237 | } | ||
218 | ret = dmxdev->demux->write(dmxdev->demux, buf, count); | 238 | ret = dmxdev->demux->write(dmxdev->demux, buf, count); |
219 | mutex_unlock(&dmxdev->mutex); | 239 | mutex_unlock(&dmxdev->mutex); |
220 | return ret; | 240 | return ret; |
@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, | |||
227 | struct dmxdev *dmxdev = dvbdev->priv; | 247 | struct dmxdev *dmxdev = dvbdev->priv; |
228 | int ret; | 248 | int ret; |
229 | 249 | ||
250 | if (dmxdev->exit) { | ||
251 | mutex_unlock(&dmxdev->mutex); | ||
252 | return -ENODEV; | ||
253 | } | ||
254 | |||
230 | //mutex_lock(&dmxdev->mutex); | 255 | //mutex_lock(&dmxdev->mutex); |
231 | ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, | 256 | ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, |
232 | file->f_flags & O_NONBLOCK, | 257 | file->f_flags & O_NONBLOCK, |
@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) | |||
665 | dmxdevfilter->feed.ts = NULL; | 690 | dmxdevfilter->feed.ts = NULL; |
666 | init_timer(&dmxdevfilter->timer); | 691 | init_timer(&dmxdevfilter->timer); |
667 | 692 | ||
693 | dvbdev->users++; | ||
694 | |||
668 | mutex_unlock(&dmxdev->mutex); | 695 | mutex_unlock(&dmxdev->mutex); |
669 | return 0; | 696 | return 0; |
670 | } | 697 | } |
@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file) | |||
943 | struct dmxdev_filter *dmxdevfilter = file->private_data; | 970 | struct dmxdev_filter *dmxdevfilter = file->private_data; |
944 | struct dmxdev *dmxdev = dmxdevfilter->dev; | 971 | struct dmxdev *dmxdev = dmxdevfilter->dev; |
945 | 972 | ||
946 | return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); | 973 | int ret; |
974 | |||
975 | ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); | ||
976 | |||
977 | mutex_lock(&dmxdev->mutex); | ||
978 | dmxdev->dvbdev->users--; | ||
979 | if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) { | ||
980 | fops_put(file->f_op); | ||
981 | file->f_op = NULL; | ||
982 | mutex_unlock(&dmxdev->mutex); | ||
983 | wake_up(&dmxdev->dvbdev->wait_queue); | ||
984 | } else | ||
985 | mutex_unlock(&dmxdev->mutex); | ||
986 | |||
987 | return ret; | ||
947 | } | 988 | } |
948 | 989 | ||
949 | static struct file_operations dvb_demux_fops = { | 990 | static struct file_operations dvb_demux_fops = { |
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = { | |||
1027 | static struct dvb_device dvbdev_dvr = { | 1068 | static struct dvb_device dvbdev_dvr = { |
1028 | .priv = NULL, | 1069 | .priv = NULL, |
1029 | .readers = 1, | 1070 | .readers = 1, |
1071 | .users = 1, | ||
1030 | .fops = &dvb_dvr_fops | 1072 | .fops = &dvb_dvr_fops |
1031 | }; | 1073 | }; |
1032 | 1074 | ||
@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init); | |||
1064 | 1106 | ||
1065 | void dvb_dmxdev_release(struct dmxdev *dmxdev) | 1107 | void dvb_dmxdev_release(struct dmxdev *dmxdev) |
1066 | { | 1108 | { |
1109 | dmxdev->exit=1; | ||
1110 | if (dmxdev->dvbdev->users > 1) { | ||
1111 | wait_event(dmxdev->dvbdev->wait_queue, | ||
1112 | dmxdev->dvbdev->users==1); | ||
1113 | } | ||
1114 | if (dmxdev->dvr_dvbdev->users > 1) { | ||
1115 | wait_event(dmxdev->dvr_dvbdev->wait_queue, | ||
1116 | dmxdev->dvr_dvbdev->users==1); | ||
1117 | } | ||
1118 | |||
1067 | dvb_unregister_device(dmxdev->dvbdev); | 1119 | dvb_unregister_device(dmxdev->dvbdev); |
1068 | dvb_unregister_device(dmxdev->dvr_dvbdev); | 1120 | dvb_unregister_device(dmxdev->dvr_dvbdev); |
1069 | 1121 | ||
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h index d2bee9ffe43c..29746e70d325 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ b/drivers/media/dvb/dvb-core/dmxdev.h | |||
@@ -91,6 +91,8 @@ struct dmxdev { | |||
91 | 91 | ||
92 | int filternum; | 92 | int filternum; |
93 | int capabilities; | 93 | int capabilities; |
94 | |||
95 | unsigned int exit:1; | ||
94 | #define DMXDEV_CAP_DUPLEX 1 | 96 | #define DMXDEV_CAP_DUPLEX 1 |
95 | struct dmx_frontend *dvr_orig_fe; | 97 | struct dmx_frontend *dvr_orig_fe; |
96 | 98 | ||
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index a21a894d3f98..f4e4ca2dcade 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -606,6 +606,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
606 | return; | 606 | return; |
607 | 607 | ||
608 | kthread_stop(fepriv->thread); | 608 | kthread_stop(fepriv->thread); |
609 | |||
609 | init_MUTEX (&fepriv->sem); | 610 | init_MUTEX (&fepriv->sem); |
610 | fepriv->state = FESTATE_IDLE; | 611 | fepriv->state = FESTATE_IDLE; |
611 | 612 | ||
@@ -1023,6 +1024,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) | |||
1023 | struct dvb_device *dvbdev = file->private_data; | 1024 | struct dvb_device *dvbdev = file->private_data; |
1024 | struct dvb_frontend *fe = dvbdev->priv; | 1025 | struct dvb_frontend *fe = dvbdev->priv; |
1025 | struct dvb_frontend_private *fepriv = fe->frontend_priv; | 1026 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
1027 | int ret; | ||
1026 | 1028 | ||
1027 | dprintk ("%s\n", __FUNCTION__); | 1029 | dprintk ("%s\n", __FUNCTION__); |
1028 | 1030 | ||
@@ -1032,7 +1034,14 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) | |||
1032 | if (fe->ops.ts_bus_ctrl) | 1034 | if (fe->ops.ts_bus_ctrl) |
1033 | fe->ops.ts_bus_ctrl (fe, 0); | 1035 | fe->ops.ts_bus_ctrl (fe, 0); |
1034 | 1036 | ||
1035 | return dvb_generic_release (inode, file); | 1037 | ret = dvb_generic_release (inode, file); |
1038 | |||
1039 | if (dvbdev->users==-1 && fepriv->exit==1) { | ||
1040 | fops_put(file->f_op); | ||
1041 | file->f_op = NULL; | ||
1042 | wake_up(&dvbdev->wait_queue); | ||
1043 | } | ||
1044 | return ret; | ||
1036 | } | 1045 | } |
1037 | 1046 | ||
1038 | static struct file_operations dvb_frontend_fops = { | 1047 | static struct file_operations dvb_frontend_fops = { |
@@ -1092,8 +1101,15 @@ int dvb_unregister_frontend(struct dvb_frontend* fe) | |||
1092 | dprintk ("%s\n", __FUNCTION__); | 1101 | dprintk ("%s\n", __FUNCTION__); |
1093 | 1102 | ||
1094 | mutex_lock(&frontend_mutex); | 1103 | mutex_lock(&frontend_mutex); |
1095 | dvb_unregister_device (fepriv->dvbdev); | ||
1096 | dvb_frontend_stop (fe); | 1104 | dvb_frontend_stop (fe); |
1105 | mutex_unlock(&frontend_mutex); | ||
1106 | |||
1107 | if (fepriv->dvbdev->users < -1) | ||
1108 | wait_event(fepriv->dvbdev->wait_queue, | ||
1109 | fepriv->dvbdev->users==-1); | ||
1110 | |||
1111 | mutex_lock(&frontend_mutex); | ||
1112 | dvb_unregister_device (fepriv->dvbdev); | ||
1097 | 1113 | ||
1098 | /* fe is invalid now */ | 1114 | /* fe is invalid now */ |
1099 | kfree(fepriv); | 1115 | kfree(fepriv); |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 6a5ab409c4e7..4ebf33a5ffa2 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -1439,11 +1439,36 @@ static int dvb_net_ioctl(struct inode *inode, struct file *file, | |||
1439 | return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); | 1439 | return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); |
1440 | } | 1440 | } |
1441 | 1441 | ||
1442 | static int dvb_net_close(struct inode *inode, struct file *file) | ||
1443 | { | ||
1444 | struct dvb_device *dvbdev = file->private_data; | ||
1445 | struct dvb_net *dvbnet = dvbdev->priv; | ||
1446 | |||
1447 | if (!dvbdev) | ||
1448 | return -ENODEV; | ||
1449 | |||
1450 | if ((file->f_flags & O_ACCMODE) == O_RDONLY) { | ||
1451 | dvbdev->readers++; | ||
1452 | } else { | ||
1453 | dvbdev->writers++; | ||
1454 | } | ||
1455 | |||
1456 | dvbdev->users++; | ||
1457 | |||
1458 | if(dvbdev->users == 1 && dvbnet->exit==1) { | ||
1459 | fops_put(file->f_op); | ||
1460 | file->f_op = NULL; | ||
1461 | wake_up(&dvbdev->wait_queue); | ||
1462 | } | ||
1463 | return 0; | ||
1464 | } | ||
1465 | |||
1466 | |||
1442 | static struct file_operations dvb_net_fops = { | 1467 | static struct file_operations dvb_net_fops = { |
1443 | .owner = THIS_MODULE, | 1468 | .owner = THIS_MODULE, |
1444 | .ioctl = dvb_net_ioctl, | 1469 | .ioctl = dvb_net_ioctl, |
1445 | .open = dvb_generic_open, | 1470 | .open = dvb_generic_open, |
1446 | .release = dvb_generic_release, | 1471 | .release = dvb_net_close, |
1447 | }; | 1472 | }; |
1448 | 1473 | ||
1449 | static struct dvb_device dvbdev_net = { | 1474 | static struct dvb_device dvbdev_net = { |
@@ -1458,6 +1483,11 @@ void dvb_net_release (struct dvb_net *dvbnet) | |||
1458 | { | 1483 | { |
1459 | int i; | 1484 | int i; |
1460 | 1485 | ||
1486 | dvbnet->exit = 1; | ||
1487 | if (dvbnet->dvbdev->users < 1) | ||
1488 | wait_event(dvbnet->dvbdev->wait_queue, | ||
1489 | dvbnet->dvbdev->users==1); | ||
1490 | |||
1461 | dvb_unregister_device(dvbnet->dvbdev); | 1491 | dvb_unregister_device(dvbnet->dvbdev); |
1462 | 1492 | ||
1463 | for (i=0; i<DVB_NET_DEVICES_MAX; i++) { | 1493 | for (i=0; i<DVB_NET_DEVICES_MAX; i++) { |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h index f14e4ca38570..3a3126cae03b 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.h +++ b/drivers/media/dvb/dvb-core/dvb_net.h | |||
@@ -36,6 +36,7 @@ struct dvb_net { | |||
36 | struct dvb_device *dvbdev; | 36 | struct dvb_device *dvbdev; |
37 | struct net_device *device[DVB_NET_DEVICES_MAX]; | 37 | struct net_device *device[DVB_NET_DEVICES_MAX]; |
38 | int state[DVB_NET_DEVICES_MAX]; | 38 | int state[DVB_NET_DEVICES_MAX]; |
39 | unsigned int exit:1; | ||
39 | struct dmx_demux *demux; | 40 | struct dmx_demux *demux; |
40 | }; | 41 | }; |
41 | 42 | ||
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 14a372a0fe8b..e23d8a0ea1d3 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -233,6 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | |||
233 | dvbdev->adapter = adap; | 233 | dvbdev->adapter = adap; |
234 | dvbdev->priv = priv; | 234 | dvbdev->priv = priv; |
235 | dvbdev->fops = dvbdevfops; | 235 | dvbdev->fops = dvbdevfops; |
236 | init_waitqueue_head (&dvbdev->wait_queue); | ||
236 | 237 | ||
237 | memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); | 238 | memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); |
238 | dvbdev->fops->owner = adap->module; | 239 | dvbdev->fops->owner = adap->module; |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 620e7887b3d3..6dff10ebf470 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -69,6 +69,7 @@ struct dvb_device { | |||
69 | int writers; | 69 | int writers; |
70 | int users; | 70 | int users; |
71 | 71 | ||
72 | wait_queue_head_t wait_queue; | ||
72 | /* don't really need those !? -- FIXME: use video_usercopy */ | 73 | /* don't really need those !? -- FIXME: use video_usercopy */ |
73 | int (*kernel_ioctl)(struct inode *inode, struct file *file, | 74 | int (*kernel_ioctl)(struct inode *inode, struct file *file, |
74 | unsigned int cmd, void *arg); | 75 | unsigned int cmd, void *arg); |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 80f67a51b908..54488737a08f 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -33,6 +33,7 @@ config DVB_USB_A800 | |||
33 | config DVB_USB_DIBUSB_MB | 33 | config DVB_USB_DIBUSB_MB |
34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" | 34 | tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" |
35 | depends on DVB_USB | 35 | depends on DVB_USB |
36 | select DVB_PLL | ||
36 | select DVB_DIB3000MB | 37 | select DVB_DIB3000MB |
37 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 38 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
38 | help | 39 | help |
@@ -88,6 +89,7 @@ config DVB_USB_DIB0700 | |||
88 | config DVB_USB_UMT_010 | 89 | config DVB_USB_UMT_010 |
89 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" | 90 | tristate "HanfTek UMT-010 DVB-T USB2.0 support" |
90 | depends on DVB_USB | 91 | depends on DVB_USB |
92 | select DVB_PLL | ||
91 | select DVB_DIB3000MC | 93 | select DVB_DIB3000MC |
92 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE | 94 | select DVB_TUNER_MT2060 if !DVB_FE_CUSTOMISE |
93 | help | 95 | help |
@@ -96,9 +98,9 @@ config DVB_USB_UMT_010 | |||
96 | config DVB_USB_CXUSB | 98 | config DVB_USB_CXUSB |
97 | tristate "Conexant USB2.0 hybrid reference design support" | 99 | tristate "Conexant USB2.0 hybrid reference design support" |
98 | depends on DVB_USB | 100 | depends on DVB_USB |
101 | select DVB_PLL | ||
99 | select DVB_CX22702 if !DVB_FE_CUSTOMISE | 102 | select DVB_CX22702 if !DVB_FE_CUSTOMISE |
100 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 103 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
101 | select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE | ||
102 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 104 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
103 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | 105 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE |
104 | help | 106 | help |
@@ -140,6 +142,7 @@ config DVB_USB_AU6610 | |||
140 | config DVB_USB_DIGITV | 142 | config DVB_USB_DIGITV |
141 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" | 143 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" |
142 | depends on DVB_USB | 144 | depends on DVB_USB |
145 | select DVB_PLL | ||
143 | select DVB_NXT6000 if !DVB_FE_CUSTOMISE | 146 | select DVB_NXT6000 if !DVB_FE_CUSTOMISE |
144 | select DVB_MT352 if !DVB_FE_CUSTOMISE | 147 | select DVB_MT352 if !DVB_FE_CUSTOMISE |
145 | help | 148 | help |
@@ -208,3 +211,10 @@ config DVB_USB_DTT200U | |||
208 | The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). | 211 | The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). |
209 | 212 | ||
210 | The WT-220U and its clones are pen-sized. | 213 | The WT-220U and its clones are pen-sized. |
214 | |||
215 | config DVB_USB_OPERA1 | ||
216 | tristate "Opera1 DVB-S USB2.0 receiver" | ||
217 | depends on DVB_USB | ||
218 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
219 | help | ||
220 | Say Y here to support the Opera DVB-S USB2.0 receiver. | ||
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 40f28f559b54..976f840cc904 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -51,4 +51,8 @@ obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o | |||
51 | dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o | 51 | dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o |
52 | obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o | 52 | obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o |
53 | 53 | ||
54 | dvb-usb-opera-objs = opera1.o | ||
55 | obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o | ||
56 | |||
57 | |||
54 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 58 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c index 0dc66a8d2baf..18e0b16fb2a9 100644 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ b/drivers/media/dvb/dvb-usb/au6610.c | |||
@@ -40,7 +40,7 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, | |||
40 | } | 40 | } |
41 | 41 | ||
42 | ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, | 42 | ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, |
43 | USB_TYPE_VENDOR|USB_DIR_IN, addr, index, usb_buf, | 43 | USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf, |
44 | sizeof(usb_buf), AU6610_USB_TIMEOUT); | 44 | sizeof(usb_buf), AU6610_USB_TIMEOUT); |
45 | 45 | ||
46 | if (ret < 0) | 46 | if (ret < 0) |
@@ -124,7 +124,7 @@ static int au6610_identify_state(struct usb_device *udev, | |||
124 | } | 124 | } |
125 | 125 | ||
126 | static struct zl10353_config au6610_zl10353_config = { | 126 | static struct zl10353_config au6610_zl10353_config = { |
127 | .demod_address = 0x1e, | 127 | .demod_address = 0x0f, |
128 | .no_tuner = 1, | 128 | .no_tuner = 1, |
129 | .parallel_ts = 1, | 129 | .parallel_ts = 1, |
130 | }; | 130 | }; |
@@ -140,7 +140,7 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) | |||
140 | } | 140 | } |
141 | 141 | ||
142 | static struct qt1010_config au6610_qt1010_config = { | 142 | static struct qt1010_config au6610_qt1010_config = { |
143 | .i2c_address = 0xc4 | 143 | .i2c_address = 0x62 |
144 | }; | 144 | }; |
145 | 145 | ||
146 | static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) | 146 | static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 127a94b9a1b5..bac2ae3b4a1f 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include "cx22702.h" | 28 | #include "cx22702.h" |
29 | #include "lgdt330x.h" | 29 | #include "lgdt330x.h" |
30 | #include "lgh06xf.h" | ||
31 | #include "mt352.h" | 30 | #include "mt352.h" |
32 | #include "mt352_priv.h" | 31 | #include "mt352_priv.h" |
33 | #include "zl10353.h" | 32 | #include "zl10353.h" |
@@ -388,7 +387,8 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) | |||
388 | 387 | ||
389 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) | 388 | static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) |
390 | { | 389 | { |
391 | dvb_attach(lgh06xf_attach, adap->fe, &adap->dev->i2c_adap); | 390 | dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, |
391 | &dvb_pll_lg_tdvs_h06xf); | ||
392 | return 0; | 392 | return 0; |
393 | } | 393 | } |
394 | 394 | ||
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index 6a4d150784a6..dddf164f269a 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c | |||
@@ -56,10 +56,6 @@ static int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u | |||
56 | if (txlen > 3) | 56 | if (txlen > 3) |
57 | index |= tx[3]; | 57 | index |= tx[3]; |
58 | 58 | ||
59 | /* think about swapping here */ | ||
60 | value = le16_to_cpu(value); | ||
61 | index = le16_to_cpu(index); | ||
62 | |||
63 | status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0], | 59 | status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0], |
64 | USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen, | 60 | USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen, |
65 | USB_CTRL_GET_TIMEOUT); | 61 | USB_CTRL_GET_TIMEOUT); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 148386aba275..97715f7514d6 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define USB_VID_ADSTECH 0x06e1 | 13 | #define USB_VID_ADSTECH 0x06e1 |
14 | #define USB_VID_ALCOR_MICRO 0x058f | 14 | #define USB_VID_ALCOR_MICRO 0x058f |
15 | #define USB_VID_ANCHOR 0x0547 | 15 | #define USB_VID_ANCHOR 0x0547 |
16 | #define USB_VID_ANUBIS_ELECTRONIC 0x10fd | ||
16 | #define USB_VID_AVERMEDIA 0x07ca | 17 | #define USB_VID_AVERMEDIA 0x07ca |
17 | #define USB_VID_COMPRO 0x185b | 18 | #define USB_VID_COMPRO 0x185b |
18 | #define USB_VID_COMPRO_UNK 0x145f | 19 | #define USB_VID_COMPRO_UNK 0x145f |
@@ -31,6 +32,7 @@ | |||
31 | #define USB_VID_LITEON 0x04ca | 32 | #define USB_VID_LITEON 0x04ca |
32 | #define USB_VID_MEDION 0x1660 | 33 | #define USB_VID_MEDION 0x1660 |
33 | #define USB_VID_MSI 0x0db0 | 34 | #define USB_VID_MSI 0x0db0 |
35 | #define USB_VID_OPERA1 0x695c | ||
34 | #define USB_VID_PINNACLE 0x2304 | 36 | #define USB_VID_PINNACLE 0x2304 |
35 | #define USB_VID_VISIONPLUS 0x13d3 | 37 | #define USB_VID_VISIONPLUS 0x13d3 |
36 | #define USB_VID_TWINHAN 0x1822 | 38 | #define USB_VID_TWINHAN 0x1822 |
@@ -127,6 +129,7 @@ | |||
127 | #define USB_PID_KYE_DVB_T_WARM 0x701f | 129 | #define USB_PID_KYE_DVB_T_WARM 0x701f |
128 | #define USB_PID_PCTV_200E 0x020e | 130 | #define USB_PID_PCTV_200E 0x020e |
129 | #define USB_PID_PCTV_400E 0x020f | 131 | #define USB_PID_PCTV_400E 0x020f |
132 | #define USB_PID_PCTV_450E 0x0222 | ||
130 | #define USB_PID_LITEON_DVB_T_COLD 0xf000 | 133 | #define USB_PID_LITEON_DVB_T_COLD 0xf000 |
131 | #define USB_PID_LITEON_DVB_T_WARM 0xf001 | 134 | #define USB_PID_LITEON_DVB_T_WARM 0xf001 |
132 | #define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360 | 135 | #define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360 |
@@ -139,6 +142,9 @@ | |||
139 | #define USB_PID_GENPIX_8PSK_COLD 0x0200 | 142 | #define USB_PID_GENPIX_8PSK_COLD 0x0200 |
140 | #define USB_PID_GENPIX_8PSK_WARM 0x0201 | 143 | #define USB_PID_GENPIX_8PSK_WARM 0x0201 |
141 | #define USB_PID_SIGMATEK_DVB_110 0x6610 | 144 | #define USB_PID_SIGMATEK_DVB_110 0x6610 |
145 | #define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 | ||
146 | #define USB_PID_OPERA1_COLD 0x2830 | ||
147 | #define USB_PID_OPERA1_WARM 0x3829 | ||
142 | 148 | ||
143 | 149 | ||
144 | #endif | 150 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index c9f38a5e70d3..e0587e663591 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include "qt1010.h" | 12 | #include "qt1010.h" |
13 | 13 | ||
14 | /* debug */ | 14 | /* debug */ |
15 | int dvb_usb_gl861_debug; | 15 | static int dvb_usb_gl861_debug; |
16 | module_param_named(debug,dvb_usb_gl861_debug, int, 0644); | 16 | module_param_named(debug,dvb_usb_gl861_debug, int, 0644); |
17 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | 17 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); |
18 | 18 | ||
@@ -20,7 +20,7 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, | |||
20 | u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) | 20 | u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) |
21 | { | 21 | { |
22 | u16 index; | 22 | u16 index; |
23 | u16 value = addr << 8; | 23 | u16 value = addr << (8 + 1); |
24 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ | 24 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ |
25 | u8 req, type; | 25 | u8 req, type; |
26 | 26 | ||
@@ -101,7 +101,7 @@ static int gl861_identify_state(struct usb_device *udev, | |||
101 | } | 101 | } |
102 | 102 | ||
103 | static struct zl10353_config gl861_zl10353_config = { | 103 | static struct zl10353_config gl861_zl10353_config = { |
104 | .demod_address = 0x1e, | 104 | .demod_address = 0x0f, |
105 | .no_tuner = 1, | 105 | .no_tuner = 1, |
106 | .parallel_ts = 1, | 106 | .parallel_ts = 1, |
107 | }; | 107 | }; |
@@ -117,7 +117,7 @@ static int gl861_frontend_attach(struct dvb_usb_adapter *adap) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | static struct qt1010_config gl861_qt1010_config = { | 119 | static struct qt1010_config gl861_qt1010_config = { |
120 | .i2c_address = 0xc4 | 120 | .i2c_address = 0x62 |
121 | }; | 121 | }; |
122 | 122 | ||
123 | static int gl861_tuner_attach(struct dvb_usb_adapter *adap) | 123 | static int gl861_tuner_attach(struct dvb_usb_adapter *adap) |
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index d48b24d9abf4..45d7bc214c18 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include "mt352.h" | 14 | #include "mt352.h" |
15 | #include "mt352_priv.h" | 15 | #include "mt352_priv.h" |
16 | #include "qt1010.h" | 16 | #include "qt1010.h" |
17 | #include "tda1004x.h" | ||
18 | #include "tda827x.h" | ||
17 | 19 | ||
18 | /* debug */ | 20 | /* debug */ |
19 | static int dvb_usb_m920x_debug; | 21 | static int dvb_usb_m920x_debug; |
@@ -47,11 +49,15 @@ static inline int m9206_read(struct usb_device *udev, u8 request, u16 value,\ | |||
47 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | 49 | ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), |
48 | request, USB_TYPE_VENDOR | USB_DIR_IN, | 50 | request, USB_TYPE_VENDOR | USB_DIR_IN, |
49 | value, index, data, size, 2000); | 51 | value, index, data, size, 2000); |
50 | if (ret < 0) | 52 | if (ret < 0) { |
53 | printk(KERN_INFO "m920x_read = error: %d\n", ret); | ||
51 | return ret; | 54 | return ret; |
55 | } | ||
52 | 56 | ||
53 | if (ret != size) | 57 | if (ret != size) { |
58 | deb_rc("m920x_read = no data\n"); | ||
54 | return -EIO; | 59 | return -EIO; |
60 | } | ||
55 | 61 | ||
56 | return 0; | 62 | return 0; |
57 | } | 63 | } |
@@ -64,19 +70,22 @@ static inline int m9206_write(struct usb_device *udev, u8 request, | |||
64 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 70 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
65 | request, USB_TYPE_VENDOR | USB_DIR_OUT, | 71 | request, USB_TYPE_VENDOR | USB_DIR_OUT, |
66 | value, index, NULL, 0, 2000); | 72 | value, index, NULL, 0, 2000); |
73 | |||
67 | return ret; | 74 | return ret; |
68 | } | 75 | } |
69 | 76 | ||
70 | static int m9206_rc_init(struct usb_device *udev) | 77 | static int m9206_init(struct dvb_usb_device *d) |
71 | { | 78 | { |
72 | int ret = 0; | 79 | int ret = 0; |
73 | 80 | ||
74 | /* Remote controller init. */ | 81 | /* Remote controller init. */ |
75 | if ((ret = m9206_write(udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0) | 82 | if (d->props.rc_query) { |
76 | return ret; | 83 | if ((ret = m9206_write(d->udev, M9206_CORE, 0xa8, M9206_RC_INIT2)) != 0) |
84 | return ret; | ||
77 | 85 | ||
78 | if ((ret = m9206_write(udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0) | 86 | if ((ret = m9206_write(d->udev, M9206_CORE, 0x51, M9206_RC_INIT1)) != 0) |
79 | return ret; | 87 | return ret; |
88 | } | ||
80 | 89 | ||
81 | return ret; | 90 | return ret; |
82 | } | 91 | } |
@@ -87,16 +96,15 @@ static int m9206_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
87 | int i, ret = 0; | 96 | int i, ret = 0; |
88 | u8 rc_state[2]; | 97 | u8 rc_state[2]; |
89 | 98 | ||
90 | |||
91 | if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) | 99 | if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) |
92 | goto unlock; | 100 | goto unlock; |
93 | 101 | ||
94 | if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) | 102 | if ((ret = m9206_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) |
95 | goto unlock; | 103 | goto unlock; |
96 | 104 | ||
97 | for (i = 0; i < ARRAY_SIZE(megasky_rc_keys); i++) | 105 | for (i = 0; i < d->props.rc_key_map_size; i++) |
98 | if (megasky_rc_keys[i].data == rc_state[1]) { | 106 | if (d->props.rc_key_map[i].data == rc_state[1]) { |
99 | *event = megasky_rc_keys[i].event; | 107 | *event = d->props.rc_key_map[i].event; |
100 | 108 | ||
101 | switch(rc_state[0]) { | 109 | switch(rc_state[0]) { |
102 | case 0x80: | 110 | case 0x80: |
@@ -137,53 +145,51 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
137 | int num) | 145 | int num) |
138 | { | 146 | { |
139 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 147 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
140 | struct m9206_state *m = d->priv; | 148 | int i, j; |
141 | int i; | ||
142 | int ret = 0; | 149 | int ret = 0; |
143 | 150 | ||
151 | if (!num) | ||
152 | return -EINVAL; | ||
153 | |||
144 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 154 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
145 | return -EAGAIN; | 155 | return -EAGAIN; |
146 | 156 | ||
147 | if (num > 2) | ||
148 | return -EINVAL; | ||
149 | |||
150 | for (i = 0; i < num; i++) { | 157 | for (i = 0; i < num; i++) { |
151 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0) | 158 | if (msg[i].flags & (I2C_M_NO_RD_ACK|I2C_M_IGNORE_NAK|I2C_M_TEN) || |
152 | goto unlock; | 159 | msg[i].len == 0) { |
153 | 160 | /* For a 0 byte message, I think sending the address to index 0x80|0x40 | |
154 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[0], 0x0)) != 0) | 161 | * would be the correct thing to do. However, zero byte messages are |
162 | * only used for probing, and since we don't know how to get the slave's | ||
163 | * ack, we can't probe. */ | ||
164 | ret = -ENOTSUPP; | ||
155 | goto unlock; | 165 | goto unlock; |
156 | 166 | } | |
157 | if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { | 167 | /* Send START & address/RW bit */ |
158 | int i2c_i; | 168 | if (!(msg[i].flags & I2C_M_NOSTART)) { |
159 | 169 | if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), 0x80)) != 0) | |
160 | for (i2c_i = 0; i2c_i < M9206_I2C_MAX; i2c_i++) | ||
161 | if (msg[i].addr == m->i2c_r[i2c_i].addr) | ||
162 | break; | ||
163 | |||
164 | if (i2c_i >= M9206_I2C_MAX) { | ||
165 | deb_rc("No magic for i2c addr!\n"); | ||
166 | ret = -EINVAL; | ||
167 | goto unlock; | 170 | goto unlock; |
171 | /* Should check for ack here, if we knew how. */ | ||
172 | } | ||
173 | if (msg[i].flags & I2C_M_RD) { | ||
174 | for (j = 0; j < msg[i].len; j++) { | ||
175 | /* Last byte of transaction? Send STOP, otherwise send ACK. */ | ||
176 | int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x01; | ||
177 | if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x20|stop, &msg[i].buf[j], 1)) != 0) | ||
178 | goto unlock; | ||
168 | } | 179 | } |
169 | |||
170 | if ((ret = m9206_write(d->udev, M9206_I2C, m->i2c_r[i2c_i].magic, 0x80)) != 0) | ||
171 | goto unlock; | ||
172 | |||
173 | if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) | ||
174 | goto unlock; | ||
175 | |||
176 | i++; | ||
177 | } else { | 180 | } else { |
178 | if (msg[i].len != 2) | 181 | for (j = 0; j < msg[i].len; j++) { |
179 | return -EINVAL; | 182 | /* Last byte of transaction? Then send STOP. */ |
180 | 183 | int stop = (i+1 == num && j+1 == msg[i].len)?0x40:0x00; | |
181 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[1], 0x40)) != 0) | 184 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0) |
182 | goto unlock; | 185 | goto unlock; |
186 | /* Should check for ack here too. */ | ||
187 | } | ||
183 | } | 188 | } |
184 | } | 189 | } |
185 | ret = i; | 190 | ret = num; |
186 | unlock: | 191 | |
192 | unlock: | ||
187 | mutex_unlock(&d->i2c_mutex); | 193 | mutex_unlock(&d->i2c_mutex); |
188 | 194 | ||
189 | return ret; | 195 | return ret; |
@@ -324,6 +330,7 @@ static int m9206_firmware_download(struct usb_device *udev, | |||
324 | i += size; | 330 | i += size; |
325 | } | 331 | } |
326 | if (i != fw->size) { | 332 | if (i != fw->size) { |
333 | deb_rc("bad firmware file!\n"); | ||
327 | ret = -EINVAL; | 334 | ret = -EINVAL; |
328 | goto done; | 335 | goto done; |
329 | } | 336 | } |
@@ -342,10 +349,10 @@ static int m9206_firmware_download(struct usb_device *udev, | |||
342 | } | 349 | } |
343 | 350 | ||
344 | /* Callbacks for DVB USB */ | 351 | /* Callbacks for DVB USB */ |
345 | static int megasky_identify_state(struct usb_device *udev, | 352 | static int m920x_identify_state(struct usb_device *udev, |
346 | struct dvb_usb_device_properties *props, | 353 | struct dvb_usb_device_properties *props, |
347 | struct dvb_usb_device_description **desc, | 354 | struct dvb_usb_device_description **desc, |
348 | int *cold) | 355 | int *cold) |
349 | { | 356 | { |
350 | struct usb_host_interface *alt; | 357 | struct usb_host_interface *alt; |
351 | 358 | ||
@@ -381,20 +388,15 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) | |||
381 | } | 388 | } |
382 | 389 | ||
383 | static struct mt352_config megasky_mt352_config = { | 390 | static struct mt352_config megasky_mt352_config = { |
384 | .demod_address = 0x1e, | 391 | .demod_address = 0x0f, |
385 | .no_tuner = 1, | 392 | .no_tuner = 1, |
386 | .demod_init = megasky_mt352_demod_init, | 393 | .demod_init = megasky_mt352_demod_init, |
387 | }; | 394 | }; |
388 | 395 | ||
389 | static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) | 396 | static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) |
390 | { | 397 | { |
391 | struct m9206_state *m = adap->dev->priv; | ||
392 | |||
393 | deb_rc("megasky_frontend_attach!\n"); | 398 | deb_rc("megasky_frontend_attach!\n"); |
394 | 399 | ||
395 | m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address; | ||
396 | m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f; | ||
397 | |||
398 | if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) | 400 | if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) |
399 | return -EIO; | 401 | return -EIO; |
400 | 402 | ||
@@ -402,16 +404,11 @@ static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) | |||
402 | } | 404 | } |
403 | 405 | ||
404 | static struct qt1010_config megasky_qt1010_config = { | 406 | static struct qt1010_config megasky_qt1010_config = { |
405 | .i2c_address = 0xc4 | 407 | .i2c_address = 0x62 |
406 | }; | 408 | }; |
407 | 409 | ||
408 | static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) | 410 | static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) |
409 | { | 411 | { |
410 | struct m9206_state *m = adap->dev->priv; | ||
411 | |||
412 | m->i2c_r[M9206_I2C_TUNER].addr = megasky_qt1010_config.i2c_address; | ||
413 | m->i2c_r[M9206_I2C_TUNER].magic = 0xc5; | ||
414 | |||
415 | if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, | 412 | if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, |
416 | &megasky_qt1010_config) == NULL) | 413 | &megasky_qt1010_config) == NULL) |
417 | return -ENODEV; | 414 | return -ENODEV; |
@@ -419,8 +416,40 @@ static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) | |||
419 | return 0; | 416 | return 0; |
420 | } | 417 | } |
421 | 418 | ||
419 | static struct tda1004x_config digivox_tda10046_config = { | ||
420 | .demod_address = 0x08, | ||
421 | .invert = 0, | ||
422 | .invert_oclk = 0, | ||
423 | .ts_mode = TDA10046_TS_SERIAL, | ||
424 | .xtal_freq = TDA10046_XTAL_16M, | ||
425 | .if_freq = TDA10046_FREQ_045, | ||
426 | .agc_config = TDA10046_AGC_TDA827X, | ||
427 | .gpio_config = TDA10046_GPTRI, | ||
428 | .request_firmware = NULL, | ||
429 | }; | ||
430 | |||
431 | static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap) | ||
432 | { | ||
433 | deb_rc("digivox_tda10046_frontend_attach!\n"); | ||
434 | |||
435 | if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config, | ||
436 | &adap->dev->i2c_adap)) == NULL) | ||
437 | return -EIO; | ||
438 | |||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap) | ||
443 | { | ||
444 | if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, | ||
445 | NULL) == NULL) | ||
446 | return -ENODEV; | ||
447 | return 0; | ||
448 | } | ||
449 | |||
422 | /* DVB USB Driver stuff */ | 450 | /* DVB USB Driver stuff */ |
423 | static struct dvb_usb_device_properties megasky_properties; | 451 | static struct dvb_usb_device_properties megasky_properties; |
452 | static struct dvb_usb_device_properties digivox_mini_ii_properties; | ||
424 | 453 | ||
425 | static int m920x_probe(struct usb_interface *intf, | 454 | static int m920x_probe(struct usb_interface *intf, |
426 | const struct usb_device_id *id) | 455 | const struct usb_device_id *id) |
@@ -429,30 +458,36 @@ static int m920x_probe(struct usb_interface *intf, | |||
429 | struct usb_host_interface *alt; | 458 | struct usb_host_interface *alt; |
430 | int ret; | 459 | int ret; |
431 | 460 | ||
432 | if ((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) { | 461 | deb_rc("Probed!\n"); |
433 | deb_rc("probed!\n"); | ||
434 | 462 | ||
435 | alt = usb_altnum_to_altsetting(intf, 1); | 463 | if (((ret = dvb_usb_device_init(intf, &megasky_properties, THIS_MODULE, &d)) == 0) || |
436 | if (alt == NULL) { | 464 | ((ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, THIS_MODULE, &d)) == 0)) |
437 | deb_rc("not alt found!\n"); | 465 | goto found; |
438 | return -ENODEV; | ||
439 | } | ||
440 | 466 | ||
441 | ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, | 467 | return ret; |
442 | alt->desc.bAlternateSetting); | ||
443 | if (ret < 0) | ||
444 | return ret; | ||
445 | |||
446 | deb_rc("Changed to alternate setting!\n"); | ||
447 | 468 | ||
448 | if ((ret = m9206_rc_init(d->udev)) != 0) | 469 | found: |
449 | return ret; | 470 | alt = usb_altnum_to_altsetting(intf, 1); |
471 | if (alt == NULL) { | ||
472 | deb_rc("No alt found!\n"); | ||
473 | return -ENODEV; | ||
450 | } | 474 | } |
475 | |||
476 | ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, | ||
477 | alt->desc.bAlternateSetting); | ||
478 | if (ret < 0) | ||
479 | return ret; | ||
480 | |||
481 | if ((ret = m9206_init(d)) != 0) | ||
482 | return ret; | ||
483 | |||
451 | return ret; | 484 | return ret; |
452 | } | 485 | } |
453 | 486 | ||
454 | static struct usb_device_id m920x_table [] = { | 487 | static struct usb_device_id m920x_table [] = { |
455 | { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, | 488 | { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, |
489 | { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, | ||
490 | USB_PID_MSI_DIGI_VOX_MINI_II) }, | ||
456 | { } /* Terminating entry */ | 491 | { } /* Terminating entry */ |
457 | }; | 492 | }; |
458 | MODULE_DEVICE_TABLE (usb, m920x_table); | 493 | MODULE_DEVICE_TABLE (usb, m920x_table); |
@@ -471,7 +506,7 @@ static struct dvb_usb_device_properties megasky_properties = { | |||
471 | 506 | ||
472 | .size_of_priv = sizeof(struct m9206_state), | 507 | .size_of_priv = sizeof(struct m9206_state), |
473 | 508 | ||
474 | .identify_state = megasky_identify_state, | 509 | .identify_state = m920x_identify_state, |
475 | .num_adapters = 1, | 510 | .num_adapters = 1, |
476 | .adapter = {{ | 511 | .adapter = {{ |
477 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | 512 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | |
@@ -502,6 +537,50 @@ static struct dvb_usb_device_properties megasky_properties = { | |||
502 | { "MSI Mega Sky 580 DVB-T USB2.0", | 537 | { "MSI Mega Sky 580 DVB-T USB2.0", |
503 | { &m920x_table[0], NULL }, | 538 | { &m920x_table[0], NULL }, |
504 | { NULL }, | 539 | { NULL }, |
540 | } | ||
541 | } | ||
542 | }; | ||
543 | |||
544 | static struct dvb_usb_device_properties digivox_mini_ii_properties = { | ||
545 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
546 | |||
547 | .usb_ctrl = DEVICE_SPECIFIC, | ||
548 | .firmware = "dvb-usb-digivox-02.fw", | ||
549 | .download_firmware = m9206_firmware_download, | ||
550 | |||
551 | .size_of_priv = sizeof(struct m9206_state), | ||
552 | |||
553 | .identify_state = m920x_identify_state, | ||
554 | .num_adapters = 1, | ||
555 | .adapter = {{ | ||
556 | .caps = DVB_USB_ADAP_HAS_PID_FILTER | | ||
557 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
558 | |||
559 | .pid_filter_count = 8, | ||
560 | .pid_filter = m9206_pid_filter, | ||
561 | .pid_filter_ctrl = m9206_pid_filter_ctrl, | ||
562 | |||
563 | .frontend_attach = digivox_tda10046_frontend_attach, | ||
564 | .tuner_attach = digivox_tda8275_tuner_attach, | ||
565 | |||
566 | .stream = { | ||
567 | .type = USB_BULK, | ||
568 | .count = 8, | ||
569 | .endpoint = 0x81, | ||
570 | .u = { | ||
571 | .bulk = { | ||
572 | .buffersize = 0x4000, | ||
573 | } | ||
574 | } | ||
575 | }, | ||
576 | }}, | ||
577 | .i2c_algo = &m9206_i2c_algo, | ||
578 | |||
579 | .num_device_descs = 1, | ||
580 | .devices = { | ||
581 | { "MSI DIGI VOX mini II DVB-T USB2.0", | ||
582 | { &m920x_table[1], NULL }, | ||
583 | { NULL }, | ||
505 | }, | 584 | }, |
506 | } | 585 | } |
507 | }; | 586 | }; |
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h index c354196ffe5d..7dd3db65c80e 100644 --- a/drivers/media/dvb/dvb-usb/m920x.h +++ b/drivers/media/dvb/dvb-usb/m920x.h | |||
@@ -19,17 +19,49 @@ | |||
19 | 19 | ||
20 | #define M9206_MAX_FILTERS 8 | 20 | #define M9206_MAX_FILTERS 8 |
21 | 21 | ||
22 | #define M9206_I2C_TUNER 0 | 22 | /* |
23 | #define M9206_I2C_DEMOD 1 | 23 | sequences found in logs: |
24 | #define M9206_I2C_MAX 2 | 24 | [index value] |
25 | 0x80 write addr | ||
26 | (0x00 out byte)* | ||
27 | 0x40 out byte | ||
28 | |||
29 | 0x80 write addr | ||
30 | (0x00 out byte)* | ||
31 | 0x80 read addr | ||
32 | (0x21 in byte)* | ||
33 | 0x60 in byte | ||
34 | |||
35 | this sequence works: | ||
36 | 0x80 read addr | ||
37 | (0x21 in byte)* | ||
38 | 0x60 in byte | ||
39 | |||
40 | Guess at API of the I2C function: | ||
41 | I2C operation is done one byte at a time with USB control messages. The | ||
42 | index the messages is sent to is made up of a set of flags that control | ||
43 | the I2C bus state: | ||
44 | 0x80: Send START condition. After a START condition, one would normally | ||
45 | always send the 7-bit slave I2C address as the 7 MSB, followed by | ||
46 | the read/write bit as the LSB. | ||
47 | 0x40: Send STOP condition. This should be set on the last byte of an | ||
48 | I2C transaction. | ||
49 | 0x20: Read a byte from the slave. As opposed to writing a byte to the | ||
50 | slave. The slave will normally not produce any data unless you | ||
51 | set the R/W bit to 1 when sending the slave's address after the | ||
52 | START condition. | ||
53 | 0x01: Respond with ACK, as opposed to a NACK. For a multi-byte read, | ||
54 | the master should send an ACK, that is pull SDA low during the 9th | ||
55 | clock cycle, after every byte but the last. This flags only makes | ||
56 | sense when bit 0x20 is set, indicating a read. | ||
57 | |||
58 | What any other bits might mean, or how to get the slave's ACK/NACK | ||
59 | response to a write, is unknown. | ||
60 | */ | ||
25 | 61 | ||
26 | struct m9206_state { | 62 | struct m9206_state { |
27 | u16 filters[M9206_MAX_FILTERS]; | 63 | u16 filters[M9206_MAX_FILTERS]; |
28 | int filtering_enabled; | 64 | int filtering_enabled; |
29 | int rep_count; | 65 | int rep_count; |
30 | struct { | ||
31 | unsigned char addr; | ||
32 | unsigned char magic; | ||
33 | }i2c_r[M9206_I2C_MAX]; | ||
34 | }; | 66 | }; |
35 | #endif | 67 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c new file mode 100644 index 000000000000..518d7ad217df --- /dev/null +++ b/drivers/media/dvb/dvb-usb/opera1.c | |||
@@ -0,0 +1,581 @@ | |||
1 | /* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card | ||
2 | * | ||
3 | * Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org) | ||
4 | * Copyright (C) 2006 Marco Gittler (g.marco@freenet.de) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation, version 2. | ||
9 | * | ||
10 | * see Documentation/dvb/README.dvb-usb for more information | ||
11 | */ | ||
12 | |||
13 | #include "opera1.h" | ||
14 | #include "stv0299.h" | ||
15 | |||
16 | #define OPERA_READ_MSG 0 | ||
17 | #define OPERA_WRITE_MSG 1 | ||
18 | #define OPERA_I2C_TUNER 0xd1 | ||
19 | |||
20 | #define READ_FX2_REG_REQ 0xba | ||
21 | #define READ_MAC_ADDR 0x08 | ||
22 | #define OPERA_WRITE_FX2 0xbb | ||
23 | #define OPERA_TUNER_REQ 0xb1 | ||
24 | #define REG_1F_SYMBOLRATE_BYTE0 0x1f | ||
25 | #define REG_20_SYMBOLRATE_BYTE1 0x20 | ||
26 | #define REG_21_SYMBOLRATE_BYTE2 0x21 | ||
27 | |||
28 | #define ADDR_B600_VOLTAGE_13V (0x02) | ||
29 | #define ADDR_B601_VOLTAGE_18V (0x03) | ||
30 | #define ADDR_B1A6_STREAM_CTRL (0x04) | ||
31 | #define ADDR_B880_READ_REMOTE (0x05) | ||
32 | |||
33 | struct opera1_state { | ||
34 | u32 last_key_pressed; | ||
35 | }; | ||
36 | struct opera_rc_keys { | ||
37 | u32 keycode; | ||
38 | u32 event; | ||
39 | }; | ||
40 | |||
41 | int dvb_usb_opera1_debug; | ||
42 | module_param_named(debug, dvb_usb_opera1_debug, int, 0644); | ||
43 | MODULE_PARM_DESC(debug, | ||
44 | "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." | ||
45 | DVB_USB_DEBUG_STATUS); | ||
46 | |||
47 | static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value, | ||
48 | u8 * data, u16 len, int flags) | ||
49 | { | ||
50 | int ret; | ||
51 | u8 r; | ||
52 | u8 u8buf[len]; | ||
53 | |||
54 | unsigned int pipe = (flags == OPERA_READ_MSG) ? | ||
55 | usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0); | ||
56 | u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; | ||
57 | |||
58 | if (flags == OPERA_WRITE_MSG) | ||
59 | memcpy(u8buf, data, len); | ||
60 | ret = | ||
61 | usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, | ||
62 | value, 0x0, u8buf, len, 2000); | ||
63 | |||
64 | if (request == OPERA_TUNER_REQ) { | ||
65 | if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
66 | OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR, | ||
67 | 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08) | ||
68 | return 0; | ||
69 | } | ||
70 | if (flags == OPERA_READ_MSG) | ||
71 | memcpy(data, u8buf, len); | ||
72 | return ret; | ||
73 | } | ||
74 | |||
75 | /* I2C */ | ||
76 | |||
77 | static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr, | ||
78 | u8 * buf, u16 len) | ||
79 | { | ||
80 | int ret = 0; | ||
81 | u8 request; | ||
82 | u16 value; | ||
83 | |||
84 | if (!dev) { | ||
85 | info("no usb_device"); | ||
86 | return -EINVAL; | ||
87 | } | ||
88 | if (mutex_lock_interruptible(&dev->usb_mutex) < 0) | ||
89 | return -EAGAIN; | ||
90 | |||
91 | switch (addr>>1){ | ||
92 | case ADDR_B600_VOLTAGE_13V: | ||
93 | request=0xb6; | ||
94 | value=0x00; | ||
95 | break; | ||
96 | case ADDR_B601_VOLTAGE_18V: | ||
97 | request=0xb6; | ||
98 | value=0x01; | ||
99 | break; | ||
100 | case ADDR_B1A6_STREAM_CTRL: | ||
101 | request=0xb1; | ||
102 | value=0xa6; | ||
103 | break; | ||
104 | case ADDR_B880_READ_REMOTE: | ||
105 | request=0xb8; | ||
106 | value=0x80; | ||
107 | break; | ||
108 | default: | ||
109 | request=0xb1; | ||
110 | value=addr; | ||
111 | } | ||
112 | ret = opera1_xilinx_rw(dev->udev, request, | ||
113 | value, buf, len, | ||
114 | addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG); | ||
115 | |||
116 | mutex_unlock(&dev->usb_mutex); | ||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||
121 | int num) | ||
122 | { | ||
123 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||
124 | int i = 0, tmp = 0; | ||
125 | |||
126 | if (!d) | ||
127 | return -ENODEV; | ||
128 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||
129 | return -EAGAIN; | ||
130 | |||
131 | for (i = 0; i < num; i++) { | ||
132 | if ((tmp = opera1_usb_i2c_msgxfer(d, | ||
133 | (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), | ||
134 | msg[i].buf, | ||
135 | msg[i].len | ||
136 | )!= msg[i].len)) { | ||
137 | break; | ||
138 | } | ||
139 | if (dvb_usb_opera1_debug & 0x10) | ||
140 | info("sending i2c mesage %d %d", tmp, msg[i].len); | ||
141 | } | ||
142 | mutex_unlock(&d->i2c_mutex); | ||
143 | return num; | ||
144 | } | ||
145 | |||
146 | static u32 opera1_i2c_func(struct i2c_adapter *adapter) | ||
147 | { | ||
148 | return I2C_FUNC_I2C; | ||
149 | } | ||
150 | |||
151 | static struct i2c_algorithm opera1_i2c_algo = { | ||
152 | .master_xfer = opera1_i2c_xfer, | ||
153 | .functionality = opera1_i2c_func, | ||
154 | }; | ||
155 | |||
156 | static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
157 | { | ||
158 | static u8 command_13v[1]={0x00}; | ||
159 | static u8 command_18v[1]={0x01}; | ||
160 | struct i2c_msg msg[] = { | ||
161 | {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1}, | ||
162 | }; | ||
163 | struct dvb_usb_adapter *udev_adap = | ||
164 | (struct dvb_usb_adapter *)(fe->dvb->priv); | ||
165 | if (voltage == SEC_VOLTAGE_18) { | ||
166 | msg[0].addr = ADDR_B601_VOLTAGE_18V; | ||
167 | msg[0].buf = command_18v; | ||
168 | } | ||
169 | i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); | ||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, | ||
174 | u32 ratio) | ||
175 | { | ||
176 | stv0299_writereg(fe, 0x13, 0x98); | ||
177 | stv0299_writereg(fe, 0x14, 0x95); | ||
178 | stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff); | ||
179 | stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff); | ||
180 | stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0); | ||
181 | return 0; | ||
182 | |||
183 | } | ||
184 | static u8 opera1_inittab[] = { | ||
185 | 0x00, 0xa1, | ||
186 | 0x01, 0x15, | ||
187 | 0x02, 0x00, | ||
188 | 0x03, 0x00, | ||
189 | 0x04, 0x7d, | ||
190 | 0x05, 0x05, | ||
191 | 0x06, 0x02, | ||
192 | 0x07, 0x00, | ||
193 | 0x0b, 0x00, | ||
194 | 0x0c, 0x01, | ||
195 | 0x0d, 0x81, | ||
196 | 0x0e, 0x44, | ||
197 | 0x0f, 0x19, | ||
198 | 0x10, 0x3f, | ||
199 | 0x11, 0x84, | ||
200 | 0x12, 0xda, | ||
201 | 0x13, 0x98, | ||
202 | 0x14, 0x95, | ||
203 | 0x15, 0xc9, | ||
204 | 0x16, 0xeb, | ||
205 | 0x17, 0x00, | ||
206 | 0x18, 0x19, | ||
207 | 0x19, 0x8b, | ||
208 | 0x1a, 0x00, | ||
209 | 0x1b, 0x82, | ||
210 | 0x1c, 0x7f, | ||
211 | 0x1d, 0x00, | ||
212 | 0x1e, 0x00, | ||
213 | REG_1F_SYMBOLRATE_BYTE0, 0x06, | ||
214 | REG_20_SYMBOLRATE_BYTE1, 0x50, | ||
215 | REG_21_SYMBOLRATE_BYTE2, 0x10, | ||
216 | 0x22, 0x00, | ||
217 | 0x23, 0x00, | ||
218 | 0x24, 0x37, | ||
219 | 0x25, 0xbc, | ||
220 | 0x26, 0x00, | ||
221 | 0x27, 0x00, | ||
222 | 0x28, 0x00, | ||
223 | 0x29, 0x1e, | ||
224 | 0x2a, 0x14, | ||
225 | 0x2b, 0x1f, | ||
226 | 0x2c, 0x09, | ||
227 | 0x2d, 0x0a, | ||
228 | 0x2e, 0x00, | ||
229 | 0x2f, 0x00, | ||
230 | 0x30, 0x00, | ||
231 | 0x31, 0x1f, | ||
232 | 0x32, 0x19, | ||
233 | 0x33, 0xfc, | ||
234 | 0x34, 0x13, | ||
235 | 0xff, 0xff, | ||
236 | }; | ||
237 | |||
238 | static struct stv0299_config opera1_stv0299_config = { | ||
239 | .demod_address = 0xd0>>1, | ||
240 | .min_delay_ms = 100, | ||
241 | .mclk = 88000000UL, | ||
242 | .invert = 1, | ||
243 | .skip_reinit = 0, | ||
244 | .lock_output = STV0229_LOCKOUTPUT_0, | ||
245 | .volt13_op0_op1 = STV0299_VOLT13_OP0, | ||
246 | .inittab = opera1_inittab, | ||
247 | .set_symbol_rate = opera1_stv0299_set_symbol_rate, | ||
248 | }; | ||
249 | |||
250 | static int opera1_frontend_attach(struct dvb_usb_adapter *d) | ||
251 | { | ||
252 | if ((d->fe = | ||
253 | dvb_attach(stv0299_attach, &opera1_stv0299_config, | ||
254 | &d->dev->i2c_adap)) != NULL) { | ||
255 | d->fe->ops.set_voltage = opera1_set_voltage; | ||
256 | return 0; | ||
257 | } | ||
258 | info("not attached stv0299"); | ||
259 | return -EIO; | ||
260 | } | ||
261 | |||
262 | static int opera1_tuner_attach(struct dvb_usb_adapter *adap) | ||
263 | { | ||
264 | dvb_attach( | ||
265 | dvb_pll_attach, adap->fe, 0xc0>>1, | ||
266 | &adap->dev->i2c_adap, &dvb_pll_opera1 | ||
267 | ); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
272 | { | ||
273 | u8 val = onoff ? 0x01 : 0x00; | ||
274 | |||
275 | if (dvb_usb_opera1_debug) | ||
276 | info("power %s", onoff ? "on" : "off"); | ||
277 | return opera1_xilinx_rw(d->udev, 0xb7, val, | ||
278 | &val, 1, OPERA_WRITE_MSG); | ||
279 | } | ||
280 | |||
281 | static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
282 | { | ||
283 | static u8 buf_start[2] = { 0xff, 0x03 }; | ||
284 | static u8 buf_stop[2] = { 0xff, 0x00 }; | ||
285 | struct i2c_msg start_tuner[] = { | ||
286 | {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2}, | ||
287 | }; | ||
288 | if (dvb_usb_opera1_debug) | ||
289 | info("streaming %s", onoff ? "on" : "off"); | ||
290 | i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, | ||
295 | int onoff) | ||
296 | { | ||
297 | u8 b_pid[3]; | ||
298 | struct i2c_msg msg[] = { | ||
299 | {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3}, | ||
300 | }; | ||
301 | if (dvb_usb_opera1_debug) | ||
302 | info("pidfilter index: %d pid: %d %s", index, pid, | ||
303 | onoff ? "on" : "off"); | ||
304 | b_pid[0] = (2 * index) + 4; | ||
305 | b_pid[1] = onoff ? (pid & 0xff) : (0x00); | ||
306 | b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00); | ||
307 | i2c_transfer(&adap->dev->i2c_adap, msg, 1); | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) | ||
312 | { | ||
313 | int u = 0x04; | ||
314 | u8 b_pid[3]; | ||
315 | struct i2c_msg msg[] = { | ||
316 | {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3}, | ||
317 | }; | ||
318 | if (dvb_usb_opera1_debug) | ||
319 | info("%s hw-pidfilter", onoff ? "enable" : "disable"); | ||
320 | for (; u < 0x7e; u += 2) { | ||
321 | b_pid[0] = u; | ||
322 | b_pid[1] = 0; | ||
323 | b_pid[2] = 0x80; | ||
324 | i2c_transfer(&adap->dev->i2c_adap, msg, 1); | ||
325 | } | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static struct dvb_usb_rc_key opera1_rc_keys[] = { | ||
330 | {0x5f, 0xa0, KEY_1}, | ||
331 | {0x51, 0xaf, KEY_2}, | ||
332 | {0x5d, 0xa2, KEY_3}, | ||
333 | {0x41, 0xbe, KEY_4}, | ||
334 | {0x0b, 0xf5, KEY_5}, | ||
335 | {0x43, 0xbd, KEY_6}, | ||
336 | {0x47, 0xb8, KEY_7}, | ||
337 | {0x49, 0xb6, KEY_8}, | ||
338 | {0x05, 0xfa, KEY_9}, | ||
339 | {0x45, 0xba, KEY_0}, | ||
340 | {0x09, 0xf6, KEY_UP}, /*chanup */ | ||
341 | {0x1b, 0xe5, KEY_DOWN}, /*chandown */ | ||
342 | {0x5d, 0xa3, KEY_LEFT}, /*voldown */ | ||
343 | {0x5f, 0xa1, KEY_RIGHT}, /*volup */ | ||
344 | {0x07, 0xf8, KEY_SPACE}, /*tab */ | ||
345 | {0x1f, 0xe1, KEY_ENTER}, /*play ok */ | ||
346 | {0x1b, 0xe4, KEY_Z}, /*zoom */ | ||
347 | {0x59, 0xa6, KEY_M}, /*mute */ | ||
348 | {0x5b, 0xa5, KEY_F}, /*tv/f */ | ||
349 | {0x19, 0xe7, KEY_R}, /*rec */ | ||
350 | {0x01, 0xfe, KEY_S}, /*Stop */ | ||
351 | {0x03, 0xfd, KEY_P}, /*pause */ | ||
352 | {0x03, 0xfc, KEY_W}, /*<- -> */ | ||
353 | {0x07, 0xf9, KEY_C}, /*capture */ | ||
354 | {0x47, 0xb9, KEY_Q}, /*exit */ | ||
355 | {0x43, 0xbc, KEY_O}, /*power */ | ||
356 | |||
357 | }; | ||
358 | |||
359 | static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) | ||
360 | { | ||
361 | struct opera1_state *opst = dev->priv; | ||
362 | u8 rcbuffer[32]; | ||
363 | const u16 startmarker1 = 0x10ed; | ||
364 | const u16 startmarker2 = 0x11ec; | ||
365 | struct i2c_msg read_remote[] = { | ||
366 | {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32}, | ||
367 | }; | ||
368 | int i = 0; | ||
369 | u32 send_key = 0; | ||
370 | |||
371 | if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) { | ||
372 | for (i = 0; i < 32; i++) { | ||
373 | if (rcbuffer[i]) | ||
374 | send_key |= 1; | ||
375 | if (i < 31) | ||
376 | send_key = send_key << 1; | ||
377 | } | ||
378 | if (send_key & 0x8000) | ||
379 | send_key = (send_key << 1) | (send_key >> 15 & 0x01); | ||
380 | |||
381 | if (send_key == 0xffff && opst->last_key_pressed != 0) { | ||
382 | *state = REMOTE_KEY_REPEAT; | ||
383 | *event = opst->last_key_pressed; | ||
384 | return 0; | ||
385 | } | ||
386 | for (; send_key != 0;) { | ||
387 | if (send_key >> 16 == startmarker2) { | ||
388 | break; | ||
389 | } else if (send_key >> 16 == startmarker1) { | ||
390 | send_key = | ||
391 | (send_key & 0xfffeffff) | (startmarker1 << 16); | ||
392 | break; | ||
393 | } else | ||
394 | send_key >>= 1; | ||
395 | } | ||
396 | |||
397 | if (send_key == 0) | ||
398 | return 0; | ||
399 | |||
400 | send_key = (send_key & 0xffff) | 0x0100; | ||
401 | |||
402 | for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) { | ||
403 | if ((opera1_rc_keys[i].custom * 256 + | ||
404 | opera1_rc_keys[i].data) == (send_key & 0xffff)) { | ||
405 | *state = REMOTE_KEY_PRESSED; | ||
406 | *event = opera1_rc_keys[i].event; | ||
407 | opst->last_key_pressed = | ||
408 | opera1_rc_keys[i].event; | ||
409 | break; | ||
410 | } | ||
411 | opst->last_key_pressed = 0; | ||
412 | } | ||
413 | } else | ||
414 | *state = REMOTE_NO_KEY_PRESSED; | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static struct usb_device_id opera1_table[] = { | ||
419 | {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)}, | ||
420 | {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)}, | ||
421 | {} | ||
422 | }; | ||
423 | |||
424 | MODULE_DEVICE_TABLE(usb, opera1_table); | ||
425 | |||
426 | static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||
427 | { | ||
428 | u8 command[] = { READ_MAC_ADDR }; | ||
429 | opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG); | ||
430 | opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG); | ||
431 | return 0; | ||
432 | } | ||
433 | static int opera1_xilinx_load_firmware(struct usb_device *dev, | ||
434 | const char *filename) | ||
435 | { | ||
436 | const struct firmware *fw = NULL; | ||
437 | u8 *b, *p; | ||
438 | int ret = 0, i; | ||
439 | u8 testval; | ||
440 | info("start downloading fpga firmware"); | ||
441 | |||
442 | if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { | ||
443 | err("did not find the firmware file. (%s) " | ||
444 | "Please see linux/Documentation/dvb/ for more details on firmware-problems.", | ||
445 | filename); | ||
446 | return ret; | ||
447 | } else { | ||
448 | p = kmalloc(fw->size, GFP_KERNEL); | ||
449 | opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG); | ||
450 | if (p != NULL && testval != 0x67) { | ||
451 | |||
452 | u8 reset = 0, fpga_command = 0; | ||
453 | memcpy(p, fw->data, fw->size); | ||
454 | /* clear fpga ? */ | ||
455 | opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1, | ||
456 | OPERA_WRITE_MSG); | ||
457 | for (i = 0; p[i] != 0 && i < fw->size;) { | ||
458 | b = (u8 *) p + i; | ||
459 | if (opera1_xilinx_rw | ||
460 | (dev, OPERA_WRITE_FX2, 0x0, b + 1, b[0], | ||
461 | OPERA_WRITE_MSG) != b[0] | ||
462 | ) { | ||
463 | err("error while transferring firmware"); | ||
464 | ret = -EINVAL; | ||
465 | break; | ||
466 | } | ||
467 | i = i + 1 + b[0]; | ||
468 | } | ||
469 | /* restart the CPU */ | ||
470 | if (ret || opera1_xilinx_rw | ||
471 | (dev, 0xa0, 0xe600, &reset, 1, | ||
472 | OPERA_WRITE_MSG) != 1) { | ||
473 | err("could not restart the USB controller CPU."); | ||
474 | ret = -EINVAL; | ||
475 | } | ||
476 | kfree(p); | ||
477 | } | ||
478 | } | ||
479 | if (fw) { | ||
480 | release_firmware(fw); | ||
481 | } | ||
482 | return ret; | ||
483 | } | ||
484 | |||
485 | static struct dvb_usb_device_properties opera1_properties = { | ||
486 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||
487 | .usb_ctrl = CYPRESS_FX2, | ||
488 | .firmware = "dvb-usb-opera-01.fw", | ||
489 | .size_of_priv = sizeof(struct opera1_state), | ||
490 | |||
491 | .power_ctrl = opera1_power_ctrl, | ||
492 | .i2c_algo = &opera1_i2c_algo, | ||
493 | |||
494 | .rc_key_map = opera1_rc_keys, | ||
495 | .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys), | ||
496 | .rc_interval = 200, | ||
497 | .rc_query = opera1_rc_query, | ||
498 | .read_mac_address = opera1_read_mac_address, | ||
499 | .generic_bulk_ctrl_endpoint = 0x00, | ||
500 | /* parameter for the MPEG2-data transfer */ | ||
501 | .num_adapters = 1, | ||
502 | .adapter = { | ||
503 | { | ||
504 | .frontend_attach = opera1_frontend_attach, | ||
505 | .streaming_ctrl = opera1_streaming_ctrl, | ||
506 | .tuner_attach = opera1_tuner_attach, | ||
507 | .caps = | ||
508 | DVB_USB_ADAP_HAS_PID_FILTER | | ||
509 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, | ||
510 | .pid_filter = opera1_pid_filter, | ||
511 | .pid_filter_ctrl = opera1_pid_filter_control, | ||
512 | .pid_filter_count = 252, | ||
513 | .stream = { | ||
514 | .type = USB_BULK, | ||
515 | .count = 10, | ||
516 | .endpoint = 0x82, | ||
517 | .u = { | ||
518 | .bulk = { | ||
519 | .buffersize = 4096, | ||
520 | } | ||
521 | } | ||
522 | }, | ||
523 | } | ||
524 | }, | ||
525 | .num_device_descs = 1, | ||
526 | .devices = { | ||
527 | {"Opera1 DVB-S USB2.0", | ||
528 | {&opera1_table[0], NULL}, | ||
529 | {&opera1_table[1], NULL}, | ||
530 | }, | ||
531 | } | ||
532 | }; | ||
533 | |||
534 | static int opera1_probe(struct usb_interface *intf, | ||
535 | const struct usb_device_id *id) | ||
536 | { | ||
537 | struct dvb_usb_device *d; | ||
538 | struct usb_device *udev = interface_to_usbdev(intf); | ||
539 | |||
540 | if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM && | ||
541 | udev->descriptor.idVendor == USB_VID_OPERA1 && | ||
542 | (d == NULL | ||
543 | || opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga.fw") != 0) | ||
544 | ) { | ||
545 | return -EINVAL; | ||
546 | } | ||
547 | |||
548 | if (dvb_usb_device_init(intf, &opera1_properties, THIS_MODULE, &d) != 0) | ||
549 | return -EINVAL; | ||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static struct usb_driver opera1_driver = { | ||
554 | .name = "opera1", | ||
555 | .probe = opera1_probe, | ||
556 | .disconnect = dvb_usb_device_exit, | ||
557 | .id_table = opera1_table, | ||
558 | }; | ||
559 | |||
560 | static int __init opera1_module_init(void) | ||
561 | { | ||
562 | int result = 0; | ||
563 | if ((result = usb_register(&opera1_driver))) { | ||
564 | err("usb_register failed. Error number %d", result); | ||
565 | } | ||
566 | return result; | ||
567 | } | ||
568 | |||
569 | static void __exit opera1_module_exit(void) | ||
570 | { | ||
571 | usb_deregister(&opera1_driver); | ||
572 | } | ||
573 | |||
574 | module_init(opera1_module_init); | ||
575 | module_exit(opera1_module_exit); | ||
576 | |||
577 | MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org"); | ||
578 | MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de"); | ||
579 | MODULE_DESCRIPTION("Driver for Opera1 DVB-S device"); | ||
580 | MODULE_VERSION("0.1"); | ||
581 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/dvb-usb/opera1.h b/drivers/media/dvb/dvb-usb/opera1.h new file mode 100644 index 000000000000..53174427902d --- /dev/null +++ b/drivers/media/dvb/dvb-usb/opera1.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef _OPERA1_H_ | ||
2 | #define _OPERA1_H_ | ||
3 | |||
4 | #define DVB_USB_LOG_PREFIX "opera" | ||
5 | #include "dvb-usb.h" | ||
6 | |||
7 | extern int dvb_usb_opera1_debug; | ||
8 | #define deb_xfer(args...) dprintk(dvb_usb_opera1_debug,0x02,args) | ||
9 | #endif | ||
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 95d29976ed78..88dc4367a2e3 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c | |||
@@ -184,6 +184,7 @@ static int ttusb2_probe(struct usb_interface *intf, | |||
184 | 184 | ||
185 | static struct usb_device_id ttusb2_table [] = { | 185 | static struct usb_device_id ttusb2_table [] = { |
186 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, | 186 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, |
187 | { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, | ||
187 | {} /* Terminating entry */ | 188 | {} /* Terminating entry */ |
188 | }; | 189 | }; |
189 | MODULE_DEVICE_TABLE (usb, ttusb2_table); | 190 | MODULE_DEVICE_TABLE (usb, ttusb2_table); |
@@ -227,12 +228,16 @@ static struct dvb_usb_device_properties ttusb2_properties = { | |||
227 | 228 | ||
228 | .generic_bulk_ctrl_endpoint = 0x01, | 229 | .generic_bulk_ctrl_endpoint = 0x01, |
229 | 230 | ||
230 | .num_device_descs = 1, | 231 | .num_device_descs = 2, |
231 | .devices = { | 232 | .devices = { |
232 | { "Pinnacle 400e DVB-S USB2.0", | 233 | { "Pinnacle 400e DVB-S USB2.0", |
233 | { &ttusb2_table[0], NULL }, | 234 | { &ttusb2_table[0], NULL }, |
234 | { NULL }, | 235 | { NULL }, |
235 | }, | 236 | }, |
237 | { "Pinnacle 450e DVB-S USB2.0", | ||
238 | { &ttusb2_table[1], NULL }, | ||
239 | { NULL }, | ||
240 | }, | ||
236 | } | 241 | } |
237 | }; | 242 | }; |
238 | 243 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 22c2cf2cea98..ff448761dcef 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -205,6 +205,13 @@ config DVB_TDA10021 | |||
205 | help | 205 | help |
206 | A DVB-C tuner module. Say Y when you want to support this frontend. | 206 | A DVB-C tuner module. Say Y when you want to support this frontend. |
207 | 207 | ||
208 | config DVB_TDA10023 | ||
209 | tristate "Philips TDA10023 based" | ||
210 | depends on DVB_CORE && I2C | ||
211 | default m if DVB_FE_CUSTOMISE | ||
212 | help | ||
213 | A DVB-C tuner module. Say Y when you want to support this frontend. | ||
214 | |||
208 | config DVB_STV0297 | 215 | config DVB_STV0297 |
209 | tristate "ST STV0297 based" | 216 | tristate "ST STV0297 based" |
210 | depends on DVB_CORE && I2C | 217 | depends on DVB_CORE && I2C |
@@ -280,8 +287,12 @@ comment "Tuners/PLL support" | |||
280 | depends on DVB_CORE | 287 | depends on DVB_CORE |
281 | 288 | ||
282 | config DVB_PLL | 289 | config DVB_PLL |
283 | tristate | 290 | tristate "Generic I2C PLL based tuners" |
284 | depends on DVB_CORE && I2C | 291 | depends on DVB_CORE && I2C |
292 | default m if DVB_FE_CUSTOMISE | ||
293 | help | ||
294 | This module driver a number of tuners based on PLL chips with a | ||
295 | common I2C interface. Say Y when you want to support these tuners. | ||
285 | 296 | ||
286 | config DVB_TDA826X | 297 | config DVB_TDA826X |
287 | tristate "Philips TDA826X silicon tuner" | 298 | tristate "Philips TDA826X silicon tuner" |
@@ -290,6 +301,13 @@ config DVB_TDA826X | |||
290 | help | 301 | help |
291 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. | 302 | A DVB-S silicon tuner module. Say Y when you want to support this tuner. |
292 | 303 | ||
304 | config DVB_TDA827X | ||
305 | tristate "Philips TDA827X silicon tuner" | ||
306 | depends on DVB_CORE && I2C | ||
307 | default m if DVB_FE_CUSTOMISE | ||
308 | help | ||
309 | A DVB-T silicon tuner module. Say Y when you want to support this tuner. | ||
310 | |||
293 | config DVB_TUNER_QT1010 | 311 | config DVB_TUNER_QT1010 |
294 | tristate "Quantek QT1010 silicon tuner" | 312 | tristate "Quantek QT1010 silicon tuner" |
295 | depends on DVB_CORE && I2C | 313 | depends on DVB_CORE && I2C |
@@ -304,14 +322,6 @@ config DVB_TUNER_MT2060 | |||
304 | help | 322 | help |
305 | A driver for the silicon IF tuner MT2060 from Microtune. | 323 | A driver for the silicon IF tuner MT2060 from Microtune. |
306 | 324 | ||
307 | config DVB_TUNER_LGH06XF | ||
308 | tristate "LG TDVS-H06xF ATSC tuner" | ||
309 | depends on DVB_CORE && I2C | ||
310 | select DVB_PLL | ||
311 | default m if DVB_FE_CUSTOMISE | ||
312 | help | ||
313 | A driver for the LG TDVS-H06xF ATSC tuner family. | ||
314 | |||
315 | comment "Miscellaneous devices" | 325 | comment "Miscellaneous devices" |
316 | depends on DVB_CORE | 326 | depends on DVB_CORE |
317 | 327 | ||
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a646d9969b71..27f386585d43 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_MT352) += mt352.o | |||
25 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o | 25 | obj-$(CONFIG_DVB_ZL10353) += zl10353.o |
26 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 26 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
27 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 27 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
28 | obj-$(CONFIG_DVB_TDA10023) += tda10023.o | ||
28 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 29 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
29 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | 30 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o |
30 | obj-$(CONFIG_DVB_OR51211) += or51211.o | 31 | obj-$(CONFIG_DVB_OR51211) += or51211.o |
@@ -37,7 +38,7 @@ obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | |||
37 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o | 38 | obj-$(CONFIG_DVB_ISL6421) += isl6421.o |
38 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o | 39 | obj-$(CONFIG_DVB_TDA10086) += tda10086.o |
39 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o | 40 | obj-$(CONFIG_DVB_TDA826X) += tda826x.o |
41 | obj-$(CONFIG_DVB_TDA827X) += tda827x.o | ||
40 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o | 42 | obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o |
41 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o | 43 | obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o |
42 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 44 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
43 | obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 62de760c844f..5f96ffda91ad 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
@@ -27,17 +27,29 @@ | |||
27 | /* ----------------------------------------------------------- */ | 27 | /* ----------------------------------------------------------- */ |
28 | /* descriptions */ | 28 | /* descriptions */ |
29 | 29 | ||
30 | /* Set AGC TOP value to 103 dBuV: | ||
31 | 0x80 = Control Byte | ||
32 | 0x40 = 250 uA charge pump (irrelevant) | ||
33 | 0x18 = Aux Byte to follow | ||
34 | 0x06 = 64.5 kHz divider (irrelevant) | ||
35 | 0x01 = Disable Vt (aka sleep) | ||
36 | |||
37 | 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) | ||
38 | 0x50 = AGC Take over point = 103 dBuV */ | ||
39 | static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; | ||
40 | |||
30 | struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { | 41 | struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { |
31 | .name = "Thomson dtt7579", | 42 | .name = "Thomson dtt7579", |
32 | .min = 177000000, | 43 | .min = 177000000, |
33 | .max = 858000000, | 44 | .max = 858000000, |
34 | .count = 5, | 45 | .iffreq= 36166667, |
46 | .sleepdata = (u8[]){ 2, 0xb4, 0x03 }, | ||
47 | .count = 4, | ||
35 | .entries = { | 48 | .entries = { |
36 | { 0, 36166667, 166666, 0xb4, 0x03 }, /* go sleep */ | 49 | { 443250000, 166667, 0xb4, 0x02 }, |
37 | { 443250000, 36166667, 166666, 0xb4, 0x02 }, | 50 | { 542000000, 166667, 0xb4, 0x08 }, |
38 | { 542000000, 36166667, 166666, 0xb4, 0x08 }, | 51 | { 771000000, 166667, 0xbc, 0x08 }, |
39 | { 771000000, 36166667, 166666, 0xbc, 0x08 }, | 52 | { 999999999, 166667, 0xf4, 0x08 }, |
40 | { 999999999, 36166667, 166666, 0xf4, 0x08 }, | ||
41 | }, | 53 | }, |
42 | }; | 54 | }; |
43 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); | 55 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7579); |
@@ -46,11 +58,12 @@ struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { | |||
46 | .name = "Thomson dtt7610", | 58 | .name = "Thomson dtt7610", |
47 | .min = 44000000, | 59 | .min = 44000000, |
48 | .max = 958000000, | 60 | .max = 958000000, |
61 | .iffreq= 44000000, | ||
49 | .count = 3, | 62 | .count = 3, |
50 | .entries = { | 63 | .entries = { |
51 | { 157250000, 44000000, 62500, 0x8e, 0x39 }, | 64 | { 157250000, 62500, 0x8e, 0x39 }, |
52 | { 454000000, 44000000, 62500, 0x8e, 0x3a }, | 65 | { 454000000, 62500, 0x8e, 0x3a }, |
53 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 66 | { 999999999, 62500, 0x8e, 0x3c }, |
54 | }, | 67 | }, |
55 | }; | 68 | }; |
56 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); | 69 | EXPORT_SYMBOL(dvb_pll_thomson_dtt7610); |
@@ -66,14 +79,15 @@ struct dvb_pll_desc dvb_pll_thomson_dtt759x = { | |||
66 | .min = 177000000, | 79 | .min = 177000000, |
67 | .max = 896000000, | 80 | .max = 896000000, |
68 | .setbw = thomson_dtt759x_bw, | 81 | .setbw = thomson_dtt759x_bw, |
69 | .count = 6, | 82 | .iffreq= 36166667, |
83 | .sleepdata = (u8[]){ 2, 0x84, 0x03 }, | ||
84 | .count = 5, | ||
70 | .entries = { | 85 | .entries = { |
71 | { 0, 36166667, 166666, 0x84, 0x03 }, | 86 | { 264000000, 166667, 0xb4, 0x02 }, |
72 | { 264000000, 36166667, 166666, 0xb4, 0x02 }, | 87 | { 470000000, 166667, 0xbc, 0x02 }, |
73 | { 470000000, 36166667, 166666, 0xbc, 0x02 }, | 88 | { 735000000, 166667, 0xbc, 0x08 }, |
74 | { 735000000, 36166667, 166666, 0xbc, 0x08 }, | 89 | { 835000000, 166667, 0xf4, 0x08 }, |
75 | { 835000000, 36166667, 166666, 0xf4, 0x08 }, | 90 | { 999999999, 166667, 0xfc, 0x08 }, |
76 | { 999999999, 36166667, 166666, 0xfc, 0x08 }, | ||
77 | }, | 91 | }, |
78 | }; | 92 | }; |
79 | EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); | 93 | EXPORT_SYMBOL(dvb_pll_thomson_dtt759x); |
@@ -82,14 +96,15 @@ struct dvb_pll_desc dvb_pll_lg_z201 = { | |||
82 | .name = "LG z201", | 96 | .name = "LG z201", |
83 | .min = 174000000, | 97 | .min = 174000000, |
84 | .max = 862000000, | 98 | .max = 862000000, |
85 | .count = 6, | 99 | .iffreq= 36166667, |
100 | .sleepdata = (u8[]){ 2, 0xbc, 0x03 }, | ||
101 | .count = 5, | ||
86 | .entries = { | 102 | .entries = { |
87 | { 0, 36166667, 166666, 0xbc, 0x03 }, | 103 | { 157500000, 166667, 0xbc, 0x01 }, |
88 | { 157500000, 36166667, 166666, 0xbc, 0x01 }, | 104 | { 443250000, 166667, 0xbc, 0x02 }, |
89 | { 443250000, 36166667, 166666, 0xbc, 0x02 }, | 105 | { 542000000, 166667, 0xbc, 0x04 }, |
90 | { 542000000, 36166667, 166666, 0xbc, 0x04 }, | 106 | { 830000000, 166667, 0xf4, 0x04 }, |
91 | { 830000000, 36166667, 166666, 0xf4, 0x04 }, | 107 | { 999999999, 166667, 0xfc, 0x04 }, |
92 | { 999999999, 36166667, 166666, 0xfc, 0x04 }, | ||
93 | }, | 108 | }, |
94 | }; | 109 | }; |
95 | EXPORT_SYMBOL(dvb_pll_lg_z201); | 110 | EXPORT_SYMBOL(dvb_pll_lg_z201); |
@@ -98,11 +113,12 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { | |||
98 | .name = "Microtune 4042 FI5", | 113 | .name = "Microtune 4042 FI5", |
99 | .min = 57000000, | 114 | .min = 57000000, |
100 | .max = 858000000, | 115 | .max = 858000000, |
116 | .iffreq= 44000000, | ||
101 | .count = 3, | 117 | .count = 3, |
102 | .entries = { | 118 | .entries = { |
103 | { 162000000, 44000000, 62500, 0x8e, 0xa1 }, | 119 | { 162000000, 62500, 0x8e, 0xa1 }, |
104 | { 457000000, 44000000, 62500, 0x8e, 0x91 }, | 120 | { 457000000, 62500, 0x8e, 0x91 }, |
105 | { 999999999, 44000000, 62500, 0x8e, 0x31 }, | 121 | { 999999999, 62500, 0x8e, 0x31 }, |
106 | }, | 122 | }, |
107 | }; | 123 | }; |
108 | EXPORT_SYMBOL(dvb_pll_microtune_4042); | 124 | EXPORT_SYMBOL(dvb_pll_microtune_4042); |
@@ -112,11 +128,13 @@ struct dvb_pll_desc dvb_pll_thomson_dtt761x = { | |||
112 | .name = "Thomson dtt761x", | 128 | .name = "Thomson dtt761x", |
113 | .min = 57000000, | 129 | .min = 57000000, |
114 | .max = 863000000, | 130 | .max = 863000000, |
131 | .iffreq= 44000000, | ||
115 | .count = 3, | 132 | .count = 3, |
133 | .initdata = tua603x_agc103, | ||
116 | .entries = { | 134 | .entries = { |
117 | { 147000000, 44000000, 62500, 0x8e, 0x39 }, | 135 | { 147000000, 62500, 0x8e, 0x39 }, |
118 | { 417000000, 44000000, 62500, 0x8e, 0x3a }, | 136 | { 417000000, 62500, 0x8e, 0x3a }, |
119 | { 999999999, 44000000, 62500, 0x8e, 0x3c }, | 137 | { 999999999, 62500, 0x8e, 0x3c }, |
120 | }, | 138 | }, |
121 | }; | 139 | }; |
122 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); | 140 | EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); |
@@ -125,17 +143,18 @@ struct dvb_pll_desc dvb_pll_unknown_1 = { | |||
125 | .name = "unknown 1", /* used by dntv live dvb-t */ | 143 | .name = "unknown 1", /* used by dntv live dvb-t */ |
126 | .min = 174000000, | 144 | .min = 174000000, |
127 | .max = 862000000, | 145 | .max = 862000000, |
146 | .iffreq= 36166667, | ||
128 | .count = 9, | 147 | .count = 9, |
129 | .entries = { | 148 | .entries = { |
130 | { 150000000, 36166667, 166666, 0xb4, 0x01 }, | 149 | { 150000000, 166667, 0xb4, 0x01 }, |
131 | { 173000000, 36166667, 166666, 0xbc, 0x01 }, | 150 | { 173000000, 166667, 0xbc, 0x01 }, |
132 | { 250000000, 36166667, 166666, 0xb4, 0x02 }, | 151 | { 250000000, 166667, 0xb4, 0x02 }, |
133 | { 400000000, 36166667, 166666, 0xbc, 0x02 }, | 152 | { 400000000, 166667, 0xbc, 0x02 }, |
134 | { 420000000, 36166667, 166666, 0xf4, 0x02 }, | 153 | { 420000000, 166667, 0xf4, 0x02 }, |
135 | { 470000000, 36166667, 166666, 0xfc, 0x02 }, | 154 | { 470000000, 166667, 0xfc, 0x02 }, |
136 | { 600000000, 36166667, 166666, 0xbc, 0x08 }, | 155 | { 600000000, 166667, 0xbc, 0x08 }, |
137 | { 730000000, 36166667, 166666, 0xf4, 0x08 }, | 156 | { 730000000, 166667, 0xf4, 0x08 }, |
138 | { 999999999, 36166667, 166666, 0xfc, 0x08 }, | 157 | { 999999999, 166667, 0xfc, 0x08 }, |
139 | }, | 158 | }, |
140 | }; | 159 | }; |
141 | EXPORT_SYMBOL(dvb_pll_unknown_1); | 160 | EXPORT_SYMBOL(dvb_pll_unknown_1); |
@@ -147,11 +166,12 @@ struct dvb_pll_desc dvb_pll_tua6010xs = { | |||
147 | .name = "Infineon TUA6010XS", | 166 | .name = "Infineon TUA6010XS", |
148 | .min = 44250000, | 167 | .min = 44250000, |
149 | .max = 858000000, | 168 | .max = 858000000, |
169 | .iffreq= 36125000, | ||
150 | .count = 3, | 170 | .count = 3, |
151 | .entries = { | 171 | .entries = { |
152 | { 115750000, 36125000, 62500, 0x8e, 0x03 }, | 172 | { 115750000, 62500, 0x8e, 0x03 }, |
153 | { 403250000, 36125000, 62500, 0x8e, 0x06 }, | 173 | { 403250000, 62500, 0x8e, 0x06 }, |
154 | { 999999999, 36125000, 62500, 0x8e, 0x85 }, | 174 | { 999999999, 62500, 0x8e, 0x85 }, |
155 | }, | 175 | }, |
156 | }; | 176 | }; |
157 | EXPORT_SYMBOL(dvb_pll_tua6010xs); | 177 | EXPORT_SYMBOL(dvb_pll_tua6010xs); |
@@ -161,12 +181,13 @@ struct dvb_pll_desc dvb_pll_env57h1xd5 = { | |||
161 | .name = "Panasonic ENV57H1XD5", | 181 | .name = "Panasonic ENV57H1XD5", |
162 | .min = 44250000, | 182 | .min = 44250000, |
163 | .max = 858000000, | 183 | .max = 858000000, |
184 | .iffreq= 36125000, | ||
164 | .count = 4, | 185 | .count = 4, |
165 | .entries = { | 186 | .entries = { |
166 | { 153000000, 36291666, 166666, 0xc2, 0x41 }, | 187 | { 153000000, 166667, 0xc2, 0x41 }, |
167 | { 470000000, 36291666, 166666, 0xc2, 0x42 }, | 188 | { 470000000, 166667, 0xc2, 0x42 }, |
168 | { 526000000, 36291666, 166666, 0xc2, 0x84 }, | 189 | { 526000000, 166667, 0xc2, 0x84 }, |
169 | { 999999999, 36291666, 166666, 0xc2, 0xa4 }, | 190 | { 999999999, 166667, 0xc2, 0xa4 }, |
170 | }, | 191 | }, |
171 | }; | 192 | }; |
172 | EXPORT_SYMBOL(dvb_pll_env57h1xd5); | 193 | EXPORT_SYMBOL(dvb_pll_env57h1xd5); |
@@ -185,20 +206,21 @@ struct dvb_pll_desc dvb_pll_tda665x = { | |||
185 | .min = 44250000, | 206 | .min = 44250000, |
186 | .max = 858000000, | 207 | .max = 858000000, |
187 | .setbw = tda665x_bw, | 208 | .setbw = tda665x_bw, |
209 | .iffreq= 36166667, | ||
188 | .count = 12, | 210 | .count = 12, |
189 | .entries = { | 211 | .entries = { |
190 | { 93834000, 36249333, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, | 212 | { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, |
191 | { 123834000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, | 213 | { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, |
192 | { 161000000, 36249333, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, | 214 | { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, |
193 | { 163834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, | 215 | { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, |
194 | { 253834000, 36249333, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, | 216 | { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, |
195 | { 383834000, 36249333, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, | 217 | { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, |
196 | { 443834000, 36249333, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, | 218 | { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, |
197 | { 444000000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, | 219 | { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
198 | { 583834000, 36249333, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, | 220 | { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, |
199 | { 793834000, 36249333, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, | 221 | { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, |
200 | { 444834000, 36249333, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, | 222 | { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, |
201 | { 861000000, 36249333, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, | 223 | { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, |
202 | } | 224 | } |
203 | }; | 225 | }; |
204 | EXPORT_SYMBOL(dvb_pll_tda665x); | 226 | EXPORT_SYMBOL(dvb_pll_tda665x); |
@@ -216,12 +238,13 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
216 | .name = "Infineon TUA6034", | 238 | .name = "Infineon TUA6034", |
217 | .min = 44250000, | 239 | .min = 44250000, |
218 | .max = 858000000, | 240 | .max = 858000000, |
241 | .iffreq= 36166667, | ||
219 | .count = 3, | 242 | .count = 3, |
220 | .setbw = tua6034_bw, | 243 | .setbw = tua6034_bw, |
221 | .entries = { | 244 | .entries = { |
222 | { 174500000, 36166667, 62500, 0xce, 0x01 }, | 245 | { 174500000, 62500, 0xce, 0x01 }, |
223 | { 230000000, 36166667, 62500, 0xce, 0x02 }, | 246 | { 230000000, 62500, 0xce, 0x02 }, |
224 | { 999999999, 36166667, 62500, 0xce, 0x04 }, | 247 | { 999999999, 62500, 0xce, 0x04 }, |
225 | }, | 248 | }, |
226 | }; | 249 | }; |
227 | EXPORT_SYMBOL(dvb_pll_tua6034); | 250 | EXPORT_SYMBOL(dvb_pll_tua6034); |
@@ -233,11 +256,13 @@ struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { | |||
233 | .name = "LG TDVS-H06xF", | 256 | .name = "LG TDVS-H06xF", |
234 | .min = 54000000, | 257 | .min = 54000000, |
235 | .max = 863000000, | 258 | .max = 863000000, |
259 | .iffreq= 44000000, | ||
260 | .initdata = tua603x_agc103, | ||
236 | .count = 3, | 261 | .count = 3, |
237 | .entries = { | 262 | .entries = { |
238 | { 165000000, 44000000, 62500, 0xce, 0x01 }, | 263 | { 165000000, 62500, 0xce, 0x01 }, |
239 | { 450000000, 44000000, 62500, 0xce, 0x02 }, | 264 | { 450000000, 62500, 0xce, 0x02 }, |
240 | { 999999999, 44000000, 62500, 0xce, 0x04 }, | 265 | { 999999999, 62500, 0xce, 0x04 }, |
241 | }, | 266 | }, |
242 | }; | 267 | }; |
243 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); | 268 | EXPORT_SYMBOL(dvb_pll_lg_tdvs_h06xf); |
@@ -255,16 +280,17 @@ struct dvb_pll_desc dvb_pll_fmd1216me = { | |||
255 | .name = "Philips FMD1216ME", | 280 | .name = "Philips FMD1216ME", |
256 | .min = 50870000, | 281 | .min = 50870000, |
257 | .max = 858000000, | 282 | .max = 858000000, |
283 | .iffreq= 36125000, | ||
258 | .setbw = fmd1216me_bw, | 284 | .setbw = fmd1216me_bw, |
259 | .count = 7, | 285 | .count = 7, |
260 | .entries = { | 286 | .entries = { |
261 | { 143870000, 36213333, 166667, 0xbc, 0x41 }, | 287 | { 143870000, 166667, 0xbc, 0x41 }, |
262 | { 158870000, 36213333, 166667, 0xf4, 0x41 }, | 288 | { 158870000, 166667, 0xf4, 0x41 }, |
263 | { 329870000, 36213333, 166667, 0xbc, 0x42 }, | 289 | { 329870000, 166667, 0xbc, 0x42 }, |
264 | { 441870000, 36213333, 166667, 0xf4, 0x42 }, | 290 | { 441870000, 166667, 0xf4, 0x42 }, |
265 | { 625870000, 36213333, 166667, 0xbc, 0x44 }, | 291 | { 625870000, 166667, 0xbc, 0x44 }, |
266 | { 803870000, 36213333, 166667, 0xf4, 0x44 }, | 292 | { 803870000, 166667, 0xf4, 0x44 }, |
267 | { 999999999, 36213333, 166667, 0xfc, 0x44 }, | 293 | { 999999999, 166667, 0xfc, 0x44 }, |
268 | } | 294 | } |
269 | }; | 295 | }; |
270 | EXPORT_SYMBOL(dvb_pll_fmd1216me); | 296 | EXPORT_SYMBOL(dvb_pll_fmd1216me); |
@@ -282,13 +308,14 @@ struct dvb_pll_desc dvb_pll_tded4 = { | |||
282 | .name = "ALPS TDED4", | 308 | .name = "ALPS TDED4", |
283 | .min = 47000000, | 309 | .min = 47000000, |
284 | .max = 863000000, | 310 | .max = 863000000, |
311 | .iffreq= 36166667, | ||
285 | .setbw = tded4_bw, | 312 | .setbw = tded4_bw, |
286 | .count = 4, | 313 | .count = 4, |
287 | .entries = { | 314 | .entries = { |
288 | { 153000000, 36166667, 166667, 0x85, 0x01 }, | 315 | { 153000000, 166667, 0x85, 0x01 }, |
289 | { 470000000, 36166667, 166667, 0x85, 0x02 }, | 316 | { 470000000, 166667, 0x85, 0x02 }, |
290 | { 823000000, 36166667, 166667, 0x85, 0x08 }, | 317 | { 823000000, 166667, 0x85, 0x08 }, |
291 | { 999999999, 36166667, 166667, 0x85, 0x88 }, | 318 | { 999999999, 166667, 0x85, 0x88 }, |
292 | } | 319 | } |
293 | }; | 320 | }; |
294 | EXPORT_SYMBOL(dvb_pll_tded4); | 321 | EXPORT_SYMBOL(dvb_pll_tded4); |
@@ -300,12 +327,13 @@ struct dvb_pll_desc dvb_pll_tdhu2 = { | |||
300 | .name = "ALPS TDHU2", | 327 | .name = "ALPS TDHU2", |
301 | .min = 54000000, | 328 | .min = 54000000, |
302 | .max = 864000000, | 329 | .max = 864000000, |
330 | .iffreq= 44000000, | ||
303 | .count = 4, | 331 | .count = 4, |
304 | .entries = { | 332 | .entries = { |
305 | { 162000000, 44000000, 62500, 0x85, 0x01 }, | 333 | { 162000000, 62500, 0x85, 0x01 }, |
306 | { 426000000, 44000000, 62500, 0x85, 0x02 }, | 334 | { 426000000, 62500, 0x85, 0x02 }, |
307 | { 782000000, 44000000, 62500, 0x85, 0x08 }, | 335 | { 782000000, 62500, 0x85, 0x08 }, |
308 | { 999999999, 44000000, 62500, 0x85, 0x88 }, | 336 | { 999999999, 62500, 0x85, 0x88 }, |
309 | } | 337 | } |
310 | }; | 338 | }; |
311 | EXPORT_SYMBOL(dvb_pll_tdhu2); | 339 | EXPORT_SYMBOL(dvb_pll_tdhu2); |
@@ -317,11 +345,12 @@ struct dvb_pll_desc dvb_pll_tuv1236d = { | |||
317 | .name = "Philips TUV1236D", | 345 | .name = "Philips TUV1236D", |
318 | .min = 54000000, | 346 | .min = 54000000, |
319 | .max = 864000000, | 347 | .max = 864000000, |
348 | .iffreq= 44000000, | ||
320 | .count = 3, | 349 | .count = 3, |
321 | .entries = { | 350 | .entries = { |
322 | { 157250000, 44000000, 62500, 0xc6, 0x41 }, | 351 | { 157250000, 62500, 0xc6, 0x41 }, |
323 | { 454000000, 44000000, 62500, 0xc6, 0x42 }, | 352 | { 454000000, 62500, 0xc6, 0x42 }, |
324 | { 999999999, 44000000, 62500, 0xc6, 0x44 }, | 353 | { 999999999, 62500, 0xc6, 0x44 }, |
325 | }, | 354 | }, |
326 | }; | 355 | }; |
327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | 356 | EXPORT_SYMBOL(dvb_pll_tuv1236d); |
@@ -333,14 +362,15 @@ struct dvb_pll_desc dvb_pll_samsung_tbmv = { | |||
333 | .name = "Samsung TBMV30111IN / TBMV30712IN1", | 362 | .name = "Samsung TBMV30111IN / TBMV30712IN1", |
334 | .min = 54000000, | 363 | .min = 54000000, |
335 | .max = 860000000, | 364 | .max = 860000000, |
365 | .iffreq= 44000000, | ||
336 | .count = 6, | 366 | .count = 6, |
337 | .entries = { | 367 | .entries = { |
338 | { 172000000, 44000000, 166666, 0xb4, 0x01 }, | 368 | { 172000000, 166667, 0xb4, 0x01 }, |
339 | { 214000000, 44000000, 166666, 0xb4, 0x02 }, | 369 | { 214000000, 166667, 0xb4, 0x02 }, |
340 | { 467000000, 44000000, 166666, 0xbc, 0x02 }, | 370 | { 467000000, 166667, 0xbc, 0x02 }, |
341 | { 721000000, 44000000, 166666, 0xbc, 0x08 }, | 371 | { 721000000, 166667, 0xbc, 0x08 }, |
342 | { 841000000, 44000000, 166666, 0xf4, 0x08 }, | 372 | { 841000000, 166667, 0xf4, 0x08 }, |
343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, | 373 | { 999999999, 166667, 0xfc, 0x02 }, |
344 | } | 374 | } |
345 | }; | 375 | }; |
346 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); | 376 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); |
@@ -352,12 +382,13 @@ struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { | |||
352 | .name = "Philips SD1878", | 382 | .name = "Philips SD1878", |
353 | .min = 950000, | 383 | .min = 950000, |
354 | .max = 2150000, | 384 | .max = 2150000, |
385 | .iffreq= 249, /* zero-IF, offset 249 is to round up */ | ||
355 | .count = 4, | 386 | .count = 4, |
356 | .entries = { | 387 | .entries = { |
357 | { 1250000, 499, 500, 0xc4, 0x00}, | 388 | { 1250000, 500, 0xc4, 0x00}, |
358 | { 1550000, 499, 500, 0xc4, 0x40}, | 389 | { 1550000, 500, 0xc4, 0x40}, |
359 | { 2050000, 499, 500, 0xc4, 0x80}, | 390 | { 2050000, 500, 0xc4, 0x80}, |
360 | { 2150000, 499, 500, 0xc4, 0xc0}, | 391 | { 2150000, 500, 0xc4, 0xc0}, |
361 | }, | 392 | }, |
362 | }; | 393 | }; |
363 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); | 394 | EXPORT_SYMBOL(dvb_pll_philips_sd1878_tda8261); |
@@ -388,18 +419,19 @@ struct dvb_pll_desc dvb_pll_philips_td1316 = { | |||
388 | .name = "Philips TD1316", | 419 | .name = "Philips TD1316", |
389 | .min = 87000000, | 420 | .min = 87000000, |
390 | .max = 895000000, | 421 | .max = 895000000, |
422 | .iffreq= 36166667, | ||
391 | .setbw = td1316_bw, | 423 | .setbw = td1316_bw, |
392 | .count = 9, | 424 | .count = 9, |
393 | .entries = { | 425 | .entries = { |
394 | { 93834000, 36166000, 166666, 0xca, 0x60}, | 426 | { 93834000, 166667, 0xca, 0x60}, |
395 | { 123834000, 36166000, 166666, 0xca, 0xa0}, | 427 | { 123834000, 166667, 0xca, 0xa0}, |
396 | { 163834000, 36166000, 166666, 0xca, 0xc0}, | 428 | { 163834000, 166667, 0xca, 0xc0}, |
397 | { 253834000, 36166000, 166666, 0xca, 0x60}, | 429 | { 253834000, 166667, 0xca, 0x60}, |
398 | { 383834000, 36166000, 166666, 0xca, 0xa0}, | 430 | { 383834000, 166667, 0xca, 0xa0}, |
399 | { 443834000, 36166000, 166666, 0xca, 0xc0}, | 431 | { 443834000, 166667, 0xca, 0xc0}, |
400 | { 583834000, 36166000, 166666, 0xca, 0x60}, | 432 | { 583834000, 166667, 0xca, 0x60}, |
401 | { 793834000, 36166000, 166666, 0xca, 0xa0}, | 433 | { 793834000, 166667, 0xca, 0xa0}, |
402 | { 858834000, 36166000, 166666, 0xca, 0xe0}, | 434 | { 858834000, 166667, 0xca, 0xe0}, |
403 | }, | 435 | }, |
404 | }; | 436 | }; |
405 | EXPORT_SYMBOL(dvb_pll_philips_td1316); | 437 | EXPORT_SYMBOL(dvb_pll_philips_td1316); |
@@ -409,15 +441,41 @@ struct dvb_pll_desc dvb_pll_thomson_fe6600 = { | |||
409 | .name = "Thomson FE6600", | 441 | .name = "Thomson FE6600", |
410 | .min = 44250000, | 442 | .min = 44250000, |
411 | .max = 858000000, | 443 | .max = 858000000, |
444 | .iffreq= 36125000, | ||
412 | .count = 4, | 445 | .count = 4, |
413 | .entries = { | 446 | .entries = { |
414 | { 250000000, 36213333, 166667, 0xb4, 0x12 }, | 447 | { 250000000, 166667, 0xb4, 0x12 }, |
415 | { 455000000, 36213333, 166667, 0xfe, 0x11 }, | 448 | { 455000000, 166667, 0xfe, 0x11 }, |
416 | { 775500000, 36213333, 166667, 0xbc, 0x18 }, | 449 | { 775500000, 166667, 0xbc, 0x18 }, |
417 | { 999999999, 36213333, 166667, 0xf4, 0x18 }, | 450 | { 999999999, 166667, 0xf4, 0x18 }, |
418 | } | 451 | } |
419 | }; | 452 | }; |
420 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); | 453 | EXPORT_SYMBOL(dvb_pll_thomson_fe6600); |
454 | static void opera1_bw(u8 *buf, u32 freq, int bandwidth) | ||
455 | { | ||
456 | if (bandwidth == BANDWIDTH_8_MHZ) | ||
457 | buf[2] |= 0x08; | ||
458 | } | ||
459 | |||
460 | struct dvb_pll_desc dvb_pll_opera1 = { | ||
461 | .name = "Opera Tuner", | ||
462 | .min = 900000, | ||
463 | .max = 2250000, | ||
464 | .iffreq= 0, | ||
465 | .setbw = opera1_bw, | ||
466 | .count = 8, | ||
467 | .entries = { | ||
468 | { 1064000, 500, 0xe5, 0xc6 }, | ||
469 | { 1169000, 500, 0xe5, 0xe6 }, | ||
470 | { 1299000, 500, 0xe5, 0x24 }, | ||
471 | { 1444000, 500, 0xe5, 0x44 }, | ||
472 | { 1606000, 500, 0xe5, 0x64 }, | ||
473 | { 1777000, 500, 0xe5, 0x84 }, | ||
474 | { 1941000, 500, 0xe5, 0xa4 }, | ||
475 | { 2250000, 500, 0xe5, 0xc4 }, | ||
476 | } | ||
477 | }; | ||
478 | EXPORT_SYMBOL(dvb_pll_opera1); | ||
421 | 479 | ||
422 | struct dvb_pll_priv { | 480 | struct dvb_pll_priv { |
423 | /* i2c details */ | 481 | /* i2c details */ |
@@ -459,7 +517,8 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
459 | if (i == desc->count) | 517 | if (i == desc->count) |
460 | return -EINVAL; | 518 | return -EINVAL; |
461 | 519 | ||
462 | div = (freq + desc->entries[i].offset) / desc->entries[i].stepsize; | 520 | div = (freq + desc->iffreq + desc->entries[i].stepsize/2) / |
521 | desc->entries[i].stepsize; | ||
463 | buf[0] = div >> 8; | 522 | buf[0] = div >> 8; |
464 | buf[1] = div & 0xff; | 523 | buf[1] = div & 0xff; |
465 | buf[2] = desc->entries[i].config; | 524 | buf[2] = desc->entries[i].config; |
@@ -473,7 +532,7 @@ int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
473 | desc->name, div, buf[0], buf[1], buf[2], buf[3]); | 532 | desc->name, div, buf[0], buf[1], buf[2], buf[3]); |
474 | 533 | ||
475 | // calculate the frequency we set it to | 534 | // calculate the frequency we set it to |
476 | return (div * desc->entries[i].stepsize) - desc->entries[i].offset; | 535 | return (div * desc->entries[i].stepsize) - desc->iffreq; |
477 | } | 536 | } |
478 | EXPORT_SYMBOL(dvb_pll_configure); | 537 | EXPORT_SYMBOL(dvb_pll_configure); |
479 | 538 | ||
@@ -487,35 +546,27 @@ static int dvb_pll_release(struct dvb_frontend *fe) | |||
487 | static int dvb_pll_sleep(struct dvb_frontend *fe) | 546 | static int dvb_pll_sleep(struct dvb_frontend *fe) |
488 | { | 547 | { |
489 | struct dvb_pll_priv *priv = fe->tuner_priv; | 548 | struct dvb_pll_priv *priv = fe->tuner_priv; |
490 | u8 buf[4]; | ||
491 | struct i2c_msg msg = | ||
492 | { .addr = priv->pll_i2c_address, .flags = 0, | ||
493 | .buf = buf, .len = sizeof(buf) }; | ||
494 | int i; | ||
495 | int result; | ||
496 | 549 | ||
497 | if (priv->i2c == NULL) | 550 | if (priv->i2c == NULL) |
498 | return -EINVAL; | 551 | return -EINVAL; |
499 | 552 | ||
500 | for (i = 0; i < priv->pll_desc->count; i++) { | 553 | if (priv->pll_desc->sleepdata) { |
501 | if (priv->pll_desc->entries[i].limit == 0) | 554 | struct i2c_msg msg = { .flags = 0, |
502 | break; | 555 | .addr = priv->pll_i2c_address, |
503 | } | 556 | .buf = priv->pll_desc->sleepdata + 1, |
504 | if (i == priv->pll_desc->count) | 557 | .len = priv->pll_desc->sleepdata[0] }; |
505 | return 0; | ||
506 | 558 | ||
507 | buf[0] = 0; | 559 | int result; |
508 | buf[1] = 0; | ||
509 | buf[2] = priv->pll_desc->entries[i].config; | ||
510 | buf[3] = priv->pll_desc->entries[i].cb; | ||
511 | 560 | ||
512 | if (fe->ops.i2c_gate_ctrl) | 561 | if (fe->ops.i2c_gate_ctrl) |
513 | fe->ops.i2c_gate_ctrl(fe, 1); | 562 | fe->ops.i2c_gate_ctrl(fe, 1); |
514 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | 563 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { |
515 | return result; | 564 | return result; |
565 | } | ||
566 | return 0; | ||
516 | } | 567 | } |
517 | 568 | /* Shouldn't be called when initdata is NULL, maybe BUG()? */ | |
518 | return 0; | 569 | return -EINVAL; |
519 | } | 570 | } |
520 | 571 | ||
521 | static int dvb_pll_set_params(struct dvb_frontend *fe, | 572 | static int dvb_pll_set_params(struct dvb_frontend *fe, |
@@ -599,9 +650,35 @@ static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
599 | return 0; | 650 | return 0; |
600 | } | 651 | } |
601 | 652 | ||
653 | static int dvb_pll_init(struct dvb_frontend *fe) | ||
654 | { | ||
655 | struct dvb_pll_priv *priv = fe->tuner_priv; | ||
656 | |||
657 | if (priv->i2c == NULL) | ||
658 | return -EINVAL; | ||
659 | |||
660 | if (priv->pll_desc->initdata) { | ||
661 | struct i2c_msg msg = { .flags = 0, | ||
662 | .addr = priv->pll_i2c_address, | ||
663 | .buf = priv->pll_desc->initdata + 1, | ||
664 | .len = priv->pll_desc->initdata[0] }; | ||
665 | |||
666 | int result; | ||
667 | if (fe->ops.i2c_gate_ctrl) | ||
668 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
669 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
670 | return result; | ||
671 | } | ||
672 | return 0; | ||
673 | } | ||
674 | /* Shouldn't be called when initdata is NULL, maybe BUG()? */ | ||
675 | return -EINVAL; | ||
676 | } | ||
677 | |||
602 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { | 678 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { |
603 | .release = dvb_pll_release, | 679 | .release = dvb_pll_release, |
604 | .sleep = dvb_pll_sleep, | 680 | .sleep = dvb_pll_sleep, |
681 | .init = dvb_pll_init, | ||
605 | .set_params = dvb_pll_set_params, | 682 | .set_params = dvb_pll_set_params, |
606 | .calc_regs = dvb_pll_calc_regs, | 683 | .calc_regs = dvb_pll_calc_regs, |
607 | .get_frequency = dvb_pll_get_frequency, | 684 | .get_frequency = dvb_pll_get_frequency, |
@@ -640,9 +717,14 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, | |||
640 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, | 717 | memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, |
641 | sizeof(struct dvb_tuner_ops)); | 718 | sizeof(struct dvb_tuner_ops)); |
642 | 719 | ||
643 | strncpy(fe->ops.tuner_ops.info.name, desc->name, 128); | 720 | strncpy(fe->ops.tuner_ops.info.name, desc->name, |
721 | sizeof(fe->ops.tuner_ops.info.name)); | ||
644 | fe->ops.tuner_ops.info.frequency_min = desc->min; | 722 | fe->ops.tuner_ops.info.frequency_min = desc->min; |
645 | fe->ops.tuner_ops.info.frequency_min = desc->max; | 723 | fe->ops.tuner_ops.info.frequency_min = desc->max; |
724 | if (!desc->initdata) | ||
725 | fe->ops.tuner_ops.init = NULL; | ||
726 | if (!desc->sleepdata) | ||
727 | fe->ops.tuner_ops.sleep = NULL; | ||
646 | 728 | ||
647 | fe->tuner_priv = priv; | 729 | fe->tuner_priv = priv; |
648 | return fe; | 730 | return fe; |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 681186a5e5eb..5209f46f0893 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -12,11 +12,13 @@ struct dvb_pll_desc { | |||
12 | char *name; | 12 | char *name; |
13 | u32 min; | 13 | u32 min; |
14 | u32 max; | 14 | u32 max; |
15 | u32 iffreq; | ||
15 | void (*setbw)(u8 *buf, u32 freq, int bandwidth); | 16 | void (*setbw)(u8 *buf, u32 freq, int bandwidth); |
17 | u8 *initdata; | ||
18 | u8 *sleepdata; | ||
16 | int count; | 19 | int count; |
17 | struct { | 20 | struct { |
18 | u32 limit; | 21 | u32 limit; |
19 | u32 offset; | ||
20 | u32 stepsize; | 22 | u32 stepsize; |
21 | u8 config; | 23 | u8 config; |
22 | u8 cb; | 24 | u8 cb; |
@@ -46,6 +48,7 @@ extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | |||
46 | extern struct dvb_pll_desc dvb_pll_philips_td1316; | 48 | extern struct dvb_pll_desc dvb_pll_philips_td1316; |
47 | 49 | ||
48 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; | 50 | extern struct dvb_pll_desc dvb_pll_thomson_fe6600; |
51 | extern struct dvb_pll_desc dvb_pll_opera1; | ||
49 | 52 | ||
50 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 53 | extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
51 | u32 freq, int bandwidth); | 54 | u32 freq, int bandwidth); |
@@ -59,9 +62,20 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | |||
59 | * @param desc dvb_pll_desc to use. | 62 | * @param desc dvb_pll_desc to use. |
60 | * @return Frontend pointer on success, NULL on failure | 63 | * @return Frontend pointer on success, NULL on failure |
61 | */ | 64 | */ |
65 | #if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) | ||
62 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | 66 | extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, |
63 | int pll_addr, | 67 | int pll_addr, |
64 | struct i2c_adapter *i2c, | 68 | struct i2c_adapter *i2c, |
65 | struct dvb_pll_desc *desc); | 69 | struct dvb_pll_desc *desc); |
70 | #else | ||
71 | static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, | ||
72 | int pll_addr, | ||
73 | struct i2c_adapter *i2c, | ||
74 | struct dvb_pll_desc *desc) | ||
75 | { | ||
76 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
77 | return NULL; | ||
78 | } | ||
79 | #endif | ||
66 | 80 | ||
67 | #endif | 81 | #endif |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index 68aad0f6519f..e25286e2d431 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
@@ -475,7 +475,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
475 | *status |= FE_HAS_CARRIER; | 475 | *status |= FE_HAS_CARRIER; |
476 | break; | 476 | break; |
477 | default: | 477 | default: |
478 | printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); | 478 | printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); |
479 | } | 479 | } |
480 | 480 | ||
481 | return 0; | 481 | return 0; |
@@ -534,7 +534,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
534 | } | 534 | } |
535 | break; | 535 | break; |
536 | default: | 536 | default: |
537 | printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); | 537 | printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); |
538 | } | 538 | } |
539 | return 0; | 539 | return 0; |
540 | } | 540 | } |
diff --git a/drivers/media/dvb/frontends/lgh06xf.c b/drivers/media/dvb/frontends/lgh06xf.c deleted file mode 100644 index 2202d0cc878b..000000000000 --- a/drivers/media/dvb/frontends/lgh06xf.c +++ /dev/null | |||
@@ -1,134 +0,0 @@ | |||
1 | /* | ||
2 | * lgh06xf.c - ATSC Tuner support for LG TDVS-H06xF | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #include "dvb-pll.h" | ||
20 | #include "lgh06xf.h" | ||
21 | |||
22 | #define LG_H06XF_PLL_I2C_ADDR 0x61 | ||
23 | |||
24 | struct lgh06xf_priv { | ||
25 | struct i2c_adapter *i2c; | ||
26 | u32 frequency; | ||
27 | }; | ||
28 | |||
29 | static int lgh06xf_release(struct dvb_frontend *fe) | ||
30 | { | ||
31 | kfree(fe->tuner_priv); | ||
32 | fe->tuner_priv = NULL; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static int lgh06xf_set_params(struct dvb_frontend* fe, | ||
37 | struct dvb_frontend_parameters* params) | ||
38 | { | ||
39 | struct lgh06xf_priv *priv = fe->tuner_priv; | ||
40 | u8 buf[4]; | ||
41 | struct i2c_msg msg = { .addr = LG_H06XF_PLL_I2C_ADDR, .flags = 0, | ||
42 | .buf = buf, .len = sizeof(buf) }; | ||
43 | u32 frequency; | ||
44 | int result; | ||
45 | |||
46 | if ((result = dvb_pll_configure(&dvb_pll_lg_tdvs_h06xf, buf, | ||
47 | params->frequency, 0)) < 0) | ||
48 | return result; | ||
49 | else | ||
50 | frequency = result; | ||
51 | |||
52 | if (fe->ops.i2c_gate_ctrl) | ||
53 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
54 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
55 | printk(KERN_WARNING "lgh06xf: %s error " | ||
56 | "(addr %02x <- %02x, result = %i)\n", | ||
57 | __FUNCTION__, buf[0], buf[1], result); | ||
58 | if (result < 0) | ||
59 | return result; | ||
60 | else | ||
61 | return -EREMOTEIO; | ||
62 | } | ||
63 | |||
64 | /* Set the Auxiliary Byte. */ | ||
65 | buf[0] = buf[2]; | ||
66 | buf[0] &= ~0x20; | ||
67 | buf[0] |= 0x18; | ||
68 | buf[1] = 0x50; | ||
69 | msg.len = 2; | ||
70 | if (fe->ops.i2c_gate_ctrl) | ||
71 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
72 | if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { | ||
73 | printk(KERN_WARNING "lgh06xf: %s error " | ||
74 | "(addr %02x <- %02x, result = %i)\n", | ||
75 | __FUNCTION__, buf[0], buf[1], result); | ||
76 | if (result < 0) | ||
77 | return result; | ||
78 | else | ||
79 | return -EREMOTEIO; | ||
80 | } | ||
81 | |||
82 | priv->frequency = frequency; | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int lgh06xf_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
88 | { | ||
89 | struct lgh06xf_priv *priv = fe->tuner_priv; | ||
90 | *frequency = priv->frequency; | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | static struct dvb_tuner_ops lgh06xf_tuner_ops = { | ||
95 | .release = lgh06xf_release, | ||
96 | .set_params = lgh06xf_set_params, | ||
97 | .get_frequency = lgh06xf_get_frequency, | ||
98 | }; | ||
99 | |||
100 | struct dvb_frontend* lgh06xf_attach(struct dvb_frontend *fe, | ||
101 | struct i2c_adapter *i2c) | ||
102 | { | ||
103 | struct lgh06xf_priv *priv = NULL; | ||
104 | |||
105 | priv = kzalloc(sizeof(struct lgh06xf_priv), GFP_KERNEL); | ||
106 | if (priv == NULL) | ||
107 | return NULL; | ||
108 | |||
109 | priv->i2c = i2c; | ||
110 | |||
111 | memcpy(&fe->ops.tuner_ops, &lgh06xf_tuner_ops, | ||
112 | sizeof(struct dvb_tuner_ops)); | ||
113 | |||
114 | strlcpy(fe->ops.tuner_ops.info.name, dvb_pll_lg_tdvs_h06xf.name, | ||
115 | sizeof(fe->ops.tuner_ops.info.name)); | ||
116 | |||
117 | fe->ops.tuner_ops.info.frequency_min = dvb_pll_lg_tdvs_h06xf.min; | ||
118 | fe->ops.tuner_ops.info.frequency_max = dvb_pll_lg_tdvs_h06xf.max; | ||
119 | |||
120 | fe->tuner_priv = priv; | ||
121 | return fe; | ||
122 | } | ||
123 | |||
124 | EXPORT_SYMBOL(lgh06xf_attach); | ||
125 | |||
126 | MODULE_DESCRIPTION("LG TDVS-H06xF ATSC Tuner support"); | ||
127 | MODULE_AUTHOR("Michael Krufky"); | ||
128 | MODULE_LICENSE("GPL"); | ||
129 | |||
130 | /* | ||
131 | * Local variables: | ||
132 | * c-basic-offset: 8 | ||
133 | * End: | ||
134 | */ | ||
diff --git a/drivers/media/dvb/frontends/lgh06xf.h b/drivers/media/dvb/frontends/lgh06xf.h deleted file mode 100644 index 510b4bedfb24..000000000000 --- a/drivers/media/dvb/frontends/lgh06xf.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * lgh06xf.h - ATSC Tuner support for LG TDVS-H06xF | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
17 | */ | ||
18 | |||
19 | #ifndef _LGH06XF_H_ | ||
20 | #define _LGH06XF_H_ | ||
21 | #include "dvb_frontend.h" | ||
22 | |||
23 | #if defined(CONFIG_DVB_TUNER_LGH06XF) || (defined(CONFIG_DVB_TUNER_LGH06XF_MODULE) && defined(MODULE)) | ||
24 | extern struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, | ||
25 | struct i2c_adapter *i2c); | ||
26 | #else | ||
27 | static inline struct dvb_frontend* lgh06xf_attach(struct dvb_frontend* fe, | ||
28 | struct i2c_adapter *i2c) | ||
29 | { | ||
30 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
31 | return NULL; | ||
32 | } | ||
33 | #endif /* CONFIG_DVB_TUNER_LGH06XF */ | ||
34 | |||
35 | #endif /* _LGH06XF_H_ */ | ||
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index 5a3a6e53cda2..4e0aca7c67aa 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -1,6 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM | 2 | * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM |
3 | * | 3 | * |
4 | * | ||
5 | * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org> | ||
6 | * | ||
4 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> | 7 | * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> |
5 | * | 8 | * |
6 | * Based on code from Jack Kelliher (kelliher@xmission.com) | 9 | * Based on code from Jack Kelliher (kelliher@xmission.com) |
@@ -69,46 +72,70 @@ struct or51132_state | |||
69 | u32 current_frequency; | 72 | u32 current_frequency; |
70 | }; | 73 | }; |
71 | 74 | ||
72 | static int i2c_writebytes (struct or51132_state* state, u8 reg, u8 *buf, int len) | 75 | |
76 | /* Write buffer to demod */ | ||
77 | static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len) | ||
73 | { | 78 | { |
74 | int err; | 79 | int err; |
75 | struct i2c_msg msg; | 80 | struct i2c_msg msg = { .addr = state->config->demod_address, |
76 | msg.addr = reg; | 81 | .flags = 0, .buf = (u8*)buf, .len = len }; |
77 | msg.flags = 0; | ||
78 | msg.len = len; | ||
79 | msg.buf = buf; | ||
80 | 82 | ||
83 | /* msleep(20); */ /* doesn't appear to be necessary */ | ||
81 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 84 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
82 | printk(KERN_WARNING "or51132: i2c_writebytes error (addr %02x, err == %i)\n", reg, err); | 85 | printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n", |
86 | msg.addr, msg.len, err); | ||
83 | return -EREMOTEIO; | 87 | return -EREMOTEIO; |
84 | } | 88 | } |
85 | |||
86 | return 0; | 89 | return 0; |
87 | } | 90 | } |
88 | 91 | ||
89 | static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len) | 92 | /* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00); |
93 | Less code and more efficient that loading a buffer on the stack with | ||
94 | the bytes to send and then calling or51132_writebuf() on that. */ | ||
95 | #define or51132_writebytes(state, data...) \ | ||
96 | ({ const static u8 _data[] = {data}; \ | ||
97 | or51132_writebuf(state, _data, sizeof(_data)); }) | ||
98 | |||
99 | /* Read data from demod into buffer. Returns 0 on success. */ | ||
100 | static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len) | ||
90 | { | 101 | { |
91 | int err; | 102 | int err; |
92 | struct i2c_msg msg; | 103 | struct i2c_msg msg = { .addr = state->config->demod_address, |
93 | msg.addr = reg; | 104 | .flags = I2C_M_RD, .buf = buf, .len = len }; |
94 | msg.flags = I2C_M_RD; | ||
95 | msg.len = len; | ||
96 | msg.buf = buf; | ||
97 | 105 | ||
106 | /* msleep(20); */ /* doesn't appear to be necessary */ | ||
98 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 107 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
99 | printk(KERN_WARNING "or51132: i2c_readbytes error (addr %02x, err == %i)\n", reg, err); | 108 | printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n", |
109 | msg.addr, msg.len, err); | ||
100 | return -EREMOTEIO; | 110 | return -EREMOTEIO; |
101 | } | 111 | } |
102 | |||
103 | return 0; | 112 | return 0; |
104 | } | 113 | } |
105 | 114 | ||
115 | /* Reads a 16-bit demod register. Returns <0 on error. */ | ||
116 | static int or51132_readreg(struct or51132_state *state, u8 reg) | ||
117 | { | ||
118 | u8 buf[2] = { 0x04, reg }; | ||
119 | struct i2c_msg msg[2] = { | ||
120 | {.addr = state->config->demod_address, .flags = 0, | ||
121 | .buf = buf, .len = 2 }, | ||
122 | {.addr = state->config->demod_address, .flags = I2C_M_RD, | ||
123 | .buf = buf, .len = 2 }}; | ||
124 | int err; | ||
125 | |||
126 | if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) { | ||
127 | printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n", | ||
128 | reg, err); | ||
129 | return -EREMOTEIO; | ||
130 | } | ||
131 | return le16_to_cpup((u16*)buf); | ||
132 | } | ||
133 | |||
106 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 134 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) |
107 | { | 135 | { |
108 | struct or51132_state* state = fe->demodulator_priv; | 136 | struct or51132_state* state = fe->demodulator_priv; |
109 | static u8 run_buf[] = {0x7F,0x01}; | 137 | const static u8 run_buf[] = {0x7F,0x01}; |
110 | u8 rec_buf[8]; | 138 | u8 rec_buf[8]; |
111 | u8 cmd_buf[3]; | ||
112 | u32 firmwareAsize, firmwareBsize; | 139 | u32 firmwareAsize, firmwareBsize; |
113 | int i,ret; | 140 | int i,ret; |
114 | 141 | ||
@@ -121,30 +148,21 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
121 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); | 148 | dprintk("FirmwareB is %i bytes\n",firmwareBsize); |
122 | 149 | ||
123 | /* Upload firmware */ | 150 | /* Upload firmware */ |
124 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 151 | if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) { |
125 | &fw->data[8],firmwareAsize))) { | ||
126 | printk(KERN_WARNING "or51132: load_firmware error 1\n"); | 152 | printk(KERN_WARNING "or51132: load_firmware error 1\n"); |
127 | return ret; | 153 | return ret; |
128 | } | 154 | } |
129 | msleep(1); /* 1ms */ | 155 | if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize], |
130 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 156 | firmwareBsize))) { |
131 | &fw->data[8+firmwareAsize],firmwareBsize))) { | ||
132 | printk(KERN_WARNING "or51132: load_firmware error 2\n"); | 157 | printk(KERN_WARNING "or51132: load_firmware error 2\n"); |
133 | return ret; | 158 | return ret; |
134 | } | 159 | } |
135 | msleep(1); /* 1ms */ | ||
136 | 160 | ||
137 | if ((ret = i2c_writebytes(state,state->config->demod_address, | 161 | if ((ret = or51132_writebuf(state, run_buf, 2))) { |
138 | run_buf,2))) { | ||
139 | printk(KERN_WARNING "or51132: load_firmware error 3\n"); | 162 | printk(KERN_WARNING "or51132: load_firmware error 3\n"); |
140 | return ret; | 163 | return ret; |
141 | } | 164 | } |
142 | 165 | if ((ret = or51132_writebuf(state, run_buf, 2))) { | |
143 | /* Wait at least 5 msec */ | ||
144 | msleep(20); /* 10ms */ | ||
145 | |||
146 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
147 | run_buf,2))) { | ||
148 | printk(KERN_WARNING "or51132: load_firmware error 4\n"); | 166 | printk(KERN_WARNING "or51132: load_firmware error 4\n"); |
149 | return ret; | 167 | return ret; |
150 | } | 168 | } |
@@ -154,43 +172,25 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
154 | 172 | ||
155 | /* Read back ucode version to besure we loaded correctly and are really up and running */ | 173 | /* Read back ucode version to besure we loaded correctly and are really up and running */ |
156 | /* Get uCode version */ | 174 | /* Get uCode version */ |
157 | cmd_buf[0] = 0x10; | 175 | if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) { |
158 | cmd_buf[1] = 0x10; | ||
159 | cmd_buf[2] = 0x00; | ||
160 | msleep(20); /* 20ms */ | ||
161 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
162 | cmd_buf,3))) { | ||
163 | printk(KERN_WARNING "or51132: load_firmware error a\n"); | 176 | printk(KERN_WARNING "or51132: load_firmware error a\n"); |
164 | return ret; | 177 | return ret; |
165 | } | 178 | } |
166 | 179 | if ((ret = or51132_writebytes(state, 0x04, 0x17))) { | |
167 | cmd_buf[0] = 0x04; | ||
168 | cmd_buf[1] = 0x17; | ||
169 | msleep(20); /* 20ms */ | ||
170 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
171 | cmd_buf,2))) { | ||
172 | printk(KERN_WARNING "or51132: load_firmware error b\n"); | 180 | printk(KERN_WARNING "or51132: load_firmware error b\n"); |
173 | return ret; | 181 | return ret; |
174 | } | 182 | } |
175 | 183 | if ((ret = or51132_writebytes(state, 0x00, 0x00))) { | |
176 | cmd_buf[0] = 0x00; | ||
177 | cmd_buf[1] = 0x00; | ||
178 | msleep(20); /* 20ms */ | ||
179 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
180 | cmd_buf,2))) { | ||
181 | printk(KERN_WARNING "or51132: load_firmware error c\n"); | 184 | printk(KERN_WARNING "or51132: load_firmware error c\n"); |
182 | return ret; | 185 | return ret; |
183 | } | 186 | } |
184 | 187 | for (i=0;i<4;i++) { | |
185 | for(i=0;i<4;i++) { | ||
186 | msleep(20); /* 20ms */ | ||
187 | /* Once upon a time, this command might have had something | 188 | /* Once upon a time, this command might have had something |
188 | to do with getting the firmware version, but it's | 189 | to do with getting the firmware version, but it's |
189 | not used anymore: | 190 | not used anymore: |
190 | {0x04,0x00,0x30,0x00,i+1} */ | 191 | {0x04,0x00,0x30,0x00,i+1} */ |
191 | /* Read 8 bytes, two bytes at a time */ | 192 | /* Read 8 bytes, two bytes at a time */ |
192 | if ((ret = i2c_readbytes(state,state->config->demod_address, | 193 | if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) { |
193 | &rec_buf[i*2],2))) { | ||
194 | printk(KERN_WARNING | 194 | printk(KERN_WARNING |
195 | "or51132: load_firmware error d - %d\n",i); | 195 | "or51132: load_firmware error d - %d\n",i); |
196 | return ret; | 196 | return ret; |
@@ -204,12 +204,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
204 | rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, | 204 | rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, |
205 | rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); | 205 | rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); |
206 | 206 | ||
207 | cmd_buf[0] = 0x10; | 207 | if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) { |
208 | cmd_buf[1] = 0x00; | ||
209 | cmd_buf[2] = 0x00; | ||
210 | msleep(20); /* 20ms */ | ||
211 | if ((ret = i2c_writebytes(state,state->config->demod_address, | ||
212 | cmd_buf,3))) { | ||
213 | printk(KERN_WARNING "or51132: load_firmware error e\n"); | 208 | printk(KERN_WARNING "or51132: load_firmware error e\n"); |
214 | return ret; | 209 | return ret; |
215 | } | 210 | } |
@@ -241,70 +236,55 @@ static int or51132_sleep(struct dvb_frontend* fe) | |||
241 | static int or51132_setmode(struct dvb_frontend* fe) | 236 | static int or51132_setmode(struct dvb_frontend* fe) |
242 | { | 237 | { |
243 | struct or51132_state* state = fe->demodulator_priv; | 238 | struct or51132_state* state = fe->demodulator_priv; |
244 | unsigned char cmd_buf[3]; | 239 | u8 cmd_buf1[3] = {0x04, 0x01, 0x5f}; |
240 | u8 cmd_buf2[3] = {0x1c, 0x00, 0 }; | ||
245 | 241 | ||
246 | dprintk("setmode %d\n",(int)state->current_modulation); | 242 | dprintk("setmode %d\n",(int)state->current_modulation); |
247 | /* set operation mode in Receiver 1 register; */ | 243 | |
248 | cmd_buf[0] = 0x04; | ||
249 | cmd_buf[1] = 0x01; | ||
250 | switch (state->current_modulation) { | 244 | switch (state->current_modulation) { |
251 | case QAM_256: | ||
252 | case QAM_64: | ||
253 | case QAM_AUTO: | ||
254 | /* Auto-deinterleave; MPEG ser, MPEG2tr, phase noise-high*/ | ||
255 | cmd_buf[2] = 0x5F; | ||
256 | break; | ||
257 | case VSB_8: | 245 | case VSB_8: |
258 | /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high*/ | 246 | /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */ |
259 | cmd_buf[2] = 0x50; | 247 | cmd_buf1[2] = 0x50; |
248 | /* REC MODE inv IF spectrum, Normal */ | ||
249 | cmd_buf2[1] = 0x03; | ||
250 | /* Channel MODE ATSC/VSB8 */ | ||
251 | cmd_buf2[2] = 0x06; | ||
260 | break; | 252 | break; |
261 | default: | 253 | /* All QAM modes are: |
262 | printk("setmode:Modulation set to unsupported value\n"); | 254 | Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high |
263 | }; | 255 | REC MODE Normal Carrier Lock */ |
264 | if (i2c_writebytes(state,state->config->demod_address, | ||
265 | cmd_buf,3)) { | ||
266 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | ||
267 | return -1; | ||
268 | } | ||
269 | dprintk("or51132: set #1 to %02x\n", cmd_buf[2]); | ||
270 | |||
271 | /* Set operation mode in Receiver 6 register */ | ||
272 | cmd_buf[0] = 0x1C; | ||
273 | switch (state->current_modulation) { | ||
274 | case QAM_AUTO: | 256 | case QAM_AUTO: |
275 | /* REC MODE Normal Carrier Lock */ | ||
276 | cmd_buf[1] = 0x00; | ||
277 | /* Channel MODE Auto QAM64/256 */ | 257 | /* Channel MODE Auto QAM64/256 */ |
278 | cmd_buf[2] = 0x4f; | 258 | cmd_buf2[2] = 0x4f; |
279 | break; | 259 | break; |
280 | case QAM_256: | 260 | case QAM_256: |
281 | /* REC MODE Normal Carrier Lock */ | ||
282 | cmd_buf[1] = 0x00; | ||
283 | /* Channel MODE QAM256 */ | 261 | /* Channel MODE QAM256 */ |
284 | cmd_buf[2] = 0x45; | 262 | cmd_buf2[2] = 0x45; |
285 | break; | 263 | break; |
286 | case QAM_64: | 264 | case QAM_64: |
287 | /* REC MODE Normal Carrier Lock */ | ||
288 | cmd_buf[1] = 0x00; | ||
289 | /* Channel MODE QAM64 */ | 265 | /* Channel MODE QAM64 */ |
290 | cmd_buf[2] = 0x43; | 266 | cmd_buf2[2] = 0x43; |
291 | break; | ||
292 | case VSB_8: | ||
293 | /* REC MODE inv IF spectrum, Normal */ | ||
294 | cmd_buf[1] = 0x03; | ||
295 | /* Channel MODE ATSC/VSB8 */ | ||
296 | cmd_buf[2] = 0x06; | ||
297 | break; | 267 | break; |
298 | default: | 268 | default: |
299 | printk("setmode: Modulation set to unsupported value\n"); | 269 | printk(KERN_WARNING |
300 | }; | 270 | "or51132: setmode: Modulation set to unsupported value (%d)\n", |
301 | msleep(20); /* 20ms */ | 271 | state->current_modulation); |
302 | if (i2c_writebytes(state,state->config->demod_address, | 272 | return -EINVAL; |
303 | cmd_buf,3)) { | 273 | } |
274 | |||
275 | /* Set Receiver 1 register */ | ||
276 | if (or51132_writebuf(state, cmd_buf1, 3)) { | ||
277 | printk(KERN_WARNING "or51132: set_mode error 1\n"); | ||
278 | return -EREMOTEIO; | ||
279 | } | ||
280 | dprintk("set #1 to %02x\n", cmd_buf1[2]); | ||
281 | |||
282 | /* Set operation mode in Receiver 6 register */ | ||
283 | if (or51132_writebuf(state, cmd_buf2, 3)) { | ||
304 | printk(KERN_WARNING "or51132: set_mode error 2\n"); | 284 | printk(KERN_WARNING "or51132: set_mode error 2\n"); |
305 | return -1; | 285 | return -EREMOTEIO; |
306 | } | 286 | } |
307 | dprintk("or51132: set #6 to 0x%02x%02x\n", cmd_buf[1], cmd_buf[2]); | 287 | dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]); |
308 | 288 | ||
309 | return 0; | 289 | return 0; |
310 | } | 290 | } |
@@ -401,28 +381,23 @@ static int or51132_get_parameters(struct dvb_frontend* fe, | |||
401 | struct dvb_frontend_parameters *param) | 381 | struct dvb_frontend_parameters *param) |
402 | { | 382 | { |
403 | struct or51132_state* state = fe->demodulator_priv; | 383 | struct or51132_state* state = fe->demodulator_priv; |
404 | u8 buf[2]; | 384 | int status; |
385 | int retry = 1; | ||
405 | 386 | ||
387 | start: | ||
406 | /* Receiver Status */ | 388 | /* Receiver Status */ |
407 | buf[0]=0x04; | 389 | if ((status = or51132_readreg(state, 0x00)) < 0) { |
408 | buf[1]=0x00; | 390 | printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n"); |
409 | msleep(30); /* 30ms */ | ||
410 | if (i2c_writebytes(state,state->config->demod_address,buf,2)) { | ||
411 | printk(KERN_WARNING "or51132: get_parameters write error\n"); | ||
412 | return -EREMOTEIO; | ||
413 | } | ||
414 | msleep(30); /* 30ms */ | ||
415 | if (i2c_readbytes(state,state->config->demod_address,buf,2)) { | ||
416 | printk(KERN_WARNING "or51132: get_parameters read error\n"); | ||
417 | return -EREMOTEIO; | 391 | return -EREMOTEIO; |
418 | } | 392 | } |
419 | switch(buf[0]) { | 393 | switch(status&0xff) { |
420 | case 0x06: param->u.vsb.modulation = VSB_8; break; | 394 | case 0x06: param->u.vsb.modulation = VSB_8; break; |
421 | case 0x43: param->u.vsb.modulation = QAM_64; break; | 395 | case 0x43: param->u.vsb.modulation = QAM_64; break; |
422 | case 0x45: param->u.vsb.modulation = QAM_256; break; | 396 | case 0x45: param->u.vsb.modulation = QAM_256; break; |
423 | default: | 397 | default: |
398 | if (retry--) goto start; | ||
424 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", | 399 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", |
425 | buf[0]); | 400 | status&0xff); |
426 | return -EREMOTEIO; | 401 | return -EREMOTEIO; |
427 | } | 402 | } |
428 | 403 | ||
@@ -438,32 +413,21 @@ static int or51132_get_parameters(struct dvb_frontend* fe, | |||
438 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) | 413 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) |
439 | { | 414 | { |
440 | struct or51132_state* state = fe->demodulator_priv; | 415 | struct or51132_state* state = fe->demodulator_priv; |
441 | unsigned char rec_buf[2]; | 416 | int reg; |
442 | unsigned char snd_buf[2]; | ||
443 | *status = 0; | ||
444 | 417 | ||
445 | /* Receiver Status */ | 418 | /* Receiver Status */ |
446 | snd_buf[0]=0x04; | 419 | if ((reg = or51132_readreg(state, 0x00)) < 0) { |
447 | snd_buf[1]=0x00; | 420 | printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg); |
448 | msleep(30); /* 30ms */ | 421 | *status = 0; |
449 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | 422 | return -EREMOTEIO; |
450 | printk(KERN_WARNING "or51132: read_status write error\n"); | ||
451 | return -1; | ||
452 | } | ||
453 | msleep(30); /* 30ms */ | ||
454 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
455 | printk(KERN_WARNING "or51132: read_status read error\n"); | ||
456 | return -1; | ||
457 | } | ||
458 | dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]); | ||
459 | |||
460 | if (rec_buf[1] & 0x01) { /* Receiver Lock */ | ||
461 | *status |= FE_HAS_SIGNAL; | ||
462 | *status |= FE_HAS_CARRIER; | ||
463 | *status |= FE_HAS_VITERBI; | ||
464 | *status |= FE_HAS_SYNC; | ||
465 | *status |= FE_HAS_LOCK; | ||
466 | } | 423 | } |
424 | dprintk("%s: read_status %04x\n", __FUNCTION__, reg); | ||
425 | |||
426 | if (reg & 0x0100) /* Receiver Lock */ | ||
427 | *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI| | ||
428 | FE_HAS_SYNC|FE_HAS_LOCK; | ||
429 | else | ||
430 | *status = 0; | ||
467 | return 0; | 431 | return 0; |
468 | } | 432 | } |
469 | 433 | ||
@@ -506,47 +470,30 @@ static u32 calculate_snr(u32 mse, u32 c) | |||
506 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) | 470 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) |
507 | { | 471 | { |
508 | struct or51132_state* state = fe->demodulator_priv; | 472 | struct or51132_state* state = fe->demodulator_priv; |
509 | u8 rec_buf[2]; | 473 | int noise, reg; |
510 | u8 snd_buf[2]; | 474 | u32 c, usK = 0; |
511 | u32 noise; | 475 | int retry = 1; |
512 | u32 c; | 476 | |
513 | u32 usK; | 477 | start: |
514 | 478 | /* SNR after Equalizer */ | |
515 | /* Register is same for VSB or QAM firmware */ | 479 | noise = or51132_readreg(state, 0x02); |
516 | snd_buf[0]=0x04; | 480 | if (noise < 0) { |
517 | snd_buf[1]=0x02; /* SNR after Equalizer */ | 481 | printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n"); |
518 | msleep(30); /* 30ms */ | ||
519 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | ||
520 | printk(KERN_WARNING "or51132: snr write error\n"); | ||
521 | return -EREMOTEIO; | ||
522 | } | ||
523 | msleep(30); /* 30ms */ | ||
524 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
525 | printk(KERN_WARNING "or51132: snr read error\n"); | ||
526 | return -EREMOTEIO; | 482 | return -EREMOTEIO; |
527 | } | 483 | } |
528 | noise = rec_buf[0] | (rec_buf[1] << 8); | 484 | dprintk("read_snr noise (%d)\n", noise); |
529 | dprintk("read_snr noise %x %x (%i)\n",rec_buf[0],rec_buf[1],noise); | ||
530 | 485 | ||
531 | /* Read status, contains modulation type for QAM_AUTO and | 486 | /* Read status, contains modulation type for QAM_AUTO and |
532 | NTSC filter for VSB */ | 487 | NTSC filter for VSB */ |
533 | snd_buf[0]=0x04; | 488 | reg = or51132_readreg(state, 0x00); |
534 | snd_buf[1]=0x00; /* Status register */ | 489 | if (reg < 0) { |
535 | msleep(30); /* 30ms */ | 490 | printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n"); |
536 | if (i2c_writebytes(state,state->config->demod_address,snd_buf,2)) { | ||
537 | printk(KERN_WARNING "or51132: status write error\n"); | ||
538 | return -EREMOTEIO; | ||
539 | } | ||
540 | msleep(30); /* 30ms */ | ||
541 | if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { | ||
542 | printk(KERN_WARNING "or51132: status read error\n"); | ||
543 | return -EREMOTEIO; | 491 | return -EREMOTEIO; |
544 | } | 492 | } |
545 | 493 | ||
546 | usK = 0; | 494 | switch (reg&0xff) { |
547 | switch (rec_buf[0]) { | ||
548 | case 0x06: | 495 | case 0x06: |
549 | usK = (rec_buf[1] & 0x10) ? 0x03000000 : 0; | 496 | if (reg & 0x1000) usK = 3 << 24; |
550 | /* Fall through to QAM64 case */ | 497 | /* Fall through to QAM64 case */ |
551 | case 0x43: | 498 | case 0x43: |
552 | c = 150204167; | 499 | c = 150204167; |
@@ -555,11 +502,12 @@ static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) | |||
555 | c = 150290396; | 502 | c = 150290396; |
556 | break; | 503 | break; |
557 | default: | 504 | default: |
558 | printk(KERN_ERR "or51132: unknown status 0x%02x\n", rec_buf[0]); | 505 | printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff); |
506 | if (retry--) goto start; | ||
559 | return -EREMOTEIO; | 507 | return -EREMOTEIO; |
560 | } | 508 | } |
561 | dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, | 509 | dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__, |
562 | rec_buf[0], rec_buf[1]&0x10?"n":"ff"); | 510 | reg&0xff, reg&0x1000?"n":"ff"); |
563 | 511 | ||
564 | /* Calculate SNR using noise, c, and NTSC rejection correction */ | 512 | /* Calculate SNR using noise, c, and NTSC rejection correction */ |
565 | state->snr = calculate_snr(noise, c) - usK; | 513 | state->snr = calculate_snr(noise, c) - usK; |
@@ -671,6 +619,7 @@ MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | |||
671 | 619 | ||
672 | MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); | 620 | MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); |
673 | MODULE_AUTHOR("Kirk Lapray"); | 621 | MODULE_AUTHOR("Kirk Lapray"); |
622 | MODULE_AUTHOR("Trent Piepho"); | ||
674 | MODULE_LICENSE("GPL"); | 623 | MODULE_LICENSE("GPL"); |
675 | 624 | ||
676 | EXPORT_SYMBOL(or51132_attach); | 625 | EXPORT_SYMBOL(or51132_attach); |
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 5b9c5bb29b23..110536843e8e 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -30,13 +30,13 @@ | |||
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | 31 | ||
32 | #include "dvb_frontend.h" | 32 | #include "dvb_frontend.h" |
33 | #include "tda10021.h" | 33 | #include "tda1002x.h" |
34 | 34 | ||
35 | 35 | ||
36 | struct tda10021_state { | 36 | struct tda10021_state { |
37 | struct i2c_adapter* i2c; | 37 | struct i2c_adapter* i2c; |
38 | /* configuration settings */ | 38 | /* configuration settings */ |
39 | const struct tda10021_config* config; | 39 | const struct tda1002x_config* config; |
40 | struct dvb_frontend frontend; | 40 | struct dvb_frontend frontend; |
41 | 41 | ||
42 | u8 pwm; | 42 | u8 pwm; |
@@ -53,9 +53,6 @@ struct tda10021_state { | |||
53 | static int verbose; | 53 | static int verbose; |
54 | 54 | ||
55 | #define XIN 57840000UL | 55 | #define XIN 57840000UL |
56 | #define DISABLE_INVERSION(reg0) do { reg0 |= 0x20; } while (0) | ||
57 | #define ENABLE_INVERSION(reg0) do { reg0 &= ~0x20; } while (0) | ||
58 | #define HAS_INVERSION(reg0) (!(reg0 & 0x20)) | ||
59 | 56 | ||
60 | #define FIN (XIN >> 4) | 57 | #define FIN (XIN >> 4) |
61 | 58 | ||
@@ -64,7 +61,7 @@ static u8 tda10021_inittab[0x40]= | |||
64 | { | 61 | { |
65 | 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, | 62 | 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, |
66 | 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, | 63 | 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, |
67 | 0xb8, 0x3f, 0xa0, 0x00, 0xcd, 0x01, 0x00, 0xff, | 64 | 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff, |
68 | 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, | 65 | 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, |
69 | 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, | 66 | 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, |
70 | 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, | 67 | 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, |
@@ -97,7 +94,8 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) | |||
97 | int ret; | 94 | int ret; |
98 | 95 | ||
99 | ret = i2c_transfer (state->i2c, msg, 2); | 96 | ret = i2c_transfer (state->i2c, msg, 2); |
100 | if (ret != 2) | 97 | // Don't print an error message if the id is read. |
98 | if (ret != 2 && reg != 0x1a) | ||
101 | printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", | 99 | printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", |
102 | __FUNCTION__, ret); | 100 | __FUNCTION__, ret); |
103 | return b1[0]; | 101 | return b1[0]; |
@@ -136,10 +134,10 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, | |||
136 | { | 134 | { |
137 | reg0 |= state->reg0 & 0x63; | 135 | reg0 |= state->reg0 & 0x63; |
138 | 136 | ||
139 | if (INVERSION_ON == inversion) | 137 | if ((INVERSION_ON == inversion) ^ (state->config->invert == 0)) |
140 | ENABLE_INVERSION(reg0); | 138 | reg0 &= ~0x20; |
141 | else if (INVERSION_OFF == inversion) | 139 | else |
142 | DISABLE_INVERSION(reg0); | 140 | reg0 |= 0x20; |
143 | 141 | ||
144 | _tda10021_writereg (state, 0x00, reg0 & 0xfe); | 142 | _tda10021_writereg (state, 0x00, reg0 & 0xfe); |
145 | _tda10021_writereg (state, 0x00, reg0 | 0x01); | 143 | _tda10021_writereg (state, 0x00, reg0 | 0x01); |
@@ -201,16 +199,6 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate | |||
201 | return 0; | 199 | return 0; |
202 | } | 200 | } |
203 | 201 | ||
204 | static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) | ||
205 | { | ||
206 | struct tda10021_state* state = fe->demodulator_priv; | ||
207 | |||
208 | if (len != 2) | ||
209 | return -EINVAL; | ||
210 | |||
211 | return _tda10021_writereg(state, buf[0], buf[1]); | ||
212 | } | ||
213 | |||
214 | static int tda10021_init (struct dvb_frontend *fe) | 202 | static int tda10021_init (struct dvb_frontend *fe) |
215 | { | 203 | { |
216 | struct tda10021_state* state = fe->demodulator_priv; | 204 | struct tda10021_state* state = fe->demodulator_priv; |
@@ -258,6 +246,9 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
258 | if (qam < 0 || qam > 5) | 246 | if (qam < 0 || qam > 5) |
259 | return -EINVAL; | 247 | return -EINVAL; |
260 | 248 | ||
249 | if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) | ||
250 | return -EINVAL; | ||
251 | |||
261 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); | 252 | //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); |
262 | 253 | ||
263 | if (fe->ops.tuner_ops.set_params) { | 254 | if (fe->ops.tuner_ops.set_params) { |
@@ -366,7 +357,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
366 | -((s32)p->u.qam.symbol_rate * afc) >> 10); | 357 | -((s32)p->u.qam.symbol_rate * afc) >> 10); |
367 | } | 358 | } |
368 | 359 | ||
369 | p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF; | 360 | p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF; |
370 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; | 361 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; |
371 | 362 | ||
372 | p->u.qam.fec_inner = FEC_NONE; | 363 | p->u.qam.fec_inner = FEC_NONE; |
@@ -408,11 +399,12 @@ static void tda10021_release(struct dvb_frontend* fe) | |||
408 | 399 | ||
409 | static struct dvb_frontend_ops tda10021_ops; | 400 | static struct dvb_frontend_ops tda10021_ops; |
410 | 401 | ||
411 | struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 402 | struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
412 | struct i2c_adapter* i2c, | 403 | struct i2c_adapter* i2c, |
413 | u8 pwm) | 404 | u8 pwm) |
414 | { | 405 | { |
415 | struct tda10021_state* state = NULL; | 406 | struct tda10021_state* state = NULL; |
407 | u8 id; | ||
416 | 408 | ||
417 | /* allocate memory for the internal state */ | 409 | /* allocate memory for the internal state */ |
418 | state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); | 410 | state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); |
@@ -425,7 +417,11 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
425 | state->reg0 = tda10021_inittab[0]; | 417 | state->reg0 = tda10021_inittab[0]; |
426 | 418 | ||
427 | /* check if the demod is there */ | 419 | /* check if the demod is there */ |
428 | if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | 420 | id = tda10021_readreg(state, 0x1a); |
421 | if ((id & 0xf0) != 0x70) goto error; | ||
422 | |||
423 | printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", | ||
424 | state->config->demod_address, id); | ||
429 | 425 | ||
430 | /* create dvb_frontend */ | 426 | /* create dvb_frontend */ |
431 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); | 427 | memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); |
@@ -447,7 +443,7 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
447 | .frequency_max = 858000000, | 443 | .frequency_max = 858000000, |
448 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ | 444 | .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ |
449 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ | 445 | .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ |
450 | #if 0 | 446 | #if 0 |
451 | .frequency_tolerance = ???, | 447 | .frequency_tolerance = ???, |
452 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ | 448 | .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ |
453 | #endif | 449 | #endif |
@@ -461,7 +457,6 @@ static struct dvb_frontend_ops tda10021_ops = { | |||
461 | 457 | ||
462 | .init = tda10021_init, | 458 | .init = tda10021_init, |
463 | .sleep = tda10021_sleep, | 459 | .sleep = tda10021_sleep, |
464 | .write = tda10021_write, | ||
465 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, | 460 | .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, |
466 | 461 | ||
467 | .set_frontend = tda10021_set_parameters, | 462 | .set_frontend = tda10021_set_parameters, |
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c new file mode 100644 index 000000000000..da796e784be3 --- /dev/null +++ b/drivers/media/dvb/frontends/tda10023.c | |||
@@ -0,0 +1,540 @@ | |||
1 | /* | ||
2 | TDA10023 - DVB-C decoder | ||
3 | (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card) | ||
4 | |||
5 | Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de) | ||
6 | Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com) | ||
7 | |||
8 | Remotely based on tda10021.c | ||
9 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> | ||
10 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> | ||
11 | Support for TDA10021 | ||
12 | |||
13 | This program is free software; you can redistribute it and/or modify | ||
14 | it under the terms of the GNU General Public License as published by | ||
15 | the Free Software Foundation; either version 2 of the License, or | ||
16 | (at your option) any later version. | ||
17 | |||
18 | This program is distributed in the hope that it will be useful, | ||
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | GNU General Public License for more details. | ||
22 | |||
23 | You should have received a copy of the GNU General Public License | ||
24 | along with this program; if not, write to the Free Software | ||
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | ||
27 | |||
28 | #include <linux/delay.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/slab.h> | ||
35 | |||
36 | #include <asm/div64.h> | ||
37 | |||
38 | #include "dvb_frontend.h" | ||
39 | #include "tda1002x.h" | ||
40 | |||
41 | |||
42 | struct tda10023_state { | ||
43 | struct i2c_adapter* i2c; | ||
44 | /* configuration settings */ | ||
45 | const struct tda1002x_config* config; | ||
46 | struct dvb_frontend frontend; | ||
47 | |||
48 | u8 pwm; | ||
49 | u8 reg0; | ||
50 | }; | ||
51 | |||
52 | |||
53 | #define dprintk(x...) | ||
54 | |||
55 | static int verbose; | ||
56 | |||
57 | #define XTAL 28920000UL | ||
58 | #define PLL_M 8UL | ||
59 | #define PLL_P 4UL | ||
60 | #define PLL_N 1UL | ||
61 | #define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000 | ||
62 | |||
63 | static u8 tda10023_inittab[]={ | ||
64 | // reg mask val | ||
65 | 0x2a,0xff,0x02, // PLL3, Bypass, Power Down | ||
66 | 0xff,0x64,0x00, // Sleep 100ms | ||
67 | 0x2a,0xff,0x03, // PLL3, Bypass, Power Down | ||
68 | 0xff,0x64,0x00, // Sleep 100ms | ||
69 | 0x28,0xff,PLL_M-1, // PLL1 M=8 | ||
70 | 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2 | ||
71 | 0x00,0xff,0x23, // GPR FSAMPLING=1 | ||
72 | 0x2a,0xff,0x08, // PLL3 PSACLK=1 | ||
73 | 0xff,0x64,0x00, // Sleep 100ms | ||
74 | 0x1f,0xff,0x00, // RESET | ||
75 | 0xff,0x64,0x00, // Sleep 100ms | ||
76 | 0xe6,0x0c,0x04, // RSCFG_IND | ||
77 | 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1 | ||
78 | |||
79 | 0x0e,0xff,0x82, // GAIN1 | ||
80 | 0x03,0x08,0x08, // CLKCONF DYN=1 | ||
81 | 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0 | ||
82 | 0x01,0xff,0x30, // AGCREF | ||
83 | 0x1e,0x84,0x84, // CONTROL SACLK_ON=1 | ||
84 | 0x1b,0xff,0xc8, // ADC TWOS=1 | ||
85 | 0x3b,0xff,0xff, // IFMAX | ||
86 | 0x3c,0xff,0x00, // IFMIN | ||
87 | 0x34,0xff,0x00, // PWMREF | ||
88 | 0x35,0xff,0xff, // TUNMAX | ||
89 | 0x36,0xff,0x00, // TUNMIN | ||
90 | 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77 | ||
91 | 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1 | ||
92 | 0x37,0xff,0xf6, // DELTAF_LSB | ||
93 | 0x38,0xff,0xff, // DELTAF_MSB | ||
94 | 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 | ||
95 | 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 | ||
96 | 0x04,0x10,0x00, // SWRAMP=1 | ||
97 | 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0 | ||
98 | 0x2b,0x01,0xa1, // INTS1 | ||
99 | 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? | ||
100 | 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0 | ||
101 | 0xc4,0xff,0x00, | ||
102 | 0xc3,0x30,0x00, | ||
103 | 0xb5,0xff,0x19, // ERAGC_THD | ||
104 | 0x00,0x03,0x01, // GPR, CLBS soft reset | ||
105 | 0x00,0x03,0x03, // GPR, CLBS soft reset | ||
106 | 0xff,0x64,0x00, // Sleep 100ms | ||
107 | 0xff,0xff,0xff | ||
108 | }; | ||
109 | |||
110 | static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) | ||
111 | { | ||
112 | u8 b0 [] = { reg }; | ||
113 | u8 b1 [] = { 0 }; | ||
114 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, | ||
115 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | ||
116 | int ret; | ||
117 | |||
118 | ret = i2c_transfer (state->i2c, msg, 2); | ||
119 | if (ret != 2) | ||
120 | printk("DVB: TDA10023: %s: readreg error (ret == %i)\n", | ||
121 | __FUNCTION__, ret); | ||
122 | return b1[0]; | ||
123 | } | ||
124 | |||
125 | static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) | ||
126 | { | ||
127 | u8 buf[] = { reg, data }; | ||
128 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
129 | int ret; | ||
130 | |||
131 | ret = i2c_transfer (state->i2c, &msg, 1); | ||
132 | if (ret != 1) | ||
133 | printk("DVB: TDA10023(%d): %s, writereg error " | ||
134 | "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
135 | state->frontend.dvb->num, __FUNCTION__, reg, data, ret); | ||
136 | |||
137 | return (ret != 1) ? -EREMOTEIO : 0; | ||
138 | } | ||
139 | |||
140 | |||
141 | static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data) | ||
142 | { | ||
143 | if (mask==0xff) | ||
144 | return tda10023_writereg(state, reg, data); | ||
145 | else { | ||
146 | u8 val; | ||
147 | val=tda10023_readreg(state,reg); | ||
148 | val&=~mask; | ||
149 | val|=(data&mask); | ||
150 | return tda10023_writereg(state, reg, val); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | static void tda10023_writetab(struct tda10023_state* state, u8* tab) | ||
155 | { | ||
156 | u8 r,m,v; | ||
157 | while (1) { | ||
158 | r=*tab++; | ||
159 | m=*tab++; | ||
160 | v=*tab++; | ||
161 | if (r==0xff) { | ||
162 | if (m==0xff) | ||
163 | break; | ||
164 | else | ||
165 | msleep(m); | ||
166 | } | ||
167 | else | ||
168 | tda10023_writebit(state,r,m,v); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | //get access to tuner | ||
173 | static int lock_tuner(struct tda10023_state* state) | ||
174 | { | ||
175 | u8 buf[2] = { 0x0f, 0xc0 }; | ||
176 | struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; | ||
177 | |||
178 | if(i2c_transfer(state->i2c, &msg, 1) != 1) | ||
179 | { | ||
180 | printk("tda10023: lock tuner fails\n"); | ||
181 | return -EREMOTEIO; | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | //release access from tuner | ||
187 | static int unlock_tuner(struct tda10023_state* state) | ||
188 | { | ||
189 | u8 buf[2] = { 0x0f, 0x40 }; | ||
190 | struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; | ||
191 | |||
192 | if(i2c_transfer(state->i2c, &msg_post, 1) != 1) | ||
193 | { | ||
194 | printk("tda10023: unlock tuner fails\n"); | ||
195 | return -EREMOTEIO; | ||
196 | } | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0) | ||
201 | { | ||
202 | reg0 |= state->reg0 & 0x63; | ||
203 | |||
204 | tda10023_writereg (state, 0x00, reg0 & 0xfe); | ||
205 | tda10023_writereg (state, 0x00, reg0 | 0x01); | ||
206 | |||
207 | state->reg0 = reg0; | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) | ||
212 | { | ||
213 | s32 BDR; | ||
214 | s32 BDRI; | ||
215 | s16 SFIL=0; | ||
216 | u16 NDEC = 0; | ||
217 | |||
218 | if (sr > (SYSCLK/(2*4))) | ||
219 | sr=SYSCLK/(2*4); | ||
220 | |||
221 | if (sr<870000) | ||
222 | sr=870000; | ||
223 | |||
224 | if (sr < (u32)(SYSCLK/98.40)) { | ||
225 | NDEC=3; | ||
226 | SFIL=1; | ||
227 | } else if (sr<(u32)(SYSCLK/64.0)) { | ||
228 | NDEC=3; | ||
229 | SFIL=0; | ||
230 | } else if (sr<(u32)(SYSCLK/49.2)) { | ||
231 | NDEC=2; | ||
232 | SFIL=1; | ||
233 | } else if (sr<(u32)(SYSCLK/32.0)) { | ||
234 | NDEC=2; | ||
235 | SFIL=0; | ||
236 | } else if (sr<(u32)(SYSCLK/24.6)) { | ||
237 | NDEC=1; | ||
238 | SFIL=1; | ||
239 | } else if (sr<(u32)(SYSCLK/16.0)) { | ||
240 | NDEC=1; | ||
241 | SFIL=0; | ||
242 | } else if (sr<(u32)(SYSCLK/12.3)) { | ||
243 | NDEC=0; | ||
244 | SFIL=1; | ||
245 | } | ||
246 | |||
247 | BDRI=SYSCLK*16; | ||
248 | BDRI>>=NDEC; | ||
249 | BDRI +=sr/2; | ||
250 | BDRI /=sr; | ||
251 | |||
252 | if (BDRI>255) | ||
253 | BDRI=255; | ||
254 | |||
255 | { | ||
256 | u64 BDRX; | ||
257 | |||
258 | BDRX=1<<(24+NDEC); | ||
259 | BDRX*=sr; | ||
260 | do_div(BDRX,SYSCLK); // BDRX/=SYSCLK; | ||
261 | |||
262 | BDR=(s32)BDRX; | ||
263 | } | ||
264 | // printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC); | ||
265 | tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); | ||
266 | tda10023_writereg (state, 0x0a, BDR&255); | ||
267 | tda10023_writereg (state, 0x0b, (BDR>>8)&255); | ||
268 | tda10023_writereg (state, 0x0c, (BDR>>16)&31); | ||
269 | tda10023_writereg (state, 0x0d, BDRI); | ||
270 | tda10023_writereg (state, 0x3d, (SFIL<<7)); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int tda10023_init (struct dvb_frontend *fe) | ||
275 | { | ||
276 | struct tda10023_state* state = fe->demodulator_priv; | ||
277 | |||
278 | dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num); | ||
279 | |||
280 | tda10023_writetab(state, tda10023_inittab); | ||
281 | |||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static int tda10023_set_parameters (struct dvb_frontend *fe, | ||
286 | struct dvb_frontend_parameters *p) | ||
287 | { | ||
288 | struct tda10023_state* state = fe->demodulator_priv; | ||
289 | |||
290 | static int qamvals[6][6] = { | ||
291 | // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD | ||
292 | { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM | ||
293 | { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM | ||
294 | { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM | ||
295 | { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM | ||
296 | { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM | ||
297 | { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM | ||
298 | }; | ||
299 | |||
300 | int qam = p->u.qam.modulation; | ||
301 | |||
302 | if (qam < 0 || qam > 5) | ||
303 | return -EINVAL; | ||
304 | |||
305 | if (fe->ops.tuner_ops.set_params) { | ||
306 | fe->ops.tuner_ops.set_params(fe, p); | ||
307 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | ||
308 | } | ||
309 | |||
310 | tda10023_set_symbolrate (state, p->u.qam.symbol_rate); | ||
311 | tda10023_writereg (state, 0x05, qamvals[qam][1]); | ||
312 | tda10023_writereg (state, 0x08, qamvals[qam][2]); | ||
313 | tda10023_writereg (state, 0x09, qamvals[qam][3]); | ||
314 | tda10023_writereg (state, 0xb4, qamvals[qam][4]); | ||
315 | tda10023_writereg (state, 0xb6, qamvals[qam][5]); | ||
316 | |||
317 | // tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); | ||
318 | // tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); | ||
319 | tda10023_writebit (state, 0x04, 0x40, 0x40); | ||
320 | tda10023_setup_reg0 (state, qamvals[qam][0]); | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
326 | { | ||
327 | struct tda10023_state* state = fe->demodulator_priv; | ||
328 | int sync; | ||
329 | |||
330 | *status = 0; | ||
331 | |||
332 | //0x11[1] == CARLOCK -> Carrier locked | ||
333 | //0x11[2] == FSYNC -> Frame synchronisation | ||
334 | //0x11[3] == FEL -> Front End locked | ||
335 | //0x11[6] == NODVB -> DVB Mode Information | ||
336 | sync = tda10023_readreg (state, 0x11); | ||
337 | |||
338 | if (sync & 2) | ||
339 | *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; | ||
340 | |||
341 | if (sync & 4) | ||
342 | *status |= FE_HAS_SYNC|FE_HAS_VITERBI; | ||
343 | |||
344 | if (sync & 8) | ||
345 | *status |= FE_HAS_LOCK; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber) | ||
351 | { | ||
352 | struct tda10023_state* state = fe->demodulator_priv; | ||
353 | u8 a,b,c; | ||
354 | a=tda10023_readreg(state, 0x14); | ||
355 | b=tda10023_readreg(state, 0x15); | ||
356 | c=tda10023_readreg(state, 0x16)&0xf; | ||
357 | tda10023_writebit (state, 0x10, 0xc0, 0x00); | ||
358 | |||
359 | *ber = a | (b<<8)| (c<<16); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
364 | { | ||
365 | struct tda10023_state* state = fe->demodulator_priv; | ||
366 | u8 ifgain=tda10023_readreg(state, 0x2f); | ||
367 | |||
368 | u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16; | ||
369 | // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90 | ||
370 | if (gain>0x90) | ||
371 | gain=gain+2*(gain-0x90); | ||
372 | if (gain>255) | ||
373 | gain=255; | ||
374 | |||
375 | *strength = (gain<<8)|gain; | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr) | ||
380 | { | ||
381 | struct tda10023_state* state = fe->demodulator_priv; | ||
382 | |||
383 | u8 quality = ~tda10023_readreg(state, 0x18); | ||
384 | *snr = (quality << 8) | quality; | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
389 | { | ||
390 | struct tda10023_state* state = fe->demodulator_priv; | ||
391 | u8 a,b,c,d; | ||
392 | a= tda10023_readreg (state, 0x74); | ||
393 | b= tda10023_readreg (state, 0x75); | ||
394 | c= tda10023_readreg (state, 0x76); | ||
395 | d= tda10023_readreg (state, 0x77); | ||
396 | *ucblocks = a | (b<<8)|(c<<16)|(d<<24); | ||
397 | |||
398 | tda10023_writebit (state, 0x10, 0x20,0x00); | ||
399 | tda10023_writebit (state, 0x10, 0x20,0x20); | ||
400 | tda10023_writebit (state, 0x13, 0x01, 0x00); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
406 | { | ||
407 | struct tda10023_state* state = fe->demodulator_priv; | ||
408 | int sync,inv; | ||
409 | s8 afc = 0; | ||
410 | |||
411 | sync = tda10023_readreg(state, 0x11); | ||
412 | afc = tda10023_readreg(state, 0x19); | ||
413 | inv = tda10023_readreg(state, 0x04); | ||
414 | |||
415 | if (verbose) { | ||
416 | /* AFC only valid when carrier has been recovered */ | ||
417 | printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" : | ||
418 | "DVB: TDA10023(%d): [AFC (%d) %dHz]\n", | ||
419 | state->frontend.dvb->num, afc, | ||
420 | -((s32)p->u.qam.symbol_rate * afc) >> 10); | ||
421 | } | ||
422 | |||
423 | p->inversion = (inv&0x20?0:1); | ||
424 | p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; | ||
425 | |||
426 | p->u.qam.fec_inner = FEC_NONE; | ||
427 | p->frequency = ((p->frequency + 31250) / 62500) * 62500; | ||
428 | |||
429 | if (sync & 2) | ||
430 | p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; | ||
431 | |||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int tda10023_sleep(struct dvb_frontend* fe) | ||
436 | { | ||
437 | struct tda10023_state* state = fe->demodulator_priv; | ||
438 | |||
439 | tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */ | ||
440 | tda10023_writereg (state, 0x00, 0x80); /* standby */ | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) | ||
446 | { | ||
447 | struct tda10023_state* state = fe->demodulator_priv; | ||
448 | |||
449 | if (enable) { | ||
450 | lock_tuner(state); | ||
451 | } else { | ||
452 | unlock_tuner(state); | ||
453 | } | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static void tda10023_release(struct dvb_frontend* fe) | ||
458 | { | ||
459 | struct tda10023_state* state = fe->demodulator_priv; | ||
460 | kfree(state); | ||
461 | } | ||
462 | |||
463 | static struct dvb_frontend_ops tda10023_ops; | ||
464 | |||
465 | struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, | ||
466 | struct i2c_adapter* i2c, | ||
467 | u8 pwm) | ||
468 | { | ||
469 | struct tda10023_state* state = NULL; | ||
470 | int i; | ||
471 | |||
472 | /* allocate memory for the internal state */ | ||
473 | state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL); | ||
474 | if (state == NULL) goto error; | ||
475 | |||
476 | /* setup the state */ | ||
477 | state->config = config; | ||
478 | state->i2c = i2c; | ||
479 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); | ||
480 | state->pwm = pwm; | ||
481 | for (i=0; i < sizeof(tda10023_inittab)/sizeof(*tda10023_inittab);i+=3) { | ||
482 | if (tda10023_inittab[i] == 0x00) { | ||
483 | state->reg0 = tda10023_inittab[i+2]; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | |||
488 | // Wakeup if in standby | ||
489 | tda10023_writereg (state, 0x00, 0x33); | ||
490 | /* check if the demod is there */ | ||
491 | if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; | ||
492 | |||
493 | /* create dvb_frontend */ | ||
494 | memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); | ||
495 | state->frontend.demodulator_priv = state; | ||
496 | return &state->frontend; | ||
497 | |||
498 | error: | ||
499 | kfree(state); | ||
500 | return NULL; | ||
501 | } | ||
502 | |||
503 | static struct dvb_frontend_ops tda10023_ops = { | ||
504 | |||
505 | .info = { | ||
506 | .name = "Philips TDA10023 DVB-C", | ||
507 | .type = FE_QAM, | ||
508 | .frequency_stepsize = 62500, | ||
509 | .frequency_min = 51000000, | ||
510 | .frequency_max = 858000000, | ||
511 | .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */ | ||
512 | .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */ | ||
513 | .caps = 0x400 | //FE_CAN_QAM_4 | ||
514 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | | ||
515 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | | ||
516 | FE_CAN_FEC_AUTO | ||
517 | }, | ||
518 | |||
519 | .release = tda10023_release, | ||
520 | |||
521 | .init = tda10023_init, | ||
522 | .sleep = tda10023_sleep, | ||
523 | .i2c_gate_ctrl = tda10023_i2c_gate_ctrl, | ||
524 | |||
525 | .set_frontend = tda10023_set_parameters, | ||
526 | .get_frontend = tda10023_get_frontend, | ||
527 | |||
528 | .read_status = tda10023_read_status, | ||
529 | .read_ber = tda10023_read_ber, | ||
530 | .read_signal_strength = tda10023_read_signal_strength, | ||
531 | .read_snr = tda10023_read_snr, | ||
532 | .read_ucblocks = tda10023_read_ucblocks, | ||
533 | }; | ||
534 | |||
535 | |||
536 | MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver"); | ||
537 | MODULE_AUTHOR("Georg Acher, Hartmut Birr"); | ||
538 | MODULE_LICENSE("GPL"); | ||
539 | |||
540 | EXPORT_SYMBOL(tda10023_attach); | ||
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda1002x.h index e3da780108f6..e9094d8123f6 100644 --- a/drivers/media/dvb/frontends/tda10021.h +++ b/drivers/media/dvb/frontends/tda1002x.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | TDA10021 - Single Chip Cable Channel Receiver driver module | 2 | TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module |
3 | used on the the Siemens DVB-C cards | 3 | used on the the Siemens DVB-C cards |
4 | 4 | ||
5 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> | 5 | Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> |
6 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> | 6 | Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> |
@@ -21,22 +21,23 @@ | |||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #ifndef TDA10021_H | 24 | #ifndef TDA1002x_H |
25 | #define TDA10021_H | 25 | #define TDA1002x_H |
26 | 26 | ||
27 | #include <linux/dvb/frontend.h> | 27 | #include <linux/dvb/frontend.h> |
28 | 28 | ||
29 | struct tda10021_config | 29 | struct tda1002x_config |
30 | { | 30 | { |
31 | /* the demodulator's i2c address */ | 31 | /* the demodulator's i2c address */ |
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | u8 invert; | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) | 36 | #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) |
36 | extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 37 | extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
37 | struct i2c_adapter* i2c, u8 pwm); | 38 | struct i2c_adapter* i2c, u8 pwm); |
38 | #else | 39 | #else |
39 | static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | 40 | static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, |
40 | struct i2c_adapter* i2c, u8 pwm) | 41 | struct i2c_adapter* i2c, u8 pwm) |
41 | { | 42 | { |
42 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | 43 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); |
@@ -44,12 +45,16 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* | |||
44 | } | 45 | } |
45 | #endif // CONFIG_DVB_TDA10021 | 46 | #endif // CONFIG_DVB_TDA10021 |
46 | 47 | ||
47 | static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { | 48 | #if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) |
48 | int r = 0; | 49 | extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, |
49 | u8 buf[] = {reg, val}; | 50 | struct i2c_adapter* i2c, u8 pwm); |
50 | if (fe->ops.write) | 51 | #else |
51 | r = fe->ops.write(fe, buf, 2); | 52 | static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, |
52 | return r; | 53 | struct i2c_adapter* i2c, u8 pwm) |
54 | { | ||
55 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
56 | return NULL; | ||
53 | } | 57 | } |
58 | #endif // CONFIG_DVB_TDA10023 | ||
54 | 59 | ||
55 | #endif // TDA10021_H | 60 | #endif // TDA1002x_H |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index f4a9cf9d26d0..33a84372c9e6 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -40,20 +40,6 @@ | |||
40 | #include "dvb_frontend.h" | 40 | #include "dvb_frontend.h" |
41 | #include "tda1004x.h" | 41 | #include "tda1004x.h" |
42 | 42 | ||
43 | enum tda1004x_demod { | ||
44 | TDA1004X_DEMOD_TDA10045, | ||
45 | TDA1004X_DEMOD_TDA10046, | ||
46 | }; | ||
47 | |||
48 | struct tda1004x_state { | ||
49 | struct i2c_adapter* i2c; | ||
50 | const struct tda1004x_config* config; | ||
51 | struct dvb_frontend frontend; | ||
52 | |||
53 | /* private demod data */ | ||
54 | enum tda1004x_demod demod_type; | ||
55 | }; | ||
56 | |||
57 | static int debug; | 43 | static int debug; |
58 | #define dprintk(args...) \ | 44 | #define dprintk(args...) \ |
59 | do { \ | 45 | do { \ |
@@ -507,35 +493,51 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
507 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); | 493 | tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); |
508 | } | 494 | } |
509 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); | 495 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); |
496 | /* set GPIO 1 and 3 */ | ||
497 | if (state->config->gpio_config != TDA10046_GPTRI) { | ||
498 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33); | ||
499 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f); | ||
500 | } | ||
510 | /* let the clocks recover from sleep */ | 501 | /* let the clocks recover from sleep */ |
511 | msleep(5); | 502 | msleep(10); |
512 | 503 | ||
513 | /* The PLLs need to be reprogrammed after sleep */ | 504 | /* The PLLs need to be reprogrammed after sleep */ |
514 | tda10046_init_plls(fe); | 505 | tda10046_init_plls(fe); |
506 | tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0); | ||
515 | 507 | ||
516 | /* don't re-upload unless necessary */ | 508 | /* don't re-upload unless necessary */ |
517 | if (tda1004x_check_upload_ok(state) == 0) | 509 | if (tda1004x_check_upload_ok(state) == 0) |
518 | return 0; | 510 | return 0; |
519 | 511 | ||
512 | printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); | ||
513 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | ||
514 | msleep(300); | ||
515 | /* don't re-upload unless necessary */ | ||
516 | if (tda1004x_check_upload_ok(state) == 0) | ||
517 | return 0; | ||
518 | |||
520 | if (state->config->request_firmware != NULL) { | 519 | if (state->config->request_firmware != NULL) { |
521 | /* request the firmware, this will block until someone uploads it */ | 520 | /* request the firmware, this will block until someone uploads it */ |
522 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); | 521 | printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); |
523 | ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); | 522 | ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); |
524 | if (ret) { | 523 | if (ret) { |
525 | printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); | 524 | /* remain compatible to old bug: try to load with tda10045 image name */ |
526 | return ret; | 525 | ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); |
526 | if (ret) { | ||
527 | printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); | ||
528 | return ret; | ||
529 | } else { | ||
530 | printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", | ||
531 | TDA10046_DEFAULT_FIRMWARE); | ||
532 | } | ||
527 | } | 533 | } |
528 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST | ||
529 | ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); | ||
530 | release_firmware(fw); | ||
531 | if (ret) | ||
532 | return ret; | ||
533 | } else { | 534 | } else { |
534 | /* boot from firmware eeprom */ | 535 | printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n"); |
535 | printk(KERN_INFO "tda1004x: booting from eeprom\n"); | 536 | return -EIO; |
536 | tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); | ||
537 | msleep(300); | ||
538 | } | 537 | } |
538 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST | ||
539 | ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); | ||
540 | release_firmware(fw); | ||
539 | return tda1004x_check_upload_ok(state); | 541 | return tda1004x_check_upload_ok(state); |
540 | } | 542 | } |
541 | 543 | ||
@@ -638,37 +640,33 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
638 | switch (state->config->agc_config) { | 640 | switch (state->config->agc_config) { |
639 | case TDA10046_AGC_DEFAULT: | 641 | case TDA10046_AGC_DEFAULT: |
640 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup | 642 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup |
641 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 643 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
642 | break; | 644 | break; |
643 | case TDA10046_AGC_IFO_AUTO_NEG: | 645 | case TDA10046_AGC_IFO_AUTO_NEG: |
644 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup | 646 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup |
645 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | 647 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
646 | break; | 648 | break; |
647 | case TDA10046_AGC_IFO_AUTO_POS: | 649 | case TDA10046_AGC_IFO_AUTO_POS: |
648 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup | 650 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup |
649 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x00); // set AGC polarities | 651 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities |
650 | break; | ||
651 | case TDA10046_AGC_TDA827X_GP11: | ||
652 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | ||
653 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | ||
654 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | ||
655 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities | ||
656 | break; | ||
657 | case TDA10046_AGC_TDA827X_GP00: | ||
658 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | ||
659 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | ||
660 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | ||
661 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities | ||
662 | break; | 652 | break; |
663 | case TDA10046_AGC_TDA827X_GP01: | 653 | case TDA10046_AGC_TDA827X: |
664 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup | 654 | tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup |
665 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold | 655 | tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold |
666 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize | 656 | tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize |
667 | tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x62); // set AGC polarities | 657 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities |
668 | break; | 658 | break; |
669 | } | 659 | } |
660 | if (state->config->ts_mode == 0) { | ||
661 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40); | ||
662 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | ||
663 | } else { | ||
664 | tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80); | ||
665 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10, | ||
666 | state->config->invert_oclk << 4); | ||
667 | } | ||
670 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); | 668 | tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); |
671 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on | 669 | tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on |
672 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } | 670 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } |
673 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values | 671 | tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values |
674 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } | 672 | tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } |
@@ -678,7 +676,6 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
678 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config | 676 | tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config |
679 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config | 677 | tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config |
680 | // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes | 678 | // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes |
681 | tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); | ||
682 | 679 | ||
683 | return 0; | 680 | return 0; |
684 | } | 681 | } |
@@ -705,7 +702,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
705 | // set frequency | 702 | // set frequency |
706 | if (fe->ops.tuner_ops.set_params) { | 703 | if (fe->ops.tuner_ops.set_params) { |
707 | fe->ops.tuner_ops.set_params(fe, fe_params); | 704 | fe->ops.tuner_ops.set_params(fe, fe_params); |
708 | if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); | 705 | if (fe->ops.i2c_gate_ctrl) |
706 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
709 | } | 707 | } |
710 | 708 | ||
711 | // Hardcoded to use auto as much as possible on the TDA10045 as it | 709 | // Hardcoded to use auto as much as possible on the TDA10045 as it |
@@ -1165,6 +1163,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
1165 | static int tda1004x_sleep(struct dvb_frontend* fe) | 1163 | static int tda1004x_sleep(struct dvb_frontend* fe) |
1166 | { | 1164 | { |
1167 | struct tda1004x_state* state = fe->demodulator_priv; | 1165 | struct tda1004x_state* state = fe->demodulator_priv; |
1166 | int gpio_conf; | ||
1168 | 1167 | ||
1169 | switch (state->demod_type) { | 1168 | switch (state->demod_type) { |
1170 | case TDA1004X_DEMOD_TDA10045: | 1169 | case TDA1004X_DEMOD_TDA10045: |
@@ -1174,6 +1173,13 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1174 | case TDA1004X_DEMOD_TDA10046: | 1173 | case TDA1004X_DEMOD_TDA10046: |
1175 | /* set outputs to tristate */ | 1174 | /* set outputs to tristate */ |
1176 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); | 1175 | tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); |
1176 | /* invert GPIO 1 and 3 if desired*/ | ||
1177 | gpio_conf = state->config->gpio_config; | ||
1178 | if (gpio_conf >= TDA10046_GP00_I) | ||
1179 | tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, | ||
1180 | (gpio_conf & 0x0f) ^ 0x0a); | ||
1181 | |||
1182 | tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0); | ||
1177 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); | 1183 | tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); |
1178 | break; | 1184 | break; |
1179 | } | 1185 | } |
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index ec502d71b83c..abae84350142 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -35,9 +35,23 @@ enum tda10046_agc { | |||
35 | TDA10046_AGC_DEFAULT, /* original configuration */ | 35 | TDA10046_AGC_DEFAULT, /* original configuration */ |
36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ | 36 | TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ |
37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ | 37 | TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ |
38 | TDA10046_AGC_TDA827X_GP11, /* IF AGC only, special setup for tda827x */ | 38 | TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ |
39 | TDA10046_AGC_TDA827X_GP00, /* same as above, but GPIOs 0 */ | 39 | }; |
40 | TDA10046_AGC_TDA827X_GP01, /* same as above, but GPIO3=0 GPIO1=1*/ | 40 | |
41 | /* Many (hybrid) boards use GPIO 1 and 3 | ||
42 | GPIO1 analog - dvb switch | ||
43 | GPIO3 firmware eeprom address switch | ||
44 | */ | ||
45 | enum tda10046_gpio { | ||
46 | TDA10046_GPTRI = 0x00, /* All GPIOs tristate */ | ||
47 | TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */ | ||
48 | TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */ | ||
49 | TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */ | ||
50 | TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */ | ||
51 | TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/ | ||
52 | TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */ | ||
53 | TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */ | ||
54 | TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */ | ||
41 | }; | 55 | }; |
42 | 56 | ||
43 | enum tda10046_if { | 57 | enum tda10046_if { |
@@ -47,6 +61,11 @@ enum tda10046_if { | |||
47 | TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ | 61 | TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ |
48 | }; | 62 | }; |
49 | 63 | ||
64 | enum tda10046_tsout { | ||
65 | TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */ | ||
66 | TDA10046_TS_SERIAL = 0x01, /* serial transport stream */ | ||
67 | }; | ||
68 | |||
50 | struct tda1004x_config | 69 | struct tda1004x_config |
51 | { | 70 | { |
52 | /* the demodulator's i2c address */ | 71 | /* the demodulator's i2c address */ |
@@ -58,6 +77,9 @@ struct tda1004x_config | |||
58 | /* Does the OCLK signal need inverted? */ | 77 | /* Does the OCLK signal need inverted? */ |
59 | u8 invert_oclk; | 78 | u8 invert_oclk; |
60 | 79 | ||
80 | /* parallel or serial transport stream */ | ||
81 | enum tda10046_tsout ts_mode; | ||
82 | |||
61 | /* Xtal frequency, 4 or 16MHz*/ | 83 | /* Xtal frequency, 4 or 16MHz*/ |
62 | enum tda10046_xtal xtal_freq; | 84 | enum tda10046_xtal xtal_freq; |
63 | 85 | ||
@@ -67,11 +89,35 @@ struct tda1004x_config | |||
67 | /* AGC configuration */ | 89 | /* AGC configuration */ |
68 | enum tda10046_agc agc_config; | 90 | enum tda10046_agc agc_config; |
69 | 91 | ||
92 | /* setting of GPIO1 and 3 */ | ||
93 | enum tda10046_gpio gpio_config; | ||
94 | |||
95 | /* slave address and configuration of the tuner */ | ||
96 | u8 tuner_address; | ||
97 | u8 tuner_config; | ||
98 | u8 antenna_switch; | ||
99 | |||
100 | /* if the board uses another I2c Bridge (tda8290), its address */ | ||
101 | u8 i2c_gate; | ||
102 | |||
70 | /* request firmware for device */ | 103 | /* request firmware for device */ |
71 | /* set this to NULL if the card has a firmware EEPROM */ | ||
72 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | 104 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); |
73 | }; | 105 | }; |
74 | 106 | ||
107 | enum tda1004x_demod { | ||
108 | TDA1004X_DEMOD_TDA10045, | ||
109 | TDA1004X_DEMOD_TDA10046, | ||
110 | }; | ||
111 | |||
112 | struct tda1004x_state { | ||
113 | struct i2c_adapter* i2c; | ||
114 | const struct tda1004x_config* config; | ||
115 | struct dvb_frontend frontend; | ||
116 | |||
117 | /* private demod data */ | ||
118 | enum tda1004x_demod demod_type; | ||
119 | }; | ||
120 | |||
75 | #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) | 121 | #if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) |
76 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | 122 | extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
77 | struct i2c_adapter* i2c); | 123 | struct i2c_adapter* i2c); |
diff --git a/drivers/media/dvb/frontends/tda827x.c b/drivers/media/dvb/frontends/tda827x.c new file mode 100644 index 000000000000..256fc4bf500b --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.c | |||
@@ -0,0 +1,512 @@ | |||
1 | /* | ||
2 | * | ||
3 | * (c) 2005 Hartmut Hackmann | ||
4 | * (c) 2007 Michael Krufky | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/dvb/frontend.h> | ||
23 | #include <asm/types.h> | ||
24 | |||
25 | #include "tda827x.h" | ||
26 | |||
27 | static int debug = 0; | ||
28 | #define dprintk(args...) \ | ||
29 | do { \ | ||
30 | if (debug) printk(KERN_DEBUG "tda827x: " args); \ | ||
31 | } while (0) | ||
32 | |||
33 | struct tda827x_priv { | ||
34 | int i2c_addr; | ||
35 | struct i2c_adapter *i2c_adap; | ||
36 | struct tda827x_config *cfg; | ||
37 | u32 frequency; | ||
38 | u32 bandwidth; | ||
39 | }; | ||
40 | |||
41 | struct tda827x_data { | ||
42 | u32 lomax; | ||
43 | u8 spd; | ||
44 | u8 bs; | ||
45 | u8 bp; | ||
46 | u8 cp; | ||
47 | u8 gc3; | ||
48 | u8 div1p5; | ||
49 | }; | ||
50 | |||
51 | static const struct tda827x_data tda827x_dvbt[] = { | ||
52 | { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
53 | { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1}, | ||
54 | { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
55 | { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0}, | ||
56 | { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
57 | { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
58 | { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
59 | { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
60 | { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
61 | { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
62 | { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
63 | { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
64 | { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
65 | { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
66 | { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
67 | { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
68 | { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
69 | { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
70 | { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
71 | { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
72 | { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
73 | { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1}, | ||
74 | { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0}, | ||
75 | { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
76 | { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
77 | { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
78 | { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0}, | ||
79 | { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0}, | ||
80 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | ||
81 | }; | ||
82 | |||
83 | static int tda827xo_set_params(struct dvb_frontend *fe, | ||
84 | struct dvb_frontend_parameters *params) | ||
85 | { | ||
86 | struct tda827x_priv *priv = fe->tuner_priv; | ||
87 | u8 buf[14]; | ||
88 | |||
89 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
90 | .buf = buf, .len = sizeof(buf) }; | ||
91 | int i, tuner_freq, if_freq; | ||
92 | u32 N; | ||
93 | |||
94 | dprintk("%s:\n", __FUNCTION__); | ||
95 | switch (params->u.ofdm.bandwidth) { | ||
96 | case BANDWIDTH_6_MHZ: | ||
97 | if_freq = 4000000; | ||
98 | break; | ||
99 | case BANDWIDTH_7_MHZ: | ||
100 | if_freq = 4500000; | ||
101 | break; | ||
102 | default: /* 8 MHz or Auto */ | ||
103 | if_freq = 5000000; | ||
104 | break; | ||
105 | } | ||
106 | tuner_freq = params->frequency + if_freq; | ||
107 | |||
108 | i = 0; | ||
109 | while (tda827x_dvbt[i].lomax < tuner_freq) { | ||
110 | if(tda827x_dvbt[i + 1].lomax == 0) | ||
111 | break; | ||
112 | i++; | ||
113 | } | ||
114 | |||
115 | N = ((tuner_freq + 125000) / 250000) << (tda827x_dvbt[i].spd + 2); | ||
116 | buf[0] = 0; | ||
117 | buf[1] = (N>>8) | 0x40; | ||
118 | buf[2] = N & 0xff; | ||
119 | buf[3] = 0; | ||
120 | buf[4] = 0x52; | ||
121 | buf[5] = (tda827x_dvbt[i].spd << 6) + (tda827x_dvbt[i].div1p5 << 5) + | ||
122 | (tda827x_dvbt[i].bs << 3) + tda827x_dvbt[i].bp; | ||
123 | buf[6] = (tda827x_dvbt[i].gc3 << 4) + 0x8f; | ||
124 | buf[7] = 0xbf; | ||
125 | buf[8] = 0x2a; | ||
126 | buf[9] = 0x05; | ||
127 | buf[10] = 0xff; | ||
128 | buf[11] = 0x00; | ||
129 | buf[12] = 0x00; | ||
130 | buf[13] = 0x40; | ||
131 | |||
132 | msg.len = 14; | ||
133 | if (fe->ops.i2c_gate_ctrl) | ||
134 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
135 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
136 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
137 | __FUNCTION__, priv->i2c_addr << 1); | ||
138 | return -EIO; | ||
139 | } | ||
140 | msleep(500); | ||
141 | /* correct CP value */ | ||
142 | buf[0] = 0x30; | ||
143 | buf[1] = 0x50 + tda827x_dvbt[i].cp; | ||
144 | msg.len = 2; | ||
145 | |||
146 | if (fe->ops.i2c_gate_ctrl) | ||
147 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
148 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
149 | |||
150 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
151 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | static int tda827xo_sleep(struct dvb_frontend *fe) | ||
157 | { | ||
158 | struct tda827x_priv *priv = fe->tuner_priv; | ||
159 | static u8 buf[] = { 0x30, 0xd0 }; | ||
160 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
161 | .buf = buf, .len = sizeof(buf) }; | ||
162 | |||
163 | dprintk("%s:\n", __FUNCTION__); | ||
164 | if (fe->ops.i2c_gate_ctrl) | ||
165 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
166 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
167 | |||
168 | if (priv->cfg && priv->cfg->sleep) | ||
169 | priv->cfg->sleep(fe); | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* ------------------------------------------------------------------ */ | ||
175 | |||
176 | struct tda827xa_data { | ||
177 | u32 lomax; | ||
178 | u8 svco; | ||
179 | u8 spd; | ||
180 | u8 scr; | ||
181 | u8 sbs; | ||
182 | u8 gc3; | ||
183 | }; | ||
184 | |||
185 | static const struct tda827xa_data tda827xa_dvbt[] = { | ||
186 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
187 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
188 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
189 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | ||
190 | { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
191 | { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
192 | { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
193 | { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
194 | { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1}, | ||
195 | { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
196 | { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
197 | { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
198 | { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1}, | ||
199 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
200 | { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
201 | { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
202 | { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
203 | { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
204 | { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1}, | ||
205 | { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
206 | { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
207 | { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
208 | { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
209 | { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0}, | ||
210 | { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0}, | ||
211 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0}, | ||
212 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | ||
213 | }; | ||
214 | |||
215 | static int tda827xa_set_params(struct dvb_frontend *fe, | ||
216 | struct dvb_frontend_parameters *params) | ||
217 | { | ||
218 | struct tda827x_priv *priv = fe->tuner_priv; | ||
219 | u8 buf[11]; | ||
220 | |||
221 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
222 | .buf = buf, .len = sizeof(buf) }; | ||
223 | |||
224 | int i, tuner_freq, if_freq; | ||
225 | u32 N; | ||
226 | |||
227 | dprintk("%s:\n", __FUNCTION__); | ||
228 | if (priv->cfg && priv->cfg->lna_gain) | ||
229 | priv->cfg->lna_gain(fe, 1); | ||
230 | msleep(20); | ||
231 | |||
232 | switch (params->u.ofdm.bandwidth) { | ||
233 | case BANDWIDTH_6_MHZ: | ||
234 | if_freq = 4000000; | ||
235 | break; | ||
236 | case BANDWIDTH_7_MHZ: | ||
237 | if_freq = 4500000; | ||
238 | break; | ||
239 | default: /* 8 MHz or Auto */ | ||
240 | if_freq = 5000000; | ||
241 | break; | ||
242 | } | ||
243 | tuner_freq = params->frequency + if_freq; | ||
244 | |||
245 | i = 0; | ||
246 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | ||
247 | if(tda827xa_dvbt[i + 1].lomax == 0) | ||
248 | break; | ||
249 | i++; | ||
250 | } | ||
251 | |||
252 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | ||
253 | buf[0] = 0; // subaddress | ||
254 | buf[1] = N >> 8; | ||
255 | buf[2] = N & 0xff; | ||
256 | buf[3] = 0; | ||
257 | buf[4] = 0x16; | ||
258 | buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | ||
259 | tda827xa_dvbt[i].sbs; | ||
260 | buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | ||
261 | buf[7] = 0x1c; | ||
262 | buf[8] = 0x06; | ||
263 | buf[9] = 0x24; | ||
264 | buf[10] = 0x00; | ||
265 | msg.len = 11; | ||
266 | if (fe->ops.i2c_gate_ctrl) | ||
267 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
268 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
269 | printk("%s: could not write to tuner at addr: 0x%02x\n", | ||
270 | __FUNCTION__, priv->i2c_addr << 1); | ||
271 | return -EIO; | ||
272 | } | ||
273 | buf[0] = 0x90; | ||
274 | buf[1] = 0xff; | ||
275 | buf[2] = 0x60; | ||
276 | buf[3] = 0x00; | ||
277 | buf[4] = 0x59; // lpsel, for 6MHz + 2 | ||
278 | msg.len = 5; | ||
279 | if (fe->ops.i2c_gate_ctrl) | ||
280 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
281 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
282 | |||
283 | buf[0] = 0xa0; | ||
284 | buf[1] = 0x40; | ||
285 | msg.len = 2; | ||
286 | if (fe->ops.i2c_gate_ctrl) | ||
287 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
288 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
289 | |||
290 | msleep(11); | ||
291 | msg.flags = I2C_M_RD; | ||
292 | if (fe->ops.i2c_gate_ctrl) | ||
293 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
294 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
295 | msg.flags = 0; | ||
296 | |||
297 | buf[1] >>= 4; | ||
298 | dprintk("tda8275a AGC2 gain is: %d\n", buf[1]); | ||
299 | if ((buf[1]) < 2) { | ||
300 | if (priv->cfg && priv->cfg->lna_gain) | ||
301 | priv->cfg->lna_gain(fe, 0); | ||
302 | buf[0] = 0x60; | ||
303 | buf[1] = 0x0c; | ||
304 | if (fe->ops.i2c_gate_ctrl) | ||
305 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
306 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
307 | } | ||
308 | |||
309 | buf[0] = 0xc0; | ||
310 | buf[1] = 0x99; // lpsel, for 6MHz + 2 | ||
311 | if (fe->ops.i2c_gate_ctrl) | ||
312 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
313 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
314 | |||
315 | buf[0] = 0x60; | ||
316 | buf[1] = 0x3c; | ||
317 | if (fe->ops.i2c_gate_ctrl) | ||
318 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
319 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
320 | |||
321 | /* correct CP value */ | ||
322 | buf[0] = 0x30; | ||
323 | buf[1] = 0x10 + tda827xa_dvbt[i].scr; | ||
324 | if (fe->ops.i2c_gate_ctrl) | ||
325 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
326 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
327 | |||
328 | msleep(163); | ||
329 | buf[0] = 0xc0; | ||
330 | buf[1] = 0x39; // lpsel, for 6MHz + 2 | ||
331 | if (fe->ops.i2c_gate_ctrl) | ||
332 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
333 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
334 | |||
335 | msleep(3); | ||
336 | /* freeze AGC1 */ | ||
337 | buf[0] = 0x50; | ||
338 | buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | ||
339 | if (fe->ops.i2c_gate_ctrl) | ||
340 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
341 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
342 | |||
343 | priv->frequency = tuner_freq - if_freq; // FIXME | ||
344 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
349 | static int tda827xa_sleep(struct dvb_frontend *fe) | ||
350 | { | ||
351 | struct tda827x_priv *priv = fe->tuner_priv; | ||
352 | static u8 buf[] = { 0x30, 0x90 }; | ||
353 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | ||
354 | .buf = buf, .len = sizeof(buf) }; | ||
355 | |||
356 | dprintk("%s:\n", __FUNCTION__); | ||
357 | if (fe->ops.i2c_gate_ctrl) | ||
358 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
359 | |||
360 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
361 | |||
362 | if (fe->ops.i2c_gate_ctrl) | ||
363 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
364 | |||
365 | if (priv->cfg && priv->cfg->sleep) | ||
366 | priv->cfg->sleep(fe); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static int tda827x_release(struct dvb_frontend *fe) | ||
372 | { | ||
373 | kfree(fe->tuner_priv); | ||
374 | fe->tuner_priv = NULL; | ||
375 | return 0; | ||
376 | } | ||
377 | |||
378 | static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
379 | { | ||
380 | struct tda827x_priv *priv = fe->tuner_priv; | ||
381 | *frequency = priv->frequency; | ||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||
386 | { | ||
387 | struct tda827x_priv *priv = fe->tuner_priv; | ||
388 | *bandwidth = priv->bandwidth; | ||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int tda827x_init(struct dvb_frontend *fe) | ||
393 | { | ||
394 | struct tda827x_priv *priv = fe->tuner_priv; | ||
395 | dprintk("%s:\n", __FUNCTION__); | ||
396 | if (priv->cfg && priv->cfg->init) | ||
397 | priv->cfg->init(fe); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int tda827x_probe_version(struct dvb_frontend *fe); | ||
403 | |||
404 | static int tda827x_initial_init(struct dvb_frontend *fe) | ||
405 | { | ||
406 | int ret; | ||
407 | ret = tda827x_probe_version(fe); | ||
408 | if (ret) | ||
409 | return ret; | ||
410 | return fe->ops.tuner_ops.init(fe); | ||
411 | } | ||
412 | |||
413 | static int tda827x_initial_sleep(struct dvb_frontend *fe) | ||
414 | { | ||
415 | int ret; | ||
416 | ret = tda827x_probe_version(fe); | ||
417 | if (ret) | ||
418 | return ret; | ||
419 | return fe->ops.tuner_ops.sleep(fe); | ||
420 | } | ||
421 | |||
422 | static struct dvb_tuner_ops tda827xo_tuner_ops = { | ||
423 | .info = { | ||
424 | .name = "Philips TDA827X", | ||
425 | .frequency_min = 55000000, | ||
426 | .frequency_max = 860000000, | ||
427 | .frequency_step = 250000 | ||
428 | }, | ||
429 | .release = tda827x_release, | ||
430 | .init = tda827x_initial_init, | ||
431 | .sleep = tda827x_initial_sleep, | ||
432 | .set_params = tda827xo_set_params, | ||
433 | .get_frequency = tda827x_get_frequency, | ||
434 | .get_bandwidth = tda827x_get_bandwidth, | ||
435 | }; | ||
436 | |||
437 | static struct dvb_tuner_ops tda827xa_tuner_ops = { | ||
438 | .info = { | ||
439 | .name = "Philips TDA827XA", | ||
440 | .frequency_min = 44000000, | ||
441 | .frequency_max = 906000000, | ||
442 | .frequency_step = 62500 | ||
443 | }, | ||
444 | .release = tda827x_release, | ||
445 | .init = tda827x_init, | ||
446 | .sleep = tda827xa_sleep, | ||
447 | .set_params = tda827xa_set_params, | ||
448 | .get_frequency = tda827x_get_frequency, | ||
449 | .get_bandwidth = tda827x_get_bandwidth, | ||
450 | }; | ||
451 | |||
452 | static int tda827x_probe_version(struct dvb_frontend *fe) | ||
453 | { u8 data; | ||
454 | struct tda827x_priv *priv = fe->tuner_priv; | ||
455 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, | ||
456 | .buf = &data, .len = 1 }; | ||
457 | if (fe->ops.i2c_gate_ctrl) | ||
458 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
459 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | ||
460 | printk("%s: could not read from tuner at addr: 0x%02x\n", | ||
461 | __FUNCTION__, msg.addr << 1); | ||
462 | return -EIO; | ||
463 | } | ||
464 | if ((data & 0x3c) == 0) { | ||
465 | dprintk("tda827x tuner found\n"); | ||
466 | fe->ops.tuner_ops.init = tda827x_init; | ||
467 | fe->ops.tuner_ops.sleep = tda827xo_sleep; | ||
468 | } else { | ||
469 | dprintk("tda827xa tuner found\n"); | ||
470 | memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
471 | } | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, | ||
476 | struct i2c_adapter *i2c, | ||
477 | struct tda827x_config *cfg) | ||
478 | { | ||
479 | struct tda827x_priv *priv = NULL; | ||
480 | |||
481 | dprintk("%s:\n", __FUNCTION__); | ||
482 | priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); | ||
483 | if (priv == NULL) | ||
484 | return NULL; | ||
485 | |||
486 | priv->i2c_addr = addr; | ||
487 | priv->i2c_adap = i2c; | ||
488 | priv->cfg = cfg; | ||
489 | memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops)); | ||
490 | |||
491 | fe->tuner_priv = priv; | ||
492 | |||
493 | return fe; | ||
494 | } | ||
495 | |||
496 | EXPORT_SYMBOL(tda827x_attach); | ||
497 | |||
498 | module_param(debug, int, 0644); | ||
499 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
500 | |||
501 | MODULE_DESCRIPTION("DVB TDA827x driver"); | ||
502 | MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>"); | ||
503 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | ||
504 | MODULE_LICENSE("GPL"); | ||
505 | |||
506 | /* | ||
507 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
508 | * --------------------------------------------------------------------------- | ||
509 | * Local variables: | ||
510 | * c-basic-offset: 8 | ||
511 | * End: | ||
512 | */ | ||
diff --git a/drivers/media/dvb/frontends/tda827x.h b/drivers/media/dvb/frontends/tda827x.h new file mode 100644 index 000000000000..69e8263d6d59 --- /dev/null +++ b/drivers/media/dvb/frontends/tda827x.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | DVB Driver for Philips tda827x / tda827xa Silicon tuners | ||
3 | |||
4 | (c) 2005 Hartmut Hackmann | ||
5 | (c) 2007 Michael Krufky | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | |||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | |||
22 | */ | ||
23 | |||
24 | #ifndef __DVB_TDA827X_H__ | ||
25 | #define __DVB_TDA827X_H__ | ||
26 | |||
27 | #include <linux/i2c.h> | ||
28 | #include "dvb_frontend.h" | ||
29 | |||
30 | struct tda827x_config | ||
31 | { | ||
32 | void (*lna_gain) (struct dvb_frontend *fe, int high); | ||
33 | int (*init) (struct dvb_frontend *fe); | ||
34 | int (*sleep) (struct dvb_frontend *fe); | ||
35 | }; | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Attach a tda827x tuner to the supplied frontend structure. | ||
40 | * | ||
41 | * @param fe Frontend to attach to. | ||
42 | * @param addr i2c address of the tuner. | ||
43 | * @param i2c i2c adapter to use. | ||
44 | * @param cfg optional callback function pointers. | ||
45 | * @return FE pointer on success, NULL on failure. | ||
46 | */ | ||
47 | #if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE)) | ||
48 | extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr, | ||
49 | struct i2c_adapter *i2c, | ||
50 | struct tda827x_config *cfg); | ||
51 | #else | ||
52 | static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, | ||
53 | int addr, | ||
54 | struct i2c_adapter *i2c, | ||
55 | struct tda827x_config *cfg) | ||
56 | { | ||
57 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); | ||
58 | return NULL; | ||
59 | } | ||
60 | #endif // CONFIG_DVB_TDA827X | ||
61 | |||
62 | #endif // __DVB_TDA827X_H__ | ||
diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig index 9b84b1bdc313..7d8e6e87bdbb 100644 --- a/drivers/media/dvb/pluto2/Kconfig +++ b/drivers/media/dvb/pluto2/Kconfig | |||
@@ -2,7 +2,6 @@ config DVB_PLUTO2 | |||
2 | tristate "Pluto2 cards" | 2 | tristate "Pluto2 cards" |
3 | depends on DVB_CORE && PCI && I2C | 3 | depends on DVB_CORE && PCI && I2C |
4 | select I2C_ALGOBIT | 4 | select I2C_ALGOBIT |
5 | select DVB_PLL | ||
6 | select DVB_TDA1004X | 5 | select DVB_TDA1004X |
7 | help | 6 | help |
8 | Support for PCI cards based on the Pluto2 FPGA like the Satelco | 7 | Support for PCI cards based on the Pluto2 FPGA like the Satelco |
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index eec7ccf41f8b..7751628e1415 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig | |||
@@ -3,7 +3,6 @@ config DVB_AV7110 | |||
3 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 | 3 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 |
4 | select FW_LOADER if !DVB_AV7110_FIRMWARE | 4 | select FW_LOADER if !DVB_AV7110_FIRMWARE |
5 | select VIDEO_SAA7146_VV | 5 | select VIDEO_SAA7146_VV |
6 | select DVB_PLL | ||
7 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | 6 | select DVB_VES1820 if !DVB_FE_CUSTOMISE |
8 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | 7 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE |
9 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 8 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
@@ -62,13 +61,13 @@ config DVB_BUDGET | |||
62 | tristate "Budget cards" | 61 | tristate "Budget cards" |
63 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 | 62 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 |
64 | select VIDEO_SAA7146 | 63 | select VIDEO_SAA7146 |
65 | select DVB_PLL | ||
66 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 64 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
67 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | 65 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE |
68 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | 66 | select DVB_VES1820 if !DVB_FE_CUSTOMISE |
69 | select DVB_L64781 if !DVB_FE_CUSTOMISE | 67 | select DVB_L64781 if !DVB_FE_CUSTOMISE |
70 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE | 68 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE |
71 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | 69 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE |
70 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
72 | select DVB_S5H1420 if !DVB_FE_CUSTOMISE | 71 | select DVB_S5H1420 if !DVB_FE_CUSTOMISE |
73 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE | 72 | select DVB_TDA10086 if !DVB_FE_CUSTOMISE |
74 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | 73 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
@@ -87,7 +86,6 @@ config DVB_BUDGET_CI | |||
87 | tristate "Budget cards with onboard CI connector" | 86 | tristate "Budget cards with onboard CI connector" |
88 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 | 87 | depends on DVB_CORE && PCI && I2C && VIDEO_V4L1 |
89 | select VIDEO_SAA7146 | 88 | select VIDEO_SAA7146 |
90 | select DVB_PLL | ||
91 | select DVB_STV0297 if !DVB_FE_CUSTOMISE | 89 | select DVB_STV0297 if !DVB_FE_CUSTOMISE |
92 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 90 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
93 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 91 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
@@ -114,6 +112,7 @@ config DVB_BUDGET_AV | |||
114 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 112 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
115 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 113 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
116 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE | 114 | select DVB_TDA10021 if !DVB_FE_CUSTOMISE |
115 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
117 | select DVB_TUA6100 if !DVB_FE_CUSTOMISE | 116 | select DVB_TUA6100 if !DVB_FE_CUSTOMISE |
118 | select FW_LOADER | 117 | select FW_LOADER |
119 | help | 118 | help |
@@ -130,7 +129,6 @@ config DVB_BUDGET_PATCH | |||
130 | tristate "AV7110 cards with Budget Patch" | 129 | tristate "AV7110 cards with Budget Patch" |
131 | depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 | 130 | depends on DVB_CORE && DVB_BUDGET && VIDEO_V4L1 |
132 | select DVB_AV7110 | 131 | select DVB_AV7110 |
133 | select DVB_PLL | ||
134 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | 132 | select DVB_STV0299 if !DVB_FE_CUSTOMISE |
135 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE | 133 | select DVB_VES1X93 if !DVB_FE_CUSTOMISE |
136 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE | 134 | select DVB_TDA8083 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 29ed532ba966..67becdd4db60 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -219,7 +219,10 @@ static void recover_arm(struct av7110 *av7110) | |||
219 | av7110->recover(av7110); | 219 | av7110->recover(av7110); |
220 | 220 | ||
221 | restart_feeds(av7110); | 221 | restart_feeds(av7110); |
222 | av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); | 222 | |
223 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
224 | av7110_check_ir_config(av7110, true); | ||
225 | #endif | ||
223 | } | 226 | } |
224 | 227 | ||
225 | static void av7110_arm_sync(struct av7110 *av7110) | 228 | static void av7110_arm_sync(struct av7110 *av7110) |
@@ -250,6 +253,10 @@ static int arm_thread(void *data) | |||
250 | if (!av7110->arm_ready) | 253 | if (!av7110->arm_ready) |
251 | continue; | 254 | continue; |
252 | 255 | ||
256 | #if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) | ||
257 | av7110_check_ir_config(av7110, false); | ||
258 | #endif | ||
259 | |||
253 | if (mutex_lock_interruptible(&av7110->dcomlock)) | 260 | if (mutex_lock_interruptible(&av7110->dcomlock)) |
254 | break; | 261 | break; |
255 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); | 262 | newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); |
@@ -667,8 +674,8 @@ static void gpioirq(unsigned long data) | |||
667 | return; | 674 | return; |
668 | 675 | ||
669 | case DATA_IRCOMMAND: | 676 | case DATA_IRCOMMAND: |
670 | if (av7110->ir_handler) | 677 | if (av7110->ir.ir_handler) |
671 | av7110->ir_handler(av7110, | 678 | av7110->ir.ir_handler(av7110, |
672 | swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); | 679 | swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); |
673 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); | 680 | iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); |
674 | break; | 681 | break; |
@@ -1907,8 +1914,10 @@ static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) | |||
1907 | if (av7110->fe_synced == synced) | 1914 | if (av7110->fe_synced == synced) |
1908 | return 0; | 1915 | return 0; |
1909 | 1916 | ||
1910 | if (av7110->playing) | 1917 | if (av7110->playing) { |
1918 | av7110->fe_synced = synced; | ||
1911 | return 0; | 1919 | return 0; |
1920 | } | ||
1912 | 1921 | ||
1913 | if (mutex_lock_interruptible(&av7110->pid_mutex)) | 1922 | if (mutex_lock_interruptible(&av7110->pid_mutex)) |
1914 | return -ERESTARTSYS; | 1923 | return -ERESTARTSYS; |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index b98bd453cade..115002b0390c 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/socket.h> | 5 | #include <linux/socket.h> |
6 | #include <linux/netdevice.h> | 6 | #include <linux/netdevice.h> |
7 | #include <linux/i2c.h> | 7 | #include <linux/i2c.h> |
8 | #include <linux/input.h> | ||
8 | 9 | ||
9 | #include <linux/dvb/video.h> | 10 | #include <linux/dvb/video.h> |
10 | #include <linux/dvb/audio.h> | 11 | #include <linux/dvb/audio.h> |
@@ -66,6 +67,27 @@ struct dvb_video_events { | |||
66 | }; | 67 | }; |
67 | 68 | ||
68 | 69 | ||
70 | struct av7110; | ||
71 | |||
72 | /* infrared remote control */ | ||
73 | struct infrared { | ||
74 | u16 key_map[256]; | ||
75 | struct input_dev *input_dev; | ||
76 | char input_phys[32]; | ||
77 | struct timer_list keyup_timer; | ||
78 | struct tasklet_struct ir_tasklet; | ||
79 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); | ||
80 | u32 ir_command; | ||
81 | u32 ir_config; | ||
82 | u32 device_mask; | ||
83 | u8 protocol; | ||
84 | u8 inversion; | ||
85 | u16 last_key; | ||
86 | u16 last_toggle; | ||
87 | u8 delay_timer_finished; | ||
88 | }; | ||
89 | |||
90 | |||
69 | /* place to store all the necessary device information */ | 91 | /* place to store all the necessary device information */ |
70 | struct av7110 { | 92 | struct av7110 { |
71 | 93 | ||
@@ -227,10 +249,7 @@ struct av7110 { | |||
227 | u16 wssMode; | 249 | u16 wssMode; |
228 | u16 wssData; | 250 | u16 wssData; |
229 | 251 | ||
230 | u32 ir_config; | 252 | struct infrared ir; |
231 | u32 ir_command; | ||
232 | void (*ir_handler)(struct av7110 *av7110, u32 ircom); | ||
233 | struct tasklet_struct ir_tasklet; | ||
234 | 253 | ||
235 | /* firmware stuff */ | 254 | /* firmware stuff */ |
236 | unsigned char *bin_fw; | 255 | unsigned char *bin_fw; |
@@ -268,6 +287,7 @@ struct av7110 { | |||
268 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 287 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
269 | u16 subpid, u16 pcrpid); | 288 | u16 subpid, u16 pcrpid); |
270 | 289 | ||
290 | extern int av7110_check_ir_config(struct av7110 *av7110, int force); | ||
271 | extern int av7110_ir_init(struct av7110 *av7110); | 291 | extern int av7110_ir_init(struct av7110 *av7110); |
272 | extern void av7110_ir_exit(struct av7110 *av7110); | 292 | extern void av7110_ir_exit(struct av7110 *av7110); |
273 | 293 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index e719af807685..654c9e919e04 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -1009,7 +1009,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1009 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) | 1009 | if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) |
1010 | ret = av7110_av_stop(av7110, RP_VIDEO); | 1010 | ret = av7110_av_stop(av7110, RP_VIDEO); |
1011 | else | 1011 | else |
1012 | ret = vidcom(av7110, VIDEO_CMD_STOP, | 1012 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, |
1013 | av7110->videostate.video_blank ? 0 : 1); | 1013 | av7110->videostate.video_blank ? 0 : 1); |
1014 | if (!ret) | 1014 | if (!ret) |
1015 | av7110->trickmode = TRICK_NONE; | 1015 | av7110->trickmode = TRICK_NONE; |
@@ -1019,7 +1019,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1019 | av7110->trickmode = TRICK_NONE; | 1019 | av7110->trickmode = TRICK_NONE; |
1020 | if (av7110->videostate.play_state == VIDEO_FREEZED) { | 1020 | if (av7110->videostate.play_state == VIDEO_FREEZED) { |
1021 | av7110->videostate.play_state = VIDEO_PLAYING; | 1021 | av7110->videostate.play_state = VIDEO_PLAYING; |
1022 | ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); | 1022 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); |
1023 | if (ret) | 1023 | if (ret) |
1024 | break; | 1024 | break; |
1025 | } | 1025 | } |
@@ -1034,7 +1034,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1034 | ret = av7110_av_start_play(av7110, RP_VIDEO); | 1034 | ret = av7110_av_start_play(av7110, RP_VIDEO); |
1035 | } | 1035 | } |
1036 | if (!ret) | 1036 | if (!ret) |
1037 | ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); | 1037 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); |
1038 | if (!ret) | 1038 | if (!ret) |
1039 | av7110->videostate.play_state = VIDEO_PLAYING; | 1039 | av7110->videostate.play_state = VIDEO_PLAYING; |
1040 | break; | 1040 | break; |
@@ -1044,7 +1044,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1044 | if (av7110->playing & RP_VIDEO) | 1044 | if (av7110->playing & RP_VIDEO) |
1045 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); | 1045 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); |
1046 | else | 1046 | else |
1047 | ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1); | 1047 | ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); |
1048 | if (!ret) | 1048 | if (!ret) |
1049 | av7110->trickmode = TRICK_FREEZE; | 1049 | av7110->trickmode = TRICK_FREEZE; |
1050 | break; | 1050 | break; |
@@ -1053,7 +1053,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1053 | if (av7110->playing & RP_VIDEO) | 1053 | if (av7110->playing & RP_VIDEO) |
1054 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); | 1054 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); |
1055 | if (!ret) | 1055 | if (!ret) |
1056 | ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); | 1056 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); |
1057 | if (!ret) { | 1057 | if (!ret) { |
1058 | av7110->videostate.play_state = VIDEO_PLAYING; | 1058 | av7110->videostate.play_state = VIDEO_PLAYING; |
1059 | av7110->trickmode = TRICK_NONE; | 1059 | av7110->trickmode = TRICK_NONE; |
@@ -1136,7 +1136,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1136 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | 1136 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, |
1137 | __Scan_I, 2, AV_PES, 0); | 1137 | __Scan_I, 2, AV_PES, 0); |
1138 | else | 1138 | else |
1139 | ret = vidcom(av7110, VIDEO_CMD_FFWD, arg); | 1139 | ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); |
1140 | if (!ret) { | 1140 | if (!ret) { |
1141 | av7110->trickmode = TRICK_FAST; | 1141 | av7110->trickmode = TRICK_FAST; |
1142 | av7110->videostate.play_state = VIDEO_PLAYING; | 1142 | av7110->videostate.play_state = VIDEO_PLAYING; |
@@ -1147,13 +1147,13 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1147 | if (av7110->playing&RP_VIDEO) { | 1147 | if (av7110->playing&RP_VIDEO) { |
1148 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); | 1148 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); |
1149 | if (!ret) | 1149 | if (!ret) |
1150 | ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); | 1150 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); |
1151 | } else { | 1151 | } else { |
1152 | ret = vidcom(av7110, VIDEO_CMD_PLAY, 0); | 1152 | ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); |
1153 | if (!ret) | 1153 | if (!ret) |
1154 | ret = vidcom(av7110, VIDEO_CMD_STOP, 0); | 1154 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); |
1155 | if (!ret) | 1155 | if (!ret) |
1156 | ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); | 1156 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); |
1157 | } | 1157 | } |
1158 | if (!ret) { | 1158 | if (!ret) { |
1159 | av7110->trickmode = TRICK_SLOW; | 1159 | av7110->trickmode = TRICK_SLOW; |
@@ -1182,10 +1182,10 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1182 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, | 1182 | ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, |
1183 | __Slow, 2, 0, 0); | 1183 | __Slow, 2, 0, 0); |
1184 | if (!ret) | 1184 | if (!ret) |
1185 | ret = vidcom(av7110, VIDEO_CMD_SLOW, arg); | 1185 | ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); |
1186 | } | 1186 | } |
1187 | if (av7110->trickmode == TRICK_FREEZE) | 1187 | if (av7110->trickmode == TRICK_FREEZE) |
1188 | ret = vidcom(av7110, VIDEO_CMD_STOP, 1); | 1188 | ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); |
1189 | } | 1189 | } |
1190 | break; | 1190 | break; |
1191 | 1191 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index 4e173c67fbb2..673d9b3f064c 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -216,11 +216,11 @@ enum av7110_command_type { | |||
216 | #define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ | 216 | #define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ |
217 | 217 | ||
218 | /* MPEG video decoder commands */ | 218 | /* MPEG video decoder commands */ |
219 | #define VIDEO_CMD_STOP 0x000e | 219 | #define AV_VIDEO_CMD_STOP 0x000e |
220 | #define VIDEO_CMD_PLAY 0x000d | 220 | #define AV_VIDEO_CMD_PLAY 0x000d |
221 | #define VIDEO_CMD_FREEZE 0x0102 | 221 | #define AV_VIDEO_CMD_FREEZE 0x0102 |
222 | #define VIDEO_CMD_FFWD 0x0016 | 222 | #define AV_VIDEO_CMD_FFWD 0x0016 |
223 | #define VIDEO_CMD_SLOW 0x0022 | 223 | #define AV_VIDEO_CMD_SLOW 0x0022 |
224 | 224 | ||
225 | /* MPEG audio decoder commands */ | 225 | /* MPEG audio decoder commands */ |
226 | #define AUDIO_CMD_MUTE 0x0001 | 226 | #define AUDIO_CMD_MUTE 0x0001 |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index f59465bb0af3..a97f166bb523 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -1,8 +1,31 @@ | |||
1 | /* | ||
2 | * Driver for the remote control of SAA7146 based AV7110 cards | ||
3 | * | ||
4 | * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de> | ||
5 | * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; either version 2 | ||
10 | * of the License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
20 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | |||
1 | #include <linux/types.h> | 25 | #include <linux/types.h> |
2 | #include <linux/init.h> | 26 | #include <linux/init.h> |
3 | #include <linux/module.h> | 27 | #include <linux/module.h> |
4 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
5 | #include <linux/input.h> | ||
6 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
7 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
8 | #include <asm/bitops.h> | 31 | #include <asm/bitops.h> |
@@ -10,18 +33,37 @@ | |||
10 | #include "av7110.h" | 33 | #include "av7110.h" |
11 | #include "av7110_hw.h" | 34 | #include "av7110_hw.h" |
12 | 35 | ||
13 | #define UP_TIMEOUT (HZ*7/25) | ||
14 | 36 | ||
15 | /* enable ir debugging by or'ing debug with 16 */ | 37 | #define AV_CNT 4 |
38 | |||
39 | #define IR_RC5 0 | ||
40 | #define IR_RCMM 1 | ||
41 | #define IR_RC5_EXT 2 /* internal only */ | ||
42 | |||
43 | #define IR_ALL 0xffffffff | ||
44 | |||
45 | #define UP_TIMEOUT (HZ*7/25) | ||
16 | 46 | ||
17 | static int av_cnt; | ||
18 | static struct av7110 *av_list[4]; | ||
19 | static struct input_dev *input_dev; | ||
20 | static char input_phys[32]; | ||
21 | 47 | ||
22 | static u8 delay_timer_finished; | 48 | /* Note: enable ir debugging by or'ing debug with 16 */ |
49 | |||
50 | static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM}; | ||
51 | module_param_array(ir_protocol, int, NULL, 0644); | ||
52 | MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)"); | ||
53 | |||
54 | static int ir_inversion[AV_CNT]; | ||
55 | module_param_array(ir_inversion, int, NULL, 0644); | ||
56 | MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted"); | ||
57 | |||
58 | static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL }; | ||
59 | module_param_array(ir_device_mask, uint, NULL, 0644); | ||
60 | MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)"); | ||
61 | |||
62 | |||
63 | static int av_cnt; | ||
64 | static struct av7110 *av_list[AV_CNT]; | ||
23 | 65 | ||
24 | static u16 key_map [256] = { | 66 | static u16 default_key_map [256] = { |
25 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, | 67 | KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, |
26 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, | 68 | KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, |
27 | KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 69 | KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
@@ -45,141 +87,194 @@ static u16 key_map [256] = { | |||
45 | }; | 87 | }; |
46 | 88 | ||
47 | 89 | ||
48 | static void av7110_emit_keyup(unsigned long data) | 90 | /* key-up timer */ |
91 | static void av7110_emit_keyup(unsigned long parm) | ||
49 | { | 92 | { |
50 | if (!data || !test_bit(data, input_dev->key)) | 93 | struct infrared *ir = (struct infrared *) parm; |
94 | |||
95 | if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) | ||
51 | return; | 96 | return; |
52 | 97 | ||
53 | input_report_key(input_dev, data, 0); | 98 | input_report_key(ir->input_dev, ir->last_key, 0); |
54 | input_sync(input_dev); | 99 | input_sync(ir->input_dev); |
55 | } | 100 | } |
56 | 101 | ||
57 | 102 | ||
58 | static struct timer_list keyup_timer = { .function = av7110_emit_keyup }; | 103 | /* tasklet */ |
59 | |||
60 | |||
61 | static void av7110_emit_key(unsigned long parm) | 104 | static void av7110_emit_key(unsigned long parm) |
62 | { | 105 | { |
63 | struct av7110 *av7110 = (struct av7110 *) parm; | 106 | struct infrared *ir = (struct infrared *) parm; |
64 | u32 ir_config = av7110->ir_config; | 107 | u32 ircom = ir->ir_command; |
65 | u32 ircom = av7110->ir_command; | ||
66 | u8 data; | 108 | u8 data; |
67 | u8 addr; | 109 | u8 addr; |
68 | static u16 old_toggle = 0; | 110 | u16 toggle; |
69 | u16 new_toggle; | ||
70 | u16 keycode; | 111 | u16 keycode; |
71 | 112 | ||
72 | /* extract device address and data */ | 113 | /* extract device address and data */ |
73 | switch (ir_config & 0x0003) { | 114 | switch (ir->protocol) { |
74 | case 0: /* RC5: 5 bits device address, 6 bits data */ | 115 | case IR_RC5: /* RC5: 5 bits device address, 6 bits data */ |
75 | data = ircom & 0x3f; | 116 | data = ircom & 0x3f; |
76 | addr = (ircom >> 6) & 0x1f; | 117 | addr = (ircom >> 6) & 0x1f; |
118 | toggle = ircom & 0x0800; | ||
77 | break; | 119 | break; |
78 | 120 | ||
79 | case 1: /* RCMM: 8(?) bits device address, 8(?) bits data */ | 121 | case IR_RCMM: /* RCMM: ? bits device address, ? bits data */ |
80 | data = ircom & 0xff; | 122 | data = ircom & 0xff; |
81 | addr = (ircom >> 8) & 0xff; | 123 | addr = (ircom >> 8) & 0x1f; |
124 | toggle = ircom & 0x8000; | ||
82 | break; | 125 | break; |
83 | 126 | ||
84 | case 2: /* extended RC5: 5 bits device address, 7 bits data */ | 127 | case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */ |
85 | data = ircom & 0x3f; | 128 | data = ircom & 0x3f; |
86 | addr = (ircom >> 6) & 0x1f; | 129 | addr = (ircom >> 6) & 0x1f; |
87 | /* invert 7th data bit for backward compatibility with RC5 keymaps */ | 130 | /* invert 7th data bit for backward compatibility with RC5 keymaps */ |
88 | if (!(ircom & 0x1000)) | 131 | if (!(ircom & 0x1000)) |
89 | data |= 0x40; | 132 | data |= 0x40; |
133 | toggle = ircom & 0x0800; | ||
90 | break; | 134 | break; |
91 | 135 | ||
92 | default: | 136 | default: |
93 | printk("invalid ir_config %x\n", ir_config); | 137 | printk("%s invalid protocol %x\n", __FUNCTION__, ir->protocol); |
94 | return; | 138 | return; |
95 | } | 139 | } |
96 | 140 | ||
97 | keycode = key_map[data]; | 141 | input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); |
142 | input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); | ||
98 | 143 | ||
99 | dprintk(16, "code %08x -> addr %i data 0x%02x -> keycode %i\n", | 144 | keycode = ir->key_map[data]; |
100 | ircom, addr, data, keycode); | ||
101 | 145 | ||
102 | /* check device address (if selected) */ | 146 | dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", |
103 | if (ir_config & 0x4000) | 147 | __FUNCTION__, ircom, addr, data, keycode); |
104 | if (addr != ((ir_config >> 16) & 0xff)) | 148 | |
105 | return; | 149 | /* check device address */ |
150 | if (!(ir->device_mask & (1 << addr))) | ||
151 | return; | ||
106 | 152 | ||
107 | if (!keycode) { | 153 | if (!keycode) { |
108 | printk ("%s: unknown key 0x%02x!!\n", __FUNCTION__, data); | 154 | printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", |
155 | __FUNCTION__, ircom, addr, data); | ||
109 | return; | 156 | return; |
110 | } | 157 | } |
111 | 158 | ||
112 | if ((ir_config & 0x0003) == 1) | 159 | if (timer_pending(&ir->keyup_timer)) { |
113 | new_toggle = 0; /* RCMM */ | 160 | del_timer(&ir->keyup_timer); |
114 | else | 161 | if (ir->last_key != keycode || toggle != ir->last_toggle) { |
115 | new_toggle = (ircom & 0x800); /* RC5, extended RC5 */ | 162 | ir->delay_timer_finished = 0; |
116 | 163 | input_event(ir->input_dev, EV_KEY, ir->last_key, 0); | |
117 | if (timer_pending(&keyup_timer)) { | 164 | input_event(ir->input_dev, EV_KEY, keycode, 1); |
118 | del_timer(&keyup_timer); | 165 | input_sync(ir->input_dev); |
119 | if (keyup_timer.data != keycode || new_toggle != old_toggle) { | 166 | } else if (ir->delay_timer_finished) { |
120 | delay_timer_finished = 0; | 167 | input_event(ir->input_dev, EV_KEY, keycode, 2); |
121 | input_event(input_dev, EV_KEY, keyup_timer.data, 0); | 168 | input_sync(ir->input_dev); |
122 | input_event(input_dev, EV_KEY, keycode, 1); | ||
123 | input_sync(input_dev); | ||
124 | } else if (delay_timer_finished) { | ||
125 | input_event(input_dev, EV_KEY, keycode, 2); | ||
126 | input_sync(input_dev); | ||
127 | } | 169 | } |
128 | } else { | 170 | } else { |
129 | delay_timer_finished = 0; | 171 | ir->delay_timer_finished = 0; |
130 | input_event(input_dev, EV_KEY, keycode, 1); | 172 | input_event(ir->input_dev, EV_KEY, keycode, 1); |
131 | input_sync(input_dev); | 173 | input_sync(ir->input_dev); |
132 | } | 174 | } |
133 | 175 | ||
134 | keyup_timer.expires = jiffies + UP_TIMEOUT; | 176 | ir->last_key = keycode; |
135 | keyup_timer.data = keycode; | 177 | ir->last_toggle = toggle; |
136 | 178 | ||
137 | add_timer(&keyup_timer); | 179 | ir->keyup_timer.expires = jiffies + UP_TIMEOUT; |
180 | add_timer(&ir->keyup_timer); | ||
138 | 181 | ||
139 | old_toggle = new_toggle; | ||
140 | } | 182 | } |
141 | 183 | ||
142 | static void input_register_keys(void) | 184 | |
185 | /* register with input layer */ | ||
186 | static void input_register_keys(struct infrared *ir) | ||
143 | { | 187 | { |
144 | int i; | 188 | int i; |
145 | 189 | ||
146 | memset(input_dev->keybit, 0, sizeof(input_dev->keybit)); | 190 | set_bit(EV_KEY, ir->input_dev->evbit); |
191 | set_bit(EV_REP, ir->input_dev->evbit); | ||
192 | set_bit(EV_MSC, ir->input_dev->evbit); | ||
147 | 193 | ||
148 | for (i = 0; i < ARRAY_SIZE(key_map); i++) { | 194 | set_bit(MSC_RAW, ir->input_dev->mscbit); |
149 | if (key_map[i] > KEY_MAX) | 195 | set_bit(MSC_SCAN, ir->input_dev->mscbit); |
150 | key_map[i] = 0; | 196 | |
151 | else if (key_map[i] > KEY_RESERVED) | 197 | memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); |
152 | set_bit(key_map[i], input_dev->keybit); | 198 | |
199 | for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { | ||
200 | if (ir->key_map[i] > KEY_MAX) | ||
201 | ir->key_map[i] = 0; | ||
202 | else if (ir->key_map[i] > KEY_RESERVED) | ||
203 | set_bit(ir->key_map[i], ir->input_dev->keybit); | ||
153 | } | 204 | } |
205 | |||
206 | ir->input_dev->keycode = ir->key_map; | ||
207 | ir->input_dev->keycodesize = sizeof(ir->key_map[0]); | ||
208 | ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); | ||
154 | } | 209 | } |
155 | 210 | ||
156 | 211 | ||
157 | static void input_repeat_key(unsigned long data) | 212 | /* called by the input driver after rep[REP_DELAY] ms */ |
213 | static void input_repeat_key(unsigned long parm) | ||
158 | { | 214 | { |
159 | /* called by the input driver after rep[REP_DELAY] ms */ | 215 | struct infrared *ir = (struct infrared *) parm; |
160 | delay_timer_finished = 1; | 216 | |
217 | ir->delay_timer_finished = 1; | ||
161 | } | 218 | } |
162 | 219 | ||
163 | 220 | ||
164 | static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | 221 | /* check for configuration changes */ |
222 | int av7110_check_ir_config(struct av7110 *av7110, int force) | ||
165 | { | 223 | { |
166 | int ret = 0; | 224 | int i; |
225 | int modified = force; | ||
226 | int ret = -ENODEV; | ||
167 | 227 | ||
168 | dprintk(4, "%p\n", av7110); | 228 | for (i = 0; i < av_cnt; i++) |
169 | if (av7110) { | 229 | if (av7110 == av_list[i]) |
170 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | 230 | break; |
171 | av7110->ir_config = ir_config; | 231 | |
232 | if (i < av_cnt && av7110) { | ||
233 | if ((av7110->ir.protocol & 1) != ir_protocol[i] || | ||
234 | av7110->ir.inversion != ir_inversion[i]) | ||
235 | modified = true; | ||
236 | |||
237 | if (modified) { | ||
238 | /* protocol */ | ||
239 | if (ir_protocol[i]) { | ||
240 | ir_protocol[i] = 1; | ||
241 | av7110->ir.protocol = IR_RCMM; | ||
242 | av7110->ir.ir_config = 0x0001; | ||
243 | } else if (FW_VERSION(av7110->arm_app) >= 0x2620) { | ||
244 | av7110->ir.protocol = IR_RC5_EXT; | ||
245 | av7110->ir.ir_config = 0x0002; | ||
246 | } else { | ||
247 | av7110->ir.protocol = IR_RC5; | ||
248 | av7110->ir.ir_config = 0x0000; | ||
249 | } | ||
250 | /* inversion */ | ||
251 | if (ir_inversion[i]) { | ||
252 | ir_inversion[i] = 1; | ||
253 | av7110->ir.ir_config |= 0x8000; | ||
254 | } | ||
255 | av7110->ir.inversion = ir_inversion[i]; | ||
256 | /* update ARM */ | ||
257 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, | ||
258 | av7110->ir.ir_config); | ||
259 | } else | ||
260 | ret = 0; | ||
261 | |||
262 | /* address */ | ||
263 | if (av7110->ir.device_mask != ir_device_mask[i]) | ||
264 | av7110->ir.device_mask = ir_device_mask[i]; | ||
172 | } | 265 | } |
266 | |||
173 | return ret; | 267 | return ret; |
174 | } | 268 | } |
175 | 269 | ||
176 | 270 | ||
271 | /* /proc/av7110_ir interface */ | ||
177 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | 272 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, |
178 | unsigned long count, void *data) | 273 | unsigned long count, void *data) |
179 | { | 274 | { |
180 | char *page; | 275 | char *page; |
181 | int size = 4 + 256 * sizeof(u16); | ||
182 | u32 ir_config; | 276 | u32 ir_config; |
277 | int size = sizeof ir_config + sizeof av_list[0]->ir.key_map; | ||
183 | int i; | 278 | int i; |
184 | 279 | ||
185 | if (count < size) | 280 | if (count < size) |
@@ -194,71 +289,86 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | |||
194 | return -EFAULT; | 289 | return -EFAULT; |
195 | } | 290 | } |
196 | 291 | ||
197 | memcpy(&ir_config, page, 4); | 292 | memcpy(&ir_config, page, sizeof ir_config); |
198 | memcpy(&key_map, page + 4, 256 * sizeof(u16)); | 293 | |
294 | for (i = 0; i < av_cnt; i++) { | ||
295 | /* keymap */ | ||
296 | memcpy(av_list[i]->ir.key_map, page + sizeof ir_config, | ||
297 | sizeof(av_list[i]->ir.key_map)); | ||
298 | /* protocol, inversion, address */ | ||
299 | ir_protocol[i] = ir_config & 0x0001; | ||
300 | ir_inversion[i] = ir_config & 0x8000 ? 1 : 0; | ||
301 | if (ir_config & 0x4000) | ||
302 | ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f); | ||
303 | else | ||
304 | ir_device_mask[i] = IR_ALL; | ||
305 | /* update configuration */ | ||
306 | av7110_check_ir_config(av_list[i], false); | ||
307 | input_register_keys(&av_list[i]->ir); | ||
308 | } | ||
199 | vfree(page); | 309 | vfree(page); |
200 | if (FW_VERSION(av_list[0]->arm_app) >= 0x2620 && !(ir_config & 0x0001)) | ||
201 | ir_config |= 0x0002; /* enable extended RC5 */ | ||
202 | for (i = 0; i < av_cnt; i++) | ||
203 | av7110_setup_irc_config(av_list[i], ir_config); | ||
204 | input_register_keys(); | ||
205 | return count; | 310 | return count; |
206 | } | 311 | } |
207 | 312 | ||
208 | 313 | ||
314 | /* interrupt handler */ | ||
209 | static void ir_handler(struct av7110 *av7110, u32 ircom) | 315 | static void ir_handler(struct av7110 *av7110, u32 ircom) |
210 | { | 316 | { |
211 | dprintk(4, "ircommand = %08x\n", ircom); | 317 | dprintk(4, "ir command = %08x\n", ircom); |
212 | av7110->ir_command = ircom; | 318 | av7110->ir.ir_command = ircom; |
213 | tasklet_schedule(&av7110->ir_tasklet); | 319 | tasklet_schedule(&av7110->ir.ir_tasklet); |
214 | } | 320 | } |
215 | 321 | ||
216 | 322 | ||
217 | int __devinit av7110_ir_init(struct av7110 *av7110) | 323 | int __devinit av7110_ir_init(struct av7110 *av7110) |
218 | { | 324 | { |
325 | struct input_dev *input_dev; | ||
219 | static struct proc_dir_entry *e; | 326 | static struct proc_dir_entry *e; |
220 | int err; | 327 | int err; |
221 | 328 | ||
222 | if (av_cnt >= ARRAY_SIZE(av_list)) | 329 | if (av_cnt >= ARRAY_SIZE(av_list)) |
223 | return -ENOSPC; | 330 | return -ENOSPC; |
224 | 331 | ||
225 | av7110_setup_irc_config(av7110, 0x0001); | ||
226 | av_list[av_cnt++] = av7110; | 332 | av_list[av_cnt++] = av7110; |
333 | av7110_check_ir_config(av7110, true); | ||
227 | 334 | ||
228 | if (av_cnt == 1) { | 335 | init_timer(&av7110->ir.keyup_timer); |
229 | init_timer(&keyup_timer); | 336 | av7110->ir.keyup_timer.function = av7110_emit_keyup; |
230 | keyup_timer.data = 0; | 337 | av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir; |
231 | 338 | ||
232 | input_dev = input_allocate_device(); | 339 | input_dev = input_allocate_device(); |
233 | if (!input_dev) | 340 | if (!input_dev) |
234 | return -ENOMEM; | 341 | return -ENOMEM; |
235 | |||
236 | snprintf(input_phys, sizeof(input_phys), | ||
237 | "pci-%s/ir0", pci_name(av7110->dev->pci)); | ||
238 | |||
239 | input_dev->name = "DVB on-card IR receiver"; | ||
240 | |||
241 | input_dev->phys = input_phys; | ||
242 | input_dev->id.bustype = BUS_PCI; | ||
243 | input_dev->id.version = 1; | ||
244 | if (av7110->dev->pci->subsystem_vendor) { | ||
245 | input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; | ||
246 | input_dev->id.product = av7110->dev->pci->subsystem_device; | ||
247 | } else { | ||
248 | input_dev->id.vendor = av7110->dev->pci->vendor; | ||
249 | input_dev->id.product = av7110->dev->pci->device; | ||
250 | } | ||
251 | input_dev->cdev.dev = &av7110->dev->pci->dev; | ||
252 | set_bit(EV_KEY, input_dev->evbit); | ||
253 | set_bit(EV_REP, input_dev->evbit); | ||
254 | input_register_keys(); | ||
255 | err = input_register_device(input_dev); | ||
256 | if (err) { | ||
257 | input_free_device(input_dev); | ||
258 | return err; | ||
259 | } | ||
260 | input_dev->timer.function = input_repeat_key; | ||
261 | 342 | ||
343 | av7110->ir.input_dev = input_dev; | ||
344 | snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys), | ||
345 | "pci-%s/ir0", pci_name(av7110->dev->pci)); | ||
346 | |||
347 | input_dev->name = "DVB on-card IR receiver"; | ||
348 | |||
349 | input_dev->phys = av7110->ir.input_phys; | ||
350 | input_dev->id.bustype = BUS_PCI; | ||
351 | input_dev->id.version = 2; | ||
352 | if (av7110->dev->pci->subsystem_vendor) { | ||
353 | input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; | ||
354 | input_dev->id.product = av7110->dev->pci->subsystem_device; | ||
355 | } else { | ||
356 | input_dev->id.vendor = av7110->dev->pci->vendor; | ||
357 | input_dev->id.product = av7110->dev->pci->device; | ||
358 | } | ||
359 | input_dev->cdev.dev = &av7110->dev->pci->dev; | ||
360 | /* initial keymap */ | ||
361 | memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); | ||
362 | input_register_keys(&av7110->ir); | ||
363 | err = input_register_device(input_dev); | ||
364 | if (err) { | ||
365 | input_free_device(input_dev); | ||
366 | return err; | ||
367 | } | ||
368 | input_dev->timer.function = input_repeat_key; | ||
369 | input_dev->timer.data = (unsigned long) &av7110->ir; | ||
370 | |||
371 | if (av_cnt == 1) { | ||
262 | e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); | 372 | e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); |
263 | if (e) { | 373 | if (e) { |
264 | e->write_proc = av7110_ir_write_proc; | 374 | e->write_proc = av7110_ir_write_proc; |
@@ -266,8 +376,8 @@ int __devinit av7110_ir_init(struct av7110 *av7110) | |||
266 | } | 376 | } |
267 | } | 377 | } |
268 | 378 | ||
269 | tasklet_init(&av7110->ir_tasklet, av7110_emit_key, (unsigned long) av7110); | 379 | tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); |
270 | av7110->ir_handler = ir_handler; | 380 | av7110->ir.ir_handler = ir_handler; |
271 | 381 | ||
272 | return 0; | 382 | return 0; |
273 | } | 383 | } |
@@ -280,8 +390,10 @@ void __devexit av7110_ir_exit(struct av7110 *av7110) | |||
280 | if (av_cnt == 0) | 390 | if (av_cnt == 0) |
281 | return; | 391 | return; |
282 | 392 | ||
283 | av7110->ir_handler = NULL; | 393 | del_timer_sync(&av7110->ir.keyup_timer); |
284 | tasklet_kill(&av7110->ir_tasklet); | 394 | av7110->ir.ir_handler = NULL; |
395 | tasklet_kill(&av7110->ir.ir_tasklet); | ||
396 | |||
285 | for (i = 0; i < av_cnt; i++) | 397 | for (i = 0; i < av_cnt; i++) |
286 | if (av_list[i] == av7110) { | 398 | if (av_list[i] == av7110) { |
287 | av_list[i] = av_list[av_cnt-1]; | 399 | av_list[i] = av_list[av_cnt-1]; |
@@ -289,14 +401,13 @@ void __devexit av7110_ir_exit(struct av7110 *av7110) | |||
289 | break; | 401 | break; |
290 | } | 402 | } |
291 | 403 | ||
292 | if (av_cnt == 1) { | 404 | if (av_cnt == 1) |
293 | del_timer_sync(&keyup_timer); | ||
294 | remove_proc_entry("av7110_ir", NULL); | 405 | remove_proc_entry("av7110_ir", NULL); |
295 | input_unregister_device(input_dev); | 406 | |
296 | } | 407 | input_unregister_device(av7110->ir.input_dev); |
297 | 408 | ||
298 | av_cnt--; | 409 | av_cnt--; |
299 | } | 410 | } |
300 | 411 | ||
301 | //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); | 412 | //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>"); |
302 | //MODULE_LICENSE("GPL"); | 413 | //MODULE_LICENSE("GPL"); |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 3035b224c7a3..0e817d6f1ce5 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include "budget.h" | 36 | #include "budget.h" |
37 | #include "stv0299.h" | 37 | #include "stv0299.h" |
38 | #include "tda10021.h" | 38 | #include "tda1002x.h" |
39 | #include "tda1004x.h" | 39 | #include "tda1004x.h" |
40 | #include "tua6100.h" | 40 | #include "tua6100.h" |
41 | #include "dvb-pll.h" | 41 | #include "dvb-pll.h" |
@@ -66,9 +66,6 @@ struct budget_av { | |||
66 | int slot_status; | 66 | int slot_status; |
67 | struct dvb_ca_en50221 ca; | 67 | struct dvb_ca_en50221 ca; |
68 | u8 reinitialise_demod:1; | 68 | u8 reinitialise_demod:1; |
69 | u8 tda10021_poclkp:1; | ||
70 | u8 tda10021_ts_enabled; | ||
71 | int (*tda10021_set_frontend)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); | ||
72 | }; | 69 | }; |
73 | 70 | ||
74 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); | 71 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); |
@@ -234,12 +231,6 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
234 | if (budget_av->reinitialise_demod) | 231 | if (budget_av->reinitialise_demod) |
235 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | 232 | dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); |
236 | 233 | ||
237 | /* set tda10021 back to original clock configuration on reset */ | ||
238 | if (budget_av->tda10021_poclkp) { | ||
239 | tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
240 | budget_av->tda10021_ts_enabled = 0; | ||
241 | } | ||
242 | |||
243 | return 0; | 234 | return 0; |
244 | } | 235 | } |
245 | 236 | ||
@@ -256,11 +247,6 @@ static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | |||
256 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 247 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); |
257 | budget_av->slot_status = SLOTSTATUS_NONE; | 248 | budget_av->slot_status = SLOTSTATUS_NONE; |
258 | 249 | ||
259 | /* set tda10021 back to original clock configuration when cam removed */ | ||
260 | if (budget_av->tda10021_poclkp) { | ||
261 | tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
262 | budget_av->tda10021_ts_enabled = 0; | ||
263 | } | ||
264 | return 0; | 250 | return 0; |
265 | } | 251 | } |
266 | 252 | ||
@@ -276,12 +262,6 @@ static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | |||
276 | 262 | ||
277 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | 263 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); |
278 | 264 | ||
279 | /* tda10021 seems to need a different TS clock config when data is routed to the CAM */ | ||
280 | if (budget_av->tda10021_poclkp) { | ||
281 | tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
282 | budget_av->tda10021_ts_enabled = 1; | ||
283 | } | ||
284 | |||
285 | return 0; | 265 | return 0; |
286 | } | 266 | } |
287 | 267 | ||
@@ -631,37 +611,62 @@ static struct stv0299_config cinergy_1200s_1894_0010_config = { | |||
631 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 611 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) |
632 | { | 612 | { |
633 | struct budget *budget = (struct budget *) fe->dvb->priv; | 613 | struct budget *budget = (struct budget *) fe->dvb->priv; |
634 | u8 buf[4]; | 614 | u8 buf[6]; |
635 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 615 | struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; |
616 | int i; | ||
636 | 617 | ||
618 | #define CU1216_IF 36125000 | ||
637 | #define TUNER_MUL 62500 | 619 | #define TUNER_MUL 62500 |
638 | 620 | ||
639 | u32 div = (params->frequency + 36125000 + TUNER_MUL / 2) / TUNER_MUL; | 621 | u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; |
640 | 622 | ||
641 | buf[0] = (div >> 8) & 0x7f; | 623 | buf[0] = (div >> 8) & 0x7f; |
642 | buf[1] = div & 0xff; | 624 | buf[1] = div & 0xff; |
643 | buf[2] = 0x86; | 625 | buf[2] = 0xce; |
644 | buf[3] = (params->frequency < 150000000 ? 0x01 : | 626 | buf[3] = (params->frequency < 150000000 ? 0x01 : |
645 | params->frequency < 445000000 ? 0x02 : 0x04); | 627 | params->frequency < 445000000 ? 0x02 : 0x04); |
628 | buf[4] = 0xde; | ||
629 | buf[5] = 0x20; | ||
630 | |||
631 | if (fe->ops.i2c_gate_ctrl) | ||
632 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
633 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | ||
634 | return -EIO; | ||
646 | 635 | ||
636 | /* wait for the pll lock */ | ||
637 | msg.flags = I2C_M_RD; | ||
638 | msg.len = 1; | ||
639 | for (i = 0; i < 20; i++) { | ||
640 | if (fe->ops.i2c_gate_ctrl) | ||
641 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
642 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40)) | ||
643 | break; | ||
644 | msleep(10); | ||
645 | } | ||
646 | |||
647 | /* switch the charge pump to the lower current */ | ||
648 | msg.flags = 0; | ||
649 | msg.len = 2; | ||
650 | msg.buf = &buf[2]; | ||
651 | buf[2] &= ~0x40; | ||
647 | if (fe->ops.i2c_gate_ctrl) | 652 | if (fe->ops.i2c_gate_ctrl) |
648 | fe->ops.i2c_gate_ctrl(fe, 1); | 653 | fe->ops.i2c_gate_ctrl(fe, 1); |
649 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 654 | if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) |
650 | return -EIO; | 655 | return -EIO; |
656 | |||
651 | return 0; | 657 | return 0; |
652 | } | 658 | } |
653 | 659 | ||
654 | static struct tda10021_config philips_cu1216_config = { | 660 | static struct tda1002x_config philips_cu1216_config = { |
655 | .demod_address = 0x0c, | 661 | .demod_address = 0x0c, |
662 | .invert = 1, | ||
656 | }; | 663 | }; |
657 | 664 | ||
658 | static struct tda10021_config philips_cu1216_config_altaddress = { | 665 | static struct tda1002x_config philips_cu1216_config_altaddress = { |
659 | .demod_address = 0x0d, | 666 | .demod_address = 0x0d, |
667 | .invert = 0, | ||
660 | }; | 668 | }; |
661 | 669 | ||
662 | |||
663 | |||
664 | |||
665 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) | 670 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) |
666 | { | 671 | { |
667 | struct budget *budget = (struct budget *) fe->dvb->priv; | 672 | struct budget *budget = (struct budget *) fe->dvb->priv; |
@@ -908,41 +913,28 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
908 | return pwm; | 913 | return pwm; |
909 | } | 914 | } |
910 | 915 | ||
911 | #define SUBID_DVBS_KNC1 0x0010 | 916 | #define SUBID_DVBS_KNC1 0x0010 |
912 | #define SUBID_DVBS_KNC1_PLUS 0x0011 | 917 | #define SUBID_DVBS_KNC1_PLUS 0x0011 |
913 | #define SUBID_DVBS_TYPHOON 0x4f56 | 918 | #define SUBID_DVBS_TYPHOON 0x4f56 |
914 | #define SUBID_DVBS_CINERGY1200 0x1154 | 919 | #define SUBID_DVBS_CINERGY1200 0x1154 |
915 | #define SUBID_DVBS_CYNERGY1200N 0x1155 | 920 | #define SUBID_DVBS_CYNERGY1200N 0x1155 |
916 | 921 | #define SUBID_DVBS_TV_STAR 0x0014 | |
917 | #define SUBID_DVBS_TV_STAR 0x0014 | 922 | #define SUBID_DVBS_TV_STAR_CI 0x0016 |
918 | #define SUBID_DVBS_TV_STAR_CI 0x0016 | 923 | #define SUBID_DVBS_EASYWATCH_1 0x001a |
919 | #define SUBID_DVBS_EASYWATCH_1 0x001a | 924 | #define SUBID_DVBS_EASYWATCH 0x001e |
920 | #define SUBID_DVBS_EASYWATCH 0x001e | 925 | |
921 | #define SUBID_DVBC_EASYWATCH 0x002a | 926 | #define SUBID_DVBC_EASYWATCH 0x002a |
922 | #define SUBID_DVBC_KNC1 0x0020 | 927 | #define SUBID_DVBC_EASYWATCH_MK3 0x002c |
923 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | 928 | #define SUBID_DVBC_KNC1 0x0020 |
924 | #define SUBID_DVBC_CINERGY1200 0x1156 | 929 | #define SUBID_DVBC_KNC1_PLUS 0x0021 |
925 | 930 | #define SUBID_DVBC_KNC1_MK3 0x0022 | |
926 | #define SUBID_DVBT_KNC1_PLUS 0x0031 | 931 | #define SUBID_DVBC_KNC1_PLUS_MK3 0x0023 |
927 | #define SUBID_DVBT_KNC1 0x0030 | 932 | #define SUBID_DVBC_CINERGY1200 0x1156 |
928 | #define SUBID_DVBT_CINERGY1200 0x1157 | 933 | #define SUBID_DVBC_CINERGY1200_MK3 0x1176 |
929 | 934 | ||
930 | 935 | #define SUBID_DVBT_KNC1_PLUS 0x0031 | |
931 | static int tda10021_set_frontend(struct dvb_frontend *fe, | 936 | #define SUBID_DVBT_KNC1 0x0030 |
932 | struct dvb_frontend_parameters *p) | 937 | #define SUBID_DVBT_CINERGY1200 0x1157 |
933 | { | ||
934 | struct budget_av* budget_av = fe->dvb->priv; | ||
935 | int result; | ||
936 | |||
937 | result = budget_av->tda10021_set_frontend(fe, p); | ||
938 | if (budget_av->tda10021_ts_enabled) { | ||
939 | tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa1); | ||
940 | } else { | ||
941 | tda10021_writereg(budget_av->budget.dvb_frontend, 0x12, 0xa0); | ||
942 | } | ||
943 | |||
944 | return result; | ||
945 | } | ||
946 | 938 | ||
947 | static void frontend_init(struct budget_av *budget_av) | 939 | static void frontend_init(struct budget_av *budget_av) |
948 | { | 940 | { |
@@ -961,6 +953,7 @@ static void frontend_init(struct budget_av *budget_av) | |||
961 | case SUBID_DVBC_KNC1_PLUS: | 953 | case SUBID_DVBC_KNC1_PLUS: |
962 | case SUBID_DVBT_KNC1_PLUS: | 954 | case SUBID_DVBT_KNC1_PLUS: |
963 | case SUBID_DVBC_EASYWATCH: | 955 | case SUBID_DVBC_EASYWATCH: |
956 | case SUBID_DVBC_KNC1_PLUS_MK3: | ||
964 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | 957 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); |
965 | break; | 958 | break; |
966 | } | 959 | } |
@@ -1017,6 +1010,7 @@ static void frontend_init(struct budget_av *budget_av) | |||
1017 | case SUBID_DVBC_CINERGY1200: | 1010 | case SUBID_DVBC_CINERGY1200: |
1018 | case SUBID_DVBC_EASYWATCH: | 1011 | case SUBID_DVBC_EASYWATCH: |
1019 | budget_av->reinitialise_demod = 1; | 1012 | budget_av->reinitialise_demod = 1; |
1013 | budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | ||
1020 | fe = dvb_attach(tda10021_attach, &philips_cu1216_config, | 1014 | fe = dvb_attach(tda10021_attach, &philips_cu1216_config, |
1021 | &budget_av->budget.i2c_adap, | 1015 | &budget_av->budget.i2c_adap, |
1022 | read_pwm(budget_av)); | 1016 | read_pwm(budget_av)); |
@@ -1025,9 +1019,20 @@ static void frontend_init(struct budget_av *budget_av) | |||
1025 | &budget_av->budget.i2c_adap, | 1019 | &budget_av->budget.i2c_adap, |
1026 | read_pwm(budget_av)); | 1020 | read_pwm(budget_av)); |
1027 | if (fe) { | 1021 | if (fe) { |
1028 | budget_av->tda10021_poclkp = 1; | 1022 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; |
1029 | budget_av->tda10021_set_frontend = fe->ops.set_frontend; | 1023 | } |
1030 | fe->ops.set_frontend = tda10021_set_frontend; | 1024 | break; |
1025 | |||
1026 | case SUBID_DVBC_EASYWATCH_MK3: | ||
1027 | case SUBID_DVBC_CINERGY1200_MK3: | ||
1028 | case SUBID_DVBC_KNC1_MK3: | ||
1029 | case SUBID_DVBC_KNC1_PLUS_MK3: | ||
1030 | budget_av->reinitialise_demod = 1; | ||
1031 | budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | ||
1032 | fe = dvb_attach(tda10023_attach, &philips_cu1216_config, | ||
1033 | &budget_av->budget.i2c_adap, | ||
1034 | read_pwm(budget_av)); | ||
1035 | if (fe) { | ||
1031 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | 1036 | fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; |
1032 | } | 1037 | } |
1033 | break; | 1038 | break; |
@@ -1260,12 +1265,16 @@ MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | |||
1260 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | 1265 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); |
1261 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | 1266 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); |
1262 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); | 1267 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); |
1268 | MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); | ||
1263 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 1269 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); |
1264 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | 1270 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); |
1271 | MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); | ||
1272 | MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); | ||
1265 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | 1273 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); |
1266 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | 1274 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); |
1267 | MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | 1275 | MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); |
1268 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); | 1276 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); |
1277 | MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); | ||
1269 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | 1278 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); |
1270 | 1279 | ||
1271 | static struct pci_device_id pci_tbl[] = { | 1280 | static struct pci_device_id pci_tbl[] = { |
@@ -1279,13 +1288,17 @@ static struct pci_device_id pci_tbl[] = { | |||
1279 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | 1288 | MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), |
1280 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | 1289 | MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), |
1281 | MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), | 1290 | MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), |
1291 | MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), | ||
1282 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1292 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1283 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 1293 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), |
1294 | MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), | ||
1295 | MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), | ||
1284 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 1296 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), |
1285 | MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), | 1297 | MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), |
1286 | MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), | 1298 | MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), |
1287 | MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), | 1299 | MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), |
1288 | MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), | 1300 | MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), |
1301 | MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176), | ||
1289 | MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), | 1302 | MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), |
1290 | { | 1303 | { |
1291 | .vendor = 0, | 1304 | .vendor = 0, |
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 464feaf1a9ad..4ed4599ce816 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -73,21 +73,15 @@ | |||
73 | #define SLOTSTATUS_READY 8 | 73 | #define SLOTSTATUS_READY 8 |
74 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | 74 | #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) |
75 | 75 | ||
76 | /* Milliseconds during which key presses are regarded as key repeat and during | 76 | /* |
77 | * which the debounce logic is active | 77 | * Milliseconds during which a key is regarded as pressed. |
78 | * If an identical command arrives within this time, the timer will start over. | ||
78 | */ | 79 | */ |
79 | #define IR_REPEAT_TIMEOUT 350 | 80 | #define IR_KEYPRESS_TIMEOUT 250 |
80 | 81 | ||
81 | /* RC5 device wildcard */ | 82 | /* RC5 device wildcard */ |
82 | #define IR_DEVICE_ANY 255 | 83 | #define IR_DEVICE_ANY 255 |
83 | 84 | ||
84 | /* Some remotes sends multiple sequences per keypress (e.g. Zenith sends two), | ||
85 | * this setting allows the superflous sequences to be ignored | ||
86 | */ | ||
87 | static int debounce = 0; | ||
88 | module_param(debounce, int, 0644); | ||
89 | MODULE_PARM_DESC(debounce, "ignore repeated IR sequences (default: 0 = ignore no sequences)"); | ||
90 | |||
91 | static int rc5_device = -1; | 85 | static int rc5_device = -1; |
92 | module_param(rc5_device, int, 0644); | 86 | module_param(rc5_device, int, 0644); |
93 | MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); | 87 | MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); |
@@ -99,10 +93,14 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | |||
99 | struct budget_ci_ir { | 93 | struct budget_ci_ir { |
100 | struct input_dev *dev; | 94 | struct input_dev *dev; |
101 | struct tasklet_struct msp430_irq_tasklet; | 95 | struct tasklet_struct msp430_irq_tasklet; |
96 | struct timer_list timer_keyup; | ||
102 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ | 97 | char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ |
103 | char phys[32]; | 98 | char phys[32]; |
104 | struct ir_input_state state; | 99 | struct ir_input_state state; |
105 | int rc5_device; | 100 | int rc5_device; |
101 | u32 last_raw; | ||
102 | u32 ir_key; | ||
103 | bool have_command; | ||
106 | }; | 104 | }; |
107 | 105 | ||
108 | struct budget_ci { | 106 | struct budget_ci { |
@@ -125,13 +123,8 @@ static void msp430_ir_interrupt(unsigned long data) | |||
125 | { | 123 | { |
126 | struct budget_ci *budget_ci = (struct budget_ci *) data; | 124 | struct budget_ci *budget_ci = (struct budget_ci *) data; |
127 | struct input_dev *dev = budget_ci->ir.dev; | 125 | struct input_dev *dev = budget_ci->ir.dev; |
128 | static int bounces = 0; | ||
129 | int device; | ||
130 | int toggle; | ||
131 | static int prev_toggle = -1; | ||
132 | static u32 ir_key; | ||
133 | static int state = 0; | ||
134 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; | 126 | u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; |
127 | u32 raw; | ||
135 | 128 | ||
136 | /* | 129 | /* |
137 | * The msp430 chip can generate two different bytes, command and device | 130 | * The msp430 chip can generate two different bytes, command and device |
@@ -143,7 +136,7 @@ static void msp430_ir_interrupt(unsigned long data) | |||
143 | * bytes and one or more device bytes. For the repeated bytes, the | 136 | * bytes and one or more device bytes. For the repeated bytes, the |
144 | * highest bit (X) is set. The first command byte is always generated | 137 | * highest bit (X) is set. The first command byte is always generated |
145 | * before the first device byte. Other than that, no specific order | 138 | * before the first device byte. Other than that, no specific order |
146 | * seems to apply. | 139 | * seems to apply. To make life interesting, bytes can also be lost. |
147 | * | 140 | * |
148 | * Only when we have a command and device byte, a keypress is | 141 | * Only when we have a command and device byte, a keypress is |
149 | * generated. | 142 | * generated. |
@@ -152,53 +145,35 @@ static void msp430_ir_interrupt(unsigned long data) | |||
152 | if (ir_debug) | 145 | if (ir_debug) |
153 | printk("budget_ci: received byte 0x%02x\n", command); | 146 | printk("budget_ci: received byte 0x%02x\n", command); |
154 | 147 | ||
155 | /* Is this a repeated byte? */ | 148 | /* Remove repeat bit, we use every command */ |
156 | if (command & 0x80) | 149 | command = command & 0x7f; |
157 | return; | ||
158 | 150 | ||
159 | /* Is this a RC5 command byte? */ | 151 | /* Is this a RC5 command byte? */ |
160 | if (command & 0x40) { | 152 | if (command & 0x40) { |
161 | state = 1; | 153 | budget_ci->ir.have_command = true; |
162 | ir_key = command & 0x3f; | 154 | budget_ci->ir.ir_key = command & 0x3f; |
163 | return; | 155 | return; |
164 | } | 156 | } |
165 | 157 | ||
166 | /* It's a RC5 device byte */ | 158 | /* It's a RC5 device byte */ |
167 | if (!state) | 159 | if (!budget_ci->ir.have_command) |
168 | return; | 160 | return; |
169 | state = 0; | 161 | budget_ci->ir.have_command = false; |
170 | device = command & 0x1f; | ||
171 | toggle = command & 0x20; | ||
172 | 162 | ||
173 | if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && budget_ci->ir.rc5_device != device) | 163 | if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && |
164 | budget_ci->ir.rc5_device != (command & 0x1f)) | ||
174 | return; | 165 | return; |
175 | 166 | ||
176 | /* Ignore repeated key sequences if requested */ | 167 | /* Is this a repeated key sequence? (same device, command, toggle) */ |
177 | if (toggle == prev_toggle && ir_key == dev->repeat_key && | 168 | raw = budget_ci->ir.ir_key | (command << 8); |
178 | bounces > 0 && timer_pending(&dev->timer)) { | 169 | if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) { |
179 | if (ir_debug) | ||
180 | printk("budget_ci: debounce logic ignored IR command\n"); | ||
181 | bounces--; | ||
182 | return; | ||
183 | } | ||
184 | prev_toggle = toggle; | ||
185 | |||
186 | /* Are we still waiting for a keyup event? */ | ||
187 | if (del_timer(&dev->timer)) | ||
188 | ir_input_nokey(dev, &budget_ci->ir.state); | ||
189 | |||
190 | /* Generate keypress */ | ||
191 | if (ir_debug) | ||
192 | printk("budget_ci: generating keypress 0x%02x\n", ir_key); | ||
193 | ir_input_keydown(dev, &budget_ci->ir.state, ir_key, (ir_key & (command << 8))); | ||
194 | |||
195 | /* Do we want to delay the keyup event? */ | ||
196 | if (debounce) { | ||
197 | bounces = debounce; | ||
198 | mod_timer(&dev->timer, jiffies + msecs_to_jiffies(IR_REPEAT_TIMEOUT)); | ||
199 | } else { | ||
200 | ir_input_nokey(dev, &budget_ci->ir.state); | 170 | ir_input_nokey(dev, &budget_ci->ir.state); |
171 | ir_input_keydown(dev, &budget_ci->ir.state, | ||
172 | budget_ci->ir.ir_key, raw); | ||
173 | budget_ci->ir.last_raw = raw; | ||
201 | } | 174 | } |
175 | |||
176 | mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT)); | ||
202 | } | 177 | } |
203 | 178 | ||
204 | static int msp430_ir_init(struct budget_ci *budget_ci) | 179 | static int msp430_ir_init(struct budget_ci *budget_ci) |
@@ -271,16 +246,21 @@ static int msp430_ir_init(struct budget_ci *budget_ci) | |||
271 | break; | 246 | break; |
272 | } | 247 | } |
273 | 248 | ||
274 | /* initialise the key-up debounce timeout handler */ | 249 | /* initialise the key-up timeout handler */ |
275 | input_dev->timer.function = msp430_ir_keyup; | 250 | init_timer(&budget_ci->ir.timer_keyup); |
276 | input_dev->timer.data = (unsigned long) &budget_ci->ir; | 251 | budget_ci->ir.timer_keyup.function = msp430_ir_keyup; |
277 | 252 | budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; | |
253 | budget_ci->ir.last_raw = 0xffff; /* An impossible value */ | ||
278 | error = input_register_device(input_dev); | 254 | error = input_register_device(input_dev); |
279 | if (error) { | 255 | if (error) { |
280 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); | 256 | printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); |
281 | goto out2; | 257 | goto out2; |
282 | } | 258 | } |
283 | 259 | ||
260 | /* note: these must be after input_register_device */ | ||
261 | input_dev->rep[REP_DELAY] = 400; | ||
262 | input_dev->rep[REP_PERIOD] = 250; | ||
263 | |||
284 | tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, | 264 | tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, |
285 | (unsigned long) budget_ci); | 265 | (unsigned long) budget_ci); |
286 | 266 | ||
@@ -304,10 +284,8 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci) | |||
304 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 284 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
305 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); | 285 | tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); |
306 | 286 | ||
307 | if (del_timer(&dev->timer)) { | 287 | del_timer_sync(&dev->timer); |
308 | ir_input_nokey(dev, &budget_ci->ir.state); | 288 | ir_input_nokey(dev, &budget_ci->ir.state); |
309 | input_sync(dev); | ||
310 | } | ||
311 | 289 | ||
312 | input_unregister_device(dev); | 290 | input_unregister_device(dev); |
313 | } | 291 | } |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index e15562f81664..6b97dc1e6b65 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -41,11 +41,14 @@ | |||
41 | 41 | ||
42 | #define TS_WIDTH (2 * TS_SIZE) | 42 | #define TS_WIDTH (2 * TS_SIZE) |
43 | #define TS_WIDTH_ACTIVY TS_SIZE | 43 | #define TS_WIDTH_ACTIVY TS_SIZE |
44 | #define TS_WIDTH_DVBC TS_SIZE | ||
44 | #define TS_HEIGHT_MASK 0xf00 | 45 | #define TS_HEIGHT_MASK 0xf00 |
45 | #define TS_HEIGHT_MASK_ACTIVY 0xc00 | 46 | #define TS_HEIGHT_MASK_ACTIVY 0xc00 |
47 | #define TS_HEIGHT_MASK_DVBC 0xe00 | ||
46 | #define TS_MIN_BUFSIZE_K 188 | 48 | #define TS_MIN_BUFSIZE_K 188 |
47 | #define TS_MAX_BUFSIZE_K 1410 | 49 | #define TS_MAX_BUFSIZE_K 1410 |
48 | #define TS_MAX_BUFSIZE_K_ACTIVY 564 | 50 | #define TS_MAX_BUFSIZE_K_ACTIVY 564 |
51 | #define TS_MAX_BUFSIZE_K_DVBC 1316 | ||
49 | #define BUFFER_WARNING_WAIT (30*HZ) | 52 | #define BUFFER_WARNING_WAIT (30*HZ) |
50 | 53 | ||
51 | int budget_debug; | 54 | int budget_debug; |
@@ -106,6 +109,19 @@ static int start_ts_capture(struct budget *budget) | |||
106 | saa7146_write(dev, MC2, (MASK_10 | MASK_26)); | 109 | saa7146_write(dev, MC2, (MASK_10 | MASK_26)); |
107 | saa7146_write(dev, BRS_CTRL, 0x60000000); | 110 | saa7146_write(dev, BRS_CTRL, 0x60000000); |
108 | break; | 111 | break; |
112 | case BUDGET_CIN1200C_MK3: | ||
113 | case BUDGET_KNC1C_MK3: | ||
114 | case BUDGET_KNC1CP_MK3: | ||
115 | if (budget->video_port == BUDGET_VIDEO_PORTA) { | ||
116 | saa7146_write(dev, DD1_INIT, 0x06000200); | ||
117 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
118 | saa7146_write(dev, BRS_CTRL, 0x00000000); | ||
119 | } else { | ||
120 | saa7146_write(dev, DD1_INIT, 0x00000600); | ||
121 | saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); | ||
122 | saa7146_write(dev, BRS_CTRL, 0x60000000); | ||
123 | } | ||
124 | break; | ||
109 | default: | 125 | default: |
110 | if (budget->video_port == BUDGET_VIDEO_PORTA) { | 126 | if (budget->video_port == BUDGET_VIDEO_PORTA) { |
111 | saa7146_write(dev, DD1_INIT, 0x06000200); | 127 | saa7146_write(dev, DD1_INIT, 0x06000200); |
@@ -122,7 +138,13 @@ static int start_ts_capture(struct budget *budget) | |||
122 | mdelay(10); | 138 | mdelay(10); |
123 | 139 | ||
124 | saa7146_write(dev, BASE_ODD3, 0); | 140 | saa7146_write(dev, BASE_ODD3, 0); |
125 | saa7146_write(dev, BASE_EVEN3, 0); | 141 | if (budget->buffer_size > budget->buffer_height * budget->buffer_width) { |
142 | // using odd/even buffers | ||
143 | saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width); | ||
144 | } else { | ||
145 | // using a single buffer | ||
146 | saa7146_write(dev, BASE_EVEN3, 0); | ||
147 | } | ||
126 | saa7146_write(dev, PROT_ADDR3, budget->buffer_size); | 148 | saa7146_write(dev, PROT_ADDR3, budget->buffer_size); |
127 | saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); | 149 | saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); |
128 | 150 | ||
@@ -399,11 +421,25 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
399 | budget->card = bi; | 421 | budget->card = bi; |
400 | budget->dev = (struct saa7146_dev *) dev; | 422 | budget->dev = (struct saa7146_dev *) dev; |
401 | 423 | ||
402 | if (budget->card->type == BUDGET_FS_ACTIVY) { | 424 | switch(budget->card->type) { |
425 | case BUDGET_FS_ACTIVY: | ||
403 | budget->buffer_width = TS_WIDTH_ACTIVY; | 426 | budget->buffer_width = TS_WIDTH_ACTIVY; |
404 | max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; | 427 | max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; |
405 | height_mask = TS_HEIGHT_MASK_ACTIVY; | 428 | height_mask = TS_HEIGHT_MASK_ACTIVY; |
406 | } else { | 429 | break; |
430 | |||
431 | case BUDGET_KNC1C: | ||
432 | case BUDGET_KNC1CP: | ||
433 | case BUDGET_CIN1200C: | ||
434 | case BUDGET_KNC1C_MK3: | ||
435 | case BUDGET_KNC1CP_MK3: | ||
436 | case BUDGET_CIN1200C_MK3: | ||
437 | budget->buffer_width = TS_WIDTH_DVBC; | ||
438 | max_bufsize = TS_MAX_BUFSIZE_K_DVBC; | ||
439 | height_mask = TS_HEIGHT_MASK_DVBC; | ||
440 | break; | ||
441 | |||
442 | default: | ||
407 | budget->buffer_width = TS_WIDTH; | 443 | budget->buffer_width = TS_WIDTH; |
408 | max_bufsize = TS_MAX_BUFSIZE_K; | 444 | max_bufsize = TS_MAX_BUFSIZE_K; |
409 | height_mask = TS_HEIGHT_MASK; | 445 | height_mask = TS_HEIGHT_MASK; |
@@ -415,14 +451,22 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
415 | dma_buffer_size = max_bufsize; | 451 | dma_buffer_size = max_bufsize; |
416 | 452 | ||
417 | budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; | 453 | budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; |
418 | budget->buffer_height &= height_mask; | 454 | if (budget->buffer_height > 0xfff) { |
419 | budget->buffer_size = budget->buffer_height * budget->buffer_width; | 455 | budget->buffer_height /= 2; |
456 | budget->buffer_height &= height_mask; | ||
457 | budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width; | ||
458 | } else { | ||
459 | budget->buffer_height &= height_mask; | ||
460 | budget->buffer_size = budget->buffer_height * budget->buffer_width; | ||
461 | } | ||
420 | budget->buffer_warning_threshold = budget->buffer_size * 80/100; | 462 | budget->buffer_warning_threshold = budget->buffer_size * 80/100; |
421 | budget->buffer_warnings = 0; | 463 | budget->buffer_warnings = 0; |
422 | budget->buffer_warning_time = jiffies; | 464 | budget->buffer_warning_time = jiffies; |
423 | 465 | ||
424 | dprintk(2, "%s: width = %d, height = %d\n", | 466 | dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n", |
425 | budget->dev->name, budget->buffer_width, budget->buffer_height); | 467 | budget->dev->name, |
468 | budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single", | ||
469 | budget->buffer_width, budget->buffer_height); | ||
426 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); | 470 | printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); |
427 | 471 | ||
428 | if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { | 472 | if ((ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, owner, &budget->dev->pci->dev)) < 0) { |
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index e8a5c79178e1..d764ffa728b0 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h | |||
@@ -99,6 +99,9 @@ static struct saa7146_pci_extension_data x_var = { \ | |||
99 | #define BUDGET_KNC1CP 12 | 99 | #define BUDGET_KNC1CP 12 |
100 | #define BUDGET_KNC1TP 13 | 100 | #define BUDGET_KNC1TP 13 |
101 | #define BUDGET_TVSTAR 14 | 101 | #define BUDGET_TVSTAR 14 |
102 | #define BUDGET_CIN1200C_MK3 15 | ||
103 | #define BUDGET_KNC1C_MK3 16 | ||
104 | #define BUDGET_KNC1CP_MK3 17 | ||
102 | 105 | ||
103 | #define BUDGET_VIDEO_PORTA 0 | 106 | #define BUDGET_VIDEO_PORTA 0 |
104 | #define BUDGET_VIDEO_PORTB 1 | 107 | #define BUDGET_VIDEO_PORTB 1 |
diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig index e78ea9227b0e..f546bccdb997 100644 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ b/drivers/media/dvb/ttusb-budget/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | config DVB_TTUSB_BUDGET | 1 | config DVB_TTUSB_BUDGET |
2 | tristate "Technotrend/Hauppauge Nova-USB devices" | 2 | tristate "Technotrend/Hauppauge Nova-USB devices" |
3 | depends on DVB_CORE && USB && I2C | 3 | depends on DVB_CORE && USB && I2C |
4 | select DVB_PLL | ||
5 | select DVB_CX22700 if !DVB_FE_CUSTOMISE | 4 | select DVB_CX22700 if !DVB_FE_CUSTOMISE |
6 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE | 5 | select DVB_TDA1004X if !DVB_FE_CUSTOMISE |
7 | select DVB_VES1820 if !DVB_FE_CUSTOMISE | 6 | select DVB_VES1820 if !DVB_FE_CUSTOMISE |