mxc_w1.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
  4. * Copyright 2008 Luotao Fu, [email protected]
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/delay.h>
  8. #include <linux/io.h>
  9. #include <linux/ktime.h>
  10. #include <linux/module.h>
  11. #include <linux/mod_devicetable.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/w1.h>
  14. /*
  15. * MXC W1 Register offsets
  16. */
  17. #define MXC_W1_CONTROL 0x00
  18. # define MXC_W1_CONTROL_RDST BIT(3)
  19. # define MXC_W1_CONTROL_WR(x) BIT(5 - (x))
  20. # define MXC_W1_CONTROL_PST BIT(6)
  21. # define MXC_W1_CONTROL_RPP BIT(7)
  22. #define MXC_W1_TIME_DIVIDER 0x02
  23. #define MXC_W1_RESET 0x04
  24. # define MXC_W1_RESET_RST BIT(0)
  25. struct mxc_w1_device {
  26. void __iomem *regs;
  27. struct clk *clk;
  28. struct w1_bus_master bus_master;
  29. };
  30. /*
  31. * this is the low level routine to
  32. * reset the device on the One Wire interface
  33. * on the hardware
  34. */
  35. static u8 mxc_w1_ds2_reset_bus(void *data)
  36. {
  37. struct mxc_w1_device *dev = data;
  38. ktime_t timeout;
  39. writeb(MXC_W1_CONTROL_RPP, dev->regs + MXC_W1_CONTROL);
  40. /* Wait for reset sequence 511+512us, use 1500us for sure */
  41. timeout = ktime_add_us(ktime_get(), 1500);
  42. udelay(511 + 512);
  43. do {
  44. u8 ctrl = readb(dev->regs + MXC_W1_CONTROL);
  45. /* PST bit is valid after the RPP bit is self-cleared */
  46. if (!(ctrl & MXC_W1_CONTROL_RPP))
  47. return !(ctrl & MXC_W1_CONTROL_PST);
  48. } while (ktime_before(ktime_get(), timeout));
  49. return 1;
  50. }
  51. /*
  52. * this is the low level routine to read/write a bit on the One Wire
  53. * interface on the hardware. It does write 0 if parameter bit is set
  54. * to 0, otherwise a write 1/read.
  55. */
  56. static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
  57. {
  58. struct mxc_w1_device *dev = data;
  59. ktime_t timeout;
  60. writeb(MXC_W1_CONTROL_WR(bit), dev->regs + MXC_W1_CONTROL);
  61. /* Wait for read/write bit (60us, Max 120us), use 200us for sure */
  62. timeout = ktime_add_us(ktime_get(), 200);
  63. udelay(60);
  64. do {
  65. u8 ctrl = readb(dev->regs + MXC_W1_CONTROL);
  66. /* RDST bit is valid after the WR1/RD bit is self-cleared */
  67. if (!(ctrl & MXC_W1_CONTROL_WR(bit)))
  68. return !!(ctrl & MXC_W1_CONTROL_RDST);
  69. } while (ktime_before(ktime_get(), timeout));
  70. return 0;
  71. }
  72. static int mxc_w1_probe(struct platform_device *pdev)
  73. {
  74. struct mxc_w1_device *mdev;
  75. unsigned long clkrate;
  76. unsigned int clkdiv;
  77. int err;
  78. mdev = devm_kzalloc(&pdev->dev, sizeof(struct mxc_w1_device),
  79. GFP_KERNEL);
  80. if (!mdev)
  81. return -ENOMEM;
  82. mdev->clk = devm_clk_get(&pdev->dev, NULL);
  83. if (IS_ERR(mdev->clk))
  84. return PTR_ERR(mdev->clk);
  85. err = clk_prepare_enable(mdev->clk);
  86. if (err)
  87. return err;
  88. clkrate = clk_get_rate(mdev->clk);
  89. if (clkrate < 10000000)
  90. dev_warn(&pdev->dev,
  91. "Low clock frequency causes improper function\n");
  92. clkdiv = DIV_ROUND_CLOSEST(clkrate, 1000000);
  93. clkrate /= clkdiv;
  94. if ((clkrate < 980000) || (clkrate > 1020000))
  95. dev_warn(&pdev->dev,
  96. "Incorrect time base frequency %lu Hz\n", clkrate);
  97. mdev->regs = devm_platform_ioremap_resource(pdev, 0);
  98. if (IS_ERR(mdev->regs)) {
  99. err = PTR_ERR(mdev->regs);
  100. goto out_disable_clk;
  101. }
  102. /* Software reset 1-Wire module */
  103. writeb(MXC_W1_RESET_RST, mdev->regs + MXC_W1_RESET);
  104. writeb(0, mdev->regs + MXC_W1_RESET);
  105. writeb(clkdiv - 1, mdev->regs + MXC_W1_TIME_DIVIDER);
  106. mdev->bus_master.data = mdev;
  107. mdev->bus_master.reset_bus = mxc_w1_ds2_reset_bus;
  108. mdev->bus_master.touch_bit = mxc_w1_ds2_touch_bit;
  109. platform_set_drvdata(pdev, mdev);
  110. err = w1_add_master_device(&mdev->bus_master);
  111. if (err)
  112. goto out_disable_clk;
  113. return 0;
  114. out_disable_clk:
  115. clk_disable_unprepare(mdev->clk);
  116. return err;
  117. }
  118. /*
  119. * disassociate the w1 device from the driver
  120. */
  121. static int mxc_w1_remove(struct platform_device *pdev)
  122. {
  123. struct mxc_w1_device *mdev = platform_get_drvdata(pdev);
  124. w1_remove_master_device(&mdev->bus_master);
  125. clk_disable_unprepare(mdev->clk);
  126. return 0;
  127. }
  128. static const struct of_device_id mxc_w1_dt_ids[] = {
  129. { .compatible = "fsl,imx21-owire" },
  130. { /* sentinel */ }
  131. };
  132. MODULE_DEVICE_TABLE(of, mxc_w1_dt_ids);
  133. static struct platform_driver mxc_w1_driver = {
  134. .driver = {
  135. .name = "mxc_w1",
  136. .of_match_table = mxc_w1_dt_ids,
  137. },
  138. .probe = mxc_w1_probe,
  139. .remove = mxc_w1_remove,
  140. };
  141. module_platform_driver(mxc_w1_driver);
  142. MODULE_LICENSE("GPL");
  143. MODULE_AUTHOR("Freescale Semiconductors Inc");
  144. MODULE_DESCRIPTION("Driver for One-Wire on MXC");