packaging: update the changelog
[profile/ivi/intel-emgd-kmod.git] / emgd / display / pi / tnc / i2c_bitbash_tnc.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: i2c_bitbash_tnc.c
4  * $Revision: 1.10 $
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  *  Bitbash to read GPIO pins are done on LPC device 0:31:0. So do not
29  *  use EMGD_READ32 and EMGD_WRITE32 macros for read/write to device 31. These
30  *  macros do mmio only on device2.
31  *  To properly read/write mmio on device 31, use
32  *  READ_MMIO_REG_TNC(port_type, reg) and
33  *  WRITE_MMIO_REG_TNC(port_type, reg, data).
34  *  These macros properly set to work for all OSes including VBIOS, but
35  *  generate more code compared to EMGD_READ32 and EMGD_WRITE32. So use as
36  *  necessary.
37  *-----------------------------------------------------------------------------
38  */
39
40 #define MODULE_NAME hal.dpd
41
42 #include <io.h>
43 #include <memory.h>
44 #include <sched.h>
45
46 #include <igd_pwr.h>
47
48 #include <general.h>
49 #include <context.h>
50 #include <mode.h>
51 #include <utils.h>
52
53 #include <tnc/regs.h>
54
55 #include <intelpci.h>
56
57 #include "../cmn/i2c_dispatch.h"
58
59 /*!
60  * @addtogroup display_group
61  * @{
62  */
63
64 static int i2c_error_recovery_tnc(
65         unsigned long hold_time);
66
67 static int i2c_write_byte_tnc(
68         unsigned char value,
69         unsigned long hold_time);
70
71 static int i2c_read_byte_tnc(
72         unsigned char *value,
73         unsigned char ack,
74         unsigned long hold_time);
75
76 int i2c_read_regs_gpio(
77         igd_context_t *context,
78         unsigned long i2c_bus,
79         unsigned long i2c_speed,
80         unsigned long dab,
81         unsigned char reg,
82         unsigned char FAR *buffer,
83         unsigned long num_bytes,
84         unsigned long flags);
85
86 int i2c_write_reg_list_gpio(
87         igd_context_t *context,
88         unsigned long i2c_bus,
89         unsigned long i2c_speed,
90         unsigned long dab,
91         pd_reg_t *reg_list,
92         unsigned long flags);
93
94 /* The LVDS GPIO clock lines are GPIOSUS[3]
95  * The LVDS GPIO data lines are GPIOSUS[4]
96  */
97 #define GPIO_CLOCK      0x08
98 #define GPIO_DATA       0x10
99
100 /*!
101  *
102  * @param context
103  *
104  * @return void
105  */
106 #if 0
107 static void enable_gpio_tnc(igd_context_t *context)
108 {
109         /*
110          * NOTE: This really should be a system BIOS job.
111          * The driver would not touch these register anymore since
112          * it would cause the 13x7 panel fail to start.
113          */
114
115         /* Enabling LVDS Data and LVDS Clock */
116         unsigned long temp;
117
118         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGEN);
119         temp |= (GPIO_DATA | GPIO_CLOCK);
120         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGEN, temp);
121
122         return;
123 }
124 #endif
125
126 /*!
127  *
128  * @param clock
129  * @param data
130  *
131  * @return void
132  */
133 static void i2c_get(unsigned long *clock,
134         unsigned long *data)
135 {
136         unsigned long temp;
137         /* Set Data as Input */
138         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGIO);
139         temp |= (GPIO_DATA);
140         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGIO, temp);
141         /* Read Data */
142         *data = (READ_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL) & GPIO_DATA) ? 1:0;
143         *clock = (READ_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL) & GPIO_CLOCK) ? 1:0;
144
145 #if 0
146         EMGD_WRITE32(0, EMGD_MMIO(mmio) + i2c_bus);
147         c = EMGD_READ32(EMGD_MMIO(mmio) + i2c_bus)>>4;
148         *data = (c>>8) & 1;
149         *clock &= 1;
150 #endif
151 }
152
153 /*!
154  *
155  * @param data
156  * @param hold_time
157  *
158  * @return void
159  */
160 static void i2c_set_data(int data,
161         unsigned long hold_time)
162 {
163         unsigned long temp;
164         /* The LVDS GPIO data lines are GPIOSUS[4] */
165         /* Set as Output */
166         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGIO);
167         temp &= ~GPIO_DATA;
168         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGIO, temp);
169         /* Read status register */
170         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL);
171
172         if(data){
173                 /* Set level to High */
174                 temp |= GPIO_DATA;
175         } else {
176                 /* Set level to low */
177                 temp &= ~GPIO_DATA;
178         }
179         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL, temp);
180
181         OS_DELAY(hold_time);
182
183 #if 0
184         /* Implementation using Display GPIO
185          * For alm, the default data value "could" be 0
186          */
187         /*
188          * Simplified definition for the bits
189          * 11: GPIO data Value
190          * 10: GPIO Data Mask
191          * 9: GPIO Data Direction Value
192          * 8: GPIO Data Direction Mask
193          */
194         EMGD_WRITE32(data ? 0x500 : 0x700, EMGD_MMIO(mmio) + i2c_bus);
195         EMGD_WRITE32(data ? 0x400 : 0x600, EMGD_MMIO(mmio) + i2c_bus);
196         OS_DELAY(hold_time);
197 #endif
198 }
199
200 /*!
201  *
202  * @param clock
203  * @param hold_time
204  *
205  * @return void
206  */
207 static void i2c_set_clock(int clock,
208         unsigned long hold_time)
209 {
210         unsigned long temp;
211         /* The LVDS GPIO clock lines are GPIOSUS[3] */
212         /* Set as Output */
213         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGIO);
214         temp &= ~GPIO_CLOCK;
215         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGIO, temp);
216         /* Read Status Register */
217         temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL);
218
219         if(clock){
220                 /* Set level to High */
221                 temp |= GPIO_CLOCK;
222
223         } else {
224                 /* Set level to low */
225                 temp &= ~GPIO_CLOCK;
226         }
227         WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGLVL, temp);
228
229         OS_DELAY(hold_time);
230
231 #if 0
232         /*
233          * Simplified definition for the bits
234          * 3: GPIO Clock Value
235          * 2: GPIO Clock Mask
236          * 1: GPIO Clock Direction Value
237          * 0: GPIO Clock Direction Mask
238          */
239
240         EMGD_WRITE32(clock ? 0x5 : 0x7, EMGD_MMIO(mmio) + i2c_bus);
241         EMGD_WRITE32(clock ? 0x4 : 0x6, EMGD_MMIO(mmio) + i2c_bus);
242         OS_DELAY(hold_time);
243 #endif
244 }
245
246 /*!
247  *
248  * @param hold_time
249  *
250  * @return 0 on success
251  * @return 1 on failure
252  */
253 static int i2c_start_tnc(unsigned long hold_time)
254 {
255         unsigned long sc, sd;
256
257         /* set sd high */
258         i2c_set_data(1, hold_time);
259
260         /* set clock high */
261         i2c_set_clock(1, hold_time);
262
263         /* Start condition happens when sd goes high to low when sc is high */
264         i2c_get(&sc, &sd);
265
266         if( 0 == sc ) {
267                 // Data must be high
268                 i2c_error_recovery_tnc(hold_time);
269                 return 1;
270         }
271
272         i2c_set_data(0, hold_time);
273         i2c_set_clock(0, hold_time);
274
275         return 0;
276 } /* end i2c_start */
277
278 /*!
279  *
280  * @param hold_time
281  *
282  * @return 0
283  */
284 static int i2c_stop_tnc(unsigned long hold_time)
285 {
286         /* Stop condition happens when sd goes low to high when sc is high */
287         unsigned long sc,sd;
288
289         i2c_set_clock(0, hold_time);
290         i2c_set_data(0, hold_time);
291
292         i2c_set_clock(1, hold_time);
293
294         i2c_get(&sc, &sd);
295         /* Try another time */
296         if (sc == 0) {
297                 i2c_set_clock(1, hold_time);
298         }
299         i2c_set_data(1, hold_time);
300
301         return 0;
302 } /* end i2c_stop */
303
304 /*!
305  *
306  * @param hold_time
307  *
308  * @return 0 on success
309  * @return 1 on failure
310  */
311 static int i2c_error_recovery_tnc(unsigned long hold_time)
312 {
313         unsigned char max_retries = 9;
314         unsigned long sc, sd;
315
316         while (max_retries--) {
317                 i2c_get(&sc, &sd);
318                 if (sd == 1 && sc == 1) {
319                         return 0;
320                 } else {
321                         i2c_stop_tnc(hold_time);
322                 }
323         }
324         EMGD_ERROR("Cannot recover I2C error.");
325
326         return 1;
327 }
328
329 /*!
330  *
331  * @param value
332  * @param hold_time
333  *
334  * @return 0 on success
335  * @return 1 on failure
336  */
337 static int i2c_write_byte_tnc(unsigned char value,
338         unsigned long hold_time)
339 {
340         int i;
341         unsigned long sc,sd;
342
343         /* I2C_DEBUG("i2c_write_byte"); */
344         for(i=7; i>=0; i--) {
345                 i2c_set_clock(0, hold_time);
346                 i2c_set_data(value>>i & 1, hold_time);
347
348                 i2c_set_clock(1, hold_time);
349         }
350
351         /* Get ACK */
352         i2c_set_clock(0, hold_time);
353         /* Set data low. Possible inteference in some lvds panel */
354         i2c_set_data(0, hold_time);
355         i2c_set_clock(1, hold_time);
356         OS_DELAY(hold_time);
357
358         i2c_get(&sc, &sd);
359
360         i2c_set_clock(0, hold_time);
361
362         if (sd != 0) {
363                 EMGD_ERROR("No ACK for byte 0x%x", value);
364                 i2c_error_recovery_tnc(hold_time);
365                 return 1;
366         }
367
368         return 0;
369
370 } /* end i2c_write_byte */
371
372 /*!
373  *
374  * @param value
375  * @param ack
376  * @param hold_time
377  *
378  * @return 0 on success
379  * @return 1 on failure
380  */
381 static int i2c_read_byte_tnc(unsigned char *value,
382         unsigned char ack,
383         unsigned long hold_time)
384 {
385         int i;
386         unsigned long sc, sd, temp;
387
388         *value = 0;
389         for(i=7; i>=0; i--) {
390                 i2c_set_clock(1, hold_time);
391                 i2c_get(&sc, &sd);
392                 OS_DELAY(hold_time);
393                 if(!sc) {
394                         EMGD_DEBUG("Clock low on read %d", i);
395                         i2c_error_recovery_tnc(hold_time);
396                         return 1;
397                 }
398                 *value |= (sd & 1)<<i;
399                 i2c_set_clock(0, hold_time);
400         }
401
402         if (ack) {
403                 i2c_set_data(0, hold_time);
404         }
405
406         /* Master does not ACK */
407         i2c_set_clock(1, hold_time);
408         i2c_set_clock(0, hold_time);
409
410         if (ack) {
411                 /* Set data as input as we continue to read */
412                 temp = READ_MMIO_REG_TNC(IGD_PORT_LPC, RGIO);
413                 temp |= GPIO_DATA;
414                 WRITE_MMIO_REG_TNC(IGD_PORT_LPC, RGIO, temp);
415         }
416
417         return 0;
418 } /* end i2c_read_byte */
419
420 /*!
421  *
422  * @param context
423  * @param i2c_bus
424  * @param i2c_speed
425  * @param dab
426  * @param reg
427  * @param buffer
428  * @param num_bytes
429  *
430  * @return 0 on success
431  * @return 1 on failure
432  */
433 int i2c_read_regs_gpio(igd_context_t *context,
434         unsigned long i2c_bus,
435         unsigned long i2c_speed,
436         unsigned long dab,
437         unsigned char reg,
438         unsigned char FAR *buffer,
439         unsigned long num_bytes,
440         unsigned long flags
441         )
442 {
443         unsigned long hold_time;
444         unsigned char temp;
445         int i;
446         if (!i2c_speed) {
447                 EMGD_DEBUG("i2c Speed failed.");
448                 return 1;
449         }
450
451         /*
452          * We are holding the clock LOW for "hold_time" and then HIGH for
453          * "hold_time". Therefore, we double the clock speed in this calculation.
454          */
455         if (flags & IGD_I2C_WRITE_FW){
456                 hold_time = 1;
457         } else {
458         hold_time = 1000/(i2c_speed * 2);
459         }
460
461         /* enable_gpio_tnc(context); */
462
463         if (i2c_start_tnc(hold_time)) {
464                 EMGD_DEBUG("i2c Start failed.");
465                 return 1;
466         }
467
468         if (i2c_write_byte_tnc((unsigned char)dab & 0xFE,
469                         hold_time)) {
470                 EMGD_DEBUG("i2c DAB(W) failed.");
471                 return 1;
472         }
473
474         if (i2c_write_byte_tnc(reg, hold_time)) {
475                 EMGD_DEBUG("RAB failed.");
476                 return 1;
477         }
478
479         if (i2c_start_tnc(hold_time)) {
480                 EMGD_DEBUG("i2c ReStart failed");
481                 return 1;
482         }
483
484         if (i2c_write_byte_tnc((unsigned char)dab | 0x01,
485                         hold_time)) {
486                 EMGD_ERROR("i2c DAB(R) failed");
487                 return 1;
488         }
489
490
491         /* Read the requested number of bytes */
492         for(i=0; i<(int)(num_bytes-1); i++) {
493                 /*
494                  * Use a local temp so that the FAR pointer doesn't have to
495                  * get passed down.
496                  */
497                 if (i2c_read_byte_tnc(&temp, 1, hold_time)) {
498                         EMGD_DEBUG("Read data byte %d failed", i);
499                         EMGD_DEBUG("Exit i2c_read_regs_tnc with error");
500                         return 1;
501                 }
502                 buffer[i] = temp;
503         }
504
505         /* No ACK on the last read */
506         if(i2c_read_byte_tnc(&temp, 0, hold_time)) {
507                 EMGD_DEBUG("Read Data %d Failed", i);
508                 EMGD_DEBUG("Exit i2c_read_regs_tnc with error");
509                 return 1;
510         }
511         buffer[i] = temp;
512
513         i2c_stop_tnc(hold_time);
514         i2c_stop_tnc(hold_time);
515
516         return 0;
517 }
518
519 /*!
520  *
521  * @param context
522  * @param i2c_bus
523  * @param i2c_speed
524  * @param dab
525  * @param reg_list
526  * @param flags
527  *
528  * @return 0 on success
529  * @return 1 on failure
530  */
531 int i2c_write_reg_list_gpio(igd_context_t *context,
532         unsigned long i2c_bus,
533         unsigned long i2c_speed,
534         unsigned long dab,
535         pd_reg_t *reg_list,
536         unsigned long flags)
537 {
538         unsigned long hold_time;
539
540         if (!i2c_speed) {
541                 return 1;
542         }
543
544         /*
545          * We are holding the clock LOW for "hold_time" and then HIGH for
546          * "hold_time". Therefore, we double the clock speed in this calculation.
547          */
548         if (flags & IGD_I2C_WRITE_FW){
549                 hold_time = 1;
550         } else {
551         hold_time = 1000/(i2c_speed * 2);
552         }
553
554         /* enable_gpio_tnc(context); */
555
556         while(reg_list->reg != PD_REG_LIST_END) {
557                 if (i2c_start_tnc(hold_time)) {
558                         EMGD_DEBUG("Start failed");
559                         return 1;
560                 }
561
562                 if (i2c_write_byte_tnc((unsigned char)dab & 0xFE,
563                                 hold_time)) {
564                         EMGD_DEBUG("DAB(W) failed");
565                         return 1;
566                 }
567
568                 /* Register Address */
569                 if (i2c_write_byte_tnc((unsigned char)reg_list->reg, hold_time)) {
570                         EMGD_DEBUG("RAB failed");
571                         return 1;
572                 }
573
574                 do {
575                         /*  New Value */
576                         if (i2c_write_byte_tnc((unsigned char)reg_list->value, hold_time)) {
577                                 EMGD_DEBUG("Data failed");
578                                 return 1;
579                         }
580
581                         if(reg_list[1].reg != (reg_list[0].reg + 1)) {
582                                 reg_list++;
583                                 break;
584                         }
585
586                         EMGD_DEBUG("I2C Multi-Write Reg[%x] = 0x%x",
587                                 (unsigned short)reg_list->reg,
588                                 (unsigned short)reg_list->value);
589                         reg_list++;
590                 } while(flags & IGD_I2C_SERIAL_WRITE);
591
592
593                 i2c_stop_tnc(hold_time);
594                 i2c_stop_tnc(hold_time);
595         }
596
597         return 0;
598 }
599