aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2006-10-15 20:35:14 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2006-12-10 05:50:58 -0500
commitcc75aede1b1ce29a478911ad7dadee94ecd45bbf (patch)
treee76e579c04f3078c3a7981444ab57be4d02619f7 /drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
parentc85f49d49f437605550322bd2739af18230cf85b (diff)
V4L/DVB (4763): Pvrusb2: Implement IR reception for 24xxx devices
Unlike 29xxx devices, the 24xxx model series does not have a dedicated I2C device for reception of IR codes. Instead IR is handled directly by the FX2 microcontroller and the results are communicated via commands to the FX2. Rather than implement a whole new IR reception pathway for 24xxx devices, this changeset instead emulates the presence of the 29xxx device's I2C based IR receiver by intercepting commands to that chip and issuing appropriate FX2 commands to do the needed action. This has the result of allowing all the usual IR frameworks (ir-kbd-i2c or lirc) to continue working unmodified for 24xxx devices. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-i2c-core.c')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c81
1 files changed, 77 insertions, 4 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 3b9012f8e380..f9bb41d8f4f3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -185,6 +185,79 @@ static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
185 } 185 }
186} 186}
187 187
188
189/* This is a special entry point for cases of I2C transaction attempts to
190 the IR receiver. The implementation here simulates the IR receiver by
191 issuing a command to the FX2 firmware and using that response to return
192 what the real I2C receiver would have returned. We use this for 24xxx
193 devices, where the IR receiver chip has been removed and replaced with
194 FX2 related logic. */
195static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
196 u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
197{
198 u8 dat[4];
199 unsigned int stat;
200
201 if (!(rlen || wlen)) {
202 /* This is a probe attempt. Just let it succeed. */
203 return 0;
204 }
205
206 /* We don't understand this kind of transaction */
207 if ((wlen != 0) || (rlen == 0)) return -EIO;
208
209 if (rlen < 3) {
210 /* Mike Isely <isely@pobox.com> Appears to be a probe
211 attempt from lirc. Just fill in zeroes and return. If
212 we try instead to do the full transaction here, then bad
213 things seem to happen within the lirc driver module
214 (version 0.8.0-7 sources from Debian, when run under
215 vanilla 2.6.17.6 kernel) - and I don't have the patience
216 to chase it down. */
217 if (rlen > 0) rdata[0] = 0;
218 if (rlen > 1) rdata[1] = 0;
219 return 0;
220 }
221
222 /* Issue a command to the FX2 to read the IR receiver. */
223 LOCK_TAKE(hdw->ctl_lock); do {
224 hdw->cmd_buffer[0] = 0xec;
225 stat = pvr2_send_request(hdw,
226 hdw->cmd_buffer,1,
227 hdw->cmd_buffer,4);
228 dat[0] = hdw->cmd_buffer[0];
229 dat[1] = hdw->cmd_buffer[1];
230 dat[2] = hdw->cmd_buffer[2];
231 dat[3] = hdw->cmd_buffer[3];
232 } while (0); LOCK_GIVE(hdw->ctl_lock);
233
234 /* Give up if that operation failed. */
235 if (stat != 0) return stat;
236
237 /* Mangle the results into something that looks like the real IR
238 receiver. */
239 rdata[2] = 0xc1;
240 if (dat[0] != 1) {
241 /* No code received. */
242 rdata[0] = 0;
243 rdata[1] = 0;
244 } else {
245 u16 val;
246 /* Mash the FX2 firmware-provided IR code into something
247 that the normal i2c chip-level driver expects. */
248 val = dat[1];
249 val <<= 8;
250 val |= dat[2];
251 val >>= 1;
252 val &= ~0x0003;
253 val |= 0x8000;
254 rdata[0] = (val >> 8) & 0xffu;
255 rdata[1] = val & 0xffu;
256 }
257
258 return 0;
259}
260
188/* This is a special entry point that is entered if an I2C operation is 261/* This is a special entry point that is entered if an I2C operation is
189 attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this 262 attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
190 part doesn't work, but we know it is really there. So let's look for 263 part doesn't work, but we know it is really there. So let's look for
@@ -887,17 +960,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
887{ 960{
888 unsigned int idx; 961 unsigned int idx;
889 962
890 // The default action for all possible I2C addresses is just to do 963 /* The default action for all possible I2C addresses is just to do
891 // the transfer normally. 964 the transfer normally. */
892 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { 965 for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
893 hdw->i2c_func[idx] = pvr2_i2c_basic_op; 966 hdw->i2c_func[idx] = pvr2_i2c_basic_op;
894 } 967 }
895 968
896 // If however we're dealing with new hardware, insert some hacks in 969 /* However, deal with various special cases for 24xxx hardware. */
897 // the I2C transfer stack to let things work better.
898 if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { 970 if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
899 hdw->i2c_func[0x1b] = i2c_hack_wm8775; 971 hdw->i2c_func[0x1b] = i2c_hack_wm8775;
900 hdw->i2c_func[0x44] = i2c_hack_cx25840; 972 hdw->i2c_func[0x44] = i2c_hack_cx25840;
973 hdw->i2c_func[0x18] = i2c_24xxx_ir;
901 } 974 }
902 975
903 // Configure the adapter and set up everything else related to it. 976 // Configure the adapter and set up everything else related to it.