aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-firmware.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-firmware.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index a71e8ba306b0..d8bf2b01729d 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -23,7 +23,10 @@
23#include "ivtv-mailbox.h" 23#include "ivtv-mailbox.h"
24#include "ivtv-firmware.h" 24#include "ivtv-firmware.h"
25#include "ivtv-yuv.h" 25#include "ivtv-yuv.h"
26#include "ivtv-ioctl.h"
27#include "ivtv-cards.h"
26#include <linux/firmware.h> 28#include <linux/firmware.h>
29#include <media/saa7127.h>
27 30
28#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE 31#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
29#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6 32#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
@@ -271,3 +274,122 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
271 } 274 }
272 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1); 275 ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
273} 276}
277
278/* Try to restart the card & restore previous settings */
279int ivtv_firmware_restart(struct ivtv *itv)
280{
281 int rc = 0;
282 v4l2_std_id std;
283 struct ivtv_open_id fh;
284 fh.itv = itv;
285
286 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
287 /* Display test image during restart */
288 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
289 SAA7127_INPUT_TYPE_TEST_IMAGE,
290 itv->card->video_outputs[itv->active_output].video_output,
291 0);
292
293 mutex_lock(&itv->udma.lock);
294
295 rc = ivtv_firmware_init(itv);
296 if (rc) {
297 mutex_unlock(&itv->udma.lock);
298 return rc;
299 }
300
301 /* Allow settings to reload */
302 ivtv_mailbox_cache_invalidate(itv);
303
304 /* Restore video standard */
305 std = itv->std;
306 itv->std = 0;
307 ivtv_s_std(NULL, &fh, &std);
308
309 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
310 ivtv_init_mpeg_decoder(itv);
311
312 /* Restore framebuffer if active */
313 if (itv->ivtvfb_restore)
314 itv->ivtvfb_restore(itv);
315
316 /* Restore alpha settings */
317 ivtv_set_osd_alpha(itv);
318
319 /* Restore normal output */
320 ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
321 SAA7127_INPUT_TYPE_NORMAL,
322 itv->card->video_outputs[itv->active_output].video_output,
323 0);
324 }
325
326 mutex_unlock(&itv->udma.lock);
327 return rc;
328}
329
330/* Check firmware running state. The checks fall through
331 allowing multiple failures to be logged. */
332int ivtv_firmware_check(struct ivtv *itv, char *where)
333{
334 int res = 0;
335
336 /* Check encoder is still running */
337 if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) {
338 IVTV_WARN("Encoder has died : %s\n", where);
339 res = -1;
340 }
341
342 /* Also check audio. Only check if not in use & encoder is okay */
343 if (!res && !atomic_read(&itv->capturing) &&
344 (!atomic_read(&itv->decoding) ||
345 (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV,
346 &itv->i_flags)))) {
347
348 if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) {
349 IVTV_WARN("Audio has died (Encoder OK) : %s\n", where);
350 res = -2;
351 }
352 }
353
354 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
355 /* Second audio check. Skip if audio already failed */
356 if (res != -2 && read_dec(0x100) != read_dec(0x104)) {
357 /* Wait & try again to be certain. */
358 ivtv_msleep_timeout(14, 0);
359 if (read_dec(0x100) != read_dec(0x104)) {
360 IVTV_WARN("Audio has died (Decoder) : %s\n",
361 where);
362 res = -1;
363 }
364 }
365
366 /* Check decoder is still running */
367 if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) {
368 IVTV_WARN("Decoder has died : %s\n", where);
369 res = -1;
370 }
371 }
372
373 /* If something failed & currently idle, try to reload */
374 if (res && !atomic_read(&itv->capturing) &&
375 !atomic_read(&itv->decoding)) {
376 IVTV_INFO("Detected in %s that firmware had failed - "
377 "Reloading\n", where);
378 res = ivtv_firmware_restart(itv);
379 /*
380 * Even if restarted ok, still signal a problem had occured.
381 * The caller can come through this function again to check
382 * if things are really ok after the restart.
383 */
384 if (!res) {
385 IVTV_INFO("Firmware restart okay\n");
386 res = -EAGAIN;
387 } else {
388 IVTV_INFO("Firmware restart failed\n");
389 }
390 } else if (res) {
391 res = -EIO;
392 }
393
394 return res;
395}