in sc27xx-efuse.c [125:201]
static int sc27xx_efuse_read(void *context, u32 offset, void *val, size_t bytes)
{
struct sc27xx_efuse *efuse = context;
u32 buf, blk_index = offset / SC27XX_EFUSE_BLOCK_WIDTH;
u32 blk_offset = (offset % SC27XX_EFUSE_BLOCK_WIDTH) * BITS_PER_BYTE;
int ret;
if (blk_index > SC27XX_EFUSE_BLOCK_MAX ||
bytes > SC27XX_EFUSE_BLOCK_WIDTH)
return -EINVAL;
ret = sc27xx_efuse_lock(efuse);
if (ret)
return ret;
/* Enable the efuse controller. */
ret = regmap_update_bits(efuse->regmap, efuse->var_data->module_en,
SC27XX_EFUSE_EN, SC27XX_EFUSE_EN);
if (ret)
goto unlock_efuse;
/*
* Before reading, we should ensure the efuse controller is in
* standby state.
*/
ret = sc27xx_efuse_poll_status(efuse, SC27XX_EFUSE_STANDBY);
if (ret)
goto disable_efuse;
/* Set the block address to be read. */
ret = regmap_write(efuse->regmap,
efuse->base + SC27XX_EFUSE_BLOCK_INDEX,
blk_index & SC27XX_EFUSE_BLOCK_MASK);
if (ret)
goto disable_efuse;
/* Start reading process from efuse memory. */
ret = regmap_update_bits(efuse->regmap,
efuse->base + SC27XX_EFUSE_MODE_CTRL,
SC27XX_EFUSE_RD_START,
SC27XX_EFUSE_RD_START);
if (ret)
goto disable_efuse;
/*
* Polling the read done status to make sure the reading process
* is completed, that means the data can be read out now.
*/
ret = sc27xx_efuse_poll_status(efuse, SC27XX_EFUSE_RD_DONE);
if (ret)
goto disable_efuse;
/* Read data from efuse memory. */
ret = regmap_read(efuse->regmap, efuse->base + SC27XX_EFUSE_DATA_RD,
&buf);
if (ret)
goto disable_efuse;
/* Clear the read done flag. */
ret = regmap_update_bits(efuse->regmap,
efuse->base + SC27XX_EFUSE_MODE_CTRL,
SC27XX_EFUSE_CLR_RDDONE,
SC27XX_EFUSE_CLR_RDDONE);
disable_efuse:
/* Disable the efuse controller after reading. */
regmap_update_bits(efuse->regmap, efuse->var_data->module_en, SC27XX_EFUSE_EN, 0);
unlock_efuse:
sc27xx_efuse_unlock(efuse);
if (!ret) {
buf >>= blk_offset;
memcpy(val, &buf, bytes);
}
return ret;
}