Chinaunix首页 | 论坛 | 博客
  • 博客访问: 69739
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2016-09-10 14:44
文章分类
文章存档

2017年(1)

2016年(48)

我的朋友

分类: LINUX

2017-11-08 23:14:34

原文地址:GPIO模拟I2C 作者:caijicheng2006


点击(此处)折叠或打开

  1. nmi_gpio_i2c.h

  2. int nmi_i2c_init(void);

  3. void nmi_i2c_deinit(void);

  4. int nmi_i2c_read(unsigned char, unsigned char *, unsigned long);

  5. int nmi_i2c_write(unsigned char, unsigned char *, unsigned long);

  6. nmi_gpio_i2c.c
  7. /******************************************************************************

  8. **

  9. **    Copyright (c) Newport Media Inc. All rights reserved.

  10. **

  11. **     Module Name: nmidrv_i2c.c

  12. **    

  13. **        This module implements the i2c interface NMI ATV

  14. **

  15. **

  16. *******************************************************************************/

  17. #include <linux/kernel.h>

  18. #include <linux/init.h>

  19. //#include <linux/android_pmem.h>

  20. #include <mach/hardware.h>

  21. #include <asm/mach-types.h>

  22. #include <asm/mach/arch.h>

  23. #include <asm/mach/map.h>

  24. #include <mach/board.h>

  25. #include <mach/hardware.h>

  26. #include <asm/io.h>

  27. #include <asm/delay.h>

  28. #include <mach/gpio.h>

  29. #include <linux/clk.h>

  30. #include <mach/mfp.h>

  31. #include <linux/i2c.h>

  32. #include <linux/i2c-gpio.h>

  33. #include "nmi_gpio_i2c.h"

  34. #include "nm5625_kernel.h"

  35. #include <linux/delay.h>







  36. #define NMI_SDA_PIN    81

  37. #define NMI_SCL_PIN    80



  38. static unsigned long I2C_func_cfg[] /*__initdata*/ = {

  39.     MFP_CFG_X(SDA, GPIO, DS3, F_PULL_UP, F_PULL_UP, IO_OE),

  40.         MFP_CFG_X(SCL, GPIO, DS3, F_PULL_UP, F_PULL_UP, IO_OE),

  41. };



  42. static unsigned long I2C_std_func_cfg[] = {
  43.     MFP_CFG_X(SDA, AF0, DS3, F_PULL_UP, F_PULL_UP, IO_NONE),

  44.         MFP_CFG_X(SCL, AF0, DS3, F_PULL_UP, F_PULL_UP, IO_NONE),
  45. };



  46. /******************************************************************************

  47. **

  48. **    I2c Defines

  49. **

  50. *******************************************************************************/

  51. //#undef _DRIVE_ //this mode is nmi600 Recommend mode. please don't change it.

  52. #define _DRIVE_

  53. #define I2C_DELAY_UNIT 2



  54. /*#define set_sda_output() mt_set_gpio_dir(NMI_SDA_PIN,1); \

  55.                                                        mt_set_gpio_out(NMI_SDA_PIN,0)

  56. #define set_sda_input() mt_set_gpio_dir(NMI_SDA_PIN,0)

  57. #define set_scl_output() mt_set_gpio_dir(NMI_SCL_PIN,1); \

  58.                                                         mt_set_gpio_out(NMI_SCL_PIN,0)

  59. #define set_scl_input() mt_set_gpio_dir(NMI_SCL_PIN,0)*/



  60. #define set_sda_output()                gpio_direction_output(NMI_SDA_PIN,0)

  61. #define set_sda_input()                    gpio_direction_input(NMI_SDA_PIN)        

  62. #define set_scl_output()                gpio_direction_output(NMI_SCL_PIN,0)

  63. #define set_scl_input()                    gpio_direction_input(NMI_SCL_PIN)



  64. #ifdef _DRIVE_

  65. #define set_i2c_scl_PIN             gpio_direction_output(NMI_SCL_PIN,1)    

  66. #define clr_i2c_scl_PIN             gpio_direction_output(NMI_SCL_PIN,0)

  67. #define set_i2c_sda_PIN             gpio_direction_output(NMI_SDA_PIN,1)

  68. #define clr_i2c_sda_PIN          gpio_direction_output(NMI_SDA_PIN,0)

  69. #else

  70. /*#define set_i2c_scl_PIN             mt_set_gpio_out(NMI_SCL_PIN,1)    

  71. #define clr_i2c_scl_PIN             mt_set_gpio_out(NMI_SCL_PIN,0)

  72. #define set_i2c_sda_PIN             mt_set_gpio_out(NMI_SDA_PIN,0)

  73. #define clr_i2c_sda_PIN          mt_set_gpio_out(NMI_SDA_PIN,1)*/

  74. #endif



  75. //#define get_i2c_sda_PIN             gpio_direction_input(NMI_SDA_PIN);gpio_get_value(NMI_SDA_PIN)

  76. //#define get_i2c_scl_PIN          gpio_direction_input(NMI_SCL_PIN);gpio_get_value(NMI_SCL_PIN)

  77. #define get_i2c_sda_PIN                gpio_get_value(NMI_SDA_PIN)

  78. #define get_i2c_scl_PIN                gpio_get_value(NMI_SCL_PIN)





  79. /******************************************************************************

  80. **

  81. **    I2c Platform Functions

  82. **

  83. *******************************************************************************/



  84. static void i2c_delay(unsigned int time)

  85. {

  86. #if 0

  87.     while(time--) {    

  88.         ;

  89.     }

  90. #else

  91.     udelay(time);

  92. #endif

  93. }



  94. static void i2c_begin(void)

  95. {

  96. #ifdef _DRIVE_



  97.     /* set SDA to high */

  98.     set_i2c_sda_PIN;

  99.     i2c_delay(I2C_DELAY_UNIT << 0);

  100.     

  101.     /* set SCL to high */

  102.     set_i2c_scl_PIN;

  103.     i2c_delay(I2C_DELAY_UNIT << 0);



  104.     /* set SDA to low */

  105.     clr_i2c_sda_PIN;

  106.     i2c_delay(I2C_DELAY_UNIT << 0);



  107.     /* set SCL to low */

  108.     clr_i2c_scl_PIN;        

  109.     i2c_delay(I2C_DELAY_UNIT << 0);



  110. #else



  111.     /* set SDA to high */

  112.     set_sda_input();

  113.     i2c_delay(I2C_DELAY_UNIT << 0);



  114.     /* set SCL to high */

  115.     set_scl_input();

  116.     i2c_delay(I2C_DELAY_UNIT << 0);



  117.     /* set SDA to low */

  118.     set_sda_output();

  119.     i2c_delay(I2C_DELAY_UNIT << 0);



  120.     /* set SCL to low */

  121.     set_scl_output();        

  122.     i2c_delay(I2C_DELAY_UNIT << 0);

  123. #endif



  124. }



  125. static void i2c_end(void)

  126. {

  127. #ifdef _DRIVE_

  128.     /* set SDA to low */

  129.     clr_i2c_sda_PIN;    

  130.     i2c_delay(I2C_DELAY_UNIT << 2);



  131.     /* set SCL to high */

  132.     set_i2c_scl_PIN;

  133.     i2c_delay(I2C_DELAY_UNIT << 0);



  134.     /* set SDA to high */

  135.     set_i2c_sda_PIN;        

  136.     i2c_delay(I2C_DELAY_UNIT << 0);



  137. #else

  138.     set_sda_output();

  139.     i2c_delay(I2C_DELAY_UNIT << 2);

  140.     set_scl_input();

  141.     i2c_delay(I2C_DELAY_UNIT << 3);

  142.     set_sda_input();

  143.     i2c_delay(I2C_DELAY_UNIT << 4);

  144. #endif

  145. }



  146. static void i2c_write_ask(unsigned char flag)

  147. {

  148. #ifdef _DRIVE_

  149.     /* set SDA to high to ack */

  150.     if(flag)

  151.         set_i2c_sda_PIN;

  152.     else

  153.         clr_i2c_sda_PIN;

  154.     i2c_delay(I2C_DELAY_UNIT << 0);



  155.     /* toggle clock */

  156.     set_i2c_scl_PIN;

  157.     i2c_delay(I2C_DELAY_UNIT << 0);

  158.     clr_i2c_scl_PIN;

  159.     i2c_delay(I2C_DELAY_UNIT << 0);



  160.     /* set SDA to 1 */

  161.     set_i2c_sda_PIN;

  162.     i2c_delay(I2C_DELAY_UNIT << 0);



  163. #else



  164.        //set_sda_output();



  165.     if(flag)

  166.         set_sda_input();

  167.     //else

  168.         //set_sda_output();

  169.     

  170.     i2c_delay(I2C_DELAY_UNIT << 0);

  171.     set_scl_input();

  172.     i2c_delay(I2C_DELAY_UNIT << 0);

  173.     set_scl_output();

  174.     i2c_delay(I2C_DELAY_UNIT << 0);

  175.     set_sda_input();

  176.     i2c_delay(I2C_DELAY_UNIT << 0);

  177. #endif

  178. }



  179. static unsigned char i2c_read_ack(void)

  180. {

  181.     unsigned char ret;



  182. #ifdef _DRIVE_

  183.     /* set SDA to input */

  184.     set_sda_input();

  185.     /* delay */

  186.     i2c_delay(I2C_DELAY_UNIT << 0);

  187.     

  188.     /* read */

  189.     //gpio_direction_input(NMI_SDA_PIN);

  190.     if (!get_i2c_sda_PIN) {

  191.         ret = 1;

  192.     } else {

  193.         ret = 0;

  194.         dPrint(N_ERR,"[MTKI2C] 1. i2c_read_ack (Error.. No Ack received)\n");

  195.         i2c_delay(I2C_DELAY_UNIT << 0);

  196.         if (!get_i2c_sda_PIN) {

  197.             ret = 1;

  198.             dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Correct after additional delay.)\n");    

  199.         } else {

  200.             ret = 0;

  201.             dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Error.. No Ack received)\n");

  202.         }

  203.     }



  204.     /* set SCL high */

  205.     set_i2c_scl_PIN;

  206.     i2c_delay(I2C_DELAY_UNIT << 0);



  207.     /* set SCL low */

  208.     clr_i2c_scl_PIN;

  209.     i2c_delay(I2C_DELAY_UNIT << 0);



  210.     /* set SDA back to output */

  211.     set_sda_output();



  212. #else



  213.     set_sda_input();

  214.     i2c_delay(I2C_DELAY_UNIT << 0);

  215.     

  216.     //gpio_direction_input(NMI_SDA_PIN);

  217.     if (!get_i2c_sda_PIN) {

  218.         ret = 1;

  219.     } else {

  220.         ret = 0;

  221.         dPrint(N_ERR,"[MTKI2C] 1. i2c_read_ack (Error.. No Ack received)\n");

  222.         i2c_delay(I2C_DELAY_UNIT << 0);

  223.         if (!get_i2c_sda_PIN) {

  224.             ret = 1;

  225.             dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Correct after additional delay.)\n");    

  226.         } else {

  227.             ret = 0;

  228.             dPrint(N_ERR,"[MTKI2C] 2.i2c_read_ack (Error.. No Ack received)\n");

  229.         }

  230.     }

  231.     

  232.     set_scl_input();

  233.     i2c_delay(I2C_DELAY_UNIT << 0);

  234.     set_scl_output();

  235.     i2c_delay(I2C_DELAY_UNIT << 0);

  236.     

  237. #endif

  238.     return ret;

  239. }



  240. static unsigned char i2c_read_byte(void)

  241. {

  242.     unsigned char i;

  243.     unsigned char ret = 0;



  244. #ifdef _DRIVE_



  245.     /* set SDA input */

  246.     set_sda_input();

  247.     

  248.     /* loop */

  249.     for (i = 0; i < 8; i++) {            

  250.         /* delay */

  251.         i2c_delay(I2C_DELAY_UNIT << 0);



  252.         /* set SCL high */

  253.         set_i2c_scl_PIN;

  254.         /* delay */

  255.         i2c_delay(I2C_DELAY_UNIT << 0);



  256.         /* read SDA */

  257.         ret    = ret<<1;

  258.         //gpio_direction_input(NMI_SDA_PIN);

  259.         if (get_i2c_sda_PIN)

  260.             ret |= 1;

  261.         /* delay */

  262.         i2c_delay(I2C_DELAY_UNIT << 0);



  263.         /* set SCL low */

  264.         clr_i2c_scl_PIN;

  265.         /* delay */

  266.         i2c_delay(I2C_DELAY_UNIT << 0);



  267.         /* if end, set SDA output */

  268.         if (i == 7) {

  269.             set_sda_output();

  270.           }

  271.         /* delay */

  272.          i2c_delay(I2C_DELAY_UNIT << 0);

  273.     }    



  274. #else

  275.     int retry,retry_val = 10000000;



  276.     ret    = 0;



  277.     set_sda_input();

  278.     for (i = 0; i < 8; i++) {            

  279.         i2c_delay(I2C_DELAY_UNIT << 0);



  280.         set_scl_input();    



  281.         i2c_delay(I2C_DELAY_UNIT << 0);

  282.         ret    = ret<<1;

  283.         if (get_i2c_sda_PIN)

  284.             ret |= 1;

  285.         i2c_delay(I2C_DELAY_UNIT << 0);



  286.         retry = retry_val;

  287.         while (retry >= 0)

  288.         {

  289.             if (get_i2c_scl_PIN)

  290.                 break;

  291.             else

  292.             {

  293.                 i2c_delay(I2C_DELAY_UNIT << 0);

  294.                 retry--;

  295.             }

  296.         }



  297.         //if (retry != retry_val)

  298.         if (retry < (retry_val-10000))

  299.         {

  300.             //NMI_ERROR("[MTKI2C] i2c_read_byte: retry = %d\n",retry);

  301.         }



  302.         set_scl_output();

  303.               i2c_delay(I2C_DELAY_UNIT << 0);



  304.         if (i==7){

  305.         set_sda_output();

  306.               }

  307.              i2c_delay(I2C_DELAY_UNIT << 0);

  308.     }        



  309. #endif    



  310.     return ret;

  311. }



  312. static unsigned char i2c_write_byte(unsigned char data)

  313. {

  314.     unsigned char i;



  315. #ifdef _DRIVE_

  316.     /* loop */

  317.     for    (i = 0; i < 8; i++) {

  318.         /* set SDA high or low depend on the data bit */

  319.         if (data & 0x80)

  320.             set_i2c_sda_PIN;

  321.         else

  322.             clr_i2c_sda_PIN;

  323.         /* delay */

  324.         i2c_delay(I2C_DELAY_UNIT << 0);



  325.         data <<= 1;



  326.         /* set SCL high */

  327.         set_i2c_scl_PIN;

  328.         /* delay */

  329.         i2c_delay(I2C_DELAY_UNIT << 0);



  330.         /* set SCL low */

  331.         clr_i2c_scl_PIN;

  332.         /* delay */

  333.         i2c_delay(I2C_DELAY_UNIT << 0);

  334.     }

  335. #else

  336.     int retry, retry_val = 10000000;



  337.     //set_sda_output();



  338.     for    (i = 0; i < 8; i++) {

  339.         if (data & 0x80)

  340.             set_sda_input();

  341.         else

  342.             set_sda_output();



  343.         data <<= 1;



  344.         i2c_delay(I2C_DELAY_UNIT << 0);

  345.         set_scl_input();

  346.         i2c_delay(I2C_DELAY_UNIT << 0);

  347.         retry = retry_val;

  348.         while (retry >= 0)

  349.         {

  350.             if (get_i2c_scl_PIN)

  351.                 break;

  352.             else

  353.             {

  354.                 i2c_delay(I2C_DELAY_UNIT << 0);

  355.                 retry--;

  356.             }

  357.         }



  358.         //if (retry != retry_val)

  359.         if (retry < (retry_val-10000))

  360.         {

  361.             dPrint(N_TRACE,"i2c write_byte: retry = %d\n",retry);

  362.         }

  363.         set_scl_output();        

  364.         i2c_delay(I2C_DELAY_UNIT << 0);

  365.     }

  366.     

  367. #endif

  368.     

  369.     return i2c_read_ack();

  370. }



  371. /******************************************************************************

  372. **

  373. **    I2c Global Functions

  374. **

  375. *******************************************************************************/



  376. int nmi_i2c_init(void)

  377. {

  378.     dPrint(N_TRACE,"nmi_i2c_init: enter...\n");



  379.     sprd_mfp_config(I2C_func_cfg, ARRAY_SIZE(I2C_func_cfg));

  380.     gpio_request(NMI_SCL_PIN,"scl");

  381.     gpio_request(NMI_SDA_PIN,"sda");

  382.     gpio_direction_output(NMI_SCL_PIN,1);

  383.     gpio_direction_output(NMI_SDA_PIN,1);

  384. /*#if 0

  385.        //disable all inside pull( pullup & pulldown)

  386.     NMI_SET_GPIO_PULL_DISABLE(NMI_SDA_PIN);

  387.     NMI_SET_GPIO_PULL_DISABLE(NMI_SCL_PIN);

  388.     //set gpio mode

  389.     NMI_SET_GPIO_MODE_ENABLE(NMI_SDA_PIN);

  390.     NMI_SET_GPIO_MODE_ENABLE(NMI_SCL_PIN);



  391. #ifdef _DRIVE_

  392.     //set output mode

  393.     NMI_SET_GPIO_DIR( NMI_SDA_PIN,1);

  394.     NMI_SET_GPIO_DIR( NMI_SCL_PIN,1);

  395.       //set gpio high

  396.     NMI_SET_GPIO_LEVEL( NMI_SDA_PIN,1);

  397.     NMI_SET_GPIO_LEVEL( NMI_SCL_PIN,1);

  398. #else

  399.     //set input mode

  400.     NMI_SET_GPIO_DIR( NMI_SDA_PIN,0);

  401.     NMI_SET_GPIO_DIR( NMI_SCL_PIN,0);

  402. #endif

  403. #else

  404.     //config scl

  405.     mt_set_gpio_mode(NMI_SCL_PIN,GPIO_MODE_00);

  406.     mt_set_gpio_dir(NMI_SCL_PIN, GPIO_DIR_OUT);

  407.     mt_set_gpio_pull_enable(NMI_SCL_PIN,true);

  408.     mt_set_gpio_pull_select(NMI_SCL_PIN, GPIO_PULL_UP);

  409.     mt_set_gpio_out(NMI_SCL_PIN, GPIO_OUT_ONE);



  410.     //config sda

  411.     mt_set_gpio_mode(NMI_SDA_PIN, GPIO_MODE_00);

  412.     mt_set_gpio_dir(NMI_SDA_PIN, GPIO_DIR_OUT);

  413.     mt_set_gpio_pull_enable(NMI_SDA_PIN,true);

  414.     mt_set_gpio_pull_select(NMI_SDA_PIN, GPIO_PULL_UP);

  415.     mt_set_gpio_out(NMI_SDA_PIN, GPIO_OUT_ONE);

  416. #endif*/

  417.     dPrint(N_TRACE,"nmi_i2c_init: exit...\n");



  418.     return 1;

  419. }



  420. void nmi_i2c_deinit(void)

  421. {

  422.     dPrint(N_TRACE,"nmi_i2c_deinit: enter...\n");



  423.     gpio_free(NMI_SDA_PIN);

  424.     gpio_free(NMI_SCL_PIN);
  425.     sprd_mfp_config(I2C_std_func_cfg, ARRAY_SIZE(I2C_std_func_cfg));

  426. #if 0

  427.     NMI_SET_GPIO_MODE_ENABLE(NMI_SDA_PIN);

  428.     NMI_SET_GPIO_MODE_ENABLE(NMI_SCL_PIN);



  429.     //set as input

  430.     NMI_SET_GPIO_DIR( NMI_SDA_PIN,0);

  431.     NMI_SET_GPIO_DIR( NMI_SCL_PIN,0);

  432. #endif

  433.     dPrint(N_TRACE,"nmi_i2c_deinit: exit...\n");



  434. }



  435. int nmi_i2c_read(unsigned char adr, unsigned char *b, unsigned long sz)

  436. {

  437.     int i;



  438.     i2c_begin();

  439.     i2c_write_byte((adr << 1)|0x1);



  440.     for(i = 0; i < sz; i++) {

  441.      b[i] = i2c_read_byte();    

  442.         

  443.      if(i == sz-1)

  444.             i2c_write_ask(1);    

  445.      else     

  446.             i2c_write_ask(0);

  447.     }



  448.     i2c_end();

  449.     return 1;

  450. }



  451. int nmi_i2c_write(unsigned char adr, unsigned char *b, unsigned long sz)

  452. {

  453.     int i;



  454.     i2c_begin();



  455.     i2c_write_byte((adr << 1));

  456.     for(i = 0; i < sz; i++) {

  457.         i2c_write_byte(b[i]);

  458.     }



  459.     i2c_end();

  460.     return 1;

  461. }

阅读(1284) | 评论(0) | 转发(0) |
0

上一篇:http协议分析2

下一篇:没有了

给主人留下些什么吧!~~