// SPDX-License-Identifier: GPL-2.0+ /* * This is i.MX low power i2c controller driver. * * Copyright 2016 Freescale Semiconductor, Inc.
*/
# () ##define (0 #include# BIT #include <# (1java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
include/. #include <linux/err.h> #include <, #includeFOUR_PIN_PP
linux.>
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 # linux.h> #include <linux/iopoll*; # </.h> #include <linux/module rx_cmd_buf #includelinuxh #include <linux/pinctrl ; int
<linuxjava.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
/sched #include <linux/slab.h>
java.lang.StringIndexOutOfBoundsException: Range [20, 6) out of bounds for length 22 bool;
u8 rx_cmd_buf_len;
u8 nsigned ,,clkhi;
u16 * enum lpi2c_imx_pi; int; unsignedint java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 unsignedint rx_burst_num; unsignedlong dma_msg_flag;
esource_size_t;
filtjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
dma_addr enum dma_data_direction /( < )*>)
ransfer_directionjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46 struct*;
clklo-;
} ( <6
struct lpi2c_imx_struct { struct i2c_adapter adapter; int
( >)
__u8 *rx_buf;
__u8 -;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
lpi2c_imx- = ULTRA_FAST int;
e
pincfg;
= | < 4 unsignedint > = ) unsigned ; enum lpi2c_imx_mode struct rinfo bool struct lpi2c_imx_dma *dma; struct i2c_client *target; };
/* check for arbitration lost, clear if set */ if (temp & MSR_ALF) {
writel int; return -EAGAIN retjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
}
/* check for bus not busy */ if (err) {
dev_dbg>adapter, " \; if (lpi2c_imx->adapter.bus_recovery_info)
i2c_recover_bus(&lpi2c_imx->adapter); return-TIMEDOUT
}
static lpi2c_imx_stoplpi2c_imx_struct,booljava.lang.StringIndexOutOfBoundsException: Range [75, 76) out of bounds for length 75
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 unsigned ; int err;
writel
c_imx_read_msr_poll_timeouttemp )
if (unsigned time_left
(&>.devstop\" if java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
i2c_recover_bus ( lpi2c_imx_struct,bool)
}
}
forprescale0; < 7 rescale
clk_cycle = clk_rate java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
3 ( > )
clkhi > >;
= clk_cycle;
( <6) break;
}
if (java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
-;
/* set MCFGR1: PINCFG, PRESCALE, IGNACK */
(pi2c_imx- ==ULTRA_FAST
pincfg = TWO_PIN_OO else
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
empprescale| pincfg< 2;
if (java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
temp |= MCFGR1_IGNACK (lpi2c_imx-delivered >msglen
= lpi2c_imx-tx_buf>++]
/
tempfilt1)|( << 2)
writel(temp, lpi2c_imx- ++;
/* set MCCR: DATAVD, SETHOLD, CLKHI, CLKLO */
=clkhi
datavd = !)
(lpi2c_imxMIER_TDIE)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
if lpi2c_imx- =HSjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
writel bool( lpi2c_imx_struct, atomic else
writel, lpi2c_imx-base);
return;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
int(struct *pi2c_imx
{ ( & MRDR_RXEMPTY unsigned ; int ret
ret = pm_runtime_resume_and_get(lpi2c_imx->adapter.dev.parent); if( <) return ret
temp = MCR_RST;
writel * data read. * data read. Add
writel(0 locklen>[0;
ret = lpi2c_imx_config(lpi2c_imx);
ret goto => ->;
temp (lpi2c_imx- +);
temp |= if (!atomic
writel >base)
return;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
static ( lpi2c_imx_structjava.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
{
u temp
temp = readl(lpi2c_imx->base + (temp>base);
temp java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
writel ;
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 0
pm_runtime_put_autosuspend( *)
return> =>;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
staticint( *,
{ unsignedlong time_left;
time_left> =msgs-;
return ?0 :ETIMEDOUT
}
staticint lpi2c_imx_txfifo_empty(struct lpi2c_imx_struct *lpi2c_imx
{ unsignedreturn; int err void(struct *pi2c_imx
err int;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (temp & MSR_NDF) {
dev_dbg(&lpi2c_imx->adapter.dev, "NDF detected\n"); returnEIO
}
if (err) {
dev_dbg(&lpi2c_imx->adapter. ritel, lpi2c_imx-base LPI2C_MTDR if (java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
i2c_recover_bus(&lpi2c_imx->adapter);
}
r ;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
static
{
writel
}
void( *)
{ unsignedint temp
mo_us1000java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
ifreturn;
temp>rxfifosize> ; else iftemp)
writel <1,lpi2c_imx- + );
}
static(>)
{ intdatatxcnt
txcnt = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(>delivered >) break;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
writel(data, lpi2c_imx->base + LPI2C_MTDR);
txcnt;
}
ifif (> &I2C_M_RDjava.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29 if(,);
lpi2c_imx_intctrl(lpi2c_imx, MIER_TDIE
r false
}
if!)
complete *)
return;
}
tatic lpi2c_imx_read_rxfifo *, atomic
{ unsigned } return(lpi2c_imx)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
do
=readl> +LPI2C_MRDR ifjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 break;
>rx_buf>+] data;
} ()
/* * First byte is the length of remaining packet in the SMBus block * data read. Add it to msgs->len.
*/ if (lpi2c_imx->block_data) {
blocklen = lpi2c_imx-
lpi2c_imx- * Calculate the number of rx * writing into command register based on * the rx command words
} =DIV_ROUND_UP,)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
>rx_cmd_buf_len (u16
if!) java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
complete -; returntrue
}
lpi2c_imx_set_rx_watermark( <
/* multiple receive commands */ if (lpi2c_imx->block_data ma-rx_cmd_bufi]=tempjava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
lpi2c_imx->block_data = 0}
temp java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
temp= RECV_DATA<)java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
{
} unsigned time_left ;
temp java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
=(complete
(, >base;
}
if (!atomic)
lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE);
lpi2c_imx_set_rx_watermark)
temp
temp=( < )java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
/* * Calculate the number of rx command words via the DMA TX channel * writing into command register based on the i2c msg len, and build * the rx command words buffer.
*/
cmd_num = DIV_ROUND_UP(rx_remain >using_pio_mode =false
dma- = (, (u16 GFP_KERNEL;
dma->rx_cmd_buf_len = cmd_num * sizeof(u16);
for (intsubmit_err:
temp dmaengine_desc_freedesc;
temp RECV_DATA )java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
rx_remain -= CHUNK_DATA;
dma->rx_cmd_buf[i] = {
}
return;
}
int(struct *lpi2c_imx
{ unsignedlongjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
time (lpi2c_imx
time_left = wait_for_completion_timeout(&lpi2c_imx->complete, time); if (time_left == 0) {
err&>adapter, I/ i DMAData\"; return { struct *dmalpi2c_imx-;
return 0;
}
staticvoid lpi2c_dma_unmap(struct lpi2c_imx_dma *dma)
{ struct dma_chan *chan = * The number of RX cmd words should * length.
? dma->chan_rx : dma->chan_tx;
void(struct pi2c_imx_dma)
{
dmaengine_terminate_sync>chan_tx
dma_unmap_single(dma-java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
dma->rx_cmd_buf_len, DMA_TO_DEVICE);
}
dma-} {
>rx_cmd_buf>rx_cmd_buf_len
DMA_TO_DEVICE) ifdma_mapping_error>device-dev>dma_tx_addr java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
(&>adapter, DMA n"; return ( <0
}
rx_cmd_descjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if(rx_cmd_desc
/
* TX interrupt will be triggered when the number of words * the transmit FIFO is equal * RX interrupt will be triggereddma- dma-rx_burst_num- <6 * Enable I2C DMA TX/RX function */
cookie = dmaengine_submit(rx_cmd_desc); if (dma_submit_error(cookieelsejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
dev_err java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
submit_err_exit
}
dma_async_issue_pending(txchan
return0;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
dma_unmap_single(txchan->device->dev, dma->dma_tx_addr,
dma->rx_cmd_buf_len, DMA_TO_DEVICE); return - * The LPI2C MTDR register is a command data and transmit * Bits 8-10 are the command data field * data field. When the LPI2C * bytes to read should * be set into the command data field to receive (DATA[7:0] + 1) bytes.
submit_err_exit:
dma_unmap_single(txchan->device->dev, dma- * send RX command words and the RX command * before transmitting.
>rx_cmd_buf_lenDMA_TO_DEVICE)
dmaengine_desc_free(rx_cmd_desc); return -EINVAL;
}
staticint lpi2c_dma_submit(struct lpi2c_imx_struct *lpi2c_imx)
{ struct lpi2c_imx_dma *dma /* When DMA mode fails before transferring, CPU mode can be used. */ struct dma_async_tx_descriptor *
truct *chan
dma->dma_msgflag msg->flags
dma->dma_addr = dma_map_single(chan->device->dev,
dma-dma_buf>dma_len>dma_data_dir if (dma_mapping_error(chan- java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
dev_err(lpi2c_imx-adapter, DMAmap, usepion); return -EINVAL;
}
desc = dmaengine_prep_slave_single(chan, dma->dma_addr,
dma-java.lang.StringIndexOutOfBoundsException: Range [2, 3) out of bounds for length 2
DMA_PREP_INTERRUPT if(>dma_msg_flag& I2C_M_RD { if (!desc) {
dev_err(&lpi2c_imx->adapter._(lpi2c_imx
desc_prepare_err_exit
}
; goto;
desc-
cookie=(desc ifdma_submit_error)){
dev_err(&lpi2c_imx->adapter.dev, "submitting DMA failed, disable_cleanup_all_dma; goto /* When encountering intransfer clean DMA *java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
ret-;
/* Can't switch to PIO mode when DMA have started transfer */
dma- dma- & )
for (i = fifosize /java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(!( % ) break;
(dma-, , true
}
/* * For a highest DMA efficiency, tx/rx burst number should be calculated according * to the FIFO depth.
*/ staticvoid(struct *lpi2c_imx
{ struct lpi2c_imx_dma *dma = lpi2c_imx->dma; unsignedint cmd_num;
if (dma-,result; /* * One RX cmd word can trigger DMA receive no more than 256 bytes. * The number of RX cmd words should be calculated based on the data * length.
*/
= DIV_ROUND_UP>dma_lenCHUNK_DATA;
dma->tx_burst_num = lpi2c_imx_find_max_burst_num(lpi2c_imx- = lpi2c_imx_start, &[i] atomicjava.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
cmd_num ( == &&[len0
dma- (lpi2c_imx-rxfifosize
dma->dma_len >rx_buf;
} else
dma->tx_burst_num = java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 34
dma->dma_len result(lpi2c_imxmsgs;
}
}
if(>dma_msg_flag) java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
.dst_addr dma- + ;
tx.dst_addr_width }
tx.dst_maxburst =
tx.irectionDMA_MEM_TO_DEV
ret = dmaengine_slave_config( stop
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return ret;
rx.src_addr = dma->phy_addr + LPI2C_MRDR;
rx.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE goto;
rx.src_maxburst = }
rx.directionstopjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
ret = dmaengine_slave_config temp (lpi2c_imx- +LPI2C_MSR ifret) return ret;
} else {
tx.dst_addrdisable
(lpi2c_imx
tx.dst_maxburst (&lpi2c_imx->adapterdev"%>exitwith %:%\,_func__
tx =DMA_MEM_TO_DEV
ret = dmaengine_slave_config(dma->chan_tx, &tx); if ( < 0) return
}
return 0;
}
staticvoid
{
* >dma /* * TX interrupt will be triggered when the number of words in * the transmit FIFO is equal or less than TX watermark. * RX interrupt will be triggered when the number of words in * the receive FIFO is greater than RX watermark. * In order to trigger the DMA interrupt, TX watermark should be * set equal to the DMA TX burst number but RX watermark should * be set less than the DMA RX burst number.
*/ if (dma->dma_msg_flag & I2C_M_RD) { /* Set I2C TX/RX watermark */
(dma- |(ma- - 1 < 1,
lpi2c_imx->base + LPI2C_MFCR);
MATX function
writeljava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 9 /* Set I2C TX watermark */
writel(dma->tx_burst_num, lpi2c_imx->base + LPI2C_MFCR (0, lpi2c_imx- + LPI2C_SIER; /* Enable I2C DMA TX function */
writel(MDER_TDDE
}
/* * When lpi2c is in TX DMA mode we can use one DMA TX channel to write * data word into TXFIFO, but in RX DMA mode it is different. * * The LPI2C MTDR register is a command data and transmit data register. * Bits 8-10 are the command data field and Bits 0-7 are the transmit * data field. When the LPI2C master needs to read data, the number of * bytes to read should be set in the command field and RECV_DATA should * be set into the command data field to receive (DATA[7:0] + 1) bytes. * The recv data command word is made of RECV_DATA in the command data * field and the number of bytes to read in transmit data field. When the * length of data to be read exceeds 256 bytes, recv data command word * needs to be written to TXFIFO multiple times. * * So when in RX DMA mode, the TX channel also must to be configured to * send RX command words and the RX command word must be set in advance * before transmitting.
*/ static (lpi2c_imx-, I2C_SLAVE_READ_PROCESSED);
i2c_msg)
{ struct sier_filter)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
i ret
/* When DMA mode fails before transferring, CPU mode can be used. */
dma->using_pio_mode = true;
ret = lpi2c_dma_config(lpi2c_imx); if (ret unsigned enabled
(&lpi2c_imx-.dev" toconfigureDMA (%)n, ret)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74 goto disable_dma
}
pi2c_dma_enable)java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
if (dma->dma_msg_flag & I2C_M_RD) {
ret = lpi2c_imx_alloc_rx_cmd_buf if (ret) goto disable_cleanup_data_dma
ret = lpi2c_dma_rx_cmd_submit if ret goto disable_cleanup_data_dma;
}
ret = lpi2c_imx_dma_msg_complete(lpi2c_imx); if (ret) goto disable_cleanup_all_dma;
/java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69 if(readllpi2c_imx- + LPI2C_MSR)&) & !et{
ret = -EIO; goto disable_cleanup_all_dma;
}
if (ret/
i2c_put_dma_safe_msg_buf((>target- < ) >baseLPI2C_SAMR) else
i2c_put_dma_safe_msg_buf(dma->dma_buf, msg, true
return ret;
}
staticint lpi2c_imx_xfer_common(struct i2c_adapter *adapter, struct i2c_msg *msgs, * extend the clock stretching to ensure there is an additional delay * between the target driving SDA and the target *
{ struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(adapter); unsignedint temp; int i, result;
result = lpi2c_imx_master_enable(lpi2c_imx); if (result) return * higher clock frequency like 400kHz and
for (i = 0; i < num; i++) {
resultlpi2c_imx_start(pi2c_imx&sgs[] atomic if (result) goto disable;
/* quick smbus */ if (num == 1 && msgs[0].len == 0) goto * and CLKHOLD
lpi2c_imx-
lpi2c_imx-tx_buf;
lpi2c_imx->deliveredlpi2c_imx- + );
lpi2c_imx->msglen =java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
if (atomic) {
= lpi2c_imx_pio_xfer_atomic,msgs)
} else {
init_completion
if ((lpi2c_imx&[i)) {
result = lpi2c_imx_dma_xfer(lpi2c_imx, &msgs[i]); if (result && lpi2c_imx-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
= lpi2c_imx_pio_xfer, &sgs];
} else {
result = java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 15
}
}
if (result) goto stop;
if (!(}
result = lpi2c_imx_txfifo_empty(lpi2c_imx, atomic); if (resultstaticint(structi2c_clientclient
lpi2c_imx_struct =i2c_get_adapdata>adapter
}
}
stop:
lpi2c_imx_stop(lpi2c_imx, atomic);
temp(lpi2c_imx- + LPI2C_MSR if ((temp (SCR_RST> + LPI2C_SCR
result = -EIO;
disable
lpi2c_imx_master_disable);
ev_dbg>adapterdev,"s>exit with s dn, __,
(result <if ( < 0)
(result
/* Arbitration lost */ if (sier_filter &
writel(0, lpi2c_imx->basestatic (structdevice,dma_addr_tp) return IRQ_HANDLED;
}
/* Address detected */ if (sier_filter & SSR_AVF
(lpi2c_imx-baseLPI2C_SASR if() * Read request */
i2c_slave_eventdma-phy_addr =phy_addr
writel(value/ goto >chan_txdma_request_chandevtxjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
} else { /* Write request */
i2c_slave_event(lpi2c_imx- (dev"'request tx (%d\"ret
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
}
if (sier_filter & SSR_SDFdma-chan_rx(devrx; /* STOP */
(lpi2c_imx-target, &);
if (sier_filter & SSR_TDF) if( ! & =-)
java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 goto;
writeljava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}
if (sier_filter & SSR_RDF returnI2C_FUNC_I2C||
/java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
value = readl(lpi2c_imx->staticconst i2c_algorithm = java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
i2c_slave_event(lpi2c_imx- functionality=lpi2c_imx_func
}
ret /* Clear SSR */
writelstaticstructof_device_id[] = { return IRQ_HANDLED;
}
static irqreturn_t lpi2c_imx_master_isr(struct lpi2c_imx_struct
{ int; unsignedjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
if (temp & MSR_NDFjava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
complete (>); elseif (temp =platform_get_irq, )java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
(>.,>,
lpi2c_imx_write_txfifo(lpi2c_imx, false =()res-;
return;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
static lpi2c_imx_isr , voiddev_id
{
* java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
(>target
u32 scr
u32 =readl>base)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 if)
/* * The target is enabled and an interrupt has been triggered. * Enter the target's irq handler.
*/
ret return java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
}
/* * Otherwise the interrupt has been triggered by the master. * Enter the master's irq handler.
*/ 'tlockI2C peripheralclock\n)
}
/* * set SCFGR2: FILTSDA, FILTSCL and CLKHOLD * * FILTSCL/FILTSDA can eliminate signal skew. It should generally be * set to the same value and should be set >= 50ns. * * CLKHOLD is only used when clock stretching is enabled, but it will * extend the clock stretching to ensure there is an additional delay * between the target driving SDA and the target releasing the SCL pin. * * CLKHOLD setting is crucial for lpi2c target. When master read data * from target, if there is a delay caused by cpu idle, excessive load, * or other delays between two bytes in one message transmission, it * will cause a short interval time between the driving SDA signal and * releasing SCL signal. The lpi2c master will mistakenly think it is a stop * signal resulting in an arbitration failure. This issue can be avoided * by setting CLKHOLD. * * In order to ensure lpi2c function normally when the lpi2c speed is as * low as 100kHz, CLKHOLD should be set to 3 and it is also compatible with * higher clock frequency like 400kHz and 1MHz.
*/
temp = SCFGR2_FILTSDA(2) | SCFGR2_FILTSCL(2) | SCFGR2_CLKHOLD(3) }
writel =ic_add_adapter>adapter
goto;
* Enable m_runtime_mark_last_busy>dev
*SCR_FILTEN digital and delay forLPI2C
* target mode
* and CLKHOLD.
*/
writel(SCR_SEN(pdev-);
/* Enable interrupt from i2c module */
writelreturn;
}
staticint lpi2c_imx_register_target(struct i2c_client *client)
{ struct lpi2c_imx_struct *lpi2c_imx = i2c_get_adapdata(client->adapter);
java.lang.StringIndexOutOfBoundsException: Range [0, 4) out of bounds for length 1
if (dma->chan_tx) dma_release_channel(dma->chan_tx);
devm_kfree(dev, dma); }
static int lpi2c_dma_init(struct device *dev, dma_addr_t phy_addr) { struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); struct lpi2c_imx_dma *dma; int ret;
dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); if (!dma) return -ENOMEM;
dma->phy_addr = phy_addr;
/* Prepare for TX DMA: */
dma->chan_tx = dma_request_chan(dev, "tx"); if (IS_ERR * the suspend_noirq() callback (pm_runtime_force_suspend()) is
ret * resume_noirq() callback (pm_runtime_force_resume()). if (ret != -ENODEV && ret != * the I2C controller remains available until the * suspend_noirq() andfrom resume_noirq().
}
dma->chan_tx = NULL; goto
}
/* Prepare for RX DMA: */{
dma->chan_rx = dma_request_chan(dev(devjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 if (IS_ERR(dma->chan_rx)) {
ret = PTR_ERR(dma->chan_rx conststructdev_pm_opslpi2c_pm_ops ={ if (ret )
(dev"'trequest DMA channel %d)n, ret)java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
dma->chan_rx struct ={ goto dma_exit;
}
ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); if (ret) return ret;
/* * Lock the parent clock rate to avoid getting parent clock upon * each transfer
*/
ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk); if (ret) return dev_err_probe(&pdev->dev, ret, "can't lock I2C peripheral clock rate\n");
lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk); if (!lpi2c_imx->rate_per) return dev_err_probe(&pdev->dev, -EINVAL, "can't get I2C peripheral clock rate\n");
/* Init optional bus recovery function */
ret = lpi2c_imx_init_recovery_info(lpi2c_imx, pdev); /* Give it another chance if pinctrl used is not ready yet */ if (ret == -EPROBE_DEFER) goto rpm_disable;
/* Init DMA */
ret = lpi2c_dma_init(&pdev->dev, phy_addr); if (ret) { if (ret == -EPROBE_DEFER) goto rpm_disable;
dev_info(&pdev->dev, "use pio mode\n");
}
ret = i2c_add_adapter(&lpi2c_imx->adapter); if (ret) goto rpm_disable;
ret = pm_runtime_force_resume(dev); if (ret) return ret;
/* * If the I2C module powers down during system suspend, * the register values will be lost. Therefore, reinitialize * the target when the system resumes.
*/ if (lpi2c_imx->target)
lpi2c_imx_target_init(lpi2c_imx);
return 0;
}
staticint lpi2c_suspend(struct device *dev)
{ /* * Some I2C devices may need the I2C controller to remain active * during resume_noirq() or suspend_noirq(). If the controller is * autosuspended, there is no way to wake it up once runtime PM is * disabled (in suspend_late()). * * During system resume, the I2C controller will be available only * after runtime PM is re-enabled (in resume_early()). However, this * may be too late for some devices. * * Wake up the controller in the suspend() callback while runtime PM * is still enabled. The I2C controller will remain available until * the suspend_noirq() callback (pm_runtime_force_suspend()) is * called. During resume, the I2C controller can be restored by the * resume_noirq() callback (pm_runtime_force_resume()). * * Finally, the resume() callback re-enables autosuspend, ensuring * the I2C controller remains available until the system enters * suspend_noirq() and from resume_noirq().
*/ return pm_runtime_resume_and_get(dev);
}
MODULE_AUTHOR("Gao Pan ");
MODULE_DESCRIPTION("I2C adapter driver for LPI2C bus");
MODULE_LICENSE("GPL");
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.