summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/target/arm/imx233/i2c-imx233.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/firmware/target/arm/imx233/i2c-imx233.c b/firmware/target/arm/imx233/i2c-imx233.c
index ee5ac1ccf6..f99cd97282 100644
--- a/firmware/target/arm/imx233/i2c-imx233.c
+++ b/firmware/target/arm/imx233/i2c-imx233.c
@@ -80,12 +80,18 @@ void INT_I2C_DMA(void)
80 semaphore_release(&i2c_sema); 80 semaphore_release(&i2c_sema);
81} 81}
82 82
83void imx233_i2c_init(void) 83void INT_I2C_ERROR(void)
84{
85 /* reset dma channel on error */
86 if(imx233_dma_is_channel_error_irq(APB_I2C))
87 imx233_dma_reset_channel(APB_I2C);
88 /* clear irq flags */
89 imx233_dma_clear_channel_interrupt(APB_I2C);
90 semaphore_release(&i2c_sema);
91}
92
93static void imx233_i2c_reset(void)
84{ 94{
85 BF_SET(I2C_CTRL0, SFTRST);
86 /* setup pins (must be done when shutdown) */
87 imx233_pinctrl_setup_vpin(VPIN_I2C_SCL, "i2c scl", PINCTRL_DRIVE_4mA, true);
88 imx233_pinctrl_setup_vpin(VPIN_I2C_SDA, "i2c sda", PINCTRL_DRIVE_4mA, true);
89 /* clear softreset */ 95 /* clear softreset */
90 imx233_reset_block(&HW_I2C_CTRL0); 96 imx233_reset_block(&HW_I2C_CTRL0);
91 /* Errata (imx233): 97 /* Errata (imx233):
@@ -103,7 +109,15 @@ void imx233_i2c_init(void)
103 HW_I2C_TIMING0 = 0x000F0007; /* tHIGH=0.6us, read at 0.3us */ 109 HW_I2C_TIMING0 = 0x000F0007; /* tHIGH=0.6us, read at 0.3us */
104 HW_I2C_TIMING1 = 0x001F000F; /* tLOW=1.3us, write at 0.6us */ 110 HW_I2C_TIMING1 = 0x001F000F; /* tLOW=1.3us, write at 0.6us */
105 HW_I2C_TIMING2 = 0x0015000D; 111 HW_I2C_TIMING2 = 0x0015000D;
106 112}
113
114void imx233_i2c_init(void)
115{
116 BF_SET(I2C_CTRL0, SFTRST);
117 /* setup pins (must be done when shutdown) */
118 imx233_pinctrl_setup_vpin(VPIN_I2C_SCL, "i2c scl", PINCTRL_DRIVE_4mA, true);
119 imx233_pinctrl_setup_vpin(VPIN_I2C_SDA, "i2c sda", PINCTRL_DRIVE_4mA, true);
120 imx233_i2c_reset();
107 mutex_init(&i2c_mutex); 121 mutex_init(&i2c_mutex);
108 semaphore_init(&i2c_sema, 1, 0); 122 semaphore_init(&i2c_sema, 1, 0);
109} 123}
@@ -183,6 +197,7 @@ enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout)
183 BF_CLR(I2C_CTRL1, ALL_IRQ); 197 BF_CLR(I2C_CTRL1, ALL_IRQ);
184 imx233_dma_reset_channel(APB_I2C); 198 imx233_dma_reset_channel(APB_I2C);
185 imx233_icoll_enable_interrupt(INT_SRC_I2C_DMA, true); 199 imx233_icoll_enable_interrupt(INT_SRC_I2C_DMA, true);
200 imx233_icoll_enable_interrupt(INT_SRC_I2C_ERROR, true);
186 imx233_dma_enable_channel_interrupt(APB_I2C, true); 201 imx233_dma_enable_channel_interrupt(APB_I2C, true);
187 imx233_dma_start_command(APB_I2C, &i2c_stage[0].dma); 202 imx233_dma_start_command(APB_I2C, &i2c_stage[0].dma);
188 203
@@ -195,7 +210,13 @@ enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout)
195 else if(BF_RD(I2C_CTRL1, MASTER_LOSS_IRQ)) 210 else if(BF_RD(I2C_CTRL1, MASTER_LOSS_IRQ))
196 ret = I2C_MASTER_LOSS; 211 ret = I2C_MASTER_LOSS;
197 else if(BF_RD(I2C_CTRL1, NO_SLAVE_ACK_IRQ)) 212 else if(BF_RD(I2C_CTRL1, NO_SLAVE_ACK_IRQ))
213 {
214 /* the core doesn't like this error, this is a workaround to prevent lock up */
215 BF_SET(I2C_CTRL1, CLR_GOT_A_NAK);
216 imx233_dma_reset_channel(APB_I2C);
217 imx233_i2c_reset();
198 ret= I2C_NO_SLAVE_ACK; 218 ret= I2C_NO_SLAVE_ACK;
219 }
199 else if(BF_RD(I2C_CTRL1, EARLY_TERM_IRQ)) 220 else if(BF_RD(I2C_CTRL1, EARLY_TERM_IRQ))
200 ret = I2C_SLAVE_NAK; 221 ret = I2C_SLAVE_NAK;
201 else 222 else