⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generic_spi.c

📁 linux下atheros的ag7100驱动
💻 C
字号:
#define here() do { printk("%s(%d)\n", __func__, __LINE__); } while(0)/* generic_spi.c */#ifdef __BDI#include "bdi.h"#define protect()#define unprotect()#else#ifdef __ECOS#include <cyg/hal/ar7100_soc.h>#include "ag7100_ecos.h" #define printk          DEBUG_PRINTF#define protect()#define unprotect()#else#include <linux/kernel.h>#include <linux/spinlock.h>#include <asm/delay.h>#include <asm/io.h>#include "ar7100.h"void ar7100_flash_spi_down(void);void ar7100_flash_spi_up(void);#define protect()   ar7100_flash_spi_down()#define unprotect() ar7100_flash_spi_up()#endif#endif#include "generic_spi.h"#include "generic_i2c.h"/* ************************************************************** */#ifdef CONFIG_AR9100#define AR9100_SPI_GPIO_OE       0x18040000 /* GPIO Output Enable */#define AR9100_SPI_GPIO_OUT      0x18040008 /* GPIO Output Value Register */#define AR9100_SPI_GPIO_FUNC     0x18040028#define AR9100_SPI_CLK_HIGH      (1<<23)#define AR9100_SPI_CLK_LOW       ~(1<<23)#define AR9100_SPI_DO_HI         (1<<0)#define AR9100_SPI_CS_DISABLE_0  (1<<12)#define AR9100_SPI_CS_DISABLE_1  (1<<13)#define AR9100_SPI_CLK#define AR9100_SPI_GPIO_IN       0x18040004#else#define GENERIC_SPI_FS           0x1f000000 /* Function select */#define GENERIC_SPI_CLOCK        0x1f000004 /* Alias-disable + clock */#define GENERIC_SPI_WRITE        0x1f000008 /* SPI_IO_CTRL					    * spi_do    = 1<<0  (reflects pin)					    * spi_clk   = 1<<8  (reflects pin)					    * cs0/gpio  = 1<<16 (active low)					    * cs1/gpio  = 1<<17 (active low)					    * cs2gpio   = 1<<18 (active low)					    */#define GENERIC_SPI_RD_SHIFT_REG 0x1f00000c /* spi_di is clocked into register pos 0 every clock */#define GENERIC_SPI_CS_DISABLE_0 (1<<16)#define GENERIC_SPI_CS_DISABLE_1 (1<<17)#define GENERIC_SPI_CS_DISABLE_2 (1<<18)#define GENERIC_SPI_CS_DIS       (GENERIC_SPI_CS_DISABLE_0|GENERIC_SPI_CS_DISABLE_1|GENERIC_SPI_CS_DISABLE_2)#define GENERIC_SPI_D0_HIGH      (1<<0)#define GENERIC_SPI_CLK_HIGH     (1<<8)#endif#ifdef CONFIG_AR9100intgeneric_spi_access_enable(int cs){  uint32_t val;  protect();  val = (ar7100_reg_rd(AR9100_SPI_GPIO_OE)|0x02);  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OE,val);  val = (ar7100_reg_rd(AR9100_SPI_GPIO_OUT) & ~(0x0A));  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OUT,val);  return 0;}intgeneric_spi_access_done(void){  uint32_t val;  val = (ar7100_reg_rd(AR9100_SPI_GPIO_OE)|0x02);  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OE,val);  val = (ar7100_reg_rd(AR9100_SPI_GPIO_OUT)|0x02);  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OUT,val);  unprotect();  return 0;}intgeneric_spi_init(int cs){        return 0;}/* Data needs to be stable on rising edge of clock */voidgeneric_spi_raw_output_u8(unsigned char val){  int ii,rd_val, wr_val;  /* Only change GPIO 0, 1 or 2 in mask */  unsigned int cs0to2mask = (0xbf000000);  rd_val = (ar7100_reg_rd(AR9100_SPI_GPIO_OE) & ~(0x08));  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OE,rd_val);  /* Shift out SPI values keeping GPIO bits the same */  for (ii = 7; ii>=0 ; ii--) {    uint32_t  jj = (val >> ii) & 1;    /* First assert data, make sure clock is low */    if(jj)    wr_val = (cs0to2mask | (1 << 22));    else    wr_val = cs0to2mask;    /* Falling edge of the spi clk*/    rd_val=ar7100_reg_rd(wr_val);    /* Leave data there, rising edge of clock causes data to be output */    rd_val=ar7100_reg_rd((wr_val | AR9100_SPI_CLK_HIGH));  }}unsigned intgeneric_spi_raw_input_u32(void){  int ii;  uint32_t val;  uint32_t rd_val = 0x0;  unsigned int cs0to2mask = 0xbf000000;  val = (ar7100_reg_rd(AR9100_SPI_GPIO_OE) & ~(0x08));  ar7100_reg_wr_nf(AR9100_SPI_GPIO_OE,val);  val=ar7100_reg_rd(cs0to2mask);  /* Only change GPIO 0, 1 or 2 in mask */  /* For each rising edge the data in is sampled and clocked into serial shift register */  for (ii = 31; ii>=0 ; ii--) {    val=ar7100_reg_rd((cs0to2mask | AR9100_SPI_CLK_HIGH));    val = ar7100_reg_rd(AR9100_SPI_GPIO_IN);    rd_val = rd_val | (((val >> 3) & 0x1)<< ii);    val=ar7100_reg_rd(cs0to2mask);  }    val=ar7100_reg_rd(cs0to2mask);  /* Shift register contains value read */  return rd_val;}#elseintgeneric_spi_access_enable(int cs){  protect();    ar7100_reg_wr(GENERIC_SPI_CLOCK, 0x43);    /* Enable access to SPI bits through memory   * mapped registers.   */  ar7100_reg_wr_nf(GENERIC_SPI_FS, 1);  ar7100_reg_wr_nf(GENERIC_SPI_WRITE, GENERIC_SPI_CS_DIS);         {	      unsigned int cs0to2mask;    cs0to2mask = ar7100_reg_rd(GENERIC_SPI_WRITE) & GENERIC_SPI_CS_DIS;    ar7100_reg_wr  (GENERIC_SPI_WRITE, cs0to2mask | GENERIC_SPI_CLK_HIGH );  }  generic_i2c_assert_cs(cs);  return 0;}intgeneric_spi_access_done(void){  generic_i2c_deassert_cs();  ar7100_reg_wr_nf(GENERIC_SPI_FS, 0);  unprotect();  return 0;}intgeneric_spi_init(int cs){  /* For now just initialize the i2c, this will be different for bdi/ecos/linux */  return generic_i2c_init_gpio();}/* Data needs to be stable on rising edge of clock */voidgeneric_spi_raw_output_u8(unsigned char val) {  int ii;  unsigned int cs0to2mask = ar7100_reg_rd(GENERIC_SPI_WRITE) & ~(GENERIC_SPI_D0_HIGH|GENERIC_SPI_CLK_HIGH);  /* Shift out SPI values keeping GPIO bits the same */  for (ii = 7; ii>=0 ; ii--) {    unsigned char  jj = (val >> ii) & 1;        ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask | jj );    ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask | jj | GENERIC_SPI_CLK_HIGH );  }}unsigned int generic_spi_raw_input_u32(void) {  int ii;  unsigned int cs0to2mask = ar7100_reg_rd(GENERIC_SPI_WRITE) & ~(GENERIC_SPI_D0_HIGH|GENERIC_SPI_CLK_HIGH);  /* For each rising edge the data in is sampled and clocked into serial shift register */  for (ii = 31; ii>=0 ; ii--) {    ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask                            );    ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask | GENERIC_SPI_CLK_HIGH     );  }  /* Shift register contains value read */  return ar7100_reg_rd(GENERIC_SPI_RD_SHIFT_REG);}unsigned int generic_spi_raw_input_u8(void) {  int ii;  unsigned int cs0to2mask = ar7100_reg_rd(GENERIC_SPI_WRITE) & ~(GENERIC_SPI_D0_HIGH|GENERIC_SPI_CLK_HIGH);  /* For each rising edge the data in is sampled and clocked into serial shift register */  for (ii = 7; ii>=0 ; ii--) {    ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask                            );    ar7100_reg_wr(GENERIC_SPI_WRITE, cs0to2mask | GENERIC_SPI_CLK_HIGH     );  }  /* Shift register contains value read */  return ar7100_reg_rd(GENERIC_SPI_RD_SHIFT_REG);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -