162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * i2c Support for Atmel's AT91 Two-Wire Interface (TWI) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2011 Weinmann Medical GmbH 662306a36Sopenharmony_ci * Author: Nikolaus Voss <n.voss@weinmann.de> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Evolved from original work by: 962306a36Sopenharmony_ci * Copyright (C) 2004 Rick Bronson 1062306a36Sopenharmony_ci * Converted to 2.6 by Andrew Victor <andrew@sanpeople.com> 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Borrowed heavily from original work by: 1362306a36Sopenharmony_ci * Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/clk.h> 1762306a36Sopenharmony_ci#include <linux/completion.h> 1862306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1962306a36Sopenharmony_ci#include <linux/dmaengine.h> 2062306a36Sopenharmony_ci#include <linux/i2c.h> 2162306a36Sopenharmony_ci#include <linux/platform_device.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#define AT91_I2C_TIMEOUT msecs_to_jiffies(100) /* transfer timeout */ 2462306a36Sopenharmony_ci#define AT91_I2C_DMA_THRESHOLD 8 /* enable DMA if transfer size is bigger than this threshold */ 2562306a36Sopenharmony_ci#define AUTOSUSPEND_TIMEOUT 2000 2662306a36Sopenharmony_ci#define AT91_I2C_MAX_ALT_CMD_DATA_SIZE 256 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* AT91 TWI register definitions */ 2962306a36Sopenharmony_ci#define AT91_TWI_CR 0x0000 /* Control Register */ 3062306a36Sopenharmony_ci#define AT91_TWI_START BIT(0) /* Send a Start Condition */ 3162306a36Sopenharmony_ci#define AT91_TWI_STOP BIT(1) /* Send a Stop Condition */ 3262306a36Sopenharmony_ci#define AT91_TWI_MSEN BIT(2) /* Master Transfer Enable */ 3362306a36Sopenharmony_ci#define AT91_TWI_MSDIS BIT(3) /* Master Transfer Disable */ 3462306a36Sopenharmony_ci#define AT91_TWI_SVEN BIT(4) /* Slave Transfer Enable */ 3562306a36Sopenharmony_ci#define AT91_TWI_SVDIS BIT(5) /* Slave Transfer Disable */ 3662306a36Sopenharmony_ci#define AT91_TWI_QUICK BIT(6) /* SMBus quick command */ 3762306a36Sopenharmony_ci#define AT91_TWI_SWRST BIT(7) /* Software Reset */ 3862306a36Sopenharmony_ci#define AT91_TWI_CLEAR BIT(15) /* Bus clear command */ 3962306a36Sopenharmony_ci#define AT91_TWI_ACMEN BIT(16) /* Alternative Command Mode Enable */ 4062306a36Sopenharmony_ci#define AT91_TWI_ACMDIS BIT(17) /* Alternative Command Mode Disable */ 4162306a36Sopenharmony_ci#define AT91_TWI_THRCLR BIT(24) /* Transmit Holding Register Clear */ 4262306a36Sopenharmony_ci#define AT91_TWI_RHRCLR BIT(25) /* Receive Holding Register Clear */ 4362306a36Sopenharmony_ci#define AT91_TWI_LOCKCLR BIT(26) /* Lock Clear */ 4462306a36Sopenharmony_ci#define AT91_TWI_FIFOEN BIT(28) /* FIFO Enable */ 4562306a36Sopenharmony_ci#define AT91_TWI_FIFODIS BIT(29) /* FIFO Disable */ 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define AT91_TWI_MMR 0x0004 /* Master Mode Register */ 4862306a36Sopenharmony_ci#define AT91_TWI_IADRSZ_1 0x0100 /* Internal Device Address Size */ 4962306a36Sopenharmony_ci#define AT91_TWI_MREAD BIT(12) /* Master Read Direction */ 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci#define AT91_TWI_SMR 0x0008 /* Slave Mode Register */ 5262306a36Sopenharmony_ci#define AT91_TWI_SMR_SADR_MAX 0x007f 5362306a36Sopenharmony_ci#define AT91_TWI_SMR_SADR(x) (((x) & AT91_TWI_SMR_SADR_MAX) << 16) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define AT91_TWI_IADR 0x000c /* Internal Address Register */ 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define AT91_TWI_CWGR 0x0010 /* Clock Waveform Generator Reg */ 5862306a36Sopenharmony_ci#define AT91_TWI_CWGR_HOLD_MAX 0x1f 5962306a36Sopenharmony_ci#define AT91_TWI_CWGR_HOLD(x) (((x) & AT91_TWI_CWGR_HOLD_MAX) << 24) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define AT91_TWI_SR 0x0020 /* Status Register */ 6262306a36Sopenharmony_ci#define AT91_TWI_TXCOMP BIT(0) /* Transmission Complete */ 6362306a36Sopenharmony_ci#define AT91_TWI_RXRDY BIT(1) /* Receive Holding Register Ready */ 6462306a36Sopenharmony_ci#define AT91_TWI_TXRDY BIT(2) /* Transmit Holding Register Ready */ 6562306a36Sopenharmony_ci#define AT91_TWI_SVREAD BIT(3) /* Slave Read */ 6662306a36Sopenharmony_ci#define AT91_TWI_SVACC BIT(4) /* Slave Access */ 6762306a36Sopenharmony_ci#define AT91_TWI_OVRE BIT(6) /* Overrun Error */ 6862306a36Sopenharmony_ci#define AT91_TWI_UNRE BIT(7) /* Underrun Error */ 6962306a36Sopenharmony_ci#define AT91_TWI_NACK BIT(8) /* Not Acknowledged */ 7062306a36Sopenharmony_ci#define AT91_TWI_EOSACC BIT(11) /* End Of Slave Access */ 7162306a36Sopenharmony_ci#define AT91_TWI_LOCK BIT(23) /* TWI Lock due to Frame Errors */ 7262306a36Sopenharmony_ci#define AT91_TWI_SCL BIT(24) /* TWI SCL status */ 7362306a36Sopenharmony_ci#define AT91_TWI_SDA BIT(25) /* TWI SDA status */ 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci#define AT91_TWI_INT_MASK \ 7662306a36Sopenharmony_ci (AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK \ 7762306a36Sopenharmony_ci | AT91_TWI_SVACC | AT91_TWI_EOSACC) 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define AT91_TWI_IER 0x0024 /* Interrupt Enable Register */ 8062306a36Sopenharmony_ci#define AT91_TWI_IDR 0x0028 /* Interrupt Disable Register */ 8162306a36Sopenharmony_ci#define AT91_TWI_IMR 0x002c /* Interrupt Mask Register */ 8262306a36Sopenharmony_ci#define AT91_TWI_RHR 0x0030 /* Receive Holding Register */ 8362306a36Sopenharmony_ci#define AT91_TWI_THR 0x0034 /* Transmit Holding Register */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci#define AT91_TWI_ACR 0x0040 /* Alternative Command Register */ 8662306a36Sopenharmony_ci#define AT91_TWI_ACR_DATAL_MASK GENMASK(15, 0) 8762306a36Sopenharmony_ci#define AT91_TWI_ACR_DATAL(len) ((len) & AT91_TWI_ACR_DATAL_MASK) 8862306a36Sopenharmony_ci#define AT91_TWI_ACR_DIR BIT(8) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#define AT91_TWI_FILTR 0x0044 9162306a36Sopenharmony_ci#define AT91_TWI_FILTR_FILT BIT(0) 9262306a36Sopenharmony_ci#define AT91_TWI_FILTR_PADFEN BIT(1) 9362306a36Sopenharmony_ci#define AT91_TWI_FILTR_THRES(v) ((v) << 8) 9462306a36Sopenharmony_ci#define AT91_TWI_FILTR_THRES_MAX 7 9562306a36Sopenharmony_ci#define AT91_TWI_FILTR_THRES_MASK GENMASK(10, 8) 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define AT91_TWI_FMR 0x0050 /* FIFO Mode Register */ 9862306a36Sopenharmony_ci#define AT91_TWI_FMR_TXRDYM(mode) (((mode) & 0x3) << 0) 9962306a36Sopenharmony_ci#define AT91_TWI_FMR_TXRDYM_MASK (0x3 << 0) 10062306a36Sopenharmony_ci#define AT91_TWI_FMR_RXRDYM(mode) (((mode) & 0x3) << 4) 10162306a36Sopenharmony_ci#define AT91_TWI_FMR_RXRDYM_MASK (0x3 << 4) 10262306a36Sopenharmony_ci#define AT91_TWI_ONE_DATA 0x0 10362306a36Sopenharmony_ci#define AT91_TWI_TWO_DATA 0x1 10462306a36Sopenharmony_ci#define AT91_TWI_FOUR_DATA 0x2 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#define AT91_TWI_FLR 0x0054 /* FIFO Level Register */ 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#define AT91_TWI_FSR 0x0060 /* FIFO Status Register */ 10962306a36Sopenharmony_ci#define AT91_TWI_FIER 0x0064 /* FIFO Interrupt Enable Register */ 11062306a36Sopenharmony_ci#define AT91_TWI_FIDR 0x0068 /* FIFO Interrupt Disable Register */ 11162306a36Sopenharmony_ci#define AT91_TWI_FIMR 0x006c /* FIFO Interrupt Mask Register */ 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci#define AT91_TWI_VER 0x00fc /* Version Register */ 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistruct at91_twi_pdata { 11662306a36Sopenharmony_ci unsigned clk_max_div; 11762306a36Sopenharmony_ci unsigned clk_offset; 11862306a36Sopenharmony_ci bool has_unre_flag; 11962306a36Sopenharmony_ci bool has_alt_cmd; 12062306a36Sopenharmony_ci bool has_hold_field; 12162306a36Sopenharmony_ci bool has_dig_filtr; 12262306a36Sopenharmony_ci bool has_adv_dig_filtr; 12362306a36Sopenharmony_ci bool has_ana_filtr; 12462306a36Sopenharmony_ci bool has_clear_cmd; 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistruct at91_twi_dma { 12862306a36Sopenharmony_ci struct dma_chan *chan_rx; 12962306a36Sopenharmony_ci struct dma_chan *chan_tx; 13062306a36Sopenharmony_ci struct scatterlist sg[2]; 13162306a36Sopenharmony_ci struct dma_async_tx_descriptor *data_desc; 13262306a36Sopenharmony_ci enum dma_data_direction direction; 13362306a36Sopenharmony_ci bool buf_mapped; 13462306a36Sopenharmony_ci bool xfer_in_progress; 13562306a36Sopenharmony_ci}; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cistruct at91_twi_dev { 13862306a36Sopenharmony_ci struct device *dev; 13962306a36Sopenharmony_ci void __iomem *base; 14062306a36Sopenharmony_ci struct completion cmd_complete; 14162306a36Sopenharmony_ci struct clk *clk; 14262306a36Sopenharmony_ci u8 *buf; 14362306a36Sopenharmony_ci size_t buf_len; 14462306a36Sopenharmony_ci struct i2c_msg *msg; 14562306a36Sopenharmony_ci int irq; 14662306a36Sopenharmony_ci unsigned imr; 14762306a36Sopenharmony_ci unsigned transfer_status; 14862306a36Sopenharmony_ci struct i2c_adapter adapter; 14962306a36Sopenharmony_ci unsigned twi_cwgr_reg; 15062306a36Sopenharmony_ci struct at91_twi_pdata *pdata; 15162306a36Sopenharmony_ci bool use_dma; 15262306a36Sopenharmony_ci bool use_alt_cmd; 15362306a36Sopenharmony_ci bool recv_len_abort; 15462306a36Sopenharmony_ci u32 fifo_size; 15562306a36Sopenharmony_ci struct at91_twi_dma dma; 15662306a36Sopenharmony_ci bool slave_detected; 15762306a36Sopenharmony_ci struct i2c_bus_recovery_info rinfo; 15862306a36Sopenharmony_ci#ifdef CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL 15962306a36Sopenharmony_ci unsigned smr; 16062306a36Sopenharmony_ci struct i2c_client *slave; 16162306a36Sopenharmony_ci#endif 16262306a36Sopenharmony_ci bool enable_dig_filt; 16362306a36Sopenharmony_ci bool enable_ana_filt; 16462306a36Sopenharmony_ci u32 filter_width; 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ciunsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg); 16862306a36Sopenharmony_civoid at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val); 16962306a36Sopenharmony_civoid at91_disable_twi_interrupts(struct at91_twi_dev *dev); 17062306a36Sopenharmony_civoid at91_twi_irq_save(struct at91_twi_dev *dev); 17162306a36Sopenharmony_civoid at91_twi_irq_restore(struct at91_twi_dev *dev); 17262306a36Sopenharmony_civoid at91_init_twi_bus(struct at91_twi_dev *dev); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_civoid at91_init_twi_bus_master(struct at91_twi_dev *dev); 17562306a36Sopenharmony_ciint at91_twi_probe_master(struct platform_device *pdev, u32 phy_addr, 17662306a36Sopenharmony_ci struct at91_twi_dev *dev); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci#ifdef CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL 17962306a36Sopenharmony_civoid at91_init_twi_bus_slave(struct at91_twi_dev *dev); 18062306a36Sopenharmony_ciint at91_twi_probe_slave(struct platform_device *pdev, u32 phy_addr, 18162306a36Sopenharmony_ci struct at91_twi_dev *dev); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#else 18462306a36Sopenharmony_cistatic inline void at91_init_twi_bus_slave(struct at91_twi_dev *dev) {} 18562306a36Sopenharmony_cistatic inline int at91_twi_probe_slave(struct platform_device *pdev, 18662306a36Sopenharmony_ci u32 phy_addr, struct at91_twi_dev *dev) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci return -EINVAL; 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci#endif 192