linux/drivers/i2c/busses/i2c-stm32f7.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for STMicroelectronics STM32F7 I2C controller
 *
 * This I2C controller is described in the STM32F75xxx and STM32F74xxx Soc
 * reference manual.
 * Please see below a link to the documentation:
 * http://www.st.com/resource/en/reference_manual/dm00124865.pdf
 *
 * Copyright (C) M'boumba Cedric Madianga 2017
 * Copyright (C) STMicroelectronics 2017
 * Author: M'boumba Cedric Madianga <[email protected]>
 *
 * This driver is based on i2c-stm32f4.c
 *
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include "i2c-stm32.h"

/* STM32F7 I2C registers */
#define STM32F7_I2C_CR1
#define STM32F7_I2C_CR2
#define STM32F7_I2C_OAR1
#define STM32F7_I2C_OAR2
#define STM32F7_I2C_PECR
#define STM32F7_I2C_TIMINGR
#define STM32F7_I2C_ISR
#define STM32F7_I2C_ICR
#define STM32F7_I2C_RXDR
#define STM32F7_I2C_TXDR

/* STM32F7 I2C control 1 */
#define STM32_I2C_CR1_FMP
#define STM32F7_I2C_CR1_PECEN
#define STM32F7_I2C_CR1_ALERTEN
#define STM32F7_I2C_CR1_SMBHEN
#define STM32F7_I2C_CR1_WUPEN
#define STM32F7_I2C_CR1_SBC
#define STM32F7_I2C_CR1_RXDMAEN
#define STM32F7_I2C_CR1_TXDMAEN
#define STM32F7_I2C_CR1_ANFOFF
#define STM32F7_I2C_CR1_DNF_MASK
#define STM32F7_I2C_CR1_DNF(n)
#define STM32F7_I2C_CR1_ERRIE
#define STM32F7_I2C_CR1_TCIE
#define STM32F7_I2C_CR1_STOPIE
#define STM32F7_I2C_CR1_NACKIE
#define STM32F7_I2C_CR1_ADDRIE
#define STM32F7_I2C_CR1_RXIE
#define STM32F7_I2C_CR1_TXIE
#define STM32F7_I2C_CR1_PE
#define STM32F7_I2C_ALL_IRQ_MASK
#define STM32F7_I2C_XFER_IRQ_MASK

/* STM32F7 I2C control 2 */
#define STM32F7_I2C_CR2_PECBYTE
#define STM32F7_I2C_CR2_RELOAD
#define STM32F7_I2C_CR2_NBYTES_MASK
#define STM32F7_I2C_CR2_NBYTES(n)
#define STM32F7_I2C_CR2_NACK
#define STM32F7_I2C_CR2_STOP
#define STM32F7_I2C_CR2_START
#define STM32F7_I2C_CR2_HEAD10R
#define STM32F7_I2C_CR2_ADD10
#define STM32F7_I2C_CR2_RD_WRN
#define STM32F7_I2C_CR2_SADD10_MASK
#define STM32F7_I2C_CR2_SADD10(n)
#define STM32F7_I2C_CR2_SADD7_MASK
#define STM32F7_I2C_CR2_SADD7(n)

/* STM32F7 I2C Own Address 1 */
#define STM32F7_I2C_OAR1_OA1EN
#define STM32F7_I2C_OAR1_OA1MODE
#define STM32F7_I2C_OAR1_OA1_10_MASK
#define STM32F7_I2C_OAR1_OA1_10(n)
#define STM32F7_I2C_OAR1_OA1_7_MASK
#define STM32F7_I2C_OAR1_OA1_7(n)
#define STM32F7_I2C_OAR1_MASK

/* STM32F7 I2C Own Address 2 */
#define STM32F7_I2C_OAR2_OA2EN
#define STM32F7_I2C_OAR2_OA2MSK_MASK
#define STM32F7_I2C_OAR2_OA2MSK(n)
#define STM32F7_I2C_OAR2_OA2_7_MASK
#define STM32F7_I2C_OAR2_OA2_7(n)
#define STM32F7_I2C_OAR2_MASK

/* STM32F7 I2C Interrupt Status */
#define STM32F7_I2C_ISR_ADDCODE_MASK
#define STM32F7_I2C_ISR_ADDCODE_GET(n)
#define STM32F7_I2C_ISR_DIR
#define STM32F7_I2C_ISR_BUSY
#define STM32F7_I2C_ISR_ALERT
#define STM32F7_I2C_ISR_PECERR
#define STM32F7_I2C_ISR_ARLO
#define STM32F7_I2C_ISR_BERR
#define STM32F7_I2C_ISR_TCR
#define STM32F7_I2C_ISR_TC
#define STM32F7_I2C_ISR_STOPF
#define STM32F7_I2C_ISR_NACKF
#define STM32F7_I2C_ISR_ADDR
#define STM32F7_I2C_ISR_RXNE
#define STM32F7_I2C_ISR_TXIS
#define STM32F7_I2C_ISR_TXE

/* STM32F7 I2C Interrupt Clear */
#define STM32F7_I2C_ICR_ALERTCF
#define STM32F7_I2C_ICR_PECCF
#define STM32F7_I2C_ICR_ARLOCF
#define STM32F7_I2C_ICR_BERRCF
#define STM32F7_I2C_ICR_STOPCF
#define STM32F7_I2C_ICR_NACKCF
#define STM32F7_I2C_ICR_ADDRCF

/* STM32F7 I2C Timing */
#define STM32F7_I2C_TIMINGR_PRESC(n)
#define STM32F7_I2C_TIMINGR_SCLDEL(n)
#define STM32F7_I2C_TIMINGR_SDADEL(n)
#define STM32F7_I2C_TIMINGR_SCLH(n)
#define STM32F7_I2C_TIMINGR_SCLL(n)

#define STM32F7_I2C_MAX_LEN
#define STM32F7_I2C_DMA_LEN_MIN
enum {};

#define STM32F7_I2C_DNF_DEFAULT
#define STM32F7_I2C_DNF_MAX

#define STM32F7_I2C_ANALOG_FILTER_DELAY_MIN
#define STM32F7_I2C_ANALOG_FILTER_DELAY_MAX

#define STM32F7_I2C_RISE_TIME_DEFAULT
#define STM32F7_I2C_FALL_TIME_DEFAULT

#define STM32F7_PRESC_MAX
#define STM32F7_SCLDEL_MAX
#define STM32F7_SDADEL_MAX
#define STM32F7_SCLH_MAX
#define STM32F7_SCLL_MAX

#define STM32F7_AUTOSUSPEND_DELAY

/**
 * struct stm32f7_i2c_regs - i2c f7 registers backup
 * @cr1: Control register 1
 * @cr2: Control register 2
 * @oar1: Own address 1 register
 * @oar2: Own address 2 register
 * @tmgr: Timing register
 */
struct stm32f7_i2c_regs {};

/**
 * struct stm32f7_i2c_spec - private i2c specification timing
 * @rate: I2C bus speed (Hz)
 * @fall_max: Max fall time of both SDA and SCL signals (ns)
 * @rise_max: Max rise time of both SDA and SCL signals (ns)
 * @hddat_min: Min data hold time (ns)
 * @vddat_max: Max data valid time (ns)
 * @sudat_min: Min data setup time (ns)
 * @l_min: Min low period of the SCL clock (ns)
 * @h_min: Min high period of the SCL clock (ns)
 */
struct stm32f7_i2c_spec {};

/**
 * struct stm32f7_i2c_setup - private I2C timing setup parameters
 * @speed_freq: I2C speed frequency  (Hz)
 * @clock_src: I2C clock source frequency (Hz)
 * @rise_time: Rise time (ns)
 * @fall_time: Fall time (ns)
 * @fmp_clr_offset: Fast Mode Plus clear register offset from set register
 * @single_it_line: Only a single IT line is used for both events/errors
 * @fmp_cr1_bit: Fast Mode Plus control is done via a bit in CR1
 */
struct stm32f7_i2c_setup {};

/**
 * struct stm32f7_i2c_timings - private I2C output parameters
 * @node: List entry
 * @presc: Prescaler value
 * @scldel: Data setup time
 * @sdadel: Data hold time
 * @sclh: SCL high period (master mode)
 * @scll: SCL low period (master mode)
 */
struct stm32f7_i2c_timings {};

/**
 * struct stm32f7_i2c_msg - client specific data
 * @addr: 8-bit or 10-bit slave addr, including r/w bit
 * @count: number of bytes to be transferred
 * @buf: data buffer
 * @result: result of the transfer
 * @stop: last I2C msg to be sent, i.e. STOP to be generated
 * @smbus: boolean to know if the I2C IP is used in SMBus mode
 * @size: type of SMBus protocol
 * @read_write: direction of SMBus protocol
 * SMBus block read and SMBus block write - block read process call protocols
 * @smbus_buf: buffer to be used for SMBus protocol transfer. It will
 * contain a maximum of 32 bytes of data + byte command + byte count + PEC
 * This buffer has to be 32-bit aligned to be compliant with memory address
 * register in DMA mode.
 */
struct stm32f7_i2c_msg {};

/**
 * struct stm32f7_i2c_alert - SMBus alert specific data
 * @setup: platform data for the smbus_alert i2c client
 * @ara: I2C slave device used to respond to the SMBus Alert with Alert
 * Response Address
 */
struct stm32f7_i2c_alert {};

/**
 * struct stm32f7_i2c_dev - private data of the controller
 * @adap: I2C adapter for this controller
 * @dev: device for this controller
 * @base: virtual memory area
 * @complete: completion of I2C message
 * @clk: hw i2c clock
 * @bus_rate: I2C clock frequency of the controller
 * @msg: Pointer to data to be written
 * @msg_num: number of I2C messages to be executed
 * @msg_id: message identifiant
 * @f7_msg: customized i2c msg for driver usage
 * @setup: I2C timing input setup
 * @timing: I2C computed timings
 * @slave: list of slave devices registered on the I2C bus
 * @slave_running: slave device currently used
 * @backup_regs: backup of i2c controller registers (for suspend/resume)
 * @slave_dir: transfer direction for the current slave device
 * @master_mode: boolean to know in which mode the I2C is running (master or
 * slave)
 * @dma: dma data
 * @use_dma: boolean to know if dma is used in the current transfer
 * @regmap: holds SYSCFG phandle for Fast Mode Plus bits
 * @fmp_sreg: register address for setting Fast Mode Plus bits
 * @fmp_creg: register address for clearing Fast Mode Plus bits
 * @fmp_mask: mask for Fast Mode Plus bits in set register
 * @wakeup_src: boolean to know if the device is a wakeup source
 * @smbus_mode: states that the controller is configured in SMBus mode
 * @host_notify_client: SMBus host-notify client
 * @analog_filter: boolean to indicate enabling of the analog filter
 * @dnf_dt: value of digital filter requested via dt
 * @dnf: value of digital filter to apply
 * @alert: SMBus alert specific data
 * @atomic: boolean indicating that current transfer is atomic
 */
struct stm32f7_i2c_dev {};

/*
 * All these values are coming from I2C Specification, Version 6.0, 4th of
 * April 2014.
 *
 * Table10. Characteristics of the SDA and SCL bus lines for Standard, Fast,
 * and Fast-mode Plus I2C-bus devices
 */
static struct stm32f7_i2c_spec stm32f7_i2c_specs[] =;

static const struct stm32f7_i2c_setup stm32f7_setup =;

static const struct stm32f7_i2c_setup stm32mp15_setup =;

static const struct stm32f7_i2c_setup stm32mp13_setup =;

static const struct stm32f7_i2c_setup stm32mp25_setup =;

static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask)
{}

static inline void stm32f7_i2c_clr_bits(void __iomem *reg, u32 mask)
{}

static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask)
{}

static struct stm32f7_i2c_spec *stm32f7_get_specs(u32 rate)
{}

#define RATE_MIN(rate)
static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
				      struct stm32f7_i2c_setup *setup,
				      struct stm32f7_i2c_timings *output)
{}

static u32 stm32f7_get_lower_rate(u32 rate)
{}

static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
				    struct stm32f7_i2c_setup *setup)
{}

static void stm32f7_i2c_disable_dma_req(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_dma_callback(void *arg)
{}

static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_write_tx_data(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_read_rx_data(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_smbus_reload(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_release_bus(struct i2c_adapter *i2c_adap)
{}

static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
				 struct i2c_msg *msg)
{}

static int stm32f7_i2c_smbus_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
				      unsigned short flags, u8 command,
				      union i2c_smbus_data *data)
{}

static void stm32f7_i2c_smbus_rep_start(struct stm32f7_i2c_dev *i2c_dev)
{}

static int stm32f7_i2c_smbus_check_pec(struct stm32f7_i2c_dev *i2c_dev)
{}

static bool stm32f7_i2c_is_addr_match(struct i2c_client *slave, u32 addcode)
{}

static void stm32f7_i2c_slave_start(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_slave_addr(struct stm32f7_i2c_dev *i2c_dev)
{}

static int stm32f7_i2c_get_slave_id(struct stm32f7_i2c_dev *i2c_dev,
				    struct i2c_client *slave, int *id)
{}

static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev,
					 struct i2c_client *slave, int *id)
{}

static bool stm32f7_i2c_is_slave_registered(struct stm32f7_i2c_dev *i2c_dev)
{}

static bool stm32f7_i2c_is_slave_busy(struct stm32f7_i2c_dev *i2c_dev)
{}

static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{}

static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{}

#define STM32F7_ERR_EVENTS
static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
{}

static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{}

static irqreturn_t stm32f7_i2c_isr_error_thread(int irq, void *data)
{}

static int stm32f7_i2c_wait_polling(struct stm32f7_i2c_dev *i2c_dev)
{}

static int stm32f7_i2c_xfer_core(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{}

static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{}

static int stm32f7_i2c_xfer_atomic(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{}

static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
				  unsigned short flags, char read_write,
				  u8 command, int size,
				  union i2c_smbus_data *data)
{}

static void stm32f7_i2c_enable_wakeup(struct stm32f7_i2c_dev *i2c_dev,
				      bool enable)
{}

static int stm32f7_i2c_reg_slave(struct i2c_client *slave)
{}

static int stm32f7_i2c_unreg_slave(struct i2c_client *slave)
{}

static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev,
					  bool enable)
{}

static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev,
					  struct stm32f7_i2c_dev *i2c_dev)
{}

static int stm32f7_i2c_enable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
{}

static int stm32f7_i2c_enable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{}

static void stm32f7_i2c_disable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{}

static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
{}

static const struct i2c_algorithm stm32f7_i2c_algo =;

static int stm32f7_i2c_probe(struct platform_device *pdev)
{}

static void stm32f7_i2c_remove(struct platform_device *pdev)
{}

static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
{}

static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
{}

static int __maybe_unused stm32f7_i2c_regs_backup(struct stm32f7_i2c_dev *i2c_dev)
{}

static int __maybe_unused stm32f7_i2c_regs_restore(struct stm32f7_i2c_dev *i2c_dev)
{}

static int __maybe_unused stm32f7_i2c_suspend(struct device *dev)
{}

static int __maybe_unused stm32f7_i2c_resume(struct device *dev)
{}

static const struct dev_pm_ops stm32f7_i2c_pm_ops =;

static const struct of_device_id stm32f7_i2c_match[] =;
MODULE_DEVICE_TABLE(of, stm32f7_i2c_match);

static struct platform_driver stm32f7_i2c_driver =;

module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();