在boot中添加i2c使用得方法

来源:互联网 发布:音频广告制作软件 编辑:程序博客网 时间:2024/05/17 22:55
//在 lk/platform/msm8226/include/platform/aboot.h 中添加 判断 判断pad与pad链接得引脚定义 #define P03_PLUG_IN                          15             //GPIO表中查询   //在 lk/platform/msm8226/include/platform/iomap.h中修改 #define RESTART_REASON_ADDR         (SYSTEM_IMEM_BASE + 0x565C)  //在lk/platform/msm8226/gpio.c中添加如下:  int gpio_get(uint32_t gpio){unsigned int *addr = (unsigned int *)GPIO_IN_OUT_ADDR(gpio);return (readl(addr) & 0x1);  } //在lk/inlcude/gpio.h中添加如下int gpio_get(unsigned nr); ///////////////////////////////////////////////////////////////////////init.c+++ //在lk/target/msms8226/init.c  中添加如下   #include <i2c_qup.h>  static struct qup_i2c_dev *dev = NULL;#define SOFTWARE_RESET0x73727374#define ADB_REBOOT0x77665501#define RECOVERY_MODE0x77665502#define UARTLOG_MODE0x77665503#define NORMAL_BOOT0x77665504#define MICROP_CABLE_IN_TRIGGER0x02#define MICROP_POWER_KEY_TRIGGER0x03 #define SCALER_I2C_ADDRESS(0x37)#define SCALER_IMAGE_I2C_ADDRESS(0xE8)#define MICROP_I2C_ADDRESS(0x15)#define MICROP_ID_I2C_ADDRESS(0x00)#define MICROP_FW_ADDRESS(0x01)#define MICROP_POWER_ON_REASON_ADDRESS(0x07)#define MICROP_VBUS_OFF_ADDRESS(0x23)#define MICROP_POWER_OFF_ADDRESS(0x55)#define MICROP_A68_READY_ADDRESS(0x05     uint8_t read_microp_hwid(uint8_t addr){int ret = 0;uint8_t data[4];/* Create a i2c_msg buffer, that is used to put the controller into readmode and then to read some data. */struct i2c_msg msg_buf[] = {{MICROP_I2C_ADDRESS, I2C_M_WR, 1, &addr},{MICROP_I2C_ADDRESS, I2C_M_RD, 4, &data}};dprintf(CRITICAL, "lion->init.c->read_microp_hwid::addr = 0x%d \r\n",addr);ret = qup_i2c_xfer(dev, msg_buf, 2);if ( ret < 0 )return ret;dprintf(INFO, "[BL]  ret[0] = 0x%x \n", data[0]);dprintf(INFO, "[BL]  ret[1] = 0x%x \n", data[1]);dprintf(INFO, "[BL]  ret[2] = 0x%x \n", data[2]);dprintf(INFO, "[BL]  ret[3] = 0x%x \n", data[3]);return data[1];}uint8_t read_microp_fw(uint8_t addr){uint8_t data[4];struct i2c_msg msg_buf[] = {{MICROP_I2C_ADDRESS, I2C_M_WR, 1, &addr},{MICROP_I2C_ADDRESS, I2C_M_RD, 4, &data}};dprintf(CRITICAL, "lion->init.c->read_microp_fw::addr = 0x%d \r\n",addr);qup_i2c_xfer(dev, msg_buf, 2);dprintf(INFO, "[BL]  ret[0] = 0x%x \n", data[0]);dprintf(INFO, "[BL]  ret[1] = 0x%x \n", data[1]);dprintf(INFO, "[BL]  ret[2] = 0x%x \n", data[2]);dprintf(INFO, "[BL]  ret[3] = 0x%x \n", data[3]);return data[0];}uint8_t read_microp_power_on_reason(uint8_t addr){uint8_t ret[4];struct i2c_msg msg_buf[] = {{MICROP_I2C_ADDRESS, I2C_M_WR, 1, &addr},{MICROP_I2C_ADDRESS, I2C_M_RD, 4, &ret}};dprintf(CRITICAL, "lion->init.c->read_microp_power_on_reason::addr = 0x%d \r\n",addr);qup_i2c_xfer(dev, msg_buf, 2);dprintf(INFO, "[BL]  ret[0] = 0x%x \n", ret[0]);dprintf(INFO, "[BL]  ret[1] = 0x%x \n", ret[1]);dprintf(INFO, "[BL]  ret[2] = 0x%x \n", ret[2]);dprintf(INFO, "[BL]  ret[3] = 0x%x \n", ret[3]);return ret[1];}uint8_t write_microp_a68_ready(uint8_t addr){int ret;uint8_t buf[2];buf[0] = addr;buf[1] = 0x96;struct i2c_msg msg_buf[] = { {MICROP_I2C_ADDRESS, I2C_M_WR, 2, &buf}};dprintf(CRITICAL, "lion->init.c->write_microp_a68_ready::addr = 0x%d \r\n",addr);ret = qup_i2c_xfer(dev, msg_buf, 1);return ret;}uint8_t write_microp_power_off(uint8_t addr){int ret;uint8_t buf[2];buf[0] = addr;buf[1] = 0xAA;struct i2c_msg msg_buf[] = { {MICROP_I2C_ADDRESS, I2C_M_WR, 2, &buf}};dprintf(CRITICAL, "lion->init.c->write_microp_power_off::addr = 0x%d \r\n",addr);ret = qup_i2c_xfer(dev, msg_buf, 1);return ret;}void shutdown_device(void){dprintf(CRITICAL, "Shutdown system.\n");//  lk/dev/pmi/pm8921/pm8921.c中实现pm8921_config_reset_pwr_off(0);/* Actually reset the chip */writel(0, MSM_PSHOLD_CTL_SU);mdelay(5000);dprintf(CRITICAL, "Shutdown failed.\n");} ///////////////////////////////////////////////////////////////////////init.c--- ///////////////////////////////////////////////////////////////////////////////////////////////////////////target_init+++ //在void target_init(void)   函数中添加如下判断  void target_init(void)  {/*判断是带PAD启动   */ if ( gpio_get(P03_PLUG_IN) ){uint8_t whoamI = 0;unsigned reboot_mode = 0; dprintf(CRITICAL, "lion->tartget_init->[GSBI]  qup_i2c_init++\n");dev = qup_i2c_init( GSBI_ID_4 , 100000, 24000000);dprintf(CRITICAL, "lion->tartget_init->[GSBI]  qup_i2c_init--\n");/* Make sure dev is created and initialized properly */if (!dev){ dprintf(CRITICAL, "[GSBI]  i2c GSBI init dev fail \n" ); }else{  /*Microp issue*/whoamI = read_microp_hwid( MICROP_ID_I2C_ADDRESS );dprintf(CRITICAL, "lion->tartget_init[Microp]  MicropID = 0x%x \n", whoamI);if ( !(whoamI < 0) ){//0x01 whoamI = read_microp_fw(MICROP_FW_ADDRESS); dprintf(CRITICAL, "lion->tartget_init[Microp]  Microp FW = 0x3%x \n", whoamI);//0x07whoamI = read_microp_power_on_reason(MICROP_POWER_ON_REASON_ADDRESS);dprintf(CRITICAL, "lion->tartget_init[Microp]  Microp power on reason = 0x%x \n", whoamI);/*If sw reset or recovery reset, don't shut down */reboot_mode = readl(RESTART_REASON_ADDR);dprintf(CRITICAL,"lion->tartget_init::reboot_mode : 0x%02x \n", reboot_mode);if ( reboot_mode == SOFTWARE_RESET  || reboot_mode == ADB_REBOOT || reboot_mode == UARTLOG_MODE || reboot_mode == NORMAL_BOOT ||reboot_mode == RECOVERY_MODE || whoamI == MICROP_CABLE_IN_TRIGGER || whoamI == MICROP_POWER_KEY_TRIGGER ) { dprintf(CRITICAL, "lion->tartget_init[Microp]  Write a68 ready \n");//0x05   write_microp_a68_ready(MICROP_A68_READY_ADDRESS);     //vibration_enable();  震动 暂时没开dprintf(INFO,"lion->tartget_init::reboot_mode : 0x%02x \n", readl(RESTART_REASON_ADDR));}//NOelse{ /*If Cable in or long press P03 power_key*/if ( whoamI == 0x01 || whoamI <= 0 ){  dprintf(CRITICAL, "[Microp]  Power off microp \n");//write_microp_vbus_off(MICROP_VBUS_OFF_ADDRESS);write_microp_power_off(MICROP_POWER_OFF_ADDRESS);dprintf(CRITICAL, "[Microp]  Power off device \n");shutdown_device(); }}}//end of   if ( !(whoamI < 0) ) }//end of    else   (!dev)} //end of  if ( gpio_get(P03_PLUG_IN) )} ///////////////////////////////////////////////////////////////////////////////////////////////////////////target_init--- ///////////////////////////////////////////////////////////////////////////////////////////////////////////qup_i2c_init+++//  修改 lk/platform/msm_shared/i2c_qup.c 中得函数qup_i2c_init struct qup_i2c_dev *qup_i2c_init(uint8_t gsbi_id, unsigned clk_freq, unsigned src_clk_freq){ /*   ....*/ //添加如下判断 switch (gsbi_id) {  case GSBI_ID_4:dev->gsbi_base = 0x16300000;dev->qup_base = 0x16300000 + 0x80000;/* Initialize the GPIO_10 and GPIO_11 for GSBI4 as i2c */gpio_tlmm_config(10, 0x9, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_2MA, GPIO_DISABLE);gpio_tlmm_config(11, 0xa, GPIO_OUTPUT, GPIO_NO_PULL,GPIO_2MA, GPIO_DISABLE);dprintf(CRITICAL, "[GSBI_4] GPIO_10 and GPIO_11 ok\n"); /* Setting i2c_mux_rw */ val = readl(0x008003E0);dprintf(CRITICAL, "[GSBI_4] rw_base value  0x%x ->", val);writel((val | 0x200), 0x008003E0);val = readl(0x008003E0);dprintf(CRITICAL, " 0x%x\n", val);/* Setting i2c_mux_ctl */val = readl(0x008020B8);dprintf(CRITICAL, "[GSBI_4] ctl_base value  0x%x ->", val);writel(((val | 0x2) & ~(0x1)), 0x008020B8);val = readl(0x008020B8);dprintf(CRITICAL, " 0x%x\n", val);dprintf(CRITICAL, "[GSBI_4] initial complete !\n");break; default:ASSERT(0);}  /* This must be done for qup_i2c_interrupt to work. */dev_addr = dev; /* Configure the GSBI Protocol Code for i2c */writel((GSBI_PROTOCOL_CODE_I2C <<GSBI_CTRL_REG_PROTOCOL_CODE_S), GSBI_CTRL_REG(dev->gsbi_base));/* Set clk_freq and src_clk_freq for i2c. */dev->clk_freq = clk_freq;dev->src_clk_freq = src_clk_freq; dev->num_irqs = 1; dev->one_bit_t = USEC_PER_SEC / dev->clk_freq;dev->clk_ctl = 0; /* Register the GSBIn QUP IRQ */register_int_handler(dev->qup_irq, (int_handler) qup_i2c_interrupt, 0); /* Then disable it */mask_interrupt(dev->qup_irq); return dev;}///////////////////////////////////////////////////////////////////////////////////////////////////////////qup_i2c_init+++///////////////////////////////////////////////////////////////////////////////// clk++  //使能microp 使用得i2c得时钟 0xF9925000 QUP3 //在lk/platform/msm8226/include/platform/iomap.h 中添加  宏定义 allows SW control of CBC soft macro ////  CLK_CTL_BASE 为0xFC400000   QUP3  0xFC400748  #define BLSP1_QUP3_I2C_APPS_CBCR    (CLK_CTL_BASE + 0x748)//在/lk/platform/msm8226/msm8226-clock.c中添加如下变量:struct branch_clk gcc_blsp1_qup3_i2c_apps_clk = {  .cbcr_reg = BLSP1_QUP3_I2C_APPS_CBCR,     .parent   = &cxo_clk_src.c,       .c = {          .dbg_name = "gcc_blsp1_qup3_i2c_apps_clk",          .ops      = &clk_ops_branch,  },//在msm_clocks_8226结构提中添加static struct clk_lookup msm_clocks_8226[] ={/* ...*/  CLK_LOOKUP("blsp1_qup3_i2c_apps_clk", gcc_blsp1_qup3_i2c_apps_clk.c),  /* ....*/}///////////////////////////////////////////////////////////////////////////////// clk--


原创粉丝点击