add auto vcr switching support (needs new drivers (fp.ko))
[vuplus_dvbapp] / lib / driver / avswitch.cpp
1 #include <unistd.h>
2 #include <fcntl.h>
3 #include <sys/ioctl.h>
4
5 #include <lib/base/init.h>
6 #include <lib/base/init_num.h>
7 #include <lib/base/eerror.h>
8 #include <lib/base/ebase.h>
9 #include <lib/driver/avswitch.h>
10
11 eAVSwitch *eAVSwitch::instance = 0;
12
13 eAVSwitch::eAVSwitch()
14 {
15         ASSERT(!instance);
16         instance = this;
17         m_video_mode = 0;
18         m_fp_fd = open("/dev/dbox/fp0", O_RDONLY|O_NONBLOCK);
19         if (m_fp_fd == -1)
20         {
21                 eDebug("couldnt open /dev/dbox/fp0 to monitor vcr scart slow blanking changed!");
22                 m_fp_notifier=0;
23         }
24         else
25         {
26                 m_fp_notifier = new eSocketNotifier(eApp, m_fp_fd, eSocketNotifier::Read);
27                 CONNECT(m_fp_notifier->activated, eAVSwitch::fp_event);
28         }
29 }
30
31 #ifndef FP_IOCTL_GET_EVENT
32 #define FP_IOCTL_GET_EVENT 20
33 #endif
34
35 #ifndef FP_IOCTL_GET_VCR
36 #define FP_IOCTL_GET_VCR 7
37 #endif
38
39 #ifndef FP_EVENT_VCR_SB_CHANGED
40 #define FP_EVENT_VCR_SB_CHANGED 1
41 #endif
42
43 int eAVSwitch::getVCRSlowBlanking()
44 {
45         int val=0;
46         if (m_fp_fd >= 0)
47         {
48                 if (ioctl(m_fp_fd, FP_IOCTL_GET_VCR, &val) < 0)
49                         eDebug("FP_GET_VCR failed (%m)");
50         }
51         return val;
52 }
53
54 void eAVSwitch::fp_event(int what)
55 {
56         int val = FP_EVENT_VCR_SB_CHANGED;  // ask only for this event
57         if (ioctl(m_fp_fd, FP_IOCTL_GET_EVENT, &val) < 0)
58                 eDebug("FP_IOCTL_GET_EVENT failed (%m)");
59         else if (val & FP_EVENT_VCR_SB_CHANGED)
60                 /* emit */ vcr_sb_notifier(getVCRSlowBlanking());
61 }
62
63 eAVSwitch::~eAVSwitch()
64 {
65 }
66
67 eAVSwitch *eAVSwitch::getInstance()
68 {
69         return instance;
70 }
71
72 void eAVSwitch::setInput(int val)
73 {
74         /*
75         0-encoder
76         1-scart
77         2-aux
78         */
79
80         char *input[] = {"encoder", "scart", "aux"};
81
82         int fd;
83         
84         if((fd = open("/proc/stb/avs/0/input", O_WRONLY)) < 0) {
85                 printf("cannot open /proc/stb/avs/0/input\n");
86                 return;
87         }
88
89         write(fd, input[val], strlen(input[val]));
90         close(fd);
91         
92         if (val == 1)
93                 setFastBlank(2);
94 }
95
96 void eAVSwitch::setFastBlank(int val)
97 {
98         int fd;
99         char *fb[] = {"low", "high", "vcr"};
100
101         if((fd = open("/proc/stb/avs/0/fb", O_WRONLY)) < 0) {
102                 printf("cannot open /proc/stb/avs/0/fb\n");
103                 return;
104         }
105
106         write(fd, fb[val], strlen(fb[0]));
107         close(fd);
108 }
109
110 void eAVSwitch::setColorFormat(int format)
111 {
112         /*
113         0-CVBS
114         1-RGB
115         2-S-Video
116         */
117         char *cvbs="cvbs";
118         char *rgb="rgb";
119         char *svideo="svideo";
120         char *yuv="yuv";
121         int fd;
122         
123         if((fd = open("/proc/stb/avs/0/colorformat", O_WRONLY)) < 0) {
124                 printf("cannot open /proc/stb/avs/0/colorformat\n");
125                 return;
126         }
127         switch(format) {
128                 case 0:
129                         write(fd, cvbs, strlen(cvbs));
130                         break;
131                 case 1:
132                         write(fd, rgb, strlen(rgb));
133                         break;
134                 case 2:
135                         write(fd, svideo, strlen(svideo));
136                         break;
137                 case 3:
138                         write(fd, yuv, strlen(yuv));
139                         break;
140         }       
141         close(fd);
142 }
143
144 void eAVSwitch::setAspectRatio(int ratio)
145 {
146         /*
147         0-4:3 Letterbox
148         1-4:3 PanScan
149         2-16:9
150         3-16:9 forced ("panscan")
151         4-16:10 Letterbox
152         5-16:10 PanScan
153         6-16:9 forced ("letterbox")
154         */
155         char *aspect[] = {"4:3", "4:3", "any", "16:9", "16:10", "16:10", "16:9", "16:9"};
156         char *policy[] = {"letterbox", "panscan", "bestfit", "panscan", "letterbox", "panscan", "letterbox"};
157
158         int fd;
159         if((fd = open("/proc/stb/video/aspect", O_WRONLY)) < 0) {
160                 printf("cannot open /proc/stb/video/aspect\n");
161                 return;
162         }
163 //      eDebug("set aspect to %s", aspect[ratio]);
164         write(fd, aspect[ratio], strlen(aspect[ratio]));
165         close(fd);
166
167         if((fd = open("/proc/stb/video/policy", O_WRONLY)) < 0) {
168                 printf("cannot open /proc/stb/video/policy\n");
169                 return;
170         }
171 //      eDebug("set ratio to %s", policy[ratio]);
172         write(fd, policy[ratio], strlen(policy[ratio]));
173         close(fd);
174
175 }
176
177 void eAVSwitch::setVideomode(int mode)
178 {
179         char *pal="pal";
180         char *ntsc="ntsc";
181         
182         if (mode == m_video_mode)
183                 return;
184         
185         int fd;
186
187         if((fd = open("/proc/stb/video/videomode", O_WRONLY)) < 0) {
188                 printf("cannot open /proc/stb/video/videomode\n");
189                 return;
190         }
191         switch(mode) {
192                 case 0:
193                         write(fd, pal, strlen(pal));
194                         break;
195                 case 1:
196                         write(fd, ntsc, strlen(ntsc));
197                         break;
198         }
199         close(fd);
200
201         m_video_mode = mode;
202 }
203
204 void eAVSwitch::setWSS(int val) // 0 = auto, 1 = auto(4:3_off)
205 {
206         int fd;
207         if((fd = open("/proc/stb/denc/0/wss", O_WRONLY)) < 0) {
208                 printf("cannot open /proc/stb/denc/0/wss\n");
209                 return;
210         }
211         char *wss[] = {
212                 "off", "auto", "auto(4:3_off)", "4:3_full_format", "16:9_full_format",
213                 "14:9_letterbox_center", "14:9_letterbox_top", "16:9_letterbox_center",
214                 "16:9_letterbox_top", ">16:9_letterbox_center", "14:9_full_format"
215         };
216         write(fd, wss[val], strlen(wss[val]));
217 //      eDebug("set wss to %s", wss[val]);
218         close(fd);
219 }
220
221 void eAVSwitch::setSlowblank(int val)
222 {
223         int fd;
224         if((fd = open("/proc/stb/avs/0/sb", O_WRONLY)) < 0) {
225                 printf("cannot open /proc/stb/avs/0/sb\n");
226                 return;
227         }
228         char *sb[] = {"0", "6", "12", "vcr", "auto"};
229         write(fd, sb[val], strlen(sb[val]));
230 //      eDebug("set slow blanking to %s", sb[val]);
231         close(fd);
232 }
233
234 //FIXME: correct "run/startlevel"
235 eAutoInitP0<eAVSwitch> init_avswitch(eAutoInitNumbers::rc, "AVSwitch Driver");