• Home
  • Raw
  • Download

Lines Matching +full:mpc5121 +full:- +full:i2c

2  * (C) Copyright 2003-2004
5 * This is a combined i2c adapter and algorithm driver for the
7 * the same I2C unit (8240, 8245, 85xx).
28 #include <linux/i2c.h>
36 #define DRV_NAME "mpc-i2c"
84 void (*setup)(struct device_node *node, struct mpc_i2c *i2c, u32 clock);
87 static inline void writeccr(struct mpc_i2c *i2c, u32 x) in writeccr() argument
89 writeb(x, i2c->base + MPC_I2C_CR); in writeccr()
94 struct mpc_i2c *i2c = dev_id; in mpc_i2c_isr() local
95 if (readb(i2c->base + MPC_I2C_SR) & CSR_MIF) { in mpc_i2c_isr()
97 i2c->interrupt = readb(i2c->base + MPC_I2C_SR); in mpc_i2c_isr()
98 writeb(0, i2c->base + MPC_I2C_SR); in mpc_i2c_isr()
99 wake_up(&i2c->queue); in mpc_i2c_isr()
110 static void mpc_i2c_fixup(struct mpc_i2c *i2c) in mpc_i2c_fixup() argument
115 for (k = 9; k; k--) { in mpc_i2c_fixup()
116 writeccr(i2c, 0); in mpc_i2c_fixup()
117 writeb(0, i2c->base + MPC_I2C_SR); /* clear any status bits */ in mpc_i2c_fixup()
118 writeccr(i2c, CCR_MEN | CCR_MSTA); /* START */ in mpc_i2c_fixup()
119 readb(i2c->base + MPC_I2C_DR); /* init xfer */ in mpc_i2c_fixup()
122 writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSTA); /* delay SDA */ in mpc_i2c_fixup()
123 readb(i2c->base + MPC_I2C_DR); in mpc_i2c_fixup()
128 writeccr(i2c, CCR_MEN); /* Initiate STOP */ in mpc_i2c_fixup()
129 readb(i2c->base + MPC_I2C_DR); in mpc_i2c_fixup()
131 writeccr(i2c, 0); in mpc_i2c_fixup()
134 static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) in i2c_wait() argument
140 if (!i2c->irq) { in i2c_wait()
141 while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) { in i2c_wait()
144 dev_dbg(i2c->dev, "timeout\n"); in i2c_wait()
145 writeccr(i2c, 0); in i2c_wait()
146 result = -ETIMEDOUT; in i2c_wait()
150 cmd_err = readb(i2c->base + MPC_I2C_SR); in i2c_wait()
151 writeb(0, i2c->base + MPC_I2C_SR); in i2c_wait()
154 result = wait_event_timeout(i2c->queue, in i2c_wait()
155 (i2c->interrupt & CSR_MIF), timeout); in i2c_wait()
157 if (unlikely(!(i2c->interrupt & CSR_MIF))) { in i2c_wait()
158 dev_dbg(i2c->dev, "wait timeout\n"); in i2c_wait()
159 writeccr(i2c, 0); in i2c_wait()
160 result = -ETIMEDOUT; in i2c_wait()
163 cmd_err = i2c->interrupt; in i2c_wait()
164 i2c->interrupt = 0; in i2c_wait()
171 dev_dbg(i2c->dev, "unfinished\n"); in i2c_wait()
172 return -EIO; in i2c_wait()
176 dev_dbg(i2c->dev, "MAL\n"); in i2c_wait()
177 return -EAGAIN; in i2c_wait()
181 dev_dbg(i2c->dev, "No RXAK\n"); in i2c_wait()
183 writeccr(i2c, CCR_MEN); in i2c_wait()
184 return -ENXIO; in i2c_wait()
189 static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) in i2c_mpc_wait_sr() argument
191 void __iomem *addr = i2c->base + MPC_I2C_SR; in i2c_mpc_wait_sr()
201 * 2. I2CCR - a0h
205 * 5. I2CCR - 00h
206 * 6. I2CCR - 22h
207 * 7. I2CCR - a2h
211 * 11. I2CCR - 82h
215 * 15. I2CCR - 80h
217 static void mpc_i2c_fixup_A004447(struct mpc_i2c *i2c) in mpc_i2c_fixup_A004447() argument
222 writeccr(i2c, CCR_MEN | CCR_MSTA); in mpc_i2c_fixup_A004447()
223 ret = i2c_mpc_wait_sr(i2c, CSR_MBB); in mpc_i2c_fixup_A004447()
225 dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); in mpc_i2c_fixup_A004447()
229 val = readb(i2c->base + MPC_I2C_SR); in mpc_i2c_fixup_A004447()
232 writeccr(i2c, 0x00); in mpc_i2c_fixup_A004447()
233 writeccr(i2c, CCR_MSTA | CCR_RSVD); in mpc_i2c_fixup_A004447()
234 writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSVD); in mpc_i2c_fixup_A004447()
235 ret = i2c_mpc_wait_sr(i2c, CSR_MBB); in mpc_i2c_fixup_A004447()
237 dev_err(i2c->dev, "timeout waiting for CSR_MBB\n"); in mpc_i2c_fixup_A004447()
240 val = readb(i2c->base + MPC_I2C_DR); in mpc_i2c_fixup_A004447()
241 ret = i2c_mpc_wait_sr(i2c, CSR_MIF); in mpc_i2c_fixup_A004447()
243 dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); in mpc_i2c_fixup_A004447()
246 writeccr(i2c, CCR_MEN | CCR_RSVD); in mpc_i2c_fixup_A004447()
248 val = readb(i2c->base + MPC_I2C_DR); in mpc_i2c_fixup_A004447()
249 ret = i2c_mpc_wait_sr(i2c, CSR_MIF); in mpc_i2c_fixup_A004447()
251 dev_err(i2c->dev, "timeout waiting for CSR_MIF\n"); in mpc_i2c_fixup_A004447()
254 writeccr(i2c, CCR_MEN); in mpc_i2c_fixup_A004447()
289 /* see below - default fdr = 0x3f -> div = 2048 */ in mpc_i2c_get_fdr_52xx()
291 return -EINVAL; in mpc_i2c_get_fdr_52xx()
298 * We want to choose an FDR/DFSR that generates an I2C bus speed that in mpc_i2c_get_fdr_52xx()
304 if (div->fdr & 0xc0 && pvr == 0x80822011) in mpc_i2c_get_fdr_52xx()
306 if (div->divider >= divider) in mpc_i2c_get_fdr_52xx()
310 *real_clk = mpc5xxx_get_bus_frequency(node) / div->divider; in mpc_i2c_get_fdr_52xx()
311 return (int)div->fdr; in mpc_i2c_get_fdr_52xx()
315 struct mpc_i2c *i2c, in mpc_i2c_setup_52xx() argument
321 dev_dbg(i2c->dev, "using fdr %d\n", in mpc_i2c_setup_52xx()
322 readb(i2c->base + MPC_I2C_FDR)); in mpc_i2c_setup_52xx()
326 ret = mpc_i2c_get_fdr_52xx(node, clock, &i2c->real_clk); in mpc_i2c_setup_52xx()
329 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); in mpc_i2c_setup_52xx()
332 dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk, in mpc_i2c_setup_52xx()
337 struct mpc_i2c *i2c, in mpc_i2c_setup_52xx() argument
345 struct mpc_i2c *i2c, in mpc_i2c_setup_512x() argument
353 /* Enable I2C interrupts for mpc5121 */ in mpc_i2c_setup_512x()
355 "fsl,mpc5121-i2c-ctrl"); in mpc_i2c_setup_512x()
359 /* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */ in mpc_i2c_setup_512x()
369 mpc_i2c_setup_52xx(node, i2c, clock); in mpc_i2c_setup_512x()
373 struct mpc_i2c *i2c, in mpc_i2c_setup_512x() argument
406 node = of_find_node_by_name(NULL, "global-utilities"); in mpc_i2c_get_sec_cfg_8xxx()
423 val = in_be32(reg) & 0x00000020; /* sec-cfg */ in mpc_i2c_get_sec_cfg_8xxx()
436 * may have prescaler 1, 2, or 3, depending on the power-on in mpc_i2c_get_prescaler_8xxx()
476 /* see below - default fdr = 0x1031 -> div = 16 * 3072 */ in mpc_i2c_get_fdr_8xxx()
478 return -EINVAL; in mpc_i2c_get_fdr_8xxx()
483 pr_debug("I2C: src_clock=%d clock=%d divider=%d\n", in mpc_i2c_get_fdr_8xxx()
487 * We want to choose an FDR/DFSR that generates an I2C bus speed that in mpc_i2c_get_fdr_8xxx()
492 if (div->divider >= divider) in mpc_i2c_get_fdr_8xxx()
496 *real_clk = fsl_get_sys_freq() / prescaler / div->divider; in mpc_i2c_get_fdr_8xxx()
497 return div ? (int)div->fdr : -EINVAL; in mpc_i2c_get_fdr_8xxx()
501 struct mpc_i2c *i2c, in mpc_i2c_setup_8xxx() argument
507 dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n", in mpc_i2c_setup_8xxx()
508 readb(i2c->base + MPC_I2C_DFSRR), in mpc_i2c_setup_8xxx()
509 readb(i2c->base + MPC_I2C_FDR)); in mpc_i2c_setup_8xxx()
513 ret = mpc_i2c_get_fdr_8xxx(node, clock, &i2c->real_clk); in mpc_i2c_setup_8xxx()
516 writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR); in mpc_i2c_setup_8xxx()
517 writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR); in mpc_i2c_setup_8xxx()
520 dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n", in mpc_i2c_setup_8xxx()
521 i2c->real_clk, fdr >> 8, fdr & 0xff); in mpc_i2c_setup_8xxx()
526 struct mpc_i2c *i2c, in mpc_i2c_setup_8xxx() argument
532 static void mpc_i2c_start(struct mpc_i2c *i2c) in mpc_i2c_start() argument
535 writeb(0, i2c->base + MPC_I2C_SR); in mpc_i2c_start()
537 writeccr(i2c, CCR_MEN); in mpc_i2c_start()
540 static void mpc_i2c_stop(struct mpc_i2c *i2c) in mpc_i2c_stop() argument
542 writeccr(i2c, CCR_MEN); in mpc_i2c_stop()
545 static int mpc_write(struct mpc_i2c *i2c, int target, in mpc_write() argument
549 unsigned timeout = i2c->adap.timeout; in mpc_write()
553 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); in mpc_write()
555 writeb((target << 1), i2c->base + MPC_I2C_DR); in mpc_write()
557 result = i2c_wait(i2c, timeout, 1); in mpc_write()
563 writeb(data[i], i2c->base + MPC_I2C_DR); in mpc_write()
565 result = i2c_wait(i2c, timeout, 1); in mpc_write()
573 static int mpc_read(struct mpc_i2c *i2c, int target, in mpc_read() argument
576 unsigned timeout = i2c->adap.timeout; in mpc_read()
580 /* Switch to read - restart */ in mpc_read()
581 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags); in mpc_read()
582 /* Write target address byte - this time with the read flag set */ in mpc_read()
583 writeb((target << 1) | 1, i2c->base + MPC_I2C_DR); in mpc_read()
585 result = i2c_wait(i2c, timeout, 1); in mpc_read()
591 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK); in mpc_read()
593 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA); in mpc_read()
595 readb(i2c->base + MPC_I2C_DR); in mpc_read()
601 result = i2c_wait(i2c, timeout, 0); in mpc_read()
611 if (i == length - 2) in mpc_read()
612 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA in mpc_read()
615 if (i == length - 1) in mpc_read()
616 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA in mpc_read()
620 byte = readb(i2c->base + MPC_I2C_DR); in mpc_read()
628 return -EPROTO; in mpc_read()
635 writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA in mpc_read()
650 struct mpc_i2c *i2c = i2c_get_adapdata(adap); in mpc_xfer() local
652 mpc_i2c_start(i2c); in mpc_xfer()
655 while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) { in mpc_xfer()
657 dev_dbg(i2c->dev, "Interrupted\n"); in mpc_xfer()
658 writeccr(i2c, 0); in mpc_xfer()
659 return -EINTR; in mpc_xfer()
662 u8 status = readb(i2c->base + MPC_I2C_SR); in mpc_xfer()
664 dev_dbg(i2c->dev, "timeout\n"); in mpc_xfer()
667 i2c->base + MPC_I2C_SR); in mpc_xfer()
668 i2c_recover_bus(&i2c->adap); in mpc_xfer()
670 return -EIO; in mpc_xfer()
677 dev_dbg(i2c->dev, in mpc_xfer()
678 "Doing %s %d bytes to 0x%02x - %d of %d messages\n", in mpc_xfer()
679 pmsg->flags & I2C_M_RD ? "read" : "write", in mpc_xfer()
680 pmsg->len, pmsg->addr, i + 1, num); in mpc_xfer()
681 if (pmsg->flags & I2C_M_RD) { in mpc_xfer()
682 bool recv_len = pmsg->flags & I2C_M_RECV_LEN; in mpc_xfer()
684 ret = mpc_read(i2c, pmsg->addr, pmsg->buf, pmsg->len, i, in mpc_xfer()
687 pmsg->len = ret; in mpc_xfer()
690 mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i); in mpc_xfer()
693 mpc_i2c_stop(i2c); /* Initiate STOP */ in mpc_xfer()
696 while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) { in mpc_xfer()
698 u8 status = readb(i2c->base + MPC_I2C_SR); in mpc_xfer()
700 dev_dbg(i2c->dev, "timeout\n"); in mpc_xfer()
703 i2c->base + MPC_I2C_SR); in mpc_xfer()
704 i2c_recover_bus(&i2c->adap); in mpc_xfer()
706 return -EIO; in mpc_xfer()
721 struct mpc_i2c *i2c = i2c_get_adapdata(adap); in fsl_i2c_bus_recovery() local
723 if (i2c->has_errata_A004447) in fsl_i2c_bus_recovery()
724 mpc_i2c_fixup_A004447(i2c); in fsl_i2c_bus_recovery()
726 mpc_i2c_fixup(i2c); in fsl_i2c_bus_recovery()
750 struct mpc_i2c *i2c; in fsl_i2c_probe() local
759 match = of_match_device(mpc_i2c_of_match, &op->dev); in fsl_i2c_probe()
761 return -EINVAL; in fsl_i2c_probe()
763 i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); in fsl_i2c_probe()
764 if (!i2c) in fsl_i2c_probe()
765 return -ENOMEM; in fsl_i2c_probe()
767 i2c->dev = &op->dev; /* for debug and error output */ in fsl_i2c_probe()
769 init_waitqueue_head(&i2c->queue); in fsl_i2c_probe()
771 i2c->base = of_iomap(op->dev.of_node, 0); in fsl_i2c_probe()
772 if (!i2c->base) { in fsl_i2c_probe()
773 dev_err(i2c->dev, "failed to map controller\n"); in fsl_i2c_probe()
774 result = -ENOMEM; in fsl_i2c_probe()
778 i2c->irq = irq_of_parse_and_map(op->dev.of_node, 0); in fsl_i2c_probe()
779 if (i2c->irq) { /* no i2c->irq implies polling */ in fsl_i2c_probe()
780 result = request_irq(i2c->irq, mpc_i2c_isr, in fsl_i2c_probe()
781 IRQF_SHARED, "i2c-mpc", i2c); in fsl_i2c_probe()
783 dev_err(i2c->dev, "failed to attach interrupt\n"); in fsl_i2c_probe()
789 * enable clock for the I2C peripheral (non fatal), in fsl_i2c_probe()
792 clk = devm_clk_get(&op->dev, NULL); in fsl_i2c_probe()
796 dev_err(&op->dev, "failed to enable clock\n"); in fsl_i2c_probe()
799 i2c->clk_per = clk; in fsl_i2c_probe()
803 if (of_property_read_bool(op->dev.of_node, "fsl,preserve-clocking")) { in fsl_i2c_probe()
806 prop = of_get_property(op->dev.of_node, "clock-frequency", in fsl_i2c_probe()
812 if (match->data) { in fsl_i2c_probe()
813 const struct mpc_i2c_data *data = match->data; in fsl_i2c_probe()
814 data->setup(op->dev.of_node, i2c, clock); in fsl_i2c_probe()
817 if (of_get_property(op->dev.of_node, "dfsrr", NULL)) in fsl_i2c_probe()
818 mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock); in fsl_i2c_probe()
821 prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen); in fsl_i2c_probe()
827 dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ); in fsl_i2c_probe()
829 platform_set_drvdata(op, i2c); in fsl_i2c_probe()
830 if (of_property_read_bool(op->dev.of_node, "fsl,i2c-erratum-a004447")) in fsl_i2c_probe()
831 i2c->has_errata_A004447 = true; in fsl_i2c_probe()
833 i2c->adap = mpc_ops; in fsl_i2c_probe()
834 of_address_to_resource(op->dev.of_node, 0, &res); in fsl_i2c_probe()
835 scnprintf(i2c->adap.name, sizeof(i2c->adap.name), in fsl_i2c_probe()
837 i2c_set_adapdata(&i2c->adap, i2c); in fsl_i2c_probe()
838 i2c->adap.dev.parent = &op->dev; in fsl_i2c_probe()
839 i2c->adap.dev.of_node = of_node_get(op->dev.of_node); in fsl_i2c_probe()
840 i2c->adap.bus_recovery_info = &fsl_i2c_recovery_info; in fsl_i2c_probe()
842 result = i2c_add_adapter(&i2c->adap); in fsl_i2c_probe()
849 if (i2c->clk_per) in fsl_i2c_probe()
850 clk_disable_unprepare(i2c->clk_per); in fsl_i2c_probe()
851 free_irq(i2c->irq, i2c); in fsl_i2c_probe()
853 irq_dispose_mapping(i2c->irq); in fsl_i2c_probe()
854 iounmap(i2c->base); in fsl_i2c_probe()
856 kfree(i2c); in fsl_i2c_probe()
862 struct mpc_i2c *i2c = platform_get_drvdata(op); in fsl_i2c_remove() local
864 i2c_del_adapter(&i2c->adap); in fsl_i2c_remove()
866 if (i2c->clk_per) in fsl_i2c_remove()
867 clk_disable_unprepare(i2c->clk_per); in fsl_i2c_remove()
869 if (i2c->irq) in fsl_i2c_remove()
870 free_irq(i2c->irq, i2c); in fsl_i2c_remove()
872 irq_dispose_mapping(i2c->irq); in fsl_i2c_remove()
873 iounmap(i2c->base); in fsl_i2c_remove()
874 kfree(i2c); in fsl_i2c_remove()
881 struct mpc_i2c *i2c = dev_get_drvdata(dev); in mpc_i2c_suspend() local
883 i2c->fdr = readb(i2c->base + MPC_I2C_FDR); in mpc_i2c_suspend()
884 i2c->dfsrr = readb(i2c->base + MPC_I2C_DFSRR); in mpc_i2c_suspend()
891 struct mpc_i2c *i2c = dev_get_drvdata(dev); in mpc_i2c_resume() local
893 writeb(i2c->fdr, i2c->base + MPC_I2C_FDR); in mpc_i2c_resume()
894 writeb(i2c->dfsrr, i2c->base + MPC_I2C_DFSRR); in mpc_i2c_resume()
926 {.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
927 {.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
928 {.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
929 {.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
930 {.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
931 {.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
932 {.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
934 {.compatible = "fsl-i2c", },
953 MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "