pwm-dwc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DesignWare PWM Controller driver (PCI part)
  4. *
  5. * Copyright (C) 2018-2020 Intel Corporation
  6. *
  7. * Author: Felipe Balbi (Intel)
  8. * Author: Jarkko Nikula <jarkko.nikula@linux.intel.com>
  9. * Author: Raymond Tan <raymond.tan@intel.com>
  10. *
  11. * Limitations:
  12. * - The hardware cannot generate a 0 % or 100 % duty cycle. Both high and low
  13. * periods are one or more input clock periods long.
  14. */
  15. #define DEFAULT_MOUDLE_NAMESPACE dwc_pwm
  16. #include <linux/bitops.h>
  17. #include <linux/export.h>
  18. #include <linux/kernel.h>
  19. #include <linux/module.h>
  20. #include <linux/pci.h>
  21. #include <linux/pm_runtime.h>
  22. #include <linux/pwm.h>
  23. #include <linux/sizes.h>
  24. #include "pwm-dwc.h"
  25. /* Elkhart Lake */
  26. static const struct dwc_pwm_info ehl_pwm_info = {
  27. .nr = 2,
  28. .size = SZ_4K,
  29. };
  30. static int dwc_pwm_init_one(struct device *dev, struct dwc_pwm_drvdata *ddata, unsigned int idx)
  31. {
  32. struct pwm_chip *chip;
  33. struct dwc_pwm *dwc;
  34. int ret;
  35. chip = dwc_pwm_alloc(dev);
  36. if (IS_ERR(chip))
  37. return PTR_ERR(chip);
  38. dwc = to_dwc_pwm(chip);
  39. dwc->base = ddata->io_base + (ddata->info->size * idx);
  40. ret = devm_pwmchip_add(dev, chip);
  41. if (ret)
  42. return ret;
  43. ddata->chips[idx] = chip;
  44. return 0;
  45. }
  46. static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
  47. {
  48. const struct dwc_pwm_info *info;
  49. struct device *dev = &pci->dev;
  50. struct dwc_pwm_drvdata *ddata;
  51. unsigned int idx;
  52. int ret;
  53. ret = pcim_enable_device(pci);
  54. if (ret)
  55. return dev_err_probe(dev, ret, "Failed to enable device\n");
  56. pci_set_master(pci);
  57. info = (const struct dwc_pwm_info *)id->driver_data;
  58. ddata = devm_kzalloc(dev, struct_size(ddata, chips, info->nr), GFP_KERNEL);
  59. if (!ddata)
  60. return -ENOMEM;
  61. ddata->io_base = pcim_iomap_region(pci, 0, "pwm-dwc");
  62. if (IS_ERR(ddata->io_base))
  63. return dev_err_probe(dev, PTR_ERR(ddata->io_base),
  64. "Failed to request / iomap PCI BAR\n");
  65. ddata->info = info;
  66. for (idx = 0; idx < ddata->info->nr; idx++) {
  67. ret = dwc_pwm_init_one(dev, ddata, idx);
  68. if (ret)
  69. return ret;
  70. }
  71. dev_set_drvdata(dev, ddata);
  72. pm_runtime_put(dev);
  73. pm_runtime_allow(dev);
  74. return 0;
  75. }
  76. static void dwc_pwm_remove(struct pci_dev *pci)
  77. {
  78. pm_runtime_forbid(&pci->dev);
  79. pm_runtime_get_noresume(&pci->dev);
  80. }
  81. static int dwc_pwm_suspend(struct device *dev)
  82. {
  83. struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
  84. unsigned int idx;
  85. for (idx = 0; idx < ddata->info->nr; idx++) {
  86. struct pwm_chip *chip = ddata->chips[idx];
  87. struct dwc_pwm *dwc = to_dwc_pwm(chip);
  88. unsigned int i;
  89. for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
  90. if (chip->pwms[i].state.enabled) {
  91. dev_err(dev, "PWM %u in use by consumer (%s)\n",
  92. i, chip->pwms[i].label);
  93. return -EBUSY;
  94. }
  95. dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
  96. dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
  97. dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
  98. }
  99. }
  100. return 0;
  101. }
  102. static int dwc_pwm_resume(struct device *dev)
  103. {
  104. struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
  105. unsigned int idx;
  106. for (idx = 0; idx < ddata->info->nr; idx++) {
  107. struct pwm_chip *chip = ddata->chips[idx];
  108. struct dwc_pwm *dwc = to_dwc_pwm(chip);
  109. unsigned int i;
  110. for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
  111. dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
  112. dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
  113. dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
  114. }
  115. }
  116. return 0;
  117. }
  118. static DEFINE_SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume);
  119. static const struct pci_device_id dwc_pwm_id_table[] = {
  120. { PCI_VDEVICE(INTEL, 0x4bb7), (kernel_ulong_t)&ehl_pwm_info },
  121. { } /* Terminating Entry */
  122. };
  123. MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);
  124. static struct pci_driver dwc_pwm_driver = {
  125. .name = "pwm-dwc",
  126. .probe = dwc_pwm_probe,
  127. .remove = dwc_pwm_remove,
  128. .id_table = dwc_pwm_id_table,
  129. .driver = {
  130. .pm = pm_sleep_ptr(&dwc_pwm_pm_ops),
  131. },
  132. };
  133. module_pci_driver(dwc_pwm_driver);
  134. MODULE_AUTHOR("Felipe Balbi (Intel)");
  135. MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
  136. MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
  137. MODULE_DESCRIPTION("DesignWare PWM Controller");
  138. MODULE_LICENSE("GPL");