/* * interrupt function */ static irqreturn_t gpio_interrupt(int irq, void *dev_id) { int handled; int value = 0; has_motion_detection_irq = 0; value = HW_REG(GPIO_RIS); if ((value & 0x1) != 0x0)//GPIO11_0 interrupt { has_motion_detection_irq |= 0x1; wake_up_interruptible(&(motion_detection_event)); } if ((value & 0x2) != 0x0)//GPIO11_1 interrupt { has_motion_detection_irq |= 0x2; wake_up_interruptible(&(motion_detection_event)); } //Clear interrupt flag. HW_REG(GPIO_IC) = 0xFF; handled = 1; HW_REG(GPIO_IE) = 0x0; return IRQ_RETVAL(handled); }
/* receives a character from I2C rountine. * * @return value: character received * */ static unsigned char i2c_receive_byte(void) { int j=0; int i; unsigned char regvalue; local_irq_disable(); for (i=0; i<8; i++) { DELAY(1); i2c_clr(SCL); DELAY(1); i2c_set(SCL); regvalue = HW_REG(GPIO_0_DIR); regvalue &= (~SDA); HW_REG(GPIO_0_DIR) = regvalue; DELAY(1); if (i2c_data_read()) j+=(1<<(7-i)); DELAY(1); i2c_clr(SCL); } local_irq_enable(); DELAY(1); // i2c_clr(SDA); // DELAY(1); return j; }
/* receives an acknowledge from I2C rountine. * * @return value: 0--Ack received; 1--Nack received * */ static int i2c_receive_ack(void) { int nack; unsigned char regvalue; DELAY(1); regvalue = HW_REG(GPIO_0_DIR); regvalue &= (~SDA); HW_REG(GPIO_0_DIR) = regvalue; DELAY(1); i2c_clr(SCL); DELAY(1); i2c_set(SCL); DELAY(1); nack = i2c_data_read(); DELAY(1); i2c_clr(SCL); DELAY(1); // i2c_set(SDA); // DELAY(1); if (nack == 0) return 1; return 0; }
static int i2c_receive_ack(int Grp) { int nack; unsigned char regvalue; DELAY(1); regvalue = HW_REG(GPIO_I2C_DIR[Grp]); regvalue &= (~GPIO_I2C_BIT[Grp][PINI2C_SDA]); HW_REG(GPIO_I2C_DIR[Grp]) = regvalue; DELAY(1); i2c_clr(Grp, PINI2C_SCL); DELAY(1); i2c_set(Grp, PINI2C_SCL); DELAY(1); nack = i2c_data_read(Grp); DELAY(1); i2c_clr(Grp, PINI2C_SCL); DELAY(1); return !nack; }
static unsigned char i2c_receive_byte(int Grp) { int j = 0; int i; unsigned char regvalue; local_irq_disable(); for (i = 0; i < 8; i ++) { DELAY(1); i2c_clr(Grp, PINI2C_SCL); DELAY(2); i2c_set(Grp, PINI2C_SCL); regvalue = HW_REG(GPIO_I2C_DIR[Grp]); regvalue &= (~GPIO_I2C_BIT[Grp][PINI2C_SDA]); HW_REG(GPIO_I2C_DIR[Grp]) = regvalue; DELAY(1); if (i2c_data_read(Grp)) { j+=(1<<(7-i)); } DELAY(1); i2c_clr(Grp, PINI2C_SCL); } local_irq_enable(); DELAY(1); return j; }
static int enableMotionDetectionIrq(void) { HW_REG(GPIO_IC) = 0xFF; //Enable GPIO11_0 and GPIO11_1. HW_REG(GPIO_IE) = 0x3; return 0; }
static void i2c_set(int Grp, int Pin) { unsigned int tmpVal; tmpVal = HW_REG(GPIO_I2C_DIR[Grp]); tmpVal |= GPIO_I2C_BIT[Grp][Pin]; HW_REG(GPIO_I2C_DIR[Grp]) = tmpVal; HW_REG(GPIO_I2C_PIN[Grp][Pin]) = GPIO_I2C_BIT[Grp][Pin]; }
int set_gpio_value(int ctl_idx, int value) { gpio_ctl_s *ctl = &g_ctl_tbl[ctl_idx]; unsigned int addr = IO_ADDRESS(ctl->mux_reg); if (HW_REG(addr) != ctl->mux_value) { BCTL_PRINTK("pin %d is not gpio mode, set first.", ctl_idx); HW_REG(addr) = ctl->mux_value; msleep(200); } return gpio_write(ctl->group, ctl->channel, value); }
static unsigned int i2c_data_read(int Grp) { unsigned int tmpVal; tmpVal = HW_REG(GPIO_I2C_DIR[Grp]); tmpVal &= (~GPIO_I2C_BIT[Grp][PINI2C_SDA]); HW_REG(GPIO_I2C_DIR[Grp]) = tmpVal; DELAY(1); tmpVal = HW_REG(GPIO_I2C_PIN[Grp][PINI2C_SDA]); return (tmpVal & GPIO_I2C_BIT[Grp][PINI2C_SDA]); }
int gpio_write(int group, int channel, unsigned int value) { unsigned int base_addr; unsigned int dir_addr; unsigned int data_addr; base_addr = GPIO_0_BASE + 0x10000 * group; dir_addr = IO_ADDRESS(base_addr + 0x400); data_addr = IO_ADDRESS(base_addr + (1 << (channel + 2))); HW_REG(dir_addr) |= 1 << channel; HW_REG(data_addr) = (value << channel); return 0; }
static unsigned char i2c_data_read(void) { unsigned char regvalue; regvalue = HW_REG(GPIO_0_DIR); regvalue &= (~SDA); HW_REG(GPIO_0_DIR) = regvalue; DELAY(1); regvalue = HW_REG(GPIO_I2C_SDA_REG); if((regvalue&SDA) != 0) return 1; else return 0; }
static int disableMotionDetectionIrq(void) { //Disable GPIO11_0 and GPIO11_1. HW_REG(GPIO_IE) = 0x0; return 0; }
unsigned long tnk_clk_init(void) { unsigned long busclk, tnkclk; unsigned long tnkctl; unsigned long toe_clk_srst; busclk = get_bus_clk(); tnkclk = busclk >> 1; toe_clk_srst = readl(REG_CRG0_OFFSET + TOE_CLK_SRST); #ifdef TNK_PRINT pr_info("%s: busclk: %.8x, tnkclk: %.8x, toe_clk_srst: %.8x\n", __func__, (unsigned int)busclk, (unsigned int)tnkclk, (unsigned int)toe_clk_srst); pr_info("REG_CRG0_OFFSET: 0x%08X\n" "REG_CRG1_OFFSET: 0x%08X\n" "A9_AXI_SCALE_REG: 0x%08X\n", (unsigned int)HW_REG(REG_CRG0_OFFSET), (unsigned int)HW_REG(REG_CRG1_OFFSET), (unsigned int)HW_REG(A9_AXI_SCALE_REG)); #endif if (toe_clk_srst & TOE_CLK_DEF_100M) { tnkctl = (TOE_DEFAULT_CLK << 12) | TOE_MAX_CON_NUM; #ifdef TNK_PRINT pr_info ("%s: Using TOE_DEFAULT_CLK %x, TOE_MAX_CON_NUM %x,tnkctl %x\n", __func__, TOE_DEFAULT_CLK, TOE_MAX_CON_NUM, (unsigned int)tnkctl); #endif return tnkctl; } else { tnkctl = ((tnkclk / 1000) << 12) | TOE_MAX_CON_NUM; #ifdef TNK_PRINT pr_info("%s: Using tnkclk %x, TOE_MAX_CON_NUM %x, tnkctl %x\n", __func__, (unsigned int)tnkclk, TOE_MAX_CON_NUM, (unsigned int)tnkctl); #endif return tnkctl; } }
int gpio_read(int group, int channel) { unsigned int base_addr; unsigned int dir_addr; unsigned int mask; unsigned int data_addr; unsigned int regValue; base_addr = GPIO_0_BASE + 0x10000 * group; dir_addr = IO_ADDRESS(base_addr + 0x400); mask = 1 << channel; data_addr = IO_ADDRESS(base_addr + (1 << (channel + 2))); regValue = HW_REG(dir_addr); regValue &= (~mask); HW_REG(dir_addr) = regValue; regValue = HW_REG(data_addr); return (regValue & mask) >> channel; }
static int initializeMotionDetectionIrq(void) { int ret; int value = 0; //Set the GPIO11_0 and GPIO11_1 as the GPIO function. HW_REG(muxctrl_reg111) = 0x0; HW_REG(muxctrl_reg112) = 0x0; //Set the GPIO11_0, GPIO11_1 as input mode. value = HW_REG(GPIO_11_DIR); value &= ~(0x1 << 0); value &= ~(0x1 << 1); HW_REG(GPIO_11_DIR) = value; //Set the interrupt source as the sensitive mode. HW_REG(GPIO_IS) = 0x3; //Set the low-level sensitive mode. HW_REG(GPIO_IEV) = 0x3; //Set the single edge mode. HW_REG(GPIO_IBE) = 0x0; //Disable GPIO interrupt. HW_REG(GPIO_IE) = 0x0; //Clear interrupt flag. HW_REG(GPIO_IC) = 0xFF; //request irq ret = request_irq(IRQ_GPIO, &gpio_interrupt, 0, \ "Motion detection interrupt", NULL); if (0 != ret) { printk(" hi3521 cx26828: failed to register IRQ_GPIO(%d), ret = %d\n", IRQ_GPIO, ret); goto IRQ_GPIO_failed; } return 0; IRQ_GPIO_failed: return ret; }
/* * I2C by GPIO simulated clear 0 routine. * * @param whichline: GPIO control line * */ static void i2c_clr(unsigned char whichline) { unsigned char regvalue; if(whichline == SCL) { regvalue = HW_REG(GPIO_0_DIR); regvalue |= SCL; HW_REG(GPIO_0_DIR) = regvalue; HW_REG(GPIO_I2C_SCL_REG) = 0; return; } else if(whichline == SDA) { regvalue = HW_REG(GPIO_0_DIR); regvalue |= SDA; HW_REG(GPIO_0_DIR) = regvalue; HW_REG(GPIO_I2C_SDA_REG) = 0; return; } else if(whichline == (SDA|SCL)) { regvalue = HW_REG(GPIO_0_DIR); regvalue |= (SDA|SCL); HW_REG(GPIO_0_DIR) = regvalue; HW_REG(GPIO_I2C_SCLSDA_REG) = 0; return; } else { printk("Error input.\n"); return; } }