pwm-dwc.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 "pwm-dwc.h"
  24. /* Elkhart Lake */
  25. static const struct dwc_pwm_info ehl_pwm_info = {
  26. .nr = 2,
  27. .size = 0x1000,
  28. };
  29. static int dwc_pwm_init_one(struct device *dev, struct dwc_pwm_drvdata *ddata, unsigned int idx)
  30. {
  31. struct pwm_chip *chip;
  32. struct dwc_pwm *dwc;
  33. int ret;
  34. chip = dwc_pwm_alloc(dev);
  35. if (IS_ERR(chip))
  36. return PTR_ERR(chip);
  37. dwc = to_dwc_pwm(chip);
  38. dwc->base = ddata->io_base + (ddata->info->size * idx);
  39. ret = devm_pwmchip_add(dev, chip);
  40. if (ret)
  41. return ret;
  42. ddata->chips[idx] = chip;
  43. return 0;
  44. }
  45. static int dwc_pwm_probe(struct pci_dev *pci, const struct pci_device_id *id)
  46. {
  47. const struct dwc_pwm_info *info;
  48. struct device *dev = &pci->dev;
  49. struct dwc_pwm_drvdata *ddata;
  50. unsigned int idx;
  51. int ret;
  52. ret = pcim_enable_device(pci);
  53. if (ret)
  54. return dev_err_probe(dev, ret, "Failed to enable device\n");
  55. pci_set_master(pci);
  56. ret = pcim_iomap_regions(pci, BIT(0), pci_name(pci));
  57. if (ret)
  58. return dev_err_probe(dev, ret, "Failed to iomap PCI BAR\n");
  59. info = (const struct dwc_pwm_info *)id->driver_data;
  60. ddata = devm_kzalloc(dev, struct_size(ddata, chips, info->nr), GFP_KERNEL);
  61. if (!ddata)
  62. return -ENOMEM;
  63. /*
  64. * No need to check for pcim_iomap_table() failure,
  65. * pcim_iomap_regions() already does it for us.
  66. */
  67. ddata->io_base = pcim_iomap_table(pci)[0];
  68. ddata->info = info;
  69. for (idx = 0; idx < ddata->info->nr; idx++) {
  70. ret = dwc_pwm_init_one(dev, ddata, idx);
  71. if (ret)
  72. return ret;
  73. }
  74. dev_set_drvdata(dev, ddata);
  75. pm_runtime_put(dev);
  76. pm_runtime_allow(dev);
  77. return 0;
  78. }
  79. static void dwc_pwm_remove(struct pci_dev *pci)
  80. {
  81. pm_runtime_forbid(&pci->dev);
  82. pm_runtime_get_noresume(&pci->dev);
  83. }
  84. static int dwc_pwm_suspend(struct device *dev)
  85. {
  86. struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
  87. unsigned int idx;
  88. for (idx = 0; idx < ddata->info->nr; idx++) {
  89. struct pwm_chip *chip = ddata->chips[idx];
  90. struct dwc_pwm *dwc = to_dwc_pwm(chip);
  91. unsigned int i;
  92. for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
  93. if (chip->pwms[i].state.enabled) {
  94. dev_err(dev, "PWM %u in use by consumer (%s)\n",
  95. i, chip->pwms[i].label);
  96. return -EBUSY;
  97. }
  98. dwc->ctx[i].cnt = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT(i));
  99. dwc->ctx[i].cnt2 = dwc_pwm_readl(dwc, DWC_TIM_LD_CNT2(i));
  100. dwc->ctx[i].ctrl = dwc_pwm_readl(dwc, DWC_TIM_CTRL(i));
  101. }
  102. }
  103. return 0;
  104. }
  105. static int dwc_pwm_resume(struct device *dev)
  106. {
  107. struct dwc_pwm_drvdata *ddata = dev_get_drvdata(dev);
  108. unsigned int idx;
  109. for (idx = 0; idx < ddata->info->nr; idx++) {
  110. struct pwm_chip *chip = ddata->chips[idx];
  111. struct dwc_pwm *dwc = to_dwc_pwm(chip);
  112. unsigned int i;
  113. for (i = 0; i < DWC_TIMERS_TOTAL; i++) {
  114. dwc_pwm_writel(dwc, dwc->ctx[i].cnt, DWC_TIM_LD_CNT(i));
  115. dwc_pwm_writel(dwc, dwc->ctx[i].cnt2, DWC_TIM_LD_CNT2(i));
  116. dwc_pwm_writel(dwc, dwc->ctx[i].ctrl, DWC_TIM_CTRL(i));
  117. }
  118. }
  119. return 0;
  120. }
  121. static DEFINE_SIMPLE_DEV_PM_OPS(dwc_pwm_pm_ops, dwc_pwm_suspend, dwc_pwm_resume);
  122. static const struct pci_device_id dwc_pwm_id_table[] = {
  123. { PCI_VDEVICE(INTEL, 0x4bb7), (kernel_ulong_t)&ehl_pwm_info },
  124. { } /* Terminating Entry */
  125. };
  126. MODULE_DEVICE_TABLE(pci, dwc_pwm_id_table);
  127. static struct pci_driver dwc_pwm_driver = {
  128. .name = "pwm-dwc",
  129. .probe = dwc_pwm_probe,
  130. .remove = dwc_pwm_remove,
  131. .id_table = dwc_pwm_id_table,
  132. .driver = {
  133. .pm = pm_sleep_ptr(&dwc_pwm_pm_ops),
  134. },
  135. };
  136. module_pci_driver(dwc_pwm_driver);
  137. MODULE_AUTHOR("Felipe Balbi (Intel)");
  138. MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
  139. MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
  140. MODULE_DESCRIPTION("DesignWare PWM Controller");
  141. MODULE_LICENSE("GPL");