0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/bitfield.h>
0017 #include <linux/clk.h>
0018 #include <linux/io.h>
0019 #include <linux/mod_devicetable.h>
0020 #include <linux/module.h>
0021 #include <linux/platform_device.h>
0022 #include <linux/pwm.h>
0023 #include <linux/regmap.h>
0024
0025 #define KMB_TOTAL_PWM_CHANNELS 6
0026 #define KMB_PWM_COUNT_MAX U16_MAX
0027 #define KMB_PWM_EN_BIT BIT(31)
0028
0029
0030 #define KMB_PWM_HIGH_MASK GENMASK(31, 16)
0031 #define KMB_PWM_LOW_MASK GENMASK(15, 0)
0032 #define KMB_PWM_LEADIN_MASK GENMASK(30, 0)
0033
0034
0035 #define KMB_PWM_LEADIN_OFFSET(ch) (0x00 + 4 * (ch))
0036 #define KMB_PWM_HIGHLOW_OFFSET(ch) (0x20 + 4 * (ch))
0037
0038 struct keembay_pwm {
0039 struct pwm_chip chip;
0040 struct device *dev;
0041 struct clk *clk;
0042 void __iomem *base;
0043 };
0044
0045 static inline struct keembay_pwm *to_keembay_pwm_dev(struct pwm_chip *chip)
0046 {
0047 return container_of(chip, struct keembay_pwm, chip);
0048 }
0049
0050 static void keembay_clk_unprepare(void *data)
0051 {
0052 clk_disable_unprepare(data);
0053 }
0054
0055 static int keembay_clk_enable(struct device *dev, struct clk *clk)
0056 {
0057 int ret;
0058
0059 ret = clk_prepare_enable(clk);
0060 if (ret)
0061 return ret;
0062
0063 return devm_add_action_or_reset(dev, keembay_clk_unprepare, clk);
0064 }
0065
0066
0067
0068
0069
0070
0071 static __always_inline void keembay_pwm_update_bits(struct keembay_pwm *priv, u32 mask,
0072 u32 val, u32 offset)
0073 {
0074 u32 buff = readl(priv->base + offset);
0075
0076 buff = u32_replace_bits(buff, val, mask);
0077 writel(buff, priv->base + offset);
0078 }
0079
0080 static void keembay_pwm_enable(struct keembay_pwm *priv, int ch)
0081 {
0082 keembay_pwm_update_bits(priv, KMB_PWM_EN_BIT, 1,
0083 KMB_PWM_LEADIN_OFFSET(ch));
0084 }
0085
0086 static void keembay_pwm_disable(struct keembay_pwm *priv, int ch)
0087 {
0088 keembay_pwm_update_bits(priv, KMB_PWM_EN_BIT, 0,
0089 KMB_PWM_LEADIN_OFFSET(ch));
0090 }
0091
0092 static void keembay_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
0093 struct pwm_state *state)
0094 {
0095 struct keembay_pwm *priv = to_keembay_pwm_dev(chip);
0096 unsigned long long high, low;
0097 unsigned long clk_rate;
0098 u32 highlow;
0099
0100 clk_rate = clk_get_rate(priv->clk);
0101
0102
0103 highlow = readl(priv->base + KMB_PWM_LEADIN_OFFSET(pwm->hwpwm));
0104 if (highlow & KMB_PWM_EN_BIT)
0105 state->enabled = true;
0106 else
0107 state->enabled = false;
0108
0109
0110 highlow = readl(priv->base + KMB_PWM_HIGHLOW_OFFSET(pwm->hwpwm));
0111 low = FIELD_GET(KMB_PWM_LOW_MASK, highlow) * NSEC_PER_SEC;
0112 high = FIELD_GET(KMB_PWM_HIGH_MASK, highlow) * NSEC_PER_SEC;
0113 state->duty_cycle = DIV_ROUND_UP_ULL(high, clk_rate);
0114 state->period = DIV_ROUND_UP_ULL(high + low, clk_rate);
0115 state->polarity = PWM_POLARITY_NORMAL;
0116 }
0117
0118 static int keembay_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0119 const struct pwm_state *state)
0120 {
0121 struct keembay_pwm *priv = to_keembay_pwm_dev(chip);
0122 struct pwm_state current_state;
0123 unsigned long long div;
0124 unsigned long clk_rate;
0125 u32 pwm_count = 0;
0126 u16 high, low;
0127
0128 if (state->polarity != PWM_POLARITY_NORMAL)
0129 return -EINVAL;
0130
0131
0132
0133
0134
0135 keembay_pwm_update_bits(priv, KMB_PWM_LEADIN_MASK, 0,
0136 KMB_PWM_LEADIN_OFFSET(pwm->hwpwm));
0137
0138 keembay_pwm_get_state(chip, pwm, ¤t_state);
0139
0140 if (!state->enabled) {
0141 if (current_state.enabled)
0142 keembay_pwm_disable(priv, pwm->hwpwm);
0143 return 0;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152 clk_rate = clk_get_rate(priv->clk);
0153 div = clk_rate * state->duty_cycle;
0154 div = DIV_ROUND_DOWN_ULL(div, NSEC_PER_SEC);
0155 if (div > KMB_PWM_COUNT_MAX)
0156 return -ERANGE;
0157
0158 high = div;
0159 div = clk_rate * state->period;
0160 div = DIV_ROUND_DOWN_ULL(div, NSEC_PER_SEC);
0161 div = div - high;
0162 if (div > KMB_PWM_COUNT_MAX)
0163 return -ERANGE;
0164
0165 low = div;
0166
0167 pwm_count = FIELD_PREP(KMB_PWM_HIGH_MASK, high) |
0168 FIELD_PREP(KMB_PWM_LOW_MASK, low);
0169
0170 writel(pwm_count, priv->base + KMB_PWM_HIGHLOW_OFFSET(pwm->hwpwm));
0171
0172 if (state->enabled && !current_state.enabled)
0173 keembay_pwm_enable(priv, pwm->hwpwm);
0174
0175 return 0;
0176 }
0177
0178 static const struct pwm_ops keembay_pwm_ops = {
0179 .owner = THIS_MODULE,
0180 .apply = keembay_pwm_apply,
0181 .get_state = keembay_pwm_get_state,
0182 };
0183
0184 static int keembay_pwm_probe(struct platform_device *pdev)
0185 {
0186 struct device *dev = &pdev->dev;
0187 struct keembay_pwm *priv;
0188 int ret;
0189
0190 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0191 if (!priv)
0192 return -ENOMEM;
0193
0194 priv->clk = devm_clk_get(dev, NULL);
0195 if (IS_ERR(priv->clk))
0196 return dev_err_probe(dev, PTR_ERR(priv->clk), "Failed to get clock\n");
0197
0198 priv->base = devm_platform_ioremap_resource(pdev, 0);
0199 if (IS_ERR(priv->base))
0200 return PTR_ERR(priv->base);
0201
0202 ret = keembay_clk_enable(dev, priv->clk);
0203 if (ret)
0204 return ret;
0205
0206 priv->chip.dev = dev;
0207 priv->chip.ops = &keembay_pwm_ops;
0208 priv->chip.npwm = KMB_TOTAL_PWM_CHANNELS;
0209
0210 ret = devm_pwmchip_add(dev, &priv->chip);
0211 if (ret)
0212 return dev_err_probe(dev, ret, "Failed to add PWM chip\n");
0213
0214 return 0;
0215 }
0216
0217 static const struct of_device_id keembay_pwm_of_match[] = {
0218 { .compatible = "intel,keembay-pwm" },
0219 { }
0220 };
0221 MODULE_DEVICE_TABLE(of, keembay_pwm_of_match);
0222
0223 static struct platform_driver keembay_pwm_driver = {
0224 .probe = keembay_pwm_probe,
0225 .driver = {
0226 .name = "pwm-keembay",
0227 .of_match_table = keembay_pwm_of_match,
0228 },
0229 };
0230 module_platform_driver(keembay_pwm_driver);
0231
0232 MODULE_ALIAS("platform:pwm-keembay");
0233 MODULE_DESCRIPTION("Intel Keem Bay PWM driver");
0234 MODULE_LICENSE("GPL v2");