Advertisement
Guest User

Untitled

a guest
Jul 5th, 2011
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.36 KB | None | 0 0
  1. /***************************************************************************
  2.  *             __________               __   ___.
  3.  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
  4.  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
  5.  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  6.  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  7.  *                     \/            \/     \/    \/            \/
  8.  * $Id$
  9.  *
  10.  * Copyright (C) 2011 by amaury Pouly
  11.  *
  12.  * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
  13.  * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
  14.  *
  15.  * This program is free software; you can redistribute it and/or
  16.  * modify it under the terms of the GNU General Public License
  17.  * as published by the Free Software Foundation; either version 2
  18.  * of the License, or (at your option) any later version.
  19.  *
  20.  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  21.  * KIND, either express or implied.
  22.  *
  23.  ****************************************************************************/
  24. #include "config.h"
  25. #include "system.h"
  26. #include "kernel.h"
  27. #include "dma-imx233.h"
  28. #include "i2c-imx233.h"
  29. #include "pinctrl-imx233.h"
  30.  
  31. #define THE_LEMON_MAN
  32.  
  33. #ifdef THE_LEMON_MAN
  34. #define HW_PINCTRL_DOUT0_CLR    (*(volatile uint32_t *)0x80018508)
  35. #define HW_PINCTRL_DOE0_CLR     (*(volatile uint32_t *)0x80018708)
  36. #define HW_PINCTRL_DOE0_SET     (*(volatile uint32_t *)0x80018704)
  37. #define HW_PINCTRL_DIN0         (*(volatile uint32_t *)0x80018600)
  38. #endif
  39.  
  40. static void i2c_delay(void)
  41. {
  42.     udelay(30);
  43. }
  44.  
  45. /* release SCL and read it */
  46. static bool i2c_read_scl(void)
  47. {
  48.     #ifndef THE_LEMON_MAN
  49.     imx233_enable_gpio_output(0, 30, false);
  50.     return !!imx233_get_gpio_input_mask(0, 1 << 30);
  51.     #else
  52.     HW_PINCTRL_DOE0_CLR = 1 << 30;
  53.     return !!(HW_PINCTRL_DIN0 & (1 << 30));
  54.     #endif
  55. }
  56.  
  57. /* release SDA and read it */
  58. static bool i2c_read_sda(void)
  59. {
  60.     #ifndef THE_LEMON_MAN
  61.     imx233_enable_gpio_output(0, 31, false);
  62.     return !!imx233_get_gpio_input_mask(0, 1 << 31);
  63.     #else
  64.     HW_PINCTRL_DOE0_CLR = 1 << 31;
  65.     return !!(HW_PINCTRL_DIN0 & (1 << 31));
  66.     #endif
  67. }
  68.  
  69. /* drive SCL to low */
  70. static void i2c_clear_scl(void)
  71. {
  72.     #ifndef THE_LEMON_MAN
  73.     imx233_enable_gpio_output(0, 30, true);
  74.     #else
  75.     HW_PINCTRL_DOE0_SET = 1 << 30;
  76.     #endif
  77. }
  78.  
  79. /* drive SDA to low */
  80. static void i2c_clear_sda(void)
  81. {
  82.     #ifndef THE_LEMON_MAN
  83.     imx233_enable_gpio_output(0, 31, true);
  84.     #else
  85.     HW_PINCTRL_DOE0_SET = 1 << 31;
  86.     #endif
  87. }
  88.  
  89. void imx233_i2c_init(void)
  90. {
  91.     /* setup pins (assume external pullups) */
  92.     #ifndef THE_LEMON_MAN
  93.     imx233_enable_gpio_output(0, 30, false);
  94.     imx233_enable_gpio_output(0, 31, false);
  95.     imx233_set_gpio_output(0, 30, false);
  96.     imx233_set_gpio_output(0, 31, false);
  97.     #else
  98.     HW_PINCTRL_DOUT0_CLR = 3 << 30;
  99.     HW_PINCTRL_DOE0_CLR = 3 << 30;
  100.     #endif
  101. }
  102.  
  103. /********************************************************/
  104.  
  105. static void i2c_do_start(bool restart)
  106. {
  107.     if(restart)
  108.     {
  109.         /* release sda (which should be high) */
  110.         i2c_read_sda();
  111.         /* wait */
  112.         i2c_delay();
  113.         /* clock stretch */
  114.         while(!i2c_read_scl());
  115.     }
  116.     /* drive sda (START) */
  117.     i2c_clear_sda();
  118.     /* wait */
  119.     i2c_delay();
  120.     /* drive scl */
  121.     i2c_clear_scl();
  122. }
  123.  
  124. static void i2c_do_stop(void)
  125. {
  126.     /* drive sda */
  127.     i2c_clear_sda();
  128.     /* wait */
  129.     i2c_delay();
  130.     /* clock stretch */
  131.     while(!i2c_read_scl());
  132.     /* clear sda */
  133.     i2c_read_sda();
  134.     /* wait (bus free) */
  135.     i2c_delay();
  136. }
  137.  
  138. static void i2c_write_bit(bool b)
  139. {
  140.     /* drive/clear sda */
  141.     if(b)
  142.         i2c_read_sda();
  143.     else
  144.         i2c_clear_sda();
  145.     /* wait */
  146.     i2c_delay();
  147.     /* clock stretch */
  148.     while(!i2c_read_scl());
  149.     /* wait */
  150.     i2c_delay();
  151.     /* drive scl */
  152.     i2c_clear_scl();
  153. }
  154.  
  155. static bool i2c_read_bit(void)
  156. {
  157.     /* release sda to let the device drive it */
  158.     i2c_read_sda();
  159.     /* wait */
  160.     i2c_delay();
  161.     /* clock stretch */
  162.     while(!i2c_read_scl());
  163.     /* read */
  164.     bool b = i2c_read_sda();
  165.     /* wait */
  166.     i2c_delay();
  167.     /* drive scl */
  168.     i2c_clear_scl();
  169.     return b;
  170. }
  171.  
  172. /* return ack */
  173. static bool i2c_write_byte(uint8_t b)
  174. {
  175.     /* MSB first */
  176.     for(int bit = 0; bit < 8; bit++)
  177.     {
  178.         i2c_write_bit(!!(b & 0x80));
  179.         b <<= 1;
  180.     }
  181.     return i2c_read_bit();
  182. }
  183.  
  184. static uint8_t i2c_read_byte(bool nak)
  185. {
  186.     uint8_t v = 0;
  187.     /* MSB first */
  188.     for(int bit = 0; bit < 8; bit++)
  189.         v = v << 1 | i2c_read_bit();
  190.     i2c_write_bit(nak);
  191.     return v;
  192. }
  193.  
  194. int i2c_readmem(int device, int address, unsigned char* buf, int count)
  195. {
  196.     i2c_do_start(false);
  197.     if(i2c_write_byte(device)) return -1;
  198.     if(i2c_write_byte(address)) return -2;
  199.     i2c_do_start(true);
  200.     if(i2c_write_byte(device | 1)) return -3;
  201.     while(count-- > 0)
  202.         *buf++ = i2c_read_byte(count == 0);
  203.     i2c_do_stop();
  204.     return 0;
  205. }
  206.  
  207. int i2c_writemem(int device, int address, const unsigned char* buf, int count)
  208. {
  209.     i2c_do_start(false);
  210.     if(i2c_write_byte(device)) return -1;
  211.     if(i2c_write_byte(address)) return -2;
  212.     while(count-- > 0)
  213.         if(i2c_write_byte(*buf++))
  214.             return -4;
  215.     i2c_do_stop();
  216.     return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement