packaging: update the changelog
[profile/ivi/intel-emgd-kmod.git] / drivers / emgd / pal / sdvo / sdvo_hdmi.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: sdvo_hdmi.c
4  * $Revision: 1.7 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *  Port driver HDMI interface functions
29  *-----------------------------------------------------------------------------
30  */
31
32 #include "sdvo_hdmi.h"
33
34 #if 0
35  /*     HDMI Attributes
36         Currently if omitting out this attributes as this should NOT be avalable
37         to user
38         TODO: Integrate this attributes into HDMI  */
39 /* HDMI attributes */
40 #define PD_HDMI_COLORIMETRY_256_RGB                                     0
41 #define PD_HDMI_COLORIMETRY_220_RGB                                     1
42 #define PD_HDMI_COLORIMETRY_422_YCRCB                           2
43 #define PD_HDMI_COLORIMETRY_444_YCRCB                           3
44
45 #define PD_HDMI_PIXEL_REPLICATION_1X_REPITION                           1
46 #define PD_HDMI_PIXEL_REPLICATION_2X_REPITION                           2
47 #define PD_HDMI_PIXEL_REPLICATION_4X_REPITION                           4
48 /-----------------------------------------------------------------------------/
49  {PD_ATTR_ID_COLORIMETRY, MAKE_NAME("Colorimetry"), {4}, {0x0F},
50   GET_CURRENT_COLORIMETRY, SET_CURRENT_COLORIMETRY},
51
52   /* 256 RGB is passthrough, real value is 0x01 but 0x00 works as well
53         and upon boot up the value is 0x00 */
54  {PD_HDMI_COLORIMETRY_256_RGB,
55   MAKE_NAME("RGB 256 level"),                                                   {0}, {0x00}, 0, 0},
56  {PD_HDMI_COLORIMETRY_220_RGB,
57   MAKE_NAME("RGB 220 level"),                                                   {0}, {0x02}, 0, 0},
58  {PD_HDMI_COLORIMETRY_422_YCRCB,
59   MAKE_NAME("4:2:2 YcrCb"),                                                     {0}, {0x04}, 0, 0},
60  {PD_HDMI_COLORIMETRY_444_YCRCB,
61   MAKE_NAME("4:4:4 YcrCb"),                                                     {0}, {0x08}, 0, 0},
62
63  {PD_ATTR_ID_PIXEL_REPLICATION, MAKE_NAME("Pixel Replication"), {3}, {0x1F},
64   GET_PIXEL_REPLICATION, SET_PIXEL_REPLICATION},
65
66  {PD_HDMI_PIXEL_REPLICATION_1X_REPITION,
67   MAKE_NAME("No Repetition"),                                                   {0}, {0x00}, 0, 0},
68  {PD_HDMI_PIXEL_REPLICATION_2X_REPITION,
69   MAKE_NAME("1X Repetition"),                                                   {0}, {0x01}, 0, 0},
70  {PD_HDMI_PIXEL_REPLICATION_4X_REPITION,
71   MAKE_NAME("3X Repetition"),                                                   {0}, {0x03}, 0, 0},
72 #endif
73 #if defined(SDVO_HDMI)
74
75 /*      ============================================================================
76         Function        :       sdvo_hdmi_transmitter
77
78         Parameters      :
79
80         Remarks         :       Detect if transmitter is a HDMI transmitter.
81
82         Returns         :
83         ------------------------------------------------------------------------- */
84 sdvo_status_t sdvo_hdmi_transmitter(sdvo_device_context_t *p_ctx)
85 {
86         return sdvo_get_supported_encoding_modes(p_ctx,&(p_ctx->hdmi.version));
87 }
88
89 /*      ============================================================================
90         Function        :       sdvo_hdmi_support is called to see if the transmitter
91                                         and the monitor device support HDMI.
92
93         Parameters      :       p_context: Pointer to port driver allocated context
94                                                                 structure
95
96         Remarks         :
97
98         Returns         :       sdvo_status_t : Status of command execution
99         ------------------------------------------------------------------------- */
100 sdvo_status_t sdvo_hdmi_support(void *p_context)
101 {
102         sdvo_device_context_t *p_ctx = (sdvo_device_context_t *)p_context;
103         sdvo_status_t status = SS_SUCCESS;
104
105         /* Monitor support is determined by valid CEA 861 extension and */
106         /* vendor block with 0xC03 IEEE regstration ID */
107         /*
108         if((p_ctx->p_callback->eld) == NULL){
109                 return SS_NOT_SUPPORTED;
110         }
111
112         if((*p_ctx->p_callback->eld)->vendor_block_size) {
113                 return SS_NOT_SUPPORTED;
114         }
115
116         if((*p_ctx->p_callback->eld)->vendor_ieee_id != CEA_IEEE_HDMI_ID) {
117                 return SS_NOT_SUPPORTED;
118         }
119         */
120         /* Transmitter support is determined by SDVO GetSupportDigitalEncodingModes */
121         status = sdvo_hdmi_transmitter(p_ctx);
122         if (status != SS_SUCCESS) {
123                 return status;
124         }
125
126         return SS_SUCCESS;
127 }
128
129
130
131 /*      ============================================================================
132         Function        :       sdvo_hdmi_audio_characteristic
133
134         Parameters      :
135
136         Remarks         :       Set audio characteristic to be used in ELD calcilation.
137                                         TODO: Make sure this is recalled if hotplug is detected
138
139         Returns         :
140         ------------------------------------------------------------------------- */
141 sdvo_status_t sdvo_hdmi_audio_characteristic(sdvo_device_context_t *p_ctx)
142 {
143         sdvo_status_t status;
144         i2c_reg_t hdmi_audio_char[3];
145
146         /* Skip since no CEA data available */
147         if((!p_ctx->p_callback) || ((p_ctx->p_callback->eld) == NULL)){
148                 return SS_NOT_SUPPORTED;
149         }
150         if(*(p_ctx->p_callback->eld) == NULL){
151                 return SS_NOT_SUPPORTED;
152         }
153
154         status = sdvo_get_hdmi_audio_transmission_char(p_ctx, hdmi_audio_char);
155         if(status == SS_SUCCESS){
156                 (*p_ctx->p_callback->eld)->audio_flag |= PD_AUDIO_CHAR_AVAIL;
157                 (*p_ctx->p_callback->eld)->NPL = hdmi_audio_char[0];
158                 (*p_ctx->p_callback->eld)->K0   = hdmi_audio_char[1];
159                 (*p_ctx->p_callback->eld)->K1   = hdmi_audio_char[2];
160         }else{
161                 (*p_ctx->p_callback->eld)->audio_flag &= ~PD_AUDIO_CHAR_AVAIL;
162         }
163
164         return SS_SUCCESS;
165 }
166
167 /*      ============================================================================
168         Function        :       sdvo_hdmi_configure is called to program AVI infoframes, SPD
169                                         infoframes, ELD data for audio, colorimetry and pixel replication.
170
171         Parameters      :       p_context: Pointer to port driver allocated context
172                                                                 structure
173                                         p_mode: Point to current video output display mode
174
175         Remarks         :
176
177         Returns         :       sdvo_status_t : Status of command execution
178         ------------------------------------------------------------------------- */
179 sdvo_status_t sdvo_hdmi_configure(sdvo_device_context_t *p_ctx)
180 {
181         i2c_reg_t data;
182         sdvo_status_t status = SS_SUCCESS;
183         i2c_reg_t encoding_mode = DVI_MODE;
184
185         if((p_ctx->p_callback->eld) == NULL){
186                 sdvo_set_digital_encoding_mode(p_ctx, encoding_mode);
187                 return SS_NOT_SUPPORTED;
188         }
189         if(*(p_ctx->p_callback->eld) == NULL){
190                 sdvo_set_digital_encoding_mode(p_ctx, encoding_mode);
191                 return SS_NOT_SUPPORTED;
192         }
193
194         /* Prepare buffer for video information. Video only requires a total of 3
195          * buffers. (0)ELD (1)AVI (2)SPD. SO we will set it to 2 indexbased buffer */
196         status = sdvo_execute_command(p_ctx, GET_HDMI_BUFFER_AUDIO_VIDEO_SPLIT,
197                                 0, NULL,
198                                 1, &data);
199         data = 2;
200         status = sdvo_execute_command(p_ctx, SET_HDMI_BUFFER_AUDIO_VIDEO_SPLIT,
201                                 1, &data,
202                                 0, NULL);
203
204         /* Send pixel replication and colorimetry */
205         if (sdvo_hdmi_pr_and_color(p_ctx) != SS_SUCCESS) {
206                 PD_ERROR("Fail toset pixel replication and colorimetry");
207         }
208
209         /* Build and send ELD Info Frames */
210         if(sdvo_hdmi_send_eld(p_ctx) != SS_SUCCESS){
211                 PD_ERROR("Fail to write ELD to transmitter");
212         }
213
214         /* Build and send AVI Info Frames */
215         if (sdvo_hdmi_avi_info_frame(p_ctx) != SS_SUCCESS) {
216                 PD_ERROR("Fail to write AVI infoframes to transmitter");
217         }
218
219         /* Build and send SPD Info Frames */
220 #ifndef CONFIG_MICRO
221         if (sdvo_hdmi_spd_info_frame(p_ctx) != SS_SUCCESS) {
222                 PD_ERROR("Fail to write SPD Infoframes to transmitter");
223         }
224 #endif
225         /* Set to HDMI mode */
226         if((*p_ctx->p_callback->eld)->audio_support){
227                 encoding_mode = HDMI_MODE;
228         }
229         status = sdvo_set_digital_encoding_mode(p_ctx, encoding_mode);
230         if (status != SS_SUCCESS) {
231                 PD_DEBUG("sdvo: Fail to set HDMI mode ");
232         }
233
234         return SS_SUCCESS;
235 }
236 /*      ============================================================================
237         Function        :       sdvo_hdmi_pr_and_color is called to send pixel replication
238                                         and colorimetry data to SDVO device.
239
240         Parameters      :       p_context: Pointer to port driver allocated context
241                                                                 structure
242
243         Remarks         :
244
245         Returns         :       sdvo_status_t : Status of command execution
246         ------------------------------------------------------------------------- */
247 sdvo_status_t sdvo_hdmi_pr_and_color(sdvo_device_context_t *p_context)
248 {
249         sdvo_device_context_t *p_ctx = (sdvo_device_context_t *)p_context;
250         sdvo_status_t status = SS_SUCCESS;
251         i2c_reg_t pixel_rep = (i2c_reg_t)(*p_ctx->p_callback->eld)->pixel_rep - 1;
252         i2c_reg_t quantization = (i2c_reg_t)(*p_ctx->p_callback->eld)->quantization;
253
254         /* Set pixel replication */
255         status = sdvo_execute_command(p_ctx, SET_PIXEL_REPLICATION,
256                                 1, &pixel_rep,
257                                 0, NULL);
258         if (status != SS_SUCCESS) {
259                 return status;
260         }
261
262         /* Set colorimetry */
263         status = sdvo_execute_command(p_ctx, SET_CURRENT_COLORIMETRY,
264                                 1, &quantization,
265                                 0, NULL);
266         if (status != SS_SUCCESS) {
267                 return status;
268         }
269         return status;
270 };
271 /*      ============================================================================
272         Function        :       sdvo_hdmi_send_eld
273
274         Parameters      :
275
276         Remarks         :       Builds eld structure and write it into SDVO ELD buffers
277
278         Returns         :
279         ------------------------------------------------------------------------- */
280 sdvo_status_t sdvo_hdmi_send_eld(sdvo_device_context_t *p_ctx)
281 {
282         sdvo_status_t status;
283         sdvo_audio_state_t audio_state;
284
285         if((p_ctx->p_callback->eld) == NULL){
286                 return SS_NOT_SUPPORTED;
287         }
288         if(*(p_ctx->p_callback->eld) == NULL){
289                 return SS_NOT_SUPPORTED;
290         }
291         if(!((*p_ctx->p_callback->eld)->audio_flag & ELD_AVAIL)){
292                 PD_DEBUG("Eld not available");
293                 return SS_NOT_SUPPORTED;
294         }
295
296         /* ELD 1.0, CEA version retrieve from callback */
297         (*p_ctx->p_callback->eld)->cea_ver = 0;
298         (*p_ctx->p_callback->eld)->eld_ver = 1;
299
300         /* Capability Flags */
301         (*p_ctx->p_callback->eld)->repeater = 0;
302         (*p_ctx->p_callback->eld)->hdcp = 0;
303 #ifdef CONFIG_MICRO
304         (*p_ctx->p_callback->eld)->_44ms = 0;
305 #endif
306
307         /* We do not provide Monitor length */
308         (*p_ctx->p_callback->eld)->mnl = 0;
309
310 #ifdef CONFIG_MICRO
311         (*p_ctx->p_callback->eld)->sadc = 0;
312 #endif
313
314         audio_state.value = 0;
315         audio_state.eld_valid = FALSE;
316         audio_state.presense_detect = TRUE;
317         status = sdvo_execute_command(p_ctx, SET_AUDIO_STATE,
318                                 1, (i2c_reg_t *)&audio_state,
319                                 0, NULL);
320         if (status != SS_SUCCESS) {
321                 PD_ERROR("Set Audio eld_valid  fail (FALSE)");
322                 return status;
323         }
324
325         /* Write ELD to SDVO buffers */
326         status = sdvo_hdmi_write_buffer(p_ctx, SDVO_HDMI_ELD_BUFFER ,
327                 0,  (*p_ctx->p_callback->eld)->eld_ptr, SDVO_HDMI_ELD_BUFFER_SIZE);
328         if (status != SS_SUCCESS) {
329                 PD_ERROR("Write ELD Failed !");
330                 return status;
331         }
332
333         /* Send audio state change by toggling eld_valid bit */
334         audio_state.eld_valid = TRUE;
335         status = sdvo_execute_command(p_ctx, SET_AUDIO_STATE,
336                                 1, (i2c_reg_t *)&audio_state,
337                                 0, NULL);
338         if (status != SS_SUCCESS) {
339                 PD_ERROR("Set Audio eld_valid  fail (TRUE)");
340                 return status;
341         }
342
343         return SS_SUCCESS;
344 }
345 /*      ============================================================================
346         Function        :       sdvo_hdmi_avi_info_frame is called to program AVI infoframes
347
348         Parameters      :       p_context: Pointer to port driver allocated context
349                                                                 structure
350                                         p_mode: Point to current video output display mode
351
352         Remarks         :
353
354         Returns         :       sdvo_status_t : Status of command execution
355         ------------------------------------------------------------------------- */
356 sdvo_status_t sdvo_hdmi_avi_info_frame(sdvo_device_context_t *p_context)
357 {
358         sdvo_device_context_t *p_ctx = (sdvo_device_context_t *)p_context;
359         sdvo_status_t status = SS_SUCCESS;
360         unsigned long sum = 0;
361         int i;
362         sdvo_avi_info_t         avi;
363
364         /* Initialize AVI InfoFrame to no scan info, no bar info, no active format */
365         /* mode rgb, active format same as picture format */
366         /* no aspect ratio, no colorimetry, no scaling */
367         pd_memset(&avi, 0, sizeof(sdvo_avi_info_t));
368         avi.header.type = SDVO_HDMI_AVI_INFO_TYPE;
369         avi.header.version = 2;
370         avi.header.length = SDVO_HDMI_AVI_BUFFER_SIZE - sizeof(sdvo_info_header_t);
371
372         /* Fill in VIC, colorimetry, aspect ratio */
373
374         /* Set Video ID Code */
375         avi.video_id_code = (unsigned char)(*p_ctx->p_callback->eld)->video_code;
376
377         /* Set aspect ratio */
378         avi.pic_aspect_ratio = (unsigned char)(*p_ctx->p_callback->eld)->aspect_ratio;
379
380         /* Set Colorimetry */
381         avi.colorimetry = (unsigned char)(*p_ctx->p_callback->eld)->colorimetry;
382
383         /* Calc checksum */
384         for (i= 0; i < SDVO_HDMI_AVI_BUFFER_SIZE; i++) {
385                 sum += avi.data[i];
386         }
387         avi.header.chksum = (unsigned char)(0x100 - (sum & 0xFF));
388
389         /* Send data to SDVO device */
390         status = sdvo_hdmi_write_buffer(p_ctx, SDVO_HDMI_AVI_BUFFER, 0, avi.data,
391                 SDVO_HDMI_AVI_BUFFER_SIZE);
392         return status;
393 };
394 /*      ============================================================================
395         Function        :       sdvo_hdmi_spd_info_frame is called to program SPD infoframes
396
397         Parameters      :       p_context: Pointer to port driver allocated context
398                                                                 structure
399
400         Remarks         :
401
402         Returns         :       sdvo_status_t : Status of command execution
403         ------------------------------------------------------------------------- */
404 sdvo_status_t sdvo_hdmi_spd_info_frame(sdvo_device_context_t *p_context)
405 {
406         sdvo_device_context_t *p_ctx = (sdvo_device_context_t *)p_context;
407         sdvo_status_t status = SS_SUCCESS;
408         sdvo_spd_info_t         spd;
409         unsigned long sum = 0;
410         int i;
411
412         /* Initialize SPD InfoFrame to zero */
413         pd_memset(&spd, 0, sizeof(sdvo_spd_info_t));
414         spd.header.type = SDVO_HDMI_SPD_INFO_TYPE;
415         spd.header.version = 1;
416         spd.header.length = SDVO_HDMI_SPD_BUFFER_SIZE - sizeof(sdvo_info_header_t);
417
418         pd_memcpy(spd.vendor_name, SDVO_HDMI_VENDOR_NAME, SDVO_HDMI_INTEL_VENDOR_NAME_SIZE);
419         pd_memcpy(spd.product_desc,
420                 SDVO_HDMI_VENDOR_DESCRIPTION, SDVO_HDMI_IEGD_VENDOR_DESCRIPTION_SIZE);
421         spd.source_device = SDVO_HDMI_SPD_SOURCE_PC;
422
423         /* Calc checksum */
424         for (i= 0; i < SDVO_HDMI_SPD_BUFFER_SIZE; i++) {
425                 sum += spd.data[i];
426         }
427         spd.header.chksum = (unsigned char)(0x100 - (sum & 0xFF));
428
429         /* Send data to SDVO device */
430         status = sdvo_hdmi_write_buffer
431                 (p_ctx, SDVO_HDMI_SPD_BUFFER, 0, spd.data, SDVO_HDMI_SPD_BUFFER_SIZE);
432         return status;
433 };
434 /*      ============================================================================
435         Function        :       sdvo_hdmi_write_buffer
436
437         Parameters      :
438
439         Remarks         :       Write into SDVO buffers
440
441         Returns         :
442         ------------------------------------------------------------------------- */
443 sdvo_status_t sdvo_hdmi_write_buffer
444         (sdvo_device_context_t *p_ctx,unsigned char index,
445         unsigned char offset, unsigned char *input, int len)
446 {
447         sdvo_status_t status;
448         i2c_reg_t hdmi_index[2],data[8];
449         int buffer_size = 0;
450         unsigned char total_bytes, *p_sdvo_buffer, *ori_p_sdvo_buffer;
451
452         /* Set Buffer index and offset */
453         hdmi_index[0] = index;
454         hdmi_index[1] = offset;
455         status = sdvo_execute_command(p_ctx, SET_HDMI_BUFFER_INDEX,
456                                 2, hdmi_index,
457                                 0, NULL);
458         if (status != SS_SUCCESS) {
459                 PD_ERROR("HDMI wirte buffer fail : Set index");
460                 return status;
461         }
462
463         /* Setup buffer transmit rate */
464         if(index != SDVO_HDMI_ELD_BUFFER){
465                 data[0] = SDVO_HDMI_TRANSMIT_EVERY;
466                 status = sdvo_execute_command(p_ctx, SET_HDMI_BUFFER_TRANSMIT_RATE,
467                                         1, data,
468                                         0, NULL);
469                 if (status != SS_SUCCESS) {
470                         PD_ERROR("HDMI wirte buffer fail : Transmite rate");
471                         return status;
472                 }
473         }
474         else {
475                 status = sdvo_execute_command(p_ctx, GET_HDMI_BUFFER_TRANSMIT_RATE,
476                                         0, NULL,
477                                         1, data);
478                 if (status != SS_SUCCESS) {
479                         PD_ERROR("HDMI wirte buffer fail : Transmite rate");
480                         return status;
481                 }
482         }
483
484         /* Get buffer size info */
485         status = sdvo_execute_command(p_ctx, GET_HDMI_BUFFER_INFO,
486                         0, NULL,
487                         1, (i2c_reg_t *)&data);
488         buffer_size = data[0] + 1;
489         /* Minimum buffer size is 3 then something is wrong */
490         if (status != SS_SUCCESS || buffer_size <0x03) {
491                 PD_ERROR("HDMI wirte buffer fail : Buffer size");
492                 return status;
493         }
494
495         /* Make sure to query size of buffer from SDVO and use it, not size of source infoframe buffers */
496         /* copy structs into cleared memory the size of SDVO buffer */
497         p_sdvo_buffer = pd_malloc(buffer_size);
498         ori_p_sdvo_buffer = p_sdvo_buffer;
499         pd_memset(p_sdvo_buffer, 0, buffer_size);
500         pd_memcpy(p_sdvo_buffer, input, (len < buffer_size) ? len : buffer_size);
501
502         while(buffer_size) {
503                 //total_bytes = (buffer_size >= 8) ? 8:buffer_size;
504                 if(buffer_size >= 8)    total_bytes = 8;
505                 else                                    total_bytes = (unsigned char)buffer_size;
506
507                 status = sdvo_execute_command(p_ctx, SET_HDMI_BUFFER_DATA,
508                                 total_bytes, (i2c_reg_t *)p_sdvo_buffer,
509                                 0, NULL);
510                 if (status != SS_SUCCESS) {
511                         PD_ERROR("HDMI wirte buffer fail : Set buffer data");
512                         return status;
513                 }
514                 p_sdvo_buffer +=total_bytes;
515                 buffer_size -= total_bytes;
516         };
517
518         pd_free(ori_p_sdvo_buffer);
519         return SS_SUCCESS;
520 }
521
522 #endif/* SDVO_HDMI */
523
524