Loading drivers/power/supply/qcom/fg-memif.c +84 −37 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ static int fg_set_address(struct fg_dev *fg, u16 address) int rc; buffer[0] = address & 0xFF; /* MSB has to be written zero */ buffer[1] = address >> 8; /* MSB has to be written zero for GEN3 FG */ if (fg->version == GEN3_FG) buffer[1] = 0; rc = fg_write(fg, MEM_IF_ADDR_LSB(fg), buffer, 2); Loading Loading @@ -103,6 +106,30 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg) usleep_range(35, 40); while (1) { if (fg->version == GEN4_FG) { val = 0x4; rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1); if (rc < 0) { pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_ADDR_MSB(fg), rc); return rc; } val = 0; rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &val, 1); if (rc < 0) { pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_WR_DATA1(fg), rc); return rc; } rc = fg_read(fg, MEM_IF_RD_DATA1(fg), &val, 1); if (rc < 0) { pr_err("failed to read 0x%04x, rc=%d\n", MEM_IF_RD_DATA1(fg), rc); return rc; } } else { /* GEN3 FG */ val = 0; rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1); if (rc < 0) { Loading @@ -125,6 +152,7 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg) MEM_IF_RD_DATA3(fg), rc); return rc; } } /* Delay for IMA hardware to clear */ usleep_range(35, 40); Loading Loading @@ -313,7 +341,7 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, int offset, u8 *val, int len) { int rc = 0, i; u8 *ptr = val, byte_enable = 0, num_bytes = 0; u8 *ptr = val, byte_enable = 0, num_bytes = 0, dummy_byte = 0; fg_dbg(fg, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len, address, offset); Loading Loading @@ -343,14 +371,12 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, } /* * The last-byte WR_DATA3 starts the write transaction. * Write a dummy value to WR_DATA3 if it does not have * The last-byte WR_DATA3/1 starts the write transaction. * Write a dummy value to WR_DATA3/1 if it does not have * valid data. This dummy data is not written to the * SRAM as byte_en for WR_DATA3 is not set. * SRAM as byte_en for WR_DATA3/1 is not set. */ if (!(byte_enable & BIT(3))) { u8 dummy_byte = 0x0; if (fg->version == GEN3_FG && !(byte_enable & BIT(3))) { rc = fg_write(fg, MEM_IF_WR_DATA3(fg), &dummy_byte, 1); if (rc < 0) { Loading @@ -358,6 +384,14 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, rc); return rc; } } else if (fg->version == GEN4_FG && !(byte_enable & BIT(1))) { rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &dummy_byte, 1); if (rc < 0) { pr_err("failed to write dummy-data to WR_DATA1 rc=%d\n", rc); return rc; } } /* check for error condition */ Loading Loading @@ -542,7 +576,8 @@ static int fg_interleaved_mem_config(struct fg_dev *fg, u8 *val, } /* configure for the read/write, single/burst mode */ burst_mode = fg->use_ima_single_mode ? false : ((offset + len) > 4); burst_mode = fg->use_ima_single_mode ? false : (offset + len) > fg->sram.num_bytes_per_word; rc = fg_config_access_mode(fg, access, burst_mode); if (rc < 0) { pr_err("failed to set memory access rc = %d\n", rc); Loading Loading @@ -588,11 +623,17 @@ int fg_interleaved_mem_read(struct fg_dev *fg, u16 address, u8 offset, u8 start_beat_count, end_beat_count, count = 0; bool retry = false; if (fg->version == GEN4_FG) { if (offset > 1) { pr_err("offset too large %d\n", offset); return -EINVAL; } } else { if (offset > 3) { pr_err("offset too large %d\n", offset); return -EINVAL; } } retry: if (count >= RETRY_COUNT) { pr_err("Tried %d times\n", RETRY_COUNT); Loading Loading @@ -673,11 +714,17 @@ int fg_interleaved_mem_write(struct fg_dev *fg, u16 address, u8 offset, u8 start_beat_count, end_beat_count, count = 0; bool retry = false; if (fg->version == GEN4_FG) { if (offset > 1) { pr_err("offset too large %d\n", offset); return -EINVAL; } } else { if (offset > 3) { pr_err("offset too large %d\n", offset); return -EINVAL; } } retry: if (count >= RETRY_COUNT) { pr_err("Tried %d times\n", RETRY_COUNT); Loading drivers/power/supply/qcom/fg-reg.h +2 −0 Original line number Diff line number Diff line Loading @@ -326,8 +326,10 @@ #define MEM_IF_ADDR_LSB(chip) ((chip->mem_if_base) + 0x61) #define MEM_IF_ADDR_MSB(chip) ((chip->mem_if_base) + 0x62) #define MEM_IF_WR_DATA0(chip) ((chip->mem_if_base) + 0x63) #define MEM_IF_WR_DATA1(chip) ((chip->mem_if_base) + 0x64) #define MEM_IF_WR_DATA3(chip) ((chip->mem_if_base) + 0x66) #define MEM_IF_RD_DATA0(chip) ((chip->mem_if_base) + 0x67) #define MEM_IF_RD_DATA1(chip) ((chip->mem_if_base) + 0x68) #define MEM_IF_RD_DATA3(chip) ((chip->mem_if_base) + 0x6A) #define MEM_IF_DMA_STS(chip) ((chip->mem_if_base) + 0x70) Loading Loading
drivers/power/supply/qcom/fg-memif.c +84 −37 Original line number Diff line number Diff line Loading @@ -30,7 +30,10 @@ static int fg_set_address(struct fg_dev *fg, u16 address) int rc; buffer[0] = address & 0xFF; /* MSB has to be written zero */ buffer[1] = address >> 8; /* MSB has to be written zero for GEN3 FG */ if (fg->version == GEN3_FG) buffer[1] = 0; rc = fg_write(fg, MEM_IF_ADDR_LSB(fg), buffer, 2); Loading Loading @@ -103,6 +106,30 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg) usleep_range(35, 40); while (1) { if (fg->version == GEN4_FG) { val = 0x4; rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1); if (rc < 0) { pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_ADDR_MSB(fg), rc); return rc; } val = 0; rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &val, 1); if (rc < 0) { pr_err("failed to write 0x%04x, rc=%d\n", MEM_IF_WR_DATA1(fg), rc); return rc; } rc = fg_read(fg, MEM_IF_RD_DATA1(fg), &val, 1); if (rc < 0) { pr_err("failed to read 0x%04x, rc=%d\n", MEM_IF_RD_DATA1(fg), rc); return rc; } } else { /* GEN3 FG */ val = 0; rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1); if (rc < 0) { Loading @@ -125,6 +152,7 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg) MEM_IF_RD_DATA3(fg), rc); return rc; } } /* Delay for IMA hardware to clear */ usleep_range(35, 40); Loading Loading @@ -313,7 +341,7 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, int offset, u8 *val, int len) { int rc = 0, i; u8 *ptr = val, byte_enable = 0, num_bytes = 0; u8 *ptr = val, byte_enable = 0, num_bytes = 0, dummy_byte = 0; fg_dbg(fg, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len, address, offset); Loading Loading @@ -343,14 +371,12 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, } /* * The last-byte WR_DATA3 starts the write transaction. * Write a dummy value to WR_DATA3 if it does not have * The last-byte WR_DATA3/1 starts the write transaction. * Write a dummy value to WR_DATA3/1 if it does not have * valid data. This dummy data is not written to the * SRAM as byte_en for WR_DATA3 is not set. * SRAM as byte_en for WR_DATA3/1 is not set. */ if (!(byte_enable & BIT(3))) { u8 dummy_byte = 0x0; if (fg->version == GEN3_FG && !(byte_enable & BIT(3))) { rc = fg_write(fg, MEM_IF_WR_DATA3(fg), &dummy_byte, 1); if (rc < 0) { Loading @@ -358,6 +384,14 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address, rc); return rc; } } else if (fg->version == GEN4_FG && !(byte_enable & BIT(1))) { rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &dummy_byte, 1); if (rc < 0) { pr_err("failed to write dummy-data to WR_DATA1 rc=%d\n", rc); return rc; } } /* check for error condition */ Loading Loading @@ -542,7 +576,8 @@ static int fg_interleaved_mem_config(struct fg_dev *fg, u8 *val, } /* configure for the read/write, single/burst mode */ burst_mode = fg->use_ima_single_mode ? false : ((offset + len) > 4); burst_mode = fg->use_ima_single_mode ? false : (offset + len) > fg->sram.num_bytes_per_word; rc = fg_config_access_mode(fg, access, burst_mode); if (rc < 0) { pr_err("failed to set memory access rc = %d\n", rc); Loading Loading @@ -588,11 +623,17 @@ int fg_interleaved_mem_read(struct fg_dev *fg, u16 address, u8 offset, u8 start_beat_count, end_beat_count, count = 0; bool retry = false; if (fg->version == GEN4_FG) { if (offset > 1) { pr_err("offset too large %d\n", offset); return -EINVAL; } } else { if (offset > 3) { pr_err("offset too large %d\n", offset); return -EINVAL; } } retry: if (count >= RETRY_COUNT) { pr_err("Tried %d times\n", RETRY_COUNT); Loading Loading @@ -673,11 +714,17 @@ int fg_interleaved_mem_write(struct fg_dev *fg, u16 address, u8 offset, u8 start_beat_count, end_beat_count, count = 0; bool retry = false; if (fg->version == GEN4_FG) { if (offset > 1) { pr_err("offset too large %d\n", offset); return -EINVAL; } } else { if (offset > 3) { pr_err("offset too large %d\n", offset); return -EINVAL; } } retry: if (count >= RETRY_COUNT) { pr_err("Tried %d times\n", RETRY_COUNT); Loading
drivers/power/supply/qcom/fg-reg.h +2 −0 Original line number Diff line number Diff line Loading @@ -326,8 +326,10 @@ #define MEM_IF_ADDR_LSB(chip) ((chip->mem_if_base) + 0x61) #define MEM_IF_ADDR_MSB(chip) ((chip->mem_if_base) + 0x62) #define MEM_IF_WR_DATA0(chip) ((chip->mem_if_base) + 0x63) #define MEM_IF_WR_DATA1(chip) ((chip->mem_if_base) + 0x64) #define MEM_IF_WR_DATA3(chip) ((chip->mem_if_base) + 0x66) #define MEM_IF_RD_DATA0(chip) ((chip->mem_if_base) + 0x67) #define MEM_IF_RD_DATA1(chip) ((chip->mem_if_base) + 0x68) #define MEM_IF_RD_DATA3(chip) ((chip->mem_if_base) + 0x6A) #define MEM_IF_DMA_STS(chip) ((chip->mem_if_base) + 0x70) Loading