Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e05ce44

Browse files
Rubuschherbertx
authored andcommitted
crypto: atmel-sha204a - add reading from otp zone
Provide a read function reading the otp zone. The otp zone can be used for storing serial numbers. The otp zone, as also data zone, are only accessible if the chip was locked before. Locking the chip is a post production customization and has to be done manually i.e. not by this driver. Without this step the chip is pretty much not usable, where putting or not putting data into the otp zone is optional. Signed-off-by: Lothar Rubusch <l.rubusch@gmail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent 3f5f746 commit e05ce44

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

drivers/crypto/atmel-i2c.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,30 @@ void atmel_i2c_init_read_config_cmd(struct atmel_i2c_cmd *cmd)
7070
}
7171
EXPORT_SYMBOL(atmel_i2c_init_read_config_cmd);
7272

73+
int atmel_i2c_init_read_otp_cmd(struct atmel_i2c_cmd *cmd, u16 addr)
74+
{
75+
if (addr < 0 || addr > OTP_ZONE_SIZE)
76+
return -1;
77+
78+
cmd->word_addr = COMMAND;
79+
cmd->opcode = OPCODE_READ;
80+
/*
81+
* Read the word from OTP zone that may contain e.g. serial
82+
* numbers or similar if persistently pre-initialized and locked
83+
*/
84+
cmd->param1 = OTP_ZONE;
85+
cmd->param2 = cpu_to_le16(addr);
86+
cmd->count = READ_COUNT;
87+
88+
atmel_i2c_checksum(cmd);
89+
90+
cmd->msecs = MAX_EXEC_TIME_READ;
91+
cmd->rxsize = READ_RSP_SIZE;
92+
93+
return 0;
94+
}
95+
EXPORT_SYMBOL(atmel_i2c_init_read_otp_cmd);
96+
7397
void atmel_i2c_init_random_cmd(struct atmel_i2c_cmd *cmd)
7498
{
7599
cmd->word_addr = COMMAND;

drivers/crypto/atmel-i2c.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ struct atmel_i2c_cmd {
6464

6565
/* Definitions for eeprom organization */
6666
#define CONFIGURATION_ZONE 0
67+
#define OTP_ZONE 1
68+
69+
/* Definitions for eeprom zone sizes */
70+
#define OTP_ZONE_SIZE 64
6771

6872
/* Definitions for Indexes common to all commands */
6973
#define RSP_DATA_IDX 1 /* buffer index of data in response */
@@ -179,6 +183,7 @@ void atmel_i2c_flush_queue(void);
179183
int atmel_i2c_send_receive(struct i2c_client *client, struct atmel_i2c_cmd *cmd);
180184

181185
void atmel_i2c_init_read_config_cmd(struct atmel_i2c_cmd *cmd);
186+
int atmel_i2c_init_read_otp_cmd(struct atmel_i2c_cmd *cmd, u16 addr);
182187
void atmel_i2c_init_random_cmd(struct atmel_i2c_cmd *cmd);
183188
void atmel_i2c_init_genkey_cmd(struct atmel_i2c_cmd *cmd, u16 keyid);
184189
int atmel_i2c_init_ecdh_cmd(struct atmel_i2c_cmd *cmd,

drivers/crypto/atmel-sha204a.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,29 @@ static int atmel_sha204a_rng_read(struct hwrng *rng, void *data, size_t max,
9191
return max;
9292
}
9393

94+
static int atmel_sha204a_otp_read(struct i2c_client *client, u16 addr, u8 *otp)
95+
{
96+
struct atmel_i2c_cmd cmd;
97+
int ret = -1;
98+
99+
if (atmel_i2c_init_read_otp_cmd(&cmd, addr) < 0) {
100+
dev_err(&client->dev, "failed, invalid otp address %04X\n",
101+
addr);
102+
return ret;
103+
}
104+
105+
ret = atmel_i2c_send_receive(client, &cmd);
106+
107+
if (cmd.data[0] == 0xff) {
108+
dev_err(&client->dev, "failed, device not ready\n");
109+
return -ret;
110+
}
111+
112+
memcpy(otp, cmd.data+1, 4);
113+
114+
return ret;
115+
}
116+
94117
static int atmel_sha204a_probe(struct i2c_client *client)
95118
{
96119
struct atmel_i2c_client_priv *i2c_priv;

0 commit comments

Comments
 (0)