blob: 9e5296fcce09c3e3a822cd61e7caac19d8dab8fc [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Copyright (c) 2017-2019, STMicroelectronics
*/
#ifndef __STM32_I2C_H
#define __STM32_I2C_H
#include <drivers/stm32_gpio.h>
#include <kernel/dt.h>
#include <mm/core_memprot.h>
#include <stdbool.h>
#include <stdint.h>
#include <util.h>
#include <types_ext.h>
/*
* I2C specification values as per version 6.0, 4th of April 2014 [1],
* table 10 page 48: Characteristics of the SDA and SCL bus lines for
* Standard, Fast, and Fast-mode Plus I2C-bus devices.
*
* [1] https://www.nxp.com/docs/en/user-guide/UM10204.pdf
*/
enum i2c_speed_e {
I2C_SPEED_STANDARD, /* 100 kHz */
I2C_SPEED_FAST, /* 400 kHz */
I2C_SPEED_FAST_PLUS, /* 1 MHz */
};
#define I2C_STANDARD_RATE 100000
#define I2C_FAST_RATE 400000
#define I2C_FAST_PLUS_RATE 1000000
/*
* Initialization configuration structure for the STM32 I2C bus.
* Refer to the SoC Reference Manual for more details on configuration items.
*
* @dt_status: non-secure/secure status read from DT
* @pbase: I2C interface base address
* @clock: I2C bus/interface clock
* @addr_mode_10b_not_7b: True if 10bit addressing mode, otherwise 7bit mode
* @own_address1: 7-bit or 10-bit first device own address.
* @dual_address_mode: True if enabling Dual-Addressing mode
* @own_address2: 7-bit second device own address (Dual-Addressing mode)
* @own_address2_masks: Acknowledge mask address (Dual-Addressing mode)
* @general_call_mode: True if enbling General-Call mode
* @no_stretch_mode: If enabling the No-Stretch mode
* @rise_time: SCL clock pin rising time in nanoseconds
* @fall_time: SCL clock pin falling time in nanoseconds
* @speed_mode: I2C clock source frequency mode
* @analog_filter: True if enabling analog filter
* @digital_filter_coef: filter coef (below STM32_I2C_DIGITAL_FILTER_MAX)
*/
struct stm32_i2c_init_s {
unsigned int dt_status;
paddr_t pbase;
unsigned int clock;
bool addr_mode_10b_not_7b;
uint32_t own_address1;
bool dual_address_mode;
uint32_t own_address2;
uint32_t own_address2_masks;
bool general_call_mode;
bool no_stretch_mode;
uint32_t rise_time;
uint32_t fall_time;
enum i2c_speed_e speed_mode;
bool analog_filter;
uint8_t digital_filter_coef;
};
enum i2c_state_e {
I2C_STATE_RESET, /* Not yet initialized */
I2C_STATE_READY, /* Ready for use */
I2C_STATE_BUSY, /* Internal process ongoing */
I2C_STATE_BUSY_TX, /* Data Transmission ongoing */
I2C_STATE_BUSY_RX, /* Data Reception ongoing */
I2C_STATE_SUSPENDED, /* Bus is supended */
};
enum i2c_mode_e {
I2C_MODE_NONE, /* No active communication */
I2C_MODE_MASTER, /* Communication in Master Mode */
I2C_MODE_SLAVE, /* Communication in Slave Mode */
I2C_MODE_MEM, /* Communication in Memory Mode */
};
#define I2C_ERROR_NONE 0x0
#define I2C_ERROR_BERR BIT(0)
#define I2C_ERROR_ARLO BIT(1)
#define I2C_ERROR_ACKF BIT(2)
#define I2C_ERROR_OVR BIT(3)
#define I2C_ERROR_DMA BIT(4)
#define I2C_ERROR_TIMEOUT BIT(5)
#define I2C_ERROR_SIZE BIT(6)
/* I2C interface registers state */
struct i2c_cfg {
uint32_t timingr;
uint32_t oar1;
uint32_t oar2;
uint32_t cr1;
uint32_t cr2;
};
/*
* I2C bus device
* @base: I2C SoC registers base address
* @dt_status: non-secure/secure status read from DT
* @clock: clock ID
* @i2c_state: Driver state ID I2C_STATE_*
* @i2c_err: Last error code I2C_ERROR_*
* @sec_cfg: I2C regsiters configuration storage
* @pinctrl: PINCTRLs configuration for the I2C PINs
* @pinctrl_count: Number of PINCTRLs elements
*/
struct i2c_handle_s {
struct io_pa_va base;
unsigned int dt_status;
unsigned long clock;
enum i2c_state_e i2c_state;
uint32_t i2c_err;
struct i2c_cfg sec_cfg;
struct stm32_pinctrl *pinctrl;
size_t pinctrl_count;
};
/* STM32 specific defines */
#define STM32_I2C_SPEED_DEFAULT I2C_SPEED_STANDARD
#define STM32_I2C_RISE_TIME_DEFAULT 25 /* ns */
#define STM32_I2C_FALL_TIME_DEFAULT 10 /* ns */
#define STM32_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */
#define STM32_I2C_ANALOG_FILTER_DELAY_MAX 260 /* ns */
#define STM32_I2C_DIGITAL_FILTER_MAX 16
/*
* Fill struct stm32_i2c_init_s from DT content for a given I2C node
*
* @fdt: Reference to DT
* @node: Target I2C node in the DT
* @init: Output stm32_i2c_init_s structure
* @pinctrl: Reference to output pinctrl array
* @pinctrl_count: Input @pinctrl array size, output expected size
* Return 0 on success else a negative value
*/
int stm32_i2c_get_setup_from_fdt(void *fdt, int node,
struct stm32_i2c_init_s *init,
struct stm32_pinctrl **pinctrl,
size_t *pinctrl_count);
/*
* Initialize I2C bus handle from input configuration directives
*
* @hi2c: Reference to I2C bus handle structure
* @init_data: Input stm32_i2c_init_s structure
* Return 0 on success else a negative value
*/
int stm32_i2c_init(struct i2c_handle_s *hi2c,
struct stm32_i2c_init_s *init_data);
/*
* Send a memory write request in the I2C bus
*
* @hi2c: Reference to I2C bus handle structure
* @dev_addr: Target device I2C address
* @mem_addr: Target device memory address
* @mem_addr_size: Byte size of internal memory address
* @p_data: Data to be written
* @size: Byte size of the data to be written
* @timeout_ms: Timeout value in milliseconds
* Return 0 on success else a negative value
*/
int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint32_t dev_addr,
uint32_t mem_addr, uint32_t mem_addr_size,
uint8_t *p_data, size_t size, unsigned int timeout_ms);
/*
* Send a memory read request in the I2C bus
*
* @hi2c: Reference to I2C bus handle structure
* @dev_addr: Target device I2C address
* @mem_addr: Target device memory address
* @mem_addr_size: Byte size of internal memory address
* @p_data: Data to be read
* @size: Byte size of the data to be read
* @timeout_ms: Timeout value in milliseconds
* Return 0 on success else a negative value
*/
int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint32_t dev_addr,
uint32_t mem_addr, uint32_t mem_addr_size,
uint8_t *p_data, size_t size, unsigned int timeout_ms);
/*
* Send a data buffer in master mode on the I2C bus
*
* @hi2c: Reference to I2C bus handle structure
* @dev_addr: Target device I2C address
* @p_data: Data to be sent
* @size: Byte size of the data to be sent
* @timeout_ms: Timeout value in milliseconds
* Return 0 on success else a negative value
*/
int stm32_i2c_master_transmit(struct i2c_handle_s *hi2c, uint32_t dev_addr,
uint8_t *p_data, size_t size,
unsigned int timeout_ms);
/*
* Receive a data buffer in master mode on the I2C bus
*
* @hi2c: Reference to I2C bus handle structure
* @dev_addr: Target device I2C address
* @p_data: Buffer for the received data
* @size: Byte size of the data to be received
* @timeout_ms: Timeout value in milliseconds
* Return 0 on success else a negative value
*/
int stm32_i2c_master_receive(struct i2c_handle_s *hi2c, uint32_t dev_addr,
uint8_t *p_data, size_t size,
unsigned int timeout_ms);
/*
* Optimized 1 byte read/write function for unpaged sequences.
* 8-bit addressing mode / single byte transferred / use default I2C timeout.
* Return 0 on success else a negative value
*/
int stm32_i2c_read_write_membyte(struct i2c_handle_s *hi2c, uint16_t dev_addr,
unsigned int mem_addr, uint8_t *p_data,
bool write);
/*
* Check link with the I2C device
*
* @hi2c: Reference to I2C bus handle structure
* @dev_addr: Target device I2C address
* @trials: Number of attempts of I2C request
* @timeout_ms: Timeout value in milliseconds for each I2C request
* Return 0 on success else a negative value
*/
bool stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint32_t dev_addr,
unsigned int trials, unsigned int timeout_ms);
/*
* Suspend I2C bus.
* Bus owner is reponsible for calling stm32_i2c_suspend().
*
* @hi2c: Reference to I2C bus handle structure
*/
void stm32_i2c_suspend(struct i2c_handle_s *hi2c);
/*
* Resume I2C bus.
* Bus owner is reponsible for calling stm32_i2c_resume().
*
* @hi2c: Reference to I2C bus handle structure
*/
void stm32_i2c_resume(struct i2c_handle_s *hi2c);
/*
* Return true if I2C bus is enabled for secure world only, false otherwise
*/
static inline bool i2c_is_secure(struct i2c_handle_s *hi2c)
{
return hi2c->dt_status == DT_STATUS_OK_SEC;
}
#endif /* __STM32_I2C_H */