0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/device.h>
0018 #include <linux/kernel.h>
0019 #include <linux/mfd/iqs62x.h>
0020 #include <linux/module.h>
0021 #include <linux/mutex.h>
0022 #include <linux/notifier.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/pwm.h>
0025 #include <linux/regmap.h>
0026 #include <linux/slab.h>
0027
0028 #define IQS620_PWR_SETTINGS 0xd2
0029 #define IQS620_PWR_SETTINGS_PWM_OUT BIT(7)
0030
0031 #define IQS620_PWM_DUTY_CYCLE 0xd8
0032
0033 #define IQS620_PWM_PERIOD_NS 1000000
0034
0035 struct iqs620_pwm_private {
0036 struct iqs62x_core *iqs62x;
0037 struct pwm_chip chip;
0038 struct notifier_block notifier;
0039 struct mutex lock;
0040 unsigned int duty_scale;
0041 };
0042
0043 static int iqs620_pwm_init(struct iqs620_pwm_private *iqs620_pwm,
0044 unsigned int duty_scale)
0045 {
0046 struct iqs62x_core *iqs62x = iqs620_pwm->iqs62x;
0047 int ret;
0048
0049 if (!duty_scale)
0050 return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
0051 IQS620_PWR_SETTINGS_PWM_OUT, 0);
0052
0053 ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
0054 duty_scale - 1);
0055 if (ret)
0056 return ret;
0057
0058 return regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
0059 IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
0060 }
0061
0062 static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
0063 const struct pwm_state *state)
0064 {
0065 struct iqs620_pwm_private *iqs620_pwm;
0066 unsigned int duty_cycle;
0067 unsigned int duty_scale;
0068 int ret;
0069
0070 if (state->polarity != PWM_POLARITY_NORMAL)
0071 return -EINVAL;
0072
0073 if (state->period < IQS620_PWM_PERIOD_NS)
0074 return -EINVAL;
0075
0076 iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 duty_cycle = min_t(u64, state->duty_cycle, IQS620_PWM_PERIOD_NS);
0091 duty_scale = duty_cycle * 256 / IQS620_PWM_PERIOD_NS;
0092
0093 if (!state->enabled)
0094 duty_scale = 0;
0095
0096 mutex_lock(&iqs620_pwm->lock);
0097
0098 ret = iqs620_pwm_init(iqs620_pwm, duty_scale);
0099 if (!ret)
0100 iqs620_pwm->duty_scale = duty_scale;
0101
0102 mutex_unlock(&iqs620_pwm->lock);
0103
0104 return ret;
0105 }
0106
0107 static void iqs620_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
0108 struct pwm_state *state)
0109 {
0110 struct iqs620_pwm_private *iqs620_pwm;
0111
0112 iqs620_pwm = container_of(chip, struct iqs620_pwm_private, chip);
0113
0114 mutex_lock(&iqs620_pwm->lock);
0115
0116
0117
0118
0119
0120
0121
0122 state->enabled = iqs620_pwm->duty_scale > 0;
0123 state->duty_cycle = DIV_ROUND_UP(iqs620_pwm->duty_scale *
0124 IQS620_PWM_PERIOD_NS, 256);
0125
0126 mutex_unlock(&iqs620_pwm->lock);
0127
0128 state->period = IQS620_PWM_PERIOD_NS;
0129 }
0130
0131 static int iqs620_pwm_notifier(struct notifier_block *notifier,
0132 unsigned long event_flags, void *context)
0133 {
0134 struct iqs620_pwm_private *iqs620_pwm;
0135 int ret;
0136
0137 if (!(event_flags & BIT(IQS62X_EVENT_SYS_RESET)))
0138 return NOTIFY_DONE;
0139
0140 iqs620_pwm = container_of(notifier, struct iqs620_pwm_private,
0141 notifier);
0142
0143 mutex_lock(&iqs620_pwm->lock);
0144
0145
0146
0147
0148
0149
0150 ret = iqs620_pwm_init(iqs620_pwm, iqs620_pwm->duty_scale);
0151
0152 mutex_unlock(&iqs620_pwm->lock);
0153
0154 if (ret) {
0155 dev_err(iqs620_pwm->chip.dev,
0156 "Failed to re-initialize device: %d\n", ret);
0157 return NOTIFY_BAD;
0158 }
0159
0160 return NOTIFY_OK;
0161 }
0162
0163 static const struct pwm_ops iqs620_pwm_ops = {
0164 .apply = iqs620_pwm_apply,
0165 .get_state = iqs620_pwm_get_state,
0166 .owner = THIS_MODULE,
0167 };
0168
0169 static void iqs620_pwm_notifier_unregister(void *context)
0170 {
0171 struct iqs620_pwm_private *iqs620_pwm = context;
0172 int ret;
0173
0174 ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh,
0175 &iqs620_pwm->notifier);
0176 if (ret)
0177 dev_err(iqs620_pwm->chip.dev,
0178 "Failed to unregister notifier: %d\n", ret);
0179 }
0180
0181 static int iqs620_pwm_probe(struct platform_device *pdev)
0182 {
0183 struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent);
0184 struct iqs620_pwm_private *iqs620_pwm;
0185 unsigned int val;
0186 int ret;
0187
0188 iqs620_pwm = devm_kzalloc(&pdev->dev, sizeof(*iqs620_pwm), GFP_KERNEL);
0189 if (!iqs620_pwm)
0190 return -ENOMEM;
0191
0192 iqs620_pwm->iqs62x = iqs62x;
0193
0194 ret = regmap_read(iqs62x->regmap, IQS620_PWR_SETTINGS, &val);
0195 if (ret)
0196 return ret;
0197
0198 if (val & IQS620_PWR_SETTINGS_PWM_OUT) {
0199 ret = regmap_read(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE, &val);
0200 if (ret)
0201 return ret;
0202
0203 iqs620_pwm->duty_scale = val + 1;
0204 }
0205
0206 iqs620_pwm->chip.dev = &pdev->dev;
0207 iqs620_pwm->chip.ops = &iqs620_pwm_ops;
0208 iqs620_pwm->chip.npwm = 1;
0209
0210 mutex_init(&iqs620_pwm->lock);
0211
0212 iqs620_pwm->notifier.notifier_call = iqs620_pwm_notifier;
0213 ret = blocking_notifier_chain_register(&iqs620_pwm->iqs62x->nh,
0214 &iqs620_pwm->notifier);
0215 if (ret) {
0216 dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret);
0217 return ret;
0218 }
0219
0220 ret = devm_add_action_or_reset(&pdev->dev,
0221 iqs620_pwm_notifier_unregister,
0222 iqs620_pwm);
0223 if (ret)
0224 return ret;
0225
0226 ret = devm_pwmchip_add(&pdev->dev, &iqs620_pwm->chip);
0227 if (ret)
0228 dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
0229
0230 return ret;
0231 }
0232
0233 static struct platform_driver iqs620_pwm_platform_driver = {
0234 .driver = {
0235 .name = "iqs620a-pwm",
0236 },
0237 .probe = iqs620_pwm_probe,
0238 };
0239 module_platform_driver(iqs620_pwm_platform_driver);
0240
0241 MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
0242 MODULE_DESCRIPTION("Azoteq IQS620A PWM Generator");
0243 MODULE_LICENSE("GPL");
0244 MODULE_ALIAS("platform:iqs620a-pwm");