Lines Matching +full:tx +full:- +full:freq

1 // SPDX-License-Identifier: GPL-2.0-or-later
10 * (C) 2000-2001 Felix Domke (tmbinc@gmx.net), Gillem (htoa@gmx.net)
15 * Converted to of_platform_device. Renamed to i2c-cpm.c.
28 #include <linux/dma-mapping.h>
51 ushort tbase; /* Tx Buffer descriptor base address */
53 u_char tfcr; /* Tx function code */
62 ushort tbptr; /* Tx Buffer descriptor pointer */
104 int freq; member
125 i2c_reg = cpm->i2c_reg; in cpm_i2c_interrupt()
128 i = in_8(&i2c_reg->i2cer); in cpm_i2c_interrupt()
129 out_8(&i2c_reg->i2cer, i); in cpm_i2c_interrupt()
131 dev_dbg(&adap->dev, "Interrupt: %x\n", i); in cpm_i2c_interrupt()
133 wake_up(&cpm->i2c_wait); in cpm_i2c_interrupt()
140 struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram; in cpm_reset_i2c_params()
143 out_be16(&i2c_ram->tbase, (u8 __iomem *)cpm->tbase - DPRAM_BASE); in cpm_reset_i2c_params()
144 out_be16(&i2c_ram->rbase, (u8 __iomem *)cpm->rbase - DPRAM_BASE); in cpm_reset_i2c_params()
146 if (cpm->version == 1) { in cpm_reset_i2c_params()
147 out_8(&i2c_ram->tfcr, I2C_EB); in cpm_reset_i2c_params()
148 out_8(&i2c_ram->rfcr, I2C_EB); in cpm_reset_i2c_params()
150 out_8(&i2c_ram->tfcr, I2C_EB_CPM2); in cpm_reset_i2c_params()
151 out_8(&i2c_ram->rfcr, I2C_EB_CPM2); in cpm_reset_i2c_params()
154 out_be16(&i2c_ram->mrblr, CPM_MAX_READ); in cpm_reset_i2c_params()
156 out_be32(&i2c_ram->rstate, 0); in cpm_reset_i2c_params()
157 out_be32(&i2c_ram->rdp, 0); in cpm_reset_i2c_params()
158 out_be16(&i2c_ram->rbptr, 0); in cpm_reset_i2c_params()
159 out_be16(&i2c_ram->rbc, 0); in cpm_reset_i2c_params()
160 out_be32(&i2c_ram->rxtmp, 0); in cpm_reset_i2c_params()
161 out_be32(&i2c_ram->tstate, 0); in cpm_reset_i2c_params()
162 out_be32(&i2c_ram->tdp, 0); in cpm_reset_i2c_params()
163 out_be16(&i2c_ram->tbptr, 0); in cpm_reset_i2c_params()
164 out_be16(&i2c_ram->tbc, 0); in cpm_reset_i2c_params()
165 out_be32(&i2c_ram->txtmp, 0); in cpm_reset_i2c_params()
171 struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg; in cpm_i2c_force_close()
173 dev_dbg(&adap->dev, "cpm_i2c_force_close()\n"); in cpm_i2c_force_close()
175 cpm_command(cpm->cp_command, CPM_CR_CLOSE_RX_BD); in cpm_i2c_force_close()
177 out_8(&i2c_reg->i2cmr, 0x00); /* Disable all interrupts */ in cpm_i2c_force_close()
178 out_8(&i2c_reg->i2cer, 0xff); in cpm_i2c_force_close()
182 struct i2c_msg *pmsg, int num, int tx, int rx) in cpm_i2c_parse_message() argument
191 tbdf = cpm->tbase + tx; in cpm_i2c_parse_message()
192 rbdf = cpm->rbase + rx; in cpm_i2c_parse_message()
196 tb = cpm->txbuf[tx]; in cpm_i2c_parse_message()
197 rb = cpm->rxbuf[rx]; in cpm_i2c_parse_message()
204 out_be16(&tbdf->cbd_datlen, pmsg->len + 1); in cpm_i2c_parse_message()
205 out_be16(&tbdf->cbd_sc, 0); in cpm_i2c_parse_message()
207 if (!(pmsg->flags & I2C_M_NOSTART)) in cpm_i2c_parse_message()
208 setbits16(&tbdf->cbd_sc, BD_I2C_START); in cpm_i2c_parse_message()
210 if (tx + 1 == num) in cpm_i2c_parse_message()
211 setbits16(&tbdf->cbd_sc, BD_SC_LAST | BD_SC_WRAP); in cpm_i2c_parse_message()
213 if (pmsg->flags & I2C_M_RD) { in cpm_i2c_parse_message()
220 dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr); in cpm_i2c_parse_message()
222 out_be16(&rbdf->cbd_datlen, 0); in cpm_i2c_parse_message()
223 out_be16(&rbdf->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); in cpm_i2c_parse_message()
226 setbits16(&rbdf->cbd_sc, BD_SC_WRAP); in cpm_i2c_parse_message()
229 setbits16(&tbdf->cbd_sc, BD_SC_READY); in cpm_i2c_parse_message()
231 dev_dbg(&adap->dev, "cpm_i2c_write(abyte=0x%x)\n", addr); in cpm_i2c_parse_message()
233 memcpy(tb+1, pmsg->buf, pmsg->len); in cpm_i2c_parse_message()
236 setbits16(&tbdf->cbd_sc, BD_SC_READY | BD_SC_INTRPT); in cpm_i2c_parse_message()
241 struct i2c_msg *pmsg, int tx, int rx) in cpm_i2c_check_message() argument
249 tbdf = cpm->tbase + tx; in cpm_i2c_check_message()
250 rbdf = cpm->rbase + rx; in cpm_i2c_check_message()
252 tb = cpm->txbuf[tx]; in cpm_i2c_check_message()
253 rb = cpm->rxbuf[rx]; in cpm_i2c_check_message()
259 if (pmsg->flags & I2C_M_RD) { in cpm_i2c_check_message()
260 dev_dbg(&adap->dev, "tx sc 0x%04x, rx sc 0x%04x\n", in cpm_i2c_check_message()
261 in_be16(&tbdf->cbd_sc), in_be16(&rbdf->cbd_sc)); in cpm_i2c_check_message()
263 if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) { in cpm_i2c_check_message()
264 dev_dbg(&adap->dev, "I2C read; No ack\n"); in cpm_i2c_check_message()
265 return -ENXIO; in cpm_i2c_check_message()
267 if (in_be16(&rbdf->cbd_sc) & BD_SC_EMPTY) { in cpm_i2c_check_message()
268 dev_err(&adap->dev, in cpm_i2c_check_message()
270 return -EREMOTEIO; in cpm_i2c_check_message()
272 if (in_be16(&rbdf->cbd_sc) & BD_SC_OV) { in cpm_i2c_check_message()
273 dev_err(&adap->dev, "I2C read; Overrun\n"); in cpm_i2c_check_message()
274 return -EREMOTEIO; in cpm_i2c_check_message()
276 memcpy(pmsg->buf, rb, pmsg->len); in cpm_i2c_check_message()
278 dev_dbg(&adap->dev, "tx sc %d 0x%04x\n", tx, in cpm_i2c_check_message()
279 in_be16(&tbdf->cbd_sc)); in cpm_i2c_check_message()
281 if (in_be16(&tbdf->cbd_sc) & BD_SC_NAK) { in cpm_i2c_check_message()
282 dev_dbg(&adap->dev, "I2C write; No ack\n"); in cpm_i2c_check_message()
283 return -ENXIO; in cpm_i2c_check_message()
285 if (in_be16(&tbdf->cbd_sc) & BD_SC_UN) { in cpm_i2c_check_message()
286 dev_err(&adap->dev, "I2C write; Underrun\n"); in cpm_i2c_check_message()
287 return -EIO; in cpm_i2c_check_message()
289 if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) { in cpm_i2c_check_message()
290 dev_err(&adap->dev, "I2C write; Collision\n"); in cpm_i2c_check_message()
291 return -EIO; in cpm_i2c_check_message()
300 struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg; in cpm_i2c_xfer()
301 struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram; in cpm_i2c_xfer()
310 out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase)); in cpm_i2c_xfer()
311 out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase)); in cpm_i2c_xfer()
313 tbdf = cpm->tbase; in cpm_i2c_xfer()
314 rbdf = cpm->rbase; in cpm_i2c_xfer()
323 if (in_be16(&tbdf->cbd_sc) & BD_SC_CL) { in cpm_i2c_xfer()
324 out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); in cpm_i2c_xfer()
329 dev_dbg(&adap->dev, "R: %d T: %d\n", rptr, tptr); in cpm_i2c_xfer()
332 if (pmsg->flags & I2C_M_RD) in cpm_i2c_xfer()
337 /* Enable RX/TX/Error interupts */ in cpm_i2c_xfer()
338 out_8(&i2c_reg->i2cmr, I2CER_TXE | I2CER_TXB | I2CER_RXB); in cpm_i2c_xfer()
339 out_8(&i2c_reg->i2cer, 0xff); /* Clear interrupt status */ in cpm_i2c_xfer()
341 setbits8(&i2c_reg->i2mod, I2MOD_EN); /* Enable */ in cpm_i2c_xfer()
343 setbits8(&i2c_reg->i2com, I2COM_START); in cpm_i2c_xfer()
350 dev_dbg(&adap->dev, "test ready.\n"); in cpm_i2c_xfer()
352 if (pmsg->flags & I2C_M_RD) in cpm_i2c_xfer()
353 ret = wait_event_timeout(cpm->i2c_wait, in cpm_i2c_xfer()
358 ret = wait_event_timeout(cpm->i2c_wait, in cpm_i2c_xfer()
362 ret = -EREMOTEIO; in cpm_i2c_xfer()
363 dev_err(&adap->dev, "I2C transfer: timeout\n"); in cpm_i2c_xfer()
367 dev_dbg(&adap->dev, "ready.\n"); in cpm_i2c_xfer()
370 if (pmsg->flags & I2C_M_RD) in cpm_i2c_xfer()
382 clrbits8(&i2c_reg->i2mod, I2MOD_EN); in cpm_i2c_xfer()
392 clrbits8(&i2c_reg->i2mod, I2MOD_EN); in cpm_i2c_xfer()
402 /* -----exported algorithm data: ------------------------------------- */
418 .name = "i2c-cpm",
425 struct platform_device *ofdev = cpm->ofdev; in cpm_i2c_setup()
433 dev_dbg(&cpm->ofdev->dev, "cpm_i2c_setup()\n"); in cpm_i2c_setup()
435 init_waitqueue_head(&cpm->i2c_wait); in cpm_i2c_setup()
437 cpm->irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); in cpm_i2c_setup()
438 if (!cpm->irq) in cpm_i2c_setup()
439 return -EINVAL; in cpm_i2c_setup()
442 ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c", in cpm_i2c_setup()
443 &cpm->adap); in cpm_i2c_setup()
448 i2c_base = of_iomap(ofdev->dev.of_node, 1); in cpm_i2c_setup()
450 ret = -EINVAL; in cpm_i2c_setup()
454 if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm1-i2c")) { in cpm_i2c_setup()
457 cpm->i2c_ram = i2c_base; in cpm_i2c_setup()
458 cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase); in cpm_i2c_setup()
464 if (cpm->i2c_addr) { in cpm_i2c_setup()
465 cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); in cpm_i2c_setup()
469 cpm->version = 1; in cpm_i2c_setup()
471 } else if (of_device_is_compatible(ofdev->dev.of_node, "fsl,cpm2-i2c")) { in cpm_i2c_setup()
472 cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64); in cpm_i2c_setup()
473 cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr); in cpm_i2c_setup()
474 out_be16(i2c_base, cpm->i2c_addr); in cpm_i2c_setup()
477 cpm->version = 2; in cpm_i2c_setup()
481 ret = -EINVAL; in cpm_i2c_setup()
486 cpm->i2c_reg = of_iomap(ofdev->dev.of_node, 0); in cpm_i2c_setup()
487 if (cpm->i2c_reg == NULL) { in cpm_i2c_setup()
488 ret = -EINVAL; in cpm_i2c_setup()
492 data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); in cpm_i2c_setup()
494 ret = -EINVAL; in cpm_i2c_setup()
497 cpm->cp_command = *data; in cpm_i2c_setup()
499 data = of_get_property(ofdev->dev.of_node, "linux,i2c-class", &len); in cpm_i2c_setup()
501 cpm->adap.class = *data; in cpm_i2c_setup()
503 data = of_get_property(ofdev->dev.of_node, "clock-frequency", &len); in cpm_i2c_setup()
505 cpm->freq = *data; in cpm_i2c_setup()
507 cpm->freq = 60000; /* use 60kHz i2c clock by default */ in cpm_i2c_setup()
513 cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8); in cpm_i2c_setup()
514 if (!cpm->dp_addr) { in cpm_i2c_setup()
515 ret = -ENOMEM; in cpm_i2c_setup()
519 cpm->tbase = cpm_muram_addr(cpm->dp_addr); in cpm_i2c_setup()
520 cpm->rbase = cpm_muram_addr(cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD); in cpm_i2c_setup()
522 /* Allocate TX and RX buffers */ in cpm_i2c_setup()
524 tbdf = cpm->tbase; in cpm_i2c_setup()
525 rbdf = cpm->rbase; in cpm_i2c_setup()
528 cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev, in cpm_i2c_setup()
530 &cpm->rxdma[i], GFP_KERNEL); in cpm_i2c_setup()
531 if (!cpm->rxbuf[i]) { in cpm_i2c_setup()
532 ret = -ENOMEM; in cpm_i2c_setup()
535 out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1)); in cpm_i2c_setup()
537 cpm->txbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev, in cpm_i2c_setup()
539 &cpm->txdma[i], GFP_KERNEL); in cpm_i2c_setup()
540 if (!cpm->txbuf[i]) { in cpm_i2c_setup()
541 ret = -ENOMEM; in cpm_i2c_setup()
544 out_be32(&tbdf[i].cbd_bufaddr, cpm->txdma[i]); in cpm_i2c_setup()
547 /* Initialize Tx/Rx parameters. */ in cpm_i2c_setup()
551 dev_dbg(&cpm->ofdev->dev, "i2c_ram 0x%p, i2c_addr 0x%04x, freq %d\n", in cpm_i2c_setup()
552 cpm->i2c_ram, cpm->i2c_addr, cpm->freq); in cpm_i2c_setup()
553 dev_dbg(&cpm->ofdev->dev, "tbase 0x%04x, rbase 0x%04x\n", in cpm_i2c_setup()
554 (u8 __iomem *)cpm->tbase - DPRAM_BASE, in cpm_i2c_setup()
555 (u8 __iomem *)cpm->rbase - DPRAM_BASE); in cpm_i2c_setup()
557 cpm_command(cpm->cp_command, CPM_CR_INIT_TRX); in cpm_i2c_setup()
562 out_8(&cpm->i2c_reg->i2add, 0x7f << 1); in cpm_i2c_setup()
569 brg = get_brgfreq() / (32 * 2 * cpm->freq) - 3; in cpm_i2c_setup()
570 out_8(&cpm->i2c_reg->i2brg, brg); in cpm_i2c_setup()
572 out_8(&cpm->i2c_reg->i2mod, 0x00); in cpm_i2c_setup()
573 out_8(&cpm->i2c_reg->i2com, I2COM_MASTER); in cpm_i2c_setup()
576 out_8(&cpm->i2c_reg->i2cmr, 0); in cpm_i2c_setup()
577 out_8(&cpm->i2c_reg->i2cer, 0xff); in cpm_i2c_setup()
583 if (cpm->rxbuf[i]) in cpm_i2c_setup()
584 dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, in cpm_i2c_setup()
585 cpm->rxbuf[i], cpm->rxdma[i]); in cpm_i2c_setup()
586 if (cpm->txbuf[i]) in cpm_i2c_setup()
587 dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, in cpm_i2c_setup()
588 cpm->txbuf[i], cpm->txdma[i]); in cpm_i2c_setup()
590 cpm_muram_free(cpm->dp_addr); in cpm_i2c_setup()
592 iounmap(cpm->i2c_reg); in cpm_i2c_setup()
594 if ((cpm->version == 1) && (!cpm->i2c_addr)) in cpm_i2c_setup()
595 iounmap(cpm->i2c_ram); in cpm_i2c_setup()
596 if (cpm->version == 2) in cpm_i2c_setup()
597 cpm_muram_free(cpm->i2c_addr); in cpm_i2c_setup()
599 free_irq(cpm->irq, &cpm->adap); in cpm_i2c_setup()
608 clrbits8(&cpm->i2c_reg->i2mod, I2MOD_EN); in cpm_i2c_shutdown()
611 out_8(&cpm->i2c_reg->i2cmr, 0); in cpm_i2c_shutdown()
612 out_8(&cpm->i2c_reg->i2cer, 0xff); in cpm_i2c_shutdown()
614 free_irq(cpm->irq, &cpm->adap); in cpm_i2c_shutdown()
618 dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, in cpm_i2c_shutdown()
619 cpm->rxbuf[i], cpm->rxdma[i]); in cpm_i2c_shutdown()
620 dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, in cpm_i2c_shutdown()
621 cpm->txbuf[i], cpm->txdma[i]); in cpm_i2c_shutdown()
624 cpm_muram_free(cpm->dp_addr); in cpm_i2c_shutdown()
625 iounmap(cpm->i2c_reg); in cpm_i2c_shutdown()
627 if ((cpm->version == 1) && (!cpm->i2c_addr)) in cpm_i2c_shutdown()
628 iounmap(cpm->i2c_ram); in cpm_i2c_shutdown()
629 if (cpm->version == 2) in cpm_i2c_shutdown()
630 cpm_muram_free(cpm->i2c_addr); in cpm_i2c_shutdown()
641 return -ENOMEM; in cpm_i2c_probe()
643 cpm->ofdev = ofdev; in cpm_i2c_probe()
647 cpm->adap = cpm_ops; in cpm_i2c_probe()
648 i2c_set_adapdata(&cpm->adap, cpm); in cpm_i2c_probe()
649 cpm->adap.dev.parent = &ofdev->dev; in cpm_i2c_probe()
650 cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node); in cpm_i2c_probe()
654 dev_err(&ofdev->dev, "Unable to init hardware\n"); in cpm_i2c_probe()
660 data = of_get_property(ofdev->dev.of_node, "linux,i2c-index", &len); in cpm_i2c_probe()
661 cpm->adap.nr = (data && len == 4) ? *data : -1; in cpm_i2c_probe()
662 result = i2c_add_numbered_adapter(&cpm->adap); in cpm_i2c_probe()
667 dev_dbg(&ofdev->dev, "hw routines for %s registered.\n", in cpm_i2c_probe()
668 cpm->adap.name); in cpm_i2c_probe()
683 i2c_del_adapter(&cpm->adap); in cpm_i2c_remove()
692 .compatible = "fsl,cpm1-i2c",
695 .compatible = "fsl,cpm2-i2c",
706 .name = "fsl-i2c-cpm",
714 MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");