162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2017, Microchip Technology Inc. 462306a36Sopenharmony_ci * Author: Tudor Ambarus 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#ifndef __ATMEL_I2C_H__ 862306a36Sopenharmony_ci#define __ATMEL_I2C_H__ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/hw_random.h> 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define ATMEL_ECC_PRIORITY 300 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define COMMAND 0x03 /* packet function */ 1662306a36Sopenharmony_ci#define SLEEP_TOKEN 0x01 1762306a36Sopenharmony_ci#define WAKE_TOKEN_MAX_SIZE 8 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* Definitions of Data and Command sizes */ 2062306a36Sopenharmony_ci#define WORD_ADDR_SIZE 1 2162306a36Sopenharmony_ci#define COUNT_SIZE 1 2262306a36Sopenharmony_ci#define CRC_SIZE 2 2362306a36Sopenharmony_ci#define CMD_OVERHEAD_SIZE (COUNT_SIZE + CRC_SIZE) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* size in bytes of the n prime */ 2662306a36Sopenharmony_ci#define ATMEL_ECC_NIST_P256_N_SIZE 32 2762306a36Sopenharmony_ci#define ATMEL_ECC_PUBKEY_SIZE (2 * ATMEL_ECC_NIST_P256_N_SIZE) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define STATUS_RSP_SIZE 4 3062306a36Sopenharmony_ci#define ECDH_RSP_SIZE (32 + CMD_OVERHEAD_SIZE) 3162306a36Sopenharmony_ci#define GENKEY_RSP_SIZE (ATMEL_ECC_PUBKEY_SIZE + \ 3262306a36Sopenharmony_ci CMD_OVERHEAD_SIZE) 3362306a36Sopenharmony_ci#define READ_RSP_SIZE (4 + CMD_OVERHEAD_SIZE) 3462306a36Sopenharmony_ci#define RANDOM_RSP_SIZE (32 + CMD_OVERHEAD_SIZE) 3562306a36Sopenharmony_ci#define MAX_RSP_SIZE GENKEY_RSP_SIZE 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci/** 3862306a36Sopenharmony_ci * atmel_i2c_cmd - structure used for communicating with the device. 3962306a36Sopenharmony_ci * @word_addr: indicates the function of the packet sent to the device. This 4062306a36Sopenharmony_ci * byte should have a value of COMMAND for normal operation. 4162306a36Sopenharmony_ci * @count : number of bytes to be transferred to (or from) the device. 4262306a36Sopenharmony_ci * @opcode : the command code. 4362306a36Sopenharmony_ci * @param1 : the first parameter; always present. 4462306a36Sopenharmony_ci * @param2 : the second parameter; always present. 4562306a36Sopenharmony_ci * @data : optional remaining input data. Includes a 2-byte CRC. 4662306a36Sopenharmony_ci * @rxsize : size of the data received from i2c client. 4762306a36Sopenharmony_ci * @msecs : command execution time in milliseconds 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_cistruct atmel_i2c_cmd { 5062306a36Sopenharmony_ci u8 word_addr; 5162306a36Sopenharmony_ci u8 count; 5262306a36Sopenharmony_ci u8 opcode; 5362306a36Sopenharmony_ci u8 param1; 5462306a36Sopenharmony_ci __le16 param2; 5562306a36Sopenharmony_ci u8 data[MAX_RSP_SIZE]; 5662306a36Sopenharmony_ci u8 msecs; 5762306a36Sopenharmony_ci u16 rxsize; 5862306a36Sopenharmony_ci} __packed; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci/* Status/Error codes */ 6162306a36Sopenharmony_ci#define STATUS_SIZE 0x04 6262306a36Sopenharmony_ci#define STATUS_NOERR 0x00 6362306a36Sopenharmony_ci#define STATUS_WAKE_SUCCESSFUL 0x11 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* Definitions for eeprom organization */ 6662306a36Sopenharmony_ci#define CONFIGURATION_ZONE 0 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/* Definitions for Indexes common to all commands */ 6962306a36Sopenharmony_ci#define RSP_DATA_IDX 1 /* buffer index of data in response */ 7062306a36Sopenharmony_ci#define DATA_SLOT_2 2 /* used for ECDH private key */ 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci/* Definitions for the device lock state */ 7362306a36Sopenharmony_ci#define DEVICE_LOCK_ADDR 0x15 7462306a36Sopenharmony_ci#define LOCK_VALUE_IDX (RSP_DATA_IDX + 2) 7562306a36Sopenharmony_ci#define LOCK_CONFIG_IDX (RSP_DATA_IDX + 3) 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci/* 7862306a36Sopenharmony_ci * Wake High delay to data communication (microseconds). SDA should be stable 7962306a36Sopenharmony_ci * high for this entire duration. 8062306a36Sopenharmony_ci */ 8162306a36Sopenharmony_ci#define TWHI_MIN 1500 8262306a36Sopenharmony_ci#define TWHI_MAX 1550 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci/* Wake Low duration */ 8562306a36Sopenharmony_ci#define TWLO_USEC 60 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci/* Command execution time (milliseconds) */ 8862306a36Sopenharmony_ci#define MAX_EXEC_TIME_ECDH 58 8962306a36Sopenharmony_ci#define MAX_EXEC_TIME_GENKEY 115 9062306a36Sopenharmony_ci#define MAX_EXEC_TIME_READ 1 9162306a36Sopenharmony_ci#define MAX_EXEC_TIME_RANDOM 50 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci/* Command opcode */ 9462306a36Sopenharmony_ci#define OPCODE_ECDH 0x43 9562306a36Sopenharmony_ci#define OPCODE_GENKEY 0x40 9662306a36Sopenharmony_ci#define OPCODE_READ 0x02 9762306a36Sopenharmony_ci#define OPCODE_RANDOM 0x1b 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* Definitions for the READ Command */ 10062306a36Sopenharmony_ci#define READ_COUNT 7 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci/* Definitions for the RANDOM Command */ 10362306a36Sopenharmony_ci#define RANDOM_COUNT 7 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* Definitions for the GenKey Command */ 10662306a36Sopenharmony_ci#define GENKEY_COUNT 7 10762306a36Sopenharmony_ci#define GENKEY_MODE_PRIVATE 0x04 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* Definitions for the ECDH Command */ 11062306a36Sopenharmony_ci#define ECDH_COUNT 71 11162306a36Sopenharmony_ci#define ECDH_PREFIX_MODE 0x00 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/* Used for binding tfm objects to i2c clients. */ 11462306a36Sopenharmony_cistruct atmel_ecc_driver_data { 11562306a36Sopenharmony_ci struct list_head i2c_client_list; 11662306a36Sopenharmony_ci spinlock_t i2c_list_lock; 11762306a36Sopenharmony_ci} ____cacheline_aligned; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/** 12062306a36Sopenharmony_ci * atmel_i2c_client_priv - i2c_client private data 12162306a36Sopenharmony_ci * @client : pointer to i2c client device 12262306a36Sopenharmony_ci * @i2c_client_list_node: part of i2c_client_list 12362306a36Sopenharmony_ci * @lock : lock for sending i2c commands 12462306a36Sopenharmony_ci * @wake_token : wake token array of zeros 12562306a36Sopenharmony_ci * @wake_token_sz : size in bytes of the wake_token 12662306a36Sopenharmony_ci * @tfm_count : number of active crypto transformations on i2c client 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * Reads and writes from/to the i2c client are sequential. The first byte 12962306a36Sopenharmony_ci * transmitted to the device is treated as the byte size. Any attempt to send 13062306a36Sopenharmony_ci * more than this number of bytes will cause the device to not ACK those bytes. 13162306a36Sopenharmony_ci * After the host writes a single command byte to the input buffer, reads are 13262306a36Sopenharmony_ci * prohibited until after the device completes command execution. Use a mutex 13362306a36Sopenharmony_ci * when sending i2c commands. 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_cistruct atmel_i2c_client_priv { 13662306a36Sopenharmony_ci struct i2c_client *client; 13762306a36Sopenharmony_ci struct list_head i2c_client_list_node; 13862306a36Sopenharmony_ci struct mutex lock; 13962306a36Sopenharmony_ci u8 wake_token[WAKE_TOKEN_MAX_SIZE]; 14062306a36Sopenharmony_ci size_t wake_token_sz; 14162306a36Sopenharmony_ci atomic_t tfm_count ____cacheline_aligned; 14262306a36Sopenharmony_ci struct hwrng hwrng; 14362306a36Sopenharmony_ci}; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci/** 14662306a36Sopenharmony_ci * atmel_i2c_work_data - data structure representing the work 14762306a36Sopenharmony_ci * @ctx : transformation context. 14862306a36Sopenharmony_ci * @cbk : pointer to a callback function to be invoked upon completion of this 14962306a36Sopenharmony_ci * request. This has the form: 15062306a36Sopenharmony_ci * callback(struct atmel_i2c_work_data *work_data, void *areq, u8 status) 15162306a36Sopenharmony_ci * where: 15262306a36Sopenharmony_ci * @work_data: data structure representing the work 15362306a36Sopenharmony_ci * @areq : optional pointer to an argument passed with the original 15462306a36Sopenharmony_ci * request. 15562306a36Sopenharmony_ci * @status : status returned from the i2c client device or i2c error. 15662306a36Sopenharmony_ci * @areq: optional pointer to a user argument for use at callback time. 15762306a36Sopenharmony_ci * @work: describes the task to be executed. 15862306a36Sopenharmony_ci * @cmd : structure used for communicating with the device. 15962306a36Sopenharmony_ci */ 16062306a36Sopenharmony_cistruct atmel_i2c_work_data { 16162306a36Sopenharmony_ci void *ctx; 16262306a36Sopenharmony_ci struct i2c_client *client; 16362306a36Sopenharmony_ci void (*cbk)(struct atmel_i2c_work_data *work_data, void *areq, 16462306a36Sopenharmony_ci int status); 16562306a36Sopenharmony_ci void *areq; 16662306a36Sopenharmony_ci struct work_struct work; 16762306a36Sopenharmony_ci struct atmel_i2c_cmd cmd; 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciint atmel_i2c_probe(struct i2c_client *client); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_civoid atmel_i2c_enqueue(struct atmel_i2c_work_data *work_data, 17362306a36Sopenharmony_ci void (*cbk)(struct atmel_i2c_work_data *work_data, 17462306a36Sopenharmony_ci void *areq, int status), 17562306a36Sopenharmony_ci void *areq); 17662306a36Sopenharmony_civoid atmel_i2c_flush_queue(void); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ciint atmel_i2c_send_receive(struct i2c_client *client, struct atmel_i2c_cmd *cmd); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_civoid atmel_i2c_init_read_cmd(struct atmel_i2c_cmd *cmd); 18162306a36Sopenharmony_civoid atmel_i2c_init_random_cmd(struct atmel_i2c_cmd *cmd); 18262306a36Sopenharmony_civoid atmel_i2c_init_genkey_cmd(struct atmel_i2c_cmd *cmd, u16 keyid); 18362306a36Sopenharmony_ciint atmel_i2c_init_ecdh_cmd(struct atmel_i2c_cmd *cmd, 18462306a36Sopenharmony_ci struct scatterlist *pubkey); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#endif /* __ATMEL_I2C_H__ */ 187