Lines Matching refs:priv
101 static void uniphier_fi2c_fill_txfifo(struct uniphier_fi2c_priv *priv, in uniphier_fi2c_fill_txfifo() argument
113 while (priv->len) { in uniphier_fi2c_fill_txfifo()
117 dev_dbg(&priv->adap.dev, "write data: %02x\n", *priv->buf); in uniphier_fi2c_fill_txfifo()
118 writel(*priv->buf++, priv->membase + UNIPHIER_FI2C_DTTX); in uniphier_fi2c_fill_txfifo()
119 priv->len--; in uniphier_fi2c_fill_txfifo()
123 static void uniphier_fi2c_drain_rxfifo(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_drain_rxfifo() argument
125 int fifo_left = priv->flags & UNIPHIER_FI2C_BYTE_WISE ? in uniphier_fi2c_drain_rxfifo()
128 while (priv->len) { in uniphier_fi2c_drain_rxfifo()
132 *priv->buf++ = readl(priv->membase + UNIPHIER_FI2C_DTRX); in uniphier_fi2c_drain_rxfifo()
133 dev_dbg(&priv->adap.dev, "read data: %02x\n", priv->buf[-1]); in uniphier_fi2c_drain_rxfifo()
134 priv->len--; in uniphier_fi2c_drain_rxfifo()
138 static void uniphier_fi2c_set_irqs(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_set_irqs() argument
140 writel(priv->enabled_irqs, priv->membase + UNIPHIER_FI2C_IE); in uniphier_fi2c_set_irqs()
143 static void uniphier_fi2c_clear_irqs(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_clear_irqs() argument
145 writel(-1, priv->membase + UNIPHIER_FI2C_IC); in uniphier_fi2c_clear_irqs()
148 static void uniphier_fi2c_stop(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_stop() argument
150 dev_dbg(&priv->adap.dev, "stop condition\n"); in uniphier_fi2c_stop()
152 priv->enabled_irqs |= UNIPHIER_FI2C_INT_STOP; in uniphier_fi2c_stop()
153 uniphier_fi2c_set_irqs(priv); in uniphier_fi2c_stop()
155 priv->membase + UNIPHIER_FI2C_CR); in uniphier_fi2c_stop()
160 struct uniphier_fi2c_priv *priv = dev_id; in uniphier_fi2c_interrupt() local
163 irq_status = readl(priv->membase + UNIPHIER_FI2C_INT); in uniphier_fi2c_interrupt()
165 dev_dbg(&priv->adap.dev, in uniphier_fi2c_interrupt()
167 priv->enabled_irqs, irq_status); in uniphier_fi2c_interrupt()
173 dev_dbg(&priv->adap.dev, "arbitration lost\n"); in uniphier_fi2c_interrupt()
174 priv->error = -EAGAIN; in uniphier_fi2c_interrupt()
179 dev_dbg(&priv->adap.dev, "could not get ACK\n"); in uniphier_fi2c_interrupt()
180 priv->error = -ENXIO; in uniphier_fi2c_interrupt()
181 if (priv->flags & UNIPHIER_FI2C_RD) { in uniphier_fi2c_interrupt()
191 uniphier_fi2c_stop(priv); in uniphier_fi2c_interrupt()
192 priv->flags |= UNIPHIER_FI2C_DEFER_STOP_COMP; in uniphier_fi2c_interrupt()
199 if (!priv->len) in uniphier_fi2c_interrupt()
202 uniphier_fi2c_fill_txfifo(priv, false); in uniphier_fi2c_interrupt()
207 uniphier_fi2c_drain_rxfifo(priv); in uniphier_fi2c_interrupt()
208 if (!priv->len) in uniphier_fi2c_interrupt()
211 if (unlikely(priv->flags & UNIPHIER_FI2C_MANUAL_NACK)) { in uniphier_fi2c_interrupt()
212 if (priv->len <= UNIPHIER_FI2C_FIFO_SIZE && in uniphier_fi2c_interrupt()
213 !(priv->flags & UNIPHIER_FI2C_BYTE_WISE)) { in uniphier_fi2c_interrupt()
214 dev_dbg(&priv->adap.dev, in uniphier_fi2c_interrupt()
216 priv->enabled_irqs |= UNIPHIER_FI2C_INT_RB; in uniphier_fi2c_interrupt()
217 uniphier_fi2c_set_irqs(priv); in uniphier_fi2c_interrupt()
218 priv->flags |= UNIPHIER_FI2C_BYTE_WISE; in uniphier_fi2c_interrupt()
220 if (priv->len <= 1) { in uniphier_fi2c_interrupt()
221 dev_dbg(&priv->adap.dev, "set NACK\n"); in uniphier_fi2c_interrupt()
224 priv->membase + UNIPHIER_FI2C_CR); in uniphier_fi2c_interrupt()
234 if (priv->flags & UNIPHIER_FI2C_STOP) { in uniphier_fi2c_interrupt()
236 uniphier_fi2c_stop(priv); in uniphier_fi2c_interrupt()
239 priv->enabled_irqs = 0; in uniphier_fi2c_interrupt()
240 uniphier_fi2c_set_irqs(priv); in uniphier_fi2c_interrupt()
241 complete(&priv->comp); in uniphier_fi2c_interrupt()
245 uniphier_fi2c_clear_irqs(priv); in uniphier_fi2c_interrupt()
250 static void uniphier_fi2c_tx_init(struct uniphier_fi2c_priv *priv, u16 addr) in uniphier_fi2c_tx_init() argument
252 priv->enabled_irqs |= UNIPHIER_FI2C_INT_TE; in uniphier_fi2c_tx_init()
254 writel(0, priv->membase + UNIPHIER_FI2C_TBC); in uniphier_fi2c_tx_init()
257 priv->membase + UNIPHIER_FI2C_DTTX); in uniphier_fi2c_tx_init()
259 uniphier_fi2c_fill_txfifo(priv, true); in uniphier_fi2c_tx_init()
262 static void uniphier_fi2c_rx_init(struct uniphier_fi2c_priv *priv, u16 addr) in uniphier_fi2c_rx_init() argument
264 priv->flags |= UNIPHIER_FI2C_RD; in uniphier_fi2c_rx_init()
266 if (likely(priv->len < 256)) { in uniphier_fi2c_rx_init()
271 writel(priv->len, priv->membase + UNIPHIER_FI2C_RBC); in uniphier_fi2c_rx_init()
272 priv->enabled_irqs |= UNIPHIER_FI2C_INT_RF | in uniphier_fi2c_rx_init()
280 writel(0, priv->membase + UNIPHIER_FI2C_RBC); in uniphier_fi2c_rx_init()
281 priv->flags |= UNIPHIER_FI2C_MANUAL_NACK; in uniphier_fi2c_rx_init()
282 priv->enabled_irqs |= UNIPHIER_FI2C_INT_RF; in uniphier_fi2c_rx_init()
287 priv->membase + UNIPHIER_FI2C_DTTX); in uniphier_fi2c_rx_init()
290 static void uniphier_fi2c_reset(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_reset() argument
292 writel(UNIPHIER_FI2C_RST_RST, priv->membase + UNIPHIER_FI2C_RST); in uniphier_fi2c_reset()
295 static void uniphier_fi2c_prepare_operation(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_prepare_operation() argument
298 priv->membase + UNIPHIER_FI2C_BRST); in uniphier_fi2c_prepare_operation()
301 static void uniphier_fi2c_recover(struct uniphier_fi2c_priv *priv) in uniphier_fi2c_recover() argument
303 uniphier_fi2c_reset(priv); in uniphier_fi2c_recover()
304 i2c_recover_bus(&priv->adap); in uniphier_fi2c_recover()
310 struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap); in uniphier_fi2c_master_xfer_one() local
317 priv->len = msg->len; in uniphier_fi2c_master_xfer_one()
318 priv->buf = msg->buf; in uniphier_fi2c_master_xfer_one()
319 priv->enabled_irqs = UNIPHIER_FI2C_INT_FAULTS; in uniphier_fi2c_master_xfer_one()
320 priv->error = 0; in uniphier_fi2c_master_xfer_one()
321 priv->flags = 0; in uniphier_fi2c_master_xfer_one()
324 priv->flags |= UNIPHIER_FI2C_STOP; in uniphier_fi2c_master_xfer_one()
326 reinit_completion(&priv->comp); in uniphier_fi2c_master_xfer_one()
327 uniphier_fi2c_clear_irqs(priv); in uniphier_fi2c_master_xfer_one()
329 priv->membase + UNIPHIER_FI2C_RST); /* reset TX/RX FIFO */ in uniphier_fi2c_master_xfer_one()
332 uniphier_fi2c_rx_init(priv, msg->addr); in uniphier_fi2c_master_xfer_one()
334 uniphier_fi2c_tx_init(priv, msg->addr); in uniphier_fi2c_master_xfer_one()
336 uniphier_fi2c_set_irqs(priv); in uniphier_fi2c_master_xfer_one()
340 priv->membase + UNIPHIER_FI2C_CR); in uniphier_fi2c_master_xfer_one()
342 time_left = wait_for_completion_timeout(&priv->comp, adap->timeout); in uniphier_fi2c_master_xfer_one()
345 uniphier_fi2c_recover(priv); in uniphier_fi2c_master_xfer_one()
350 if (unlikely(priv->flags & UNIPHIER_FI2C_DEFER_STOP_COMP)) { in uniphier_fi2c_master_xfer_one()
351 u32 status = readl(priv->membase + UNIPHIER_FI2C_SR); in uniphier_fi2c_master_xfer_one()
357 uniphier_fi2c_recover(priv); in uniphier_fi2c_master_xfer_one()
362 return priv->error; in uniphier_fi2c_master_xfer_one()
367 struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap); in uniphier_fi2c_check_bus_busy() local
369 if (readl(priv->membase + UNIPHIER_FI2C_SR) & UNIPHIER_FI2C_SR_DB) { in uniphier_fi2c_check_bus_busy()
370 if (priv->busy_cnt++ > 3) { in uniphier_fi2c_check_bus_busy()
375 uniphier_fi2c_recover(priv); in uniphier_fi2c_check_bus_busy()
376 priv->busy_cnt = 0; in uniphier_fi2c_check_bus_busy()
382 priv->busy_cnt = 0; in uniphier_fi2c_check_bus_busy()
423 struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap); in uniphier_fi2c_get_scl() local
425 return !!(readl(priv->membase + UNIPHIER_FI2C_BM) & in uniphier_fi2c_get_scl()
431 struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap); in uniphier_fi2c_set_scl() local
434 priv->membase + UNIPHIER_FI2C_BRST); in uniphier_fi2c_set_scl()
439 struct uniphier_fi2c_priv *priv = i2c_get_adapdata(adap); in uniphier_fi2c_get_sda() local
441 return !!(readl(priv->membase + UNIPHIER_FI2C_BM) & in uniphier_fi2c_get_sda()
459 struct uniphier_fi2c_priv *priv) in uniphier_fi2c_clk_init() argument
473 priv->clk = devm_clk_get(dev, NULL); in uniphier_fi2c_clk_init()
474 if (IS_ERR(priv->clk)) { in uniphier_fi2c_clk_init()
476 return PTR_ERR(priv->clk); in uniphier_fi2c_clk_init()
479 ret = clk_prepare_enable(priv->clk); in uniphier_fi2c_clk_init()
483 clk_rate = clk_get_rate(priv->clk); in uniphier_fi2c_clk_init()
485 uniphier_fi2c_reset(priv); in uniphier_fi2c_clk_init()
489 writel(clk_count, priv->membase + UNIPHIER_FI2C_CYC); in uniphier_fi2c_clk_init()
490 writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_LCTL); in uniphier_fi2c_clk_init()
491 writel(clk_count / 2, priv->membase + UNIPHIER_FI2C_SSUT); in uniphier_fi2c_clk_init()
492 writel(clk_count / 16, priv->membase + UNIPHIER_FI2C_DSUT); in uniphier_fi2c_clk_init()
494 uniphier_fi2c_prepare_operation(priv); in uniphier_fi2c_clk_init()
502 struct uniphier_fi2c_priv *priv; in uniphier_fi2c_probe() local
507 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); in uniphier_fi2c_probe()
508 if (!priv) in uniphier_fi2c_probe()
512 priv->membase = devm_ioremap_resource(dev, regs); in uniphier_fi2c_probe()
513 if (IS_ERR(priv->membase)) in uniphier_fi2c_probe()
514 return PTR_ERR(priv->membase); in uniphier_fi2c_probe()
522 init_completion(&priv->comp); in uniphier_fi2c_probe()
523 priv->adap.owner = THIS_MODULE; in uniphier_fi2c_probe()
524 priv->adap.algo = &uniphier_fi2c_algo; in uniphier_fi2c_probe()
525 priv->adap.dev.parent = dev; in uniphier_fi2c_probe()
526 priv->adap.dev.of_node = dev->of_node; in uniphier_fi2c_probe()
527 strlcpy(priv->adap.name, "UniPhier FI2C", sizeof(priv->adap.name)); in uniphier_fi2c_probe()
528 priv->adap.bus_recovery_info = &uniphier_fi2c_bus_recovery_info; in uniphier_fi2c_probe()
529 i2c_set_adapdata(&priv->adap, priv); in uniphier_fi2c_probe()
530 platform_set_drvdata(pdev, priv); in uniphier_fi2c_probe()
532 ret = uniphier_fi2c_clk_init(dev, priv); in uniphier_fi2c_probe()
537 pdev->name, priv); in uniphier_fi2c_probe()
543 ret = i2c_add_adapter(&priv->adap); in uniphier_fi2c_probe()
551 clk_disable_unprepare(priv->clk); in uniphier_fi2c_probe()
558 struct uniphier_fi2c_priv *priv = platform_get_drvdata(pdev); in uniphier_fi2c_remove() local
560 i2c_del_adapter(&priv->adap); in uniphier_fi2c_remove()
561 clk_disable_unprepare(priv->clk); in uniphier_fi2c_remove()