Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * * Author: Arun R Murthy <arun.murthy@stericsson.com> * Datasheet: https://web.archive.org/web/20130614115108/http://www.stericsson.com/developers/CD00291561_UM1031_AB8500_user_manual-rev5_CTDS_public.pdf */ #include <linux/err.h> #include <linux/platform_device.h> #include <linux/slab.h> #include <linux/pwm.h> #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500.h> #include <linux/module.h> /* * PWM Out generators * Bank: 0x10 */ #define AB8500_PWM_OUT_CTRL1_REG 0x60 #define AB8500_PWM_OUT_CTRL2_REG 0x61 #define AB8500_PWM_OUT_CTRL7_REG 0x66 #define AB8500_PWM_CLKRATE 9600000 struct ab8500_pwm_chip { struct pwm_chip chip; unsigned int hwid; }; static struct ab8500_pwm_chip *ab8500_pwm_from_chip(struct pwm_chip *chip) { return container_of(chip, struct ab8500_pwm_chip, chip); } static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, const struct pwm_state *state) { int ret; u8 reg; u8 higher_val, lower_val; unsigned int duty_steps, div; struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); if (state->polarity != PWM_POLARITY_NORMAL) return -EINVAL; if (state->enabled) { /* * A time quantum is * q = (32 - FreqPWMOutx[3:0]) / AB8500_PWM_CLKRATE * The period is always 1024 q, duty_cycle is between 1q and 1024q. * * FreqPWMOutx[3:0] | output frequency | output frequency | 1024q = period * | (from manual) | (1 / 1024q) | = 1 / freq * -----------------+------------------+------------------+-------------- * b0000 | 293 Hz | 292.968750 Hz | 3413333.33 ns * b0001 | 302 Hz | 302.419355 Hz | 3306666.66 ns * b0010 | 312 Hz | 312.500000 Hz | 3200000 ns * b0011 | 323 Hz | 323.275862 Hz | 3093333.33 ns * b0100 | 334 Hz | 334.821429 Hz | 2986666.66 ns * b0101 | 347 Hz | 347.222222 Hz | 2880000 ns * b0110 | 360 Hz | 360.576923 Hz | 2773333.33 ns * b0111 | 375 Hz | 375.000000 Hz | 2666666.66 ns * b1000 | 390 Hz | 390.625000 Hz | 2560000 ns * b1001 | 407 Hz | 407.608696 Hz | 2453333.33 ns * b1010 | 426 Hz | 426.136364 Hz | 2346666.66 ns * b1011 | 446 Hz | 446.428571 Hz | 2240000 ns * b1100 | 468 Hz | 468.750000 Hz | 2133333.33 ns * b1101 | 493 Hz | 493.421053 Hz | 2026666.66 ns * b1110 | 520 Hz | 520.833333 Hz | 1920000 ns * b1111 | 551 Hz | 551.470588 Hz | 1813333.33 ns * * * AB8500_PWM_CLKRATE is a multiple of 1024, so the division by * 1024 can be done in this factor without loss of precision. */ div = min_t(u64, mul_u64_u64_div_u64(state->period, AB8500_PWM_CLKRATE >> 10, NSEC_PER_SEC), 32); /* 32 - FreqPWMOutx[3:0] */ if (div <= 16) /* requested period < 3413333.33 */ return -EINVAL; duty_steps = max_t(u64, mul_u64_u64_div_u64(state->duty_cycle, AB8500_PWM_CLKRATE, (u64)NSEC_PER_SEC * div), 1024); } /* * The hardware doesn't support duty_steps = 0 explicitly, but emits low * when disabled. */ if (!state->enabled || duty_steps == 0) { ret = abx500_mask_and_set_register_interruptible(chip->dev, AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 1 << ab8500->hwid, 0); if (ret < 0) dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", pwm->label, ret); return ret; } /* * The lower 8 bits of duty_steps is written to ... * AB8500_PWM_OUT_CTRL1_REG[0:7] */ lower_val = (duty_steps - 1) & 0x00ff; /* * The two remaining high bits to * AB8500_PWM_OUT_CTRL2_REG[0:1]; together with FreqPWMOutx. */ higher_val = ((duty_steps - 1) & 0x0300) >> 8 | (32 - div) << 4; reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2); ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, reg, lower_val); if (ret < 0) return ret; ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, (reg + 1), higher_val); if (ret < 0) return ret; /* enable */ ret = abx500_mask_and_set_register_interruptible(chip->dev, AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 1 << ab8500->hwid, 1 << ab8500->hwid); if (ret < 0) dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", pwm->label, ret); return ret; } static int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, struct pwm_state *state) { u8 ctrl7, lower_val, higher_val; int ret; struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); unsigned int div, duty_steps; ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, &ctrl7); if (ret) return ret; state->polarity = PWM_POLARITY_NORMAL; if (!(ctrl7 & 1 << ab8500->hwid)) { state->enabled = false; return 0; } ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2), &lower_val); if (ret) return ret; ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2), &higher_val); if (ret) return ret; div = 32 - ((higher_val & 0xf0) >> 4); duty_steps = ((higher_val & 3) << 8 | lower_val) + 1; state->period = DIV64_U64_ROUND_UP((u64)div << 10, AB8500_PWM_CLKRATE); state->duty_cycle = DIV64_U64_ROUND_UP((u64)div * duty_steps, AB8500_PWM_CLKRATE); return 0; } static const struct pwm_ops ab8500_pwm_ops = { .apply = ab8500_pwm_apply, .get_state = ab8500_pwm_get_state, .owner = THIS_MODULE, }; static int ab8500_pwm_probe(struct platform_device *pdev) { struct ab8500_pwm_chip *ab8500; int err; if (pdev->id < 1 || pdev->id > 31) return dev_err_probe(&pdev->dev, -EINVAL, "Invalid device id %d\n", pdev->id); /* * Nothing to be done in probe, this is required to get the * device which is required for ab8500 read and write */ ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); if (ab8500 == NULL) return -ENOMEM; ab8500->chip.dev = &pdev->dev; ab8500->chip.ops = &ab8500_pwm_ops; ab8500->chip.npwm = 1; ab8500->hwid = pdev->id - 1; err = devm_pwmchip_add(&pdev->dev, &ab8500->chip); if (err < 0) return dev_err_probe(&pdev->dev, err, "Failed to add pwm chip\n"); dev_dbg(&pdev->dev, "pwm probe successful\n"); return 0; } static struct platform_driver ab8500_pwm_driver = { .driver = { .name = "ab8500-pwm", }, .probe = ab8500_pwm_probe, }; module_platform_driver(ab8500_pwm_driver); MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>"); MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver"); MODULE_ALIAS("platform:ab8500-pwm"); MODULE_LICENSE("GPL v2"); |