diff options
author | Paul Mackerras <paulus@samba.org> | 2007-04-29 22:38:01 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-29 22:38:01 -0400 |
commit | 49e1900d4cc2e7bcecb681fe60f0990bec2dcce8 (patch) | |
tree | 253801ebf57e0a23856a2c7be129c2c178f62fdf /drivers/media/dvb/ttpci | |
parent | 34f6d749c0a328817d5e36274e53121c1db734dc (diff) | |
parent | b9099ff63c75216d6ca10bce5a1abcd9293c27e6 (diff) |
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'drivers/media/dvb/ttpci')
-rw-r--r-- | drivers/media/dvb/ttpci/Kconfig | 6 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.c | 17 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110.h | 28 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_av.c | 24 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_hw.h | 10 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/av7110_ir.c | 365 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget-av.c | 147 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget-ci.c | 96 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget-core.c | 58 | ||||
-rw-r--r-- | drivers/media/dvb/ttpci/budget.h | 3 |
10 files changed, 465 insertions, 289 deletions
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 |