aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/msp3400-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/msp3400-driver.c')
-rw-r--r--drivers/media/video/msp3400-driver.c249
1 files changed, 43 insertions, 206 deletions
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 11ea9765769c..c40e8ba9a2ea 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -53,10 +53,11 @@
53#include <linux/videodev.h> 53#include <linux/videodev.h>
54#include <linux/videodev2.h> 54#include <linux/videodev2.h>
55#include <media/v4l2-common.h> 55#include <media/v4l2-common.h>
56#include <media/audiochip.h> 56#include <media/tvaudio.h>
57#include <media/msp3400.h>
57#include <linux/kthread.h> 58#include <linux/kthread.h>
58#include <linux/suspend.h> 59#include <linux/suspend.h>
59#include "msp3400.h" 60#include "msp3400-driver.h"
60 61
61/* ---------------------------------------------------------------------- */ 62/* ---------------------------------------------------------------------- */
62 63
@@ -245,31 +246,31 @@ int msp_write_dsp(struct i2c_client *client, int addr, int val)
245 * ----------------------------------------------------------------------- */ 246 * ----------------------------------------------------------------------- */
246 247
247static int scarts[3][9] = { 248static int scarts[3][9] = {
248 /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ 249 /* MASK IN1 IN2 IN3 IN4 IN1_DA IN2_DA MONO MUTE */
249 /* SCART DSP Input select */ 250 /* SCART DSP Input select */
250 { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, 251 { 0x0320, 0x0000, 0x0200, 0x0300, 0x0020, -1, -1, 0x0100, 0x0320 },
251 /* SCART1 Output select */ 252 /* SCART1 Output select */
252 { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, 253 { 0x0c40, 0x0440, 0x0400, 0x0000, 0x0840, 0x0c00, 0x0040, 0x0800, 0x0c40 },
253 /* SCART2 Output select */ 254 /* SCART2 Output select */
254 { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, 255 { 0x3080, 0x1000, 0x1080, 0x2080, 0x3080, 0x0000, 0x0080, 0x2000, 0x3000 },
255}; 256};
256 257
257static char *scart_names[] = { 258static char *scart_names[] = {
258 "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" 259 "in1", "in2", "in3", "in4", "in1 da", "in2 da", "mono", "mute"
259}; 260};
260 261
261void msp_set_scart(struct i2c_client *client, int in, int out) 262void msp_set_scart(struct i2c_client *client, int in, int out)
262{ 263{
263 struct msp_state *state = i2c_get_clientdata(client); 264 struct msp_state *state = i2c_get_clientdata(client);
264 265
265 state->in_scart=in; 266 state->in_scart = in;
266 267
267 if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { 268 if (in >= 0 && in <= 7 && out >= 0 && out <= 2) {
268 if (-1 == scarts[out][in]) 269 if (-1 == scarts[out][in + 1])
269 return; 270 return;
270 271
271 state->acb &= ~scarts[out][SCART_MASK]; 272 state->acb &= ~scarts[out][0];
272 state->acb |= scarts[out][in]; 273 state->acb |= scarts[out][in + 1];
273 } else 274 } else
274 state->acb = 0xf60; /* Mute Input and SCART 1 Output */ 275 state->acb = 0xf60; /* Mute Input and SCART 1 Output */
275 276
@@ -336,37 +337,6 @@ void msp_set_audio(struct i2c_client *client)
336 msp_write_dsp(client, 0x0033, loudness); 337 msp_write_dsp(client, 0x0033, loudness);
337} 338}
338 339
339int msp_modus(struct i2c_client *client)
340{
341 struct msp_state *state = i2c_get_clientdata(client);
342
343 if (state->radio) {
344 v4l_dbg(1, msp_debug, client, "video mode selected to Radio\n");
345 return 0x0003;
346 }
347
348 if (state->v4l2_std & V4L2_STD_PAL) {
349 v4l_dbg(1, msp_debug, client, "video mode selected to PAL\n");
350
351#if 1
352 /* experimental: not sure this works with all chip versions */
353 return 0x7003;
354#else
355 /* previous value, try this if it breaks ... */
356 return 0x1003;
357#endif
358 }
359 if (state->v4l2_std & V4L2_STD_NTSC) {
360 v4l_dbg(1, msp_debug, client, "video mode selected to NTSC\n");
361 return 0x2003;
362 }
363 if (state->v4l2_std & V4L2_STD_SECAM) {
364 v4l_dbg(1, msp_debug, client, "video mode selected to SECAM\n");
365 return 0x0003;
366 }
367 return 0x0003;
368}
369
370/* ------------------------------------------------------------------------ */ 340/* ------------------------------------------------------------------------ */
371 341
372 342
@@ -585,51 +555,11 @@ static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
585static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) 555static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
586{ 556{
587 struct msp_state *state = i2c_get_clientdata(client); 557 struct msp_state *state = i2c_get_clientdata(client);
588 u16 *sarg = arg;
589 int scart = 0;
590 558
591 if (msp_debug >= 2) 559 if (msp_debug >= 2)
592 v4l_i2c_print_ioctl(client, cmd); 560 v4l_i2c_print_ioctl(client, cmd);
593 561
594 switch (cmd) { 562 switch (cmd) {
595 case AUDC_SET_INPUT:
596 if (*sarg == state->input)
597 break;
598 state->input = *sarg;
599 switch (*sarg) {
600 case AUDIO_RADIO:
601 /* Hauppauge uses IN2 for the radio */
602 state->mode = MSP_MODE_FM_RADIO;
603 scart = SCART_IN2;
604 break;
605 case AUDIO_EXTERN_1:
606 /* IN1 is often used for external input ... */
607 state->mode = MSP_MODE_EXTERN;
608 scart = SCART_IN1;
609 break;
610 case AUDIO_EXTERN_2:
611 /* ... sometimes it is IN2 through ;) */
612 state->mode = MSP_MODE_EXTERN;
613 scart = SCART_IN2;
614 break;
615 case AUDIO_TUNER:
616 state->mode = -1;
617 break;
618 default:
619 if (*sarg & AUDIO_MUTE)
620 msp_set_scart(client, SCART_MUTE, 0);
621 break;
622 }
623 if (scart) {
624 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
625 msp_set_scart(client, scart, 0);
626 msp_write_dsp(client, 0x000d, 0x1900);
627 if (state->opmode != OPMODE_AUTOSELECT)
628 msp_set_audmode(client);
629 }
630 msp_wake_thread(client);
631 break;
632
633 case AUDC_SET_RADIO: 563 case AUDC_SET_RADIO:
634 if (state->radio) 564 if (state->radio)
635 return 0; 565 return 0;
@@ -692,6 +622,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
692 622
693 if (va->mode != 0 && state->radio == 0) { 623 if (va->mode != 0 && state->radio == 0) {
694 state->audmode = msp_mode_v4l1_to_v4l2(va->mode); 624 state->audmode = msp_mode_v4l1_to_v4l2(va->mode);
625 msp_set_audmode(client);
695 } 626 }
696 break; 627 break;
697 } 628 }
@@ -728,15 +659,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
728 break; 659 break;
729 } 660 }
730 661
731 /* msp34xx specific */
732 case MSP_SET_MATRIX:
733 {
734 struct msp_matrix *mspm = arg;
735
736 msp_set_scart(client, mspm->input, mspm->output);
737 break;
738 }
739
740 /* --- v4l2 ioctls --- */ 662 /* --- v4l2 ioctls --- */
741 case VIDIOC_S_STD: 663 case VIDIOC_S_STD:
742 { 664 {
@@ -750,90 +672,34 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
750 return 0; 672 return 0;
751 } 673 }
752 674
753 case VIDIOC_ENUMINPUT: 675 case VIDIOC_INT_G_AUDIO_ROUTING:
754 {
755 struct v4l2_input *i = arg;
756
757 if (i->index != 0)
758 return -EINVAL;
759
760 i->type = V4L2_INPUT_TYPE_TUNER;
761 switch (i->index) {
762 case AUDIO_RADIO:
763 strcpy(i->name, "Radio");
764 break;
765 case AUDIO_EXTERN_1:
766 strcpy(i->name, "Extern 1");
767 break;
768 case AUDIO_EXTERN_2:
769 strcpy(i->name, "Extern 2");
770 break;
771 case AUDIO_TUNER:
772 strcpy(i->name, "Television");
773 break;
774 default:
775 return -EINVAL;
776 }
777 return 0;
778 }
779
780 case VIDIOC_G_AUDIO:
781 { 676 {
782 struct v4l2_audio *a = arg; 677 struct v4l2_routing *rt = arg;
783 678
784 memset(a, 0, sizeof(*a)); 679 *rt = state->routing;
785
786 switch (a->index) {
787 case AUDIO_RADIO:
788 strcpy(a->name, "Radio");
789 break;
790 case AUDIO_EXTERN_1:
791 strcpy(a->name, "Extern 1");
792 break;
793 case AUDIO_EXTERN_2:
794 strcpy(a->name, "Extern 2");
795 break;
796 case AUDIO_TUNER:
797 strcpy(a->name, "Television");
798 break;
799 default:
800 return -EINVAL;
801 }
802
803 a->capability = V4L2_AUDCAP_STEREO;
804 a->mode = 0; /* TODO: add support for AVL */
805 break; 680 break;
806 } 681 }
807 682
808 case VIDIOC_S_AUDIO: 683 case VIDIOC_INT_S_AUDIO_ROUTING:
809 { 684 {
810 struct v4l2_audio *sarg = arg; 685 struct v4l2_routing *rt = arg;
811 686 int tuner = (rt->input >> 3) & 1;
812 switch (sarg->index) { 687 int sc_in = rt->input & 0x7;
813 case AUDIO_RADIO: 688 int sc1_out = rt->output & 0xf;
814 /* Hauppauge uses IN2 for the radio */ 689 int sc2_out = (rt->output >> 4) & 0xf;
815 state->mode = MSP_MODE_FM_RADIO; 690 u16 val;
816 scart = SCART_IN2; 691
817 break; 692 state->routing = *rt;
818 case AUDIO_EXTERN_1: 693 if (state->opmode == OPMODE_AUTOSELECT) {
819 /* IN1 is often used for external input ... */ 694 val = msp_read_dem(client, 0x30) & ~0x100;
820 state->mode = MSP_MODE_EXTERN; 695 msp_write_dem(client, 0x30, val | (tuner ? 0x100 : 0));
821 scart = SCART_IN1; 696 } else {
822 break; 697 val = msp_read_dem(client, 0xbb) & ~0x100;
823 case AUDIO_EXTERN_2: 698 msp_write_dem(client, 0xbb, val | (tuner ? 0x100 : 0));
824 /* ... sometimes it is IN2 through ;) */
825 state->mode = MSP_MODE_EXTERN;
826 scart = SCART_IN2;
827 break;
828 case AUDIO_TUNER:
829 state->mode = -1;
830 break;
831 }
832 if (scart) {
833 state->rxsubchans = V4L2_TUNER_SUB_STEREO;
834 msp_set_scart(client, scart, 0);
835 msp_write_dsp(client, 0x000d, 0x1900);
836 } 699 }
700 msp_set_scart(client, sc_in, 0);
701 msp_set_scart(client, sc1_out, 1);
702 msp_set_scart(client, sc2_out, 2);
837 msp_set_audmode(client); 703 msp_set_audmode(client);
838 msp_wake_thread(client); 704 msp_wake_thread(client);
839 break; 705 break;
@@ -866,42 +732,6 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
866 break; 732 break;
867 } 733 }
868 734
869 case VIDIOC_G_AUDOUT:
870 {
871 struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
872 int idx = a->index;
873
874 memset(a, 0, sizeof(*a));
875
876 switch (idx) {
877 case 0:
878 strcpy(a->name, "Scart1 Out");
879 break;
880 case 1:
881 strcpy(a->name, "Scart2 Out");
882 break;
883 case 2:
884 strcpy(a->name, "I2S Out");
885 break;
886 default:
887 return -EINVAL;
888 }
889 break;
890 }
891
892 case VIDIOC_S_AUDOUT:
893 {
894 struct v4l2_audioout *a = (struct v4l2_audioout *)arg;
895
896 if (a->index < 0 || a->index > 2)
897 return -EINVAL;
898
899 v4l_dbg(1, msp_debug, client, "Setting audio out on msp34xx to input %i\n", a->index);
900 msp_set_scart(client, state->in_scart, a->index + 1);
901
902 break;
903 }
904
905 case VIDIOC_INT_I2S_CLOCK_FREQ: 735 case VIDIOC_INT_I2S_CLOCK_FREQ:
906 { 736 {
907 u32 *a = (u32 *)arg; 737 u32 *a = (u32 *)arg;
@@ -979,12 +809,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
979 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 809 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
980 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 810 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
981 } else { 811 } else {
982 v4l_info(client, "Mode: %s\n", p); 812 if (state->opmode == OPMODE_AUTODETECT)
813 v4l_info(client, "Mode: %s\n", p);
983 v4l_info(client, "Standard: %s (%s%s)\n", 814 v4l_info(client, "Standard: %s (%s%s)\n",
984 msp_standard_std_name(state->std), 815 msp_standard_std_name(state->std),
985 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", 816 (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono",
986 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); 817 (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : "");
987 } 818 }
819 v4l_info(client, "Audmode: 0x%04x\n", state->audmode);
820 v4l_info(client, "Routing: 0x%08x (input) 0x%08x (output)\n",
821 state->routing.input, state->routing.output);
988 v4l_info(client, "ACB: 0x%04x\n", state->acb); 822 v4l_info(client, "ACB: 0x%04x\n", state->acb);
989 break; 823 break;
990 } 824 }
@@ -1063,6 +897,9 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind)
1063 state->muted = 0; 897 state->muted = 0;
1064 state->i2s_mode = 0; 898 state->i2s_mode = 0;
1065 init_waitqueue_head(&state->wq); 899 init_waitqueue_head(&state->wq);
900 /* These are the reset input/output positions */
901 state->routing.input = MSP_INPUT_DEFAULT;
902 state->routing.output = MSP_OUTPUT_DEFAULT;
1066 903
1067 state->rev1 = msp_read_dsp(client, 0x1e); 904 state->rev1 = msp_read_dsp(client, 0x1e);
1068 if (state->rev1 != -1) 905 if (state->rev1 != -1)