Source
static inline void __exit ab3100_otp_exit_debugfs(struct ab3100_otp *otp)
/*
* drivers/mfd/ab3100_otp.c
*
* Copyright (C) 2007-2009 ST-Ericsson AB
* License terms: GNU General Public License (GPL) version 2
* Driver to read out OTP from the AB3100 Mixed-signal circuit
* Author: Linus Walleij <linus.walleij@stericsson.com>
*/
/* The OTP registers */
/**
* struct ab3100_otp
* @dev containing device
* @locked whether the OTP is locked, after locking, no more bits
* can be changed but before locking it is still possible
* to change bits from 1->0.
* @freq clocking frequency for the OTP, this frequency is either
* 32768Hz or 1MHz/30
* @paf product activation flag, indicates whether this is a real
* product (paf true) or a lab board etc (paf false)
* @imeich if this is set it is possible to override the
* IMEI number found in the tac, fac and svn fields with
* (secured) software
* @cid customer ID
* @tac type allocation code of the IMEI
* @fac final assembly code of the IMEI
* @svn software version number of the IMEI
* @debugfs a debugfs file used when dumping to file
*/
struct ab3100_otp {
struct device *dev;
bool locked;
u32 freq;
bool paf;
bool imeich;
u16 cid:14;
u32 tac:20;
u8 fac;
u32 svn:20;
struct dentry *debugfs;
};
static int __init ab3100_otp_read(struct ab3100_otp *otp)
{
u8 otpval[8];
u8 otpp;
int err;
err = abx500_get_register_interruptible(otp->dev, 0,
AB3100_OTPP, &otpp);
if (err) {
dev_err(otp->dev, "unable to read OTPP register\n");
return err;
}
err = abx500_get_register_page_interruptible(otp->dev, 0,
AB3100_OTP0, otpval, 8);
if (err) {
dev_err(otp->dev, "unable to read OTP register page\n");
return err;
}
/* Cache OTP properties, they never change by nature */
otp->locked = (otpp & 0x80);
otp->freq = (otpp & 0x40) ? 32768 : 34100;
otp->paf = (otpval[1] & 0x80);
otp->imeich = (otpval[1] & 0x40);
otp->cid = ((otpval[1] << 8) | otpval[0]) & 0x3fff;
otp->tac = ((otpval[4] & 0x0f) << 16) | (otpval[3] << 8) | otpval[2];
otp->fac = ((otpval[5] & 0x0f) << 4) | (otpval[4] >> 4);
otp->svn = (otpval[7] << 12) | (otpval[6] << 4) | (otpval[5] >> 4);
return 0;
}