0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/clk.h>
0012 #include <linux/err.h>
0013 #include <linux/gpio.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mfd/ingenic-tcu.h>
0016 #include <linux/mfd/syscon.h>
0017 #include <linux/module.h>
0018 #include <linux/of_device.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/pwm.h>
0021 #include <linux/regmap.h>
0022
0023 struct soc_info {
0024 unsigned int num_pwms;
0025 };
0026
0027 struct jz4740_pwm_chip {
0028 struct pwm_chip chip;
0029 struct regmap *map;
0030 };
0031
0032 static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
0033 {
0034 return container_of(chip, struct jz4740_pwm_chip, chip);
0035 }
0036
0037 static bool jz4740_pwm_can_use_chn(struct jz4740_pwm_chip *jz,
0038 unsigned int channel)
0039 {
0040
0041 u32 pwm_channels_mask = GENMASK(jz->chip.npwm - 1, 2);
0042
0043 device_property_read_u32(jz->chip.dev->parent,
0044 "ingenic,pwm-channels-mask",
0045 &pwm_channels_mask);
0046
0047 return !!(pwm_channels_mask & BIT(channel));
0048 }
0049
0050 static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
0051 {
0052 struct jz4740_pwm_chip *jz = to_jz4740(chip);
0053 struct clk *clk;
0054 char name[16];
0055 int err;
0056
0057 if (!jz4740_pwm_can_use_chn(jz, pwm->hwpwm))
0058 return -EBUSY;
0059
0060 snprintf(name, sizeof(name), "timer%u", pwm->hwpwm);
0061
0062 clk = clk_get(chip->dev, name);
0063 if (IS_ERR(clk))
0064 return dev_err_probe(chip->dev, PTR_ERR(clk),
0065 "Failed to get clock\n");
0066
0067 err = clk_prepare_enable(clk);
0068 if (err < 0) {
0069 clk_put(clk);
0070 return err;
0071 }
0072
0073 pwm_set_chip_data(pwm, clk);
0074
0075 return 0;
0076 }
0077
0078 static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
0079 {
0080 struct clk *clk = pwm_get_chip_data(pwm);
0081
0082 clk_disable_unprepare(clk);
0083 clk_put(clk);
0084 }
0085
0086 static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
0087 {
0088 struct jz4740_pwm_chip *jz = to_jz4740(chip);
0089
0090
0091 regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
0092 TCU_TCSR_PWM_EN, TCU_TCSR_PWM_EN);
0093
0094
0095 regmap_write(jz->map, TCU_REG_TESR, BIT(pwm->hwpwm));
0096
0097 return 0;
0098 }
0099
0100 static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
0101 {
0102 struct jz4740_pwm_chip *jz = to_jz4740(chip);
0103
0104
0105
0106
0107
0108 regmap_write(jz->map, TCU_REG_TDHRc(pwm->hwpwm), 0xffff);
0109 regmap_write(jz->map, TCU_REG_TDFRc(pwm->hwpwm), 0x0);
0110
0111
0112
0113
0114
0115
0116 regmap_update_bits(jz->map, TCU_REG_TCSRc(pwm->hwpwm),
0117 TCU_TCSR_PWM_EN, 0);
0118
0119
0120 regmap_write(jz->map, TCU_REG_TECR, BIT(pwm->hwpwm));
0121 }
0122
0123 static int jz4740_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0124 const struct pwm_state *state)
0125 {
0126 struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
0127 unsigned long long tmp = 0xffffull * NSEC_PER_SEC;
0128 struct clk *clk = pwm_get_chip_data(pwm);
0129 unsigned long period, duty;
0130 long rate;
0131 int err;
0132
0133
0134
0135
0136
0137 do_div(tmp, state->period);
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 rate = clk_round_rate(clk, tmp);
0151 if (rate < 0) {
0152 dev_err(chip->dev, "Unable to round rate: %ld", rate);
0153 return rate;
0154 }
0155
0156
0157 tmp = (unsigned long long)rate * state->period;
0158 do_div(tmp, NSEC_PER_SEC);
0159 period = tmp;
0160
0161
0162 tmp = (unsigned long long)rate * state->duty_cycle;
0163 do_div(tmp, NSEC_PER_SEC);
0164 duty = tmp;
0165
0166 if (duty >= period)
0167 duty = period - 1;
0168
0169 jz4740_pwm_disable(chip, pwm);
0170
0171 err = clk_set_rate(clk, rate);
0172 if (err) {
0173 dev_err(chip->dev, "Unable to set rate: %d", err);
0174 return err;
0175 }
0176
0177
0178 regmap_write(jz4740->map, TCU_REG_TCNTc(pwm->hwpwm), 0);
0179
0180
0181 regmap_write(jz4740->map, TCU_REG_TDHRc(pwm->hwpwm), duty);
0182
0183
0184 regmap_write(jz4740->map, TCU_REG_TDFRc(pwm->hwpwm), period);
0185
0186
0187 regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0188 TCU_TCSR_PWM_SD, TCU_TCSR_PWM_SD);
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 if ((state->polarity == PWM_POLARITY_NORMAL) ^ state->enabled)
0204 regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0205 TCU_TCSR_PWM_INITL_HIGH, 0);
0206 else
0207 regmap_update_bits(jz4740->map, TCU_REG_TCSRc(pwm->hwpwm),
0208 TCU_TCSR_PWM_INITL_HIGH,
0209 TCU_TCSR_PWM_INITL_HIGH);
0210
0211 if (state->enabled)
0212 jz4740_pwm_enable(chip, pwm);
0213
0214 return 0;
0215 }
0216
0217 static const struct pwm_ops jz4740_pwm_ops = {
0218 .request = jz4740_pwm_request,
0219 .free = jz4740_pwm_free,
0220 .apply = jz4740_pwm_apply,
0221 .owner = THIS_MODULE,
0222 };
0223
0224 static int jz4740_pwm_probe(struct platform_device *pdev)
0225 {
0226 struct device *dev = &pdev->dev;
0227 struct jz4740_pwm_chip *jz4740;
0228 const struct soc_info *info;
0229
0230 info = device_get_match_data(dev);
0231 if (!info)
0232 return -EINVAL;
0233
0234 jz4740 = devm_kzalloc(dev, sizeof(*jz4740), GFP_KERNEL);
0235 if (!jz4740)
0236 return -ENOMEM;
0237
0238 jz4740->map = device_node_to_regmap(dev->parent->of_node);
0239 if (IS_ERR(jz4740->map)) {
0240 dev_err(dev, "regmap not found: %ld\n", PTR_ERR(jz4740->map));
0241 return PTR_ERR(jz4740->map);
0242 }
0243
0244 jz4740->chip.dev = dev;
0245 jz4740->chip.ops = &jz4740_pwm_ops;
0246 jz4740->chip.npwm = info->num_pwms;
0247
0248 return devm_pwmchip_add(dev, &jz4740->chip);
0249 }
0250
0251 static const struct soc_info __maybe_unused jz4740_soc_info = {
0252 .num_pwms = 8,
0253 };
0254
0255 static const struct soc_info __maybe_unused jz4725b_soc_info = {
0256 .num_pwms = 6,
0257 };
0258
0259 static const struct soc_info __maybe_unused x1000_soc_info = {
0260 .num_pwms = 5,
0261 };
0262
0263 #ifdef CONFIG_OF
0264 static const struct of_device_id jz4740_pwm_dt_ids[] = {
0265 { .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
0266 { .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
0267 { .compatible = "ingenic,x1000-pwm", .data = &x1000_soc_info },
0268 {},
0269 };
0270 MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
0271 #endif
0272
0273 static struct platform_driver jz4740_pwm_driver = {
0274 .driver = {
0275 .name = "jz4740-pwm",
0276 .of_match_table = of_match_ptr(jz4740_pwm_dt_ids),
0277 },
0278 .probe = jz4740_pwm_probe,
0279 };
0280 module_platform_driver(jz4740_pwm_driver);
0281
0282 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
0283 MODULE_DESCRIPTION("Ingenic JZ4740 PWM driver");
0284 MODULE_ALIAS("platform:jz4740-pwm");
0285 MODULE_LICENSE("GPL");