packaging: update the changelog
[profile/ivi/intel-emgd-kmod.git] / drivers / emgd / display / pi / tnc / i2c_gmbus_tnc.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: i2c_gmbus_tnc.c
4  * $Revision: 1.15 $
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  *
29  *-----------------------------------------------------------------------------
30  */
31
32 #define MODULE_NAME hal.dpd
33
34 #include <io.h>
35 #include <memory.h>
36 #include <sched.h>
37
38 #include <igd_pwr.h>
39
40 #include <general.h>
41 #include <context.h>
42 #include <mode.h>
43 #include <utils.h>
44
45 #include <tnc/regs.h>
46
47 #include "../cmn/i2c_dispatch.h"
48
49 /*!
50  * @addtogroup display_group
51  * @{
52  */
53
54 /*......................................................................... */
55 extern igd_display_port_t dvob_port_tnc;
56
57 /*......................................................................... */
58 static int i2c_read_regs_tnc(
59         igd_context_t *context,
60         unsigned long i2c_bus,
61         unsigned long i2c_speed,
62         unsigned long dab,
63         unsigned char reg,
64         unsigned char FAR *buffer,
65         unsigned long num_bytes,
66         unsigned long flags);
67
68 static int i2c_write_reg_list_tnc(
69         igd_context_t *context,
70         unsigned long i2c_bus,
71         unsigned long i2c_speed,
72         unsigned long dab,
73         pd_reg_t *reg_list,
74         unsigned long flags);
75
76 i2c_dispatch_t i2c_dispatch_tnc = {
77         i2c_read_regs_tnc,
78         i2c_write_reg_list_tnc,
79 };
80
81
82 /*.......................................................................... */
83 typedef enum {
84
85         GMBUS_SPEED_50K     = 0x0100,
86         GMBUS_SPEED_100K        = 0x0000,
87         GMBUS_SPEED_400K        = 0x0200,
88         GMBUS_SPEED_1000K       = 0x0300,
89
90 } gmbus_speed_t;
91
92 typedef enum {
93
94         SDVOB_ADDR      = 0x70,
95
96 } sdvo_dev_addr_t;
97
98 typedef enum {
99
100         DDC1_ADDR = 0xA0,
101         DDC2_ADDR = 0xA2,
102
103 } gmbus_ddc_addr_t;
104
105
106 typedef enum {
107
108         GMBUS_PINS_DEDICATED = 1, /* Dedicated Control/GMBUS Pins */
109         GMBUS_PINS_SDVO     = 5,  /* SDVO Registers, DDC, PROM */
110
111 } gmbus_pins_pair_t;
112
113
114 typedef enum {
115
116         I2C_WRITE = 0,
117         I2C_READ  = 1,
118
119 } i2c_bus_dir_t;
120
121 /*.......................................................................... */
122 typedef enum {
123
124         SDVO_BUS_PROM = BIT(0),
125         SDVO_BUS_DDC1 = BIT(1),
126         SDVO_BUS_DDC2 = BIT(2),
127
128 } sdvo_bus_switch_t;
129
130 #define SDVO_OPCODE_BUS_SWITCH  0x7A
131
132 #define SDVO_INDEX_PARAM_1              0x07
133 #define SDVO_INDEX_OPCODE               0x08
134 #define SDVO_INDEX_STATUS               0x09
135
136 #define SDVO_STATUS_SUCCESS     0x01
137 #define SDVO_STATUS_PENDING     0x04
138
139 /*.......................................................................... */
140 /*
141  * In 16-bit, the mmio is a 16-bit pointer, the watcom 1.2 compiler will have
142  * error if directly convert it to unsigned long.  Normally, have to cast it to
143  * unsigned short first then cast again to unsigned long; then, it will be
144  * correct.  But this type of casting may cause some error in the 32 and 64 bit
145  * code.  Since mmio will be equal to zero for 16-bit code.  Add the checking
146  * for MICRO definition code to correct the macro by remove mmio.
147  */
148 #define READ_GMCH_REG(reg)        READ_MMIO_REG_TNC(IGD_PORT_SDVO, reg)
149 #define WRITE_GMCH_REG(reg, data) WRITE_MMIO_REG_TNC(IGD_PORT_SDVO, reg, data)
150
151 static int gmbus_init(unsigned long i2c_bus,
152         unsigned long i2c_speed);
153
154 static int gmbus_read_edid(unsigned long ddc_addr,
155         unsigned long slave_addr,
156         unsigned long index,
157         unsigned long num_bytes,
158         unsigned char FAR *buffer);
159
160 static int gmbus_read_reg(unsigned long slave_addr,
161         unsigned long index,
162         unsigned char FAR *data);
163
164 static int gmbus_write_reg(unsigned long slave_addr,
165         unsigned long index,
166         unsigned char data);
167
168 static int gmbus_set_control_bus_switch(unsigned long slave_addr,
169         gmbus_ddc_addr_t ddc_addr);
170
171 static int gmbus_wait_event_one(unsigned long bit);
172 static int gmbus_wait_event_zero(unsigned long bit);
173 static int gmbus_error_handler(void);
174
175 /*.......................................................................... */
176 extern int i2c_read_regs_gpio(
177         igd_context_t *context,
178         unsigned long i2c_bus,
179         unsigned long i2c_speed,
180         unsigned long dab,
181         unsigned char reg,
182         unsigned char FAR *buffer,
183         unsigned long num_bytes,
184         unsigned long flags);
185
186 extern int i2c_write_reg_list_gpio(
187         igd_context_t *context,
188         unsigned long i2c_bus,
189         unsigned long i2c_speed,
190         unsigned long dab,
191         pd_reg_t *reg_list,
192         unsigned long flags);
193
194
195 /*!
196  * i2c_read_regs_tnc is called to read Edid or a single sDVO register
197  *
198  * @param context
199  * @param i2c_bus port->ddc_reg, port->i2c_reg
200  * @param i2c_speed 50, 100, 400, 1000 (Khz)
201  * @param dab 0x70/0x72 (sDVO Regs), 0xA0/0xA2 (sDVO/Analog DDC)
202  * @param reg I2C Reg Index
203  * @param num_bytes <= 508
204  * @param buffer Data read
205  *
206  * @return 0 on success
207  * @return 1 on failure
208  */
209 static int i2c_read_regs_tnc(igd_context_t *context,
210         unsigned long i2c_bus,
211         unsigned long i2c_speed,
212         unsigned long dab,
213         unsigned char reg,
214         unsigned char FAR *buffer,
215         unsigned long num_bytes,
216         unsigned long flags)
217 {
218         unsigned long slave_addr = 0;
219
220         if(i2c_bus == I2C_INT_LVDS_DDC){
221                 /*
222                  * Atom E6xx LVDS does not have GMBUS support. To read DDC register, we bit bash.
223                  * The i2c_speed is necessary to calculate the hold time. But i2c_bus is not needed.
224                  */
225
226                 EMGD_DEBUG("i2c_read_regs_tnc : Using GPIO to read DDC");
227                 return i2c_read_regs_gpio(context, i2c_bus, i2c_speed,  dab, reg, buffer, num_bytes, flags);
228
229         } else {
230
231                 if (! gmbus_init(i2c_bus, i2c_speed)) {
232                         EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_init() failed");
233                         return 1;
234                 }
235
236                 /*      If the request is to read Edid from sDVO display, find out the */
237                 /*      i2c addres of the sDVO device */
238                 if (i2c_bus == GMBUS_DVOB_DDC) {
239                         slave_addr = dvob_port_tnc.dab;
240                 }
241
242                 switch (i2c_bus) {
243                 case GMBUS_DVOB_DDC :
244                         if (! gmbus_read_edid(dab, slave_addr, reg, num_bytes, buffer)) {
245
246                                 EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_read_edid() failed");
247                                 return 1;
248                         }
249                         break;
250
251                 case GMBUS_DVO_REG :
252                         if (! gmbus_read_reg(dab, reg, buffer)) {
253
254                                 EMGD_DEBUG("Error ! i2c_read_regs_tnc : gmbus_read_reg() failed");
255                                 return 1;
256                         }
257                         break;
258
259                 default :
260                         EMGD_ERROR("Error ! i2c_read_regs_tnc : Invalid i2c_bus=0x%lx",
261                                 i2c_bus);
262                         return 1;
263                 }
264         }
265
266         return 0;
267 }
268
269 /*!
270  * i2c_write_reg_list_tnc is called to write a list of i2c registers to sDVO
271  * device
272  *
273  * @param context
274  * @param i2c_bus NAP_GMBUS_DVOB_DDC/NAP_GMBUS_DVOC_DDC
275  * @param i2c_speed 1000 Khz
276  * @param dab 0x70/0x72
277  * @param reg_list List of i2c indexes and data, terminated with register index
278  *  set to PD_REG_LIST_END
279  *
280  * @return 0 on success
281  * @return 1 on failure
282  */
283 static int i2c_write_reg_list_tnc(igd_context_t *context,
284         unsigned long i2c_bus,
285         unsigned long i2c_speed,
286         unsigned long dab,
287         pd_reg_t *reg_list,
288         unsigned long flags)
289 {
290         unsigned long reg_num = 0, ddc_addr = 0, slave_addr = 0;
291
292         if(i2c_bus == I2C_INT_LVDS_DDC){
293                 /* There are no GMBUS pins for internal LVDS on Atom E6xx.
294                  * Forcing us to use bit bashing */
295                 /* FIXME: determine which GPIO pin is used for bit bashing
296                  *              i2c_bus is not defined
297                  */
298                 EMGD_DEBUG("i2c_write_reg_list_tnc : Using GPIO to write DDC");
299                 return i2c_write_reg_list_gpio(context, i2c_bus, i2c_speed, dab, reg_list, flags);
300
301         } else {
302
303                 if (! gmbus_init(i2c_bus, i2c_speed)) {
304
305                         EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_init() failed");
306                         return 1;
307                 }
308                 /*If it is SDVO Make sure we issue SDVO command to enable DDC access*/
309                 if (i2c_bus == GMBUS_DVOB_DDC) {
310                         slave_addr = dvob_port_tnc.dab;
311                         ddc_addr = 0;
312
313                         if (! gmbus_set_control_bus_switch(slave_addr, ddc_addr)) {
314                                 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_set_control_bus_switch()"
315                                                  " failed");
316                                 return 1;
317                         }
318                         while (reg_list[reg_num].reg != PD_REG_LIST_END) {
319
320                                 if (! gmbus_write_reg(dab, reg_list[reg_num].reg,
321                                                   (unsigned char)reg_list[reg_num].value)) {
322
323                                         EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_write_reg() failed, reg_num=%lu",
324                                                 reg_num);
325
326                                         return 1;
327                                 }
328                         reg_num++;
329                         }
330                         /*...................................................................... */
331                         /* Issue a Stop Command */
332                         gmbus_wait_event_one(HW_WAIT);
333                         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
334                         gmbus_wait_event_one(HW_RDY);
335                         gmbus_wait_event_zero(GA);
336                         gmbus_error_handler();
337                         WRITE_GMCH_REG(GMBUS1, SW_RDY);
338                         WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
339                         WRITE_GMCH_REG(GMBUS1, 0);
340                         WRITE_GMCH_REG(GMBUS5, 0);
341                         WRITE_GMCH_REG(GMBUS0, 0);
342                         /*...................................................................... */
343                         return 0;
344                 }
345                 while (reg_list[reg_num].reg != PD_REG_LIST_END) {
346
347                         if (! gmbus_write_reg(dab, reg_list[reg_num].reg,
348                                         (unsigned char)reg_list[reg_num].value)) {
349
350                                 EMGD_DEBUG("Error ! i2c_write_reg_list_tnc : gmbus_write_reg() failed, reg_num=%lu",
351                                         reg_num);
352
353                                 return 1;
354                         }
355
356                         reg_num++;
357                 }
358         }
359
360         return 0;
361 }
362
363 /*!
364  * gmbus_init initializes the GMBUS controller with specified bus and speed
365  *
366  * @param i2c_bus sDVO B/C Reg/DDC or Analog DDC
367  * @param i2c_speed 50/100/400/1000 Khz
368  *
369  * @return TRUE(1) on success
370  * @return FALSE(0) on failure
371  */
372 static int gmbus_init(unsigned long i2c_bus,
373         unsigned long i2c_speed)
374 {
375         gmbus_pins_pair_t pin_pair;
376         gmbus_speed_t bus_speed;
377
378         switch (i2c_bus) {
379
380         case GMBUS_DVO_REG :
381         case GMBUS_DVOB_DDC :
382                 pin_pair = GMBUS_PINS_SDVO;
383                 break;
384
385         default :
386                 EMGD_ERROR("Error ! gmbus_init : Invalid i2c_bus=0x%lx", i2c_bus);
387                 return 0;
388         }
389
390         switch (i2c_speed) {
391
392         case 50 :               /* Slow speed */
393                 bus_speed = GMBUS_SPEED_50K;
394                 break;
395
396         case 400 :              /* SPD */
397                 bus_speed = GMBUS_SPEED_400K;
398                 break;
399
400         case 1000 :     /* sDVO Registers */
401                 //bus_speed = GMBUS_SPEED_1000K;
402                 bus_speed = GMBUS_SPEED_400K;
403                 break;
404
405         case 100 :      /* DDC */
406         default :
407                 bus_speed = GMBUS_SPEED_100K;
408                 break;
409         }
410
411         WRITE_GMCH_REG(GMBUS5, 0);   /* Clear the word index reg */
412         WRITE_GMCH_REG(GMBUS0, pin_pair | bus_speed);
413
414         return 1;
415 }
416
417 /*!
418  * gmbus_wait_event_zero waits for specified GMBUS2 register bit to be deasserted
419  *
420  * @param bit
421  *
422  * @return TRUE(1) on success. The bit was deasserted in the specified timeout period
423  * @return FALSE(0) on failure
424  */
425 static int gmbus_wait_event_zero(unsigned long bit)
426 {
427         unsigned long i;
428         unsigned long status;
429
430         for (i = 0; i < 0x1000; i++) {
431
432                 status = READ_GMCH_REG(GMBUS2);
433
434                 if ((status & bit) == 0) {
435
436                         return 1;
437                 }
438         }
439
440         EMGD_DEBUG("Error ! gmbus_wait_event_zero : Failed : bit=0x%lx, status=0x%lx",
441                 bit, status);
442
443         return 0;
444 }
445
446 /*!
447  * gmbus_wait_event_one wait for specified GMBUS2 register bits to be asserted
448  *
449  * @param bit
450  *
451  * @return TRUE(1) on success. The bit was asserted in the specified timeout period
452  * @return FALSE(0) on failure
453  */
454 static int gmbus_wait_event_one(unsigned long bit)
455 {
456         unsigned long i;
457         unsigned long status;
458
459         for (i = 0; i < 0x10000; i++) {
460
461                 status = READ_GMCH_REG(GMBUS2);
462                 if ((status & bit) != 0) {
463
464                         return 1;
465                 }
466         }
467
468         EMGD_DEBUG("Error ! gmbus_wait_event_one : Failed : bit=0x%lx, status=0x%lx",
469                 bit, status);
470
471         return 0;
472 }
473
474 /*!
475  * gmbus_error_handler attempts to recover from timeout error
476  *
477  *
478  * @return TRUE(1) error was detected and handled
479  * @return FALSE(0) there was no error
480  */
481 static int gmbus_error_handler(void)
482 {
483         unsigned long status = READ_GMCH_REG(GMBUS2);
484
485         /* Clear the SW_INT, wait for HWRDY and GMBus active (GA) */
486         if ((status & HW_BUS_ERR) || (status & HW_TMOUT)) {
487
488                 EMGD_DEBUG("Error ! gmbus_error_handler : Resolving error=0x%lx",
489                         status);
490
491                 WRITE_GMCH_REG(GMBUS1, SW_RDY);
492                 WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
493                 WRITE_GMCH_REG(GMBUS1, 0);
494
495                 gmbus_wait_event_zero(GA);
496
497                 return 1;       /* Handled the error */
498         }
499
500         return 0;       /* There was no error */
501 }
502
503 /*!
504  * Assemble 32 bit GMBUS1 command
505  *
506  * @param slave_addr 0x70/0x72
507  * @param index 0 - 256
508  * @param num_bytes Bytes to transfer
509  * @param flags Bits 25-31 of GMBUS1
510  * @param i2c_dir I2C_READ / I2C_WRITE
511  *
512  * @return The assembled command
513  */
514 static unsigned long gmbus_assemble_command(unsigned long slave_addr, unsigned long index,
515         unsigned long num_bytes, unsigned long flags,
516         i2c_bus_dir_t i2c_dir)
517 {
518         unsigned long cmd = flags | ENIDX | ENT | (num_bytes << 16) | (index << 8) |
519                                                 slave_addr | i2c_dir;
520
521         return cmd;
522 }
523
524 /*!
525  * gmbus_send_pkt transmits a block a data to specified i2c slave device
526  *
527  * @param slave_addr I2C device address
528  * @param index Starting i2c register index
529  * @param pkt_size 1 - 508 bytes
530  * @param pkt Bytes to send
531  *
532  * @return TRUE(1) if successful in sending the specified number of bytes
533  * @return FALSE(0) on failure
534  */
535 static int gmbus_send_pkt(unsigned long slave_addr, unsigned long index,
536         unsigned long pkt_size, void *pkt)
537 {
538         unsigned long gmbus1_cmd;
539         unsigned long bytes_sent;
540         unsigned long *data;
541
542         if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
543
544                 return 0;
545         }
546
547         data = (unsigned long *)pkt;
548
549         /*...................................................................... */
550         gmbus_error_handler();
551
552         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
553                                                                                 STA, I2C_WRITE);
554         if (pkt_size <= 4) {
555
556                 gmbus1_cmd |= SW_RDY;
557         }
558
559         /*...................................................................... */
560         bytes_sent = 0;
561
562         do {
563
564                 WRITE_GMCH_REG(GMBUS3, *data);
565
566                 if (bytes_sent == 0) {
567
568                         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
569                 }
570
571                 if (! gmbus_wait_event_one(HW_RDY)) {
572
573                         EMGD_DEBUG("Error ! gmbus_send_pkt : Failed to get HW_RDY, bytes_sent=%ld",
574                                 bytes_sent);
575
576                         return 0;
577                 }
578
579                 if (gmbus_error_handler()) {
580
581                         EMGD_DEBUG("Error ! gmbus_send_pkt : gmbus error, bytes_sent=%ld",
582                                 bytes_sent);
583
584                         return 0;
585                 }
586
587                 data++;
588
589                 if (pkt_size >= 4) {
590                         bytes_sent += 4;
591
592                 } else {
593                         bytes_sent += pkt_size;
594                 }
595
596         } while (bytes_sent < pkt_size);
597
598         /*...................................................................... */
599         if (bytes_sent != pkt_size) {
600
601                 return 0;
602
603         } else {
604
605                 return 1;
606         }
607 }
608
609 /*!
610  * gmbus_recv_pkt reads a block of data from specified i2c slave device
611  *
612  * @param slave_addr I2C device address
613  * @param index Starting i2c register index
614  * @param pkt_size 1 - 508 bytes
615  * @param pkt Bytes to send
616  *
617  * @return TRUE(1) if successful in receiving specified number of bytes
618  * @return FALSE(0) on failure
619  */
620 static int gmbus_recv_pkt(unsigned long slave_addr, unsigned long index,
621         unsigned long pkt_size, void FAR *pkt)
622 {
623         unsigned long gmbus1_cmd;
624         unsigned long bytes_rcvd;
625         unsigned long FAR *data;
626
627         if ((pkt_size == 0) || (pkt == NULL) || (pkt_size > 508)) {
628
629                 return 0;
630         }
631
632         data = (unsigned long FAR *)pkt;
633
634         /*...................................................................... */
635         gmbus_error_handler();
636
637         /* Program the command */
638         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, pkt_size,
639                                                                                 STA | SW_RDY, I2C_READ);
640         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
641
642         /*...................................................................... */
643         bytes_rcvd = 0;
644         do {
645
646                 unsigned long gmbus3_data;
647                 unsigned long bytes_left = pkt_size - bytes_rcvd;
648
649                 if (! gmbus_wait_event_one(HW_RDY)) {
650
651                         EMGD_DEBUG("Error ! gmbus_recv_pkt : Failed to get HW_RDY, "
652                                 "bytes_rcvd=%ld", bytes_rcvd);
653                         break;
654                 }
655
656                 if (gmbus_error_handler()) {
657
658                         EMGD_DEBUG("Error ! gmbus_recv_pkt : gmbus error, bytes_rcvd=%ld",
659                                 bytes_rcvd);
660                         break;
661                 }
662
663                 gmbus3_data = READ_GMCH_REG(GMBUS3);
664
665                 switch (bytes_left) {
666
667                 case 1 :
668                         *(unsigned char *)data = (unsigned char)gmbus3_data;
669                         break;
670
671                 case 2 :
672                         *(unsigned short *)data = (unsigned short)gmbus3_data;
673                         break;
674
675                 case 3 :
676                 {
677                         unsigned char *dest = (unsigned char *)data;
678                          unsigned char *src  = (unsigned char *)&(gmbus3_data);
679                         dest[0] = src[0];
680                         dest[1] = src[1];
681                         dest[2] = src[2];
682
683                         break;
684                 }
685
686                 default :       /* >= 4 */
687                         *data = gmbus3_data;
688                         break;
689                 }
690
691                 if (bytes_left > 4) {
692                         bytes_rcvd += 4;
693                         data++;
694
695                 } else {
696                         bytes_rcvd += bytes_left;
697
698                 }
699
700         } while (bytes_rcvd < pkt_size);
701
702         /*...................................................................... */
703         if (bytes_rcvd < pkt_size) {
704                 return 0;
705
706         } else {
707                 return 1;
708         }
709 }
710
711 /*!
712  * gmbus_set_control_bus_switch sends sDVO command to switch i2c bus to read EDID
713  * or SPD data
714  *
715  * @param slave_addr sDVO device address (0x70/0x72)
716  * @param ddc_addr DDC1_ADDR/DDC2_ADDR
717  *
718  * @return TRUE(1) if successful in sending the opcode
719  * @return FALSE(0) on failure
720  */
721 static int gmbus_set_control_bus_switch(unsigned long slave_addr,
722         gmbus_ddc_addr_t ddc_addr)
723 {
724         unsigned char data;
725         sdvo_bus_switch_t bus_switch;
726         int retry;
727
728         bus_switch = SDVO_BUS_DDC1;
729
730         /*...................................................................... */
731         /*      Transmit the Arguments */
732         if (! gmbus_send_pkt(slave_addr, SDVO_INDEX_PARAM_1, 1, &bus_switch)) {
733
734                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt() failed");
735
736                 return 0;
737         }
738
739         /*...................................................................... */
740         /* Generate I2C stop cycle */
741         gmbus_wait_event_one(HW_WAIT);
742         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
743         gmbus_wait_event_one(HW_RDY);
744         gmbus_wait_event_zero(GA);
745
746         /*...................................................................... */
747         /* Transmit the Opcode */
748         data = SDVO_OPCODE_BUS_SWITCH;
749         if (! gmbus_send_pkt(slave_addr, SDVO_INDEX_OPCODE, 1, &data)) {
750
751                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : gmbus_send_pkt(Opcode)"
752                                  " failed");
753
754                 return 0;
755         }
756
757         /*...................................................................... */
758         /* Read Status */
759         for (retry = 0; retry < 3; retry++) {
760                 if (! gmbus_recv_pkt(slave_addr, SDVO_INDEX_STATUS, 1, &data)) {
761
762                         continue;
763                 }
764
765                 if (data != SDVO_STATUS_PENDING) {
766
767                         break;
768                 }
769         }
770
771         /*...................................................................... */
772         /* Send Stop */
773         gmbus_wait_event_one(HW_WAIT);
774         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | slave_addr);
775         gmbus_wait_event_one(HW_RDY);
776         gmbus_wait_event_zero(GA);
777
778         /*...................................................................... */
779         if (data != SDVO_STATUS_SUCCESS) {
780
781                 EMGD_DEBUG("Error ! gmbus_set_control_bus_switch : Opcode Bus Switch failed");
782
783                 return 0;
784         }
785
786         return 1;
787 }
788
789 /*!
790  * gmbus_read_edid reads specified number of Edid data bytes
791  *
792  * @param ddc_addr 0xA0/0xA2 (DDC1/DDC2)
793  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC), 0 Analog
794  * @param index i2c register index
795  * @param num_bytes <= 508
796  * @param buffer Edid data read from the display
797  *
798  * @return TRUE(1) if successful in reading Edid
799  * @return FALSE(0) on failure
800  */
801 static int gmbus_read_edid(unsigned long ddc_addr,
802         unsigned long slave_addr,
803         unsigned long index,
804         unsigned long num_bytes,
805         unsigned char FAR *buffer)
806 {
807         int status;
808
809         if (slave_addr == SDVOB_ADDR) {
810
811                 if (! gmbus_set_control_bus_switch(slave_addr, ddc_addr)) {
812
813                         EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_set_control_bus_switch()"
814                                          " failed");
815
816                         return 0;
817                 }
818         } else {
819                 /*      Reset the bus */
820                 gmbus_recv_pkt(ddc_addr, 0, 1, buffer);
821         }
822
823         status = gmbus_recv_pkt(ddc_addr, index, num_bytes, buffer);
824         if (! status) {
825
826                 EMGD_DEBUG("Error ! gmbus_read_edid : gmbus_recv_pkt() failed");
827         }
828
829         /*...................................................................... */
830         /* Issue a Stop Command */
831
832         gmbus_wait_event_one(HW_WAIT);
833         WRITE_GMCH_REG(GMBUS1, STO | SW_RDY | ddc_addr);
834         gmbus_wait_event_one(HW_RDY);
835
836         gmbus_wait_event_zero(GA);
837
838         gmbus_error_handler();
839         WRITE_GMCH_REG(GMBUS1, SW_RDY);
840         WRITE_GMCH_REG(GMBUS1, SW_CLR_INT);
841         WRITE_GMCH_REG(GMBUS1, 0);
842         WRITE_GMCH_REG(GMBUS5, 0);
843         WRITE_GMCH_REG(GMBUS0, 0);
844
845         /*...................................................................... */
846         return status;
847 }
848
849 /*!
850  * gmbus_read_reg reads one i2c register
851  *
852  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
853  * @param index i2c register index
854  * @param data register data
855  *
856  * @return TRUE(1) if successful in reading the i2c register
857  * @return FALSE(0) on failure
858  */
859 static int gmbus_read_reg(unsigned long slave_addr,
860         unsigned long index,
861         unsigned char FAR *data)
862 {
863         unsigned long gmbus1_cmd;
864
865         WRITE_GMCH_REG(GMBUS5, 0x0);            /* Clear Word Index register */
866
867         if (! gmbus_wait_event_zero(GA)) {
868
869                 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(1)");
870
871                 return 0;
872         }
873
874         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
875                                                                                 STO | STA, I2C_READ);
876         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
877
878         if (! gmbus_wait_event_zero(GA)) {
879
880                 EMGD_DEBUG("Error ! gmbus_read_reg : Failed to get GA(2)");
881
882                 return 0;
883         }
884
885         *data = (unsigned char)READ_GMCH_REG(GMBUS3);
886
887         return 1;
888 }
889
890 /*!
891  * gmbus_write_reg writes one i2c register
892  *
893  * @param slave_addr 0x70/0x72 (sDVOB, sDVOC)
894  * @param index i2c register index
895  * @param data register data
896  *
897  * @return TRUE(1) if successful in updating the i2c register
898  * @return FALSE(0) if failed to update the register
899  */
900 static int gmbus_write_reg(unsigned long slave_addr,
901         unsigned long index,
902         unsigned char data)
903 {
904         unsigned long gmbus1_cmd;
905
906         WRITE_GMCH_REG(GMBUS5, 0x0);            /* Clear Word Index register */
907
908         if (! gmbus_wait_event_zero(GA)) {
909
910                 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(1)");
911
912                 return 0;
913         }
914
915         WRITE_GMCH_REG(GMBUS3, data);
916
917         gmbus1_cmd = gmbus_assemble_command(slave_addr, index, 1,
918                                                                                 STO | STA, I2C_WRITE);
919         WRITE_GMCH_REG(GMBUS1, gmbus1_cmd);
920
921         if (! gmbus_wait_event_zero(GA)) {
922
923                 EMGD_DEBUG("Error ! gmbus_write_reg : Failed to get GA(2)");
924                 return 0;
925         }
926
927         return 1;
928 }
929