162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) ST-Ericsson SA 2010 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Arun R Murthy <arun.murthy@stericsson.com> 662306a36Sopenharmony_ci * Datasheet: https://web.archive.org/web/20130614115108/http://www.stericsson.com/developers/CD00291561_UM1031_AB8500_user_manual-rev5_CTDS_public.pdf 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci#include <linux/err.h> 962306a36Sopenharmony_ci#include <linux/platform_device.h> 1062306a36Sopenharmony_ci#include <linux/slab.h> 1162306a36Sopenharmony_ci#include <linux/pwm.h> 1262306a36Sopenharmony_ci#include <linux/mfd/abx500.h> 1362306a36Sopenharmony_ci#include <linux/mfd/abx500/ab8500.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * PWM Out generators 1862306a36Sopenharmony_ci * Bank: 0x10 1962306a36Sopenharmony_ci */ 2062306a36Sopenharmony_ci#define AB8500_PWM_OUT_CTRL1_REG 0x60 2162306a36Sopenharmony_ci#define AB8500_PWM_OUT_CTRL2_REG 0x61 2262306a36Sopenharmony_ci#define AB8500_PWM_OUT_CTRL7_REG 0x66 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define AB8500_PWM_CLKRATE 9600000 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cistruct ab8500_pwm_chip { 2762306a36Sopenharmony_ci struct pwm_chip chip; 2862306a36Sopenharmony_ci unsigned int hwid; 2962306a36Sopenharmony_ci}; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic struct ab8500_pwm_chip *ab8500_pwm_from_chip(struct pwm_chip *chip) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci return container_of(chip, struct ab8500_pwm_chip, chip); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 3762306a36Sopenharmony_ci const struct pwm_state *state) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci int ret; 4062306a36Sopenharmony_ci u8 reg; 4162306a36Sopenharmony_ci u8 higher_val, lower_val; 4262306a36Sopenharmony_ci unsigned int duty_steps, div; 4362306a36Sopenharmony_ci struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (state->polarity != PWM_POLARITY_NORMAL) 4662306a36Sopenharmony_ci return -EINVAL; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (state->enabled) { 4962306a36Sopenharmony_ci /* 5062306a36Sopenharmony_ci * A time quantum is 5162306a36Sopenharmony_ci * q = (32 - FreqPWMOutx[3:0]) / AB8500_PWM_CLKRATE 5262306a36Sopenharmony_ci * The period is always 1024 q, duty_cycle is between 1q and 1024q. 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * FreqPWMOutx[3:0] | output frequency | output frequency | 1024q = period 5562306a36Sopenharmony_ci * | (from manual) | (1 / 1024q) | = 1 / freq 5662306a36Sopenharmony_ci * -----------------+------------------+------------------+-------------- 5762306a36Sopenharmony_ci * b0000 | 293 Hz | 292.968750 Hz | 3413333.33 ns 5862306a36Sopenharmony_ci * b0001 | 302 Hz | 302.419355 Hz | 3306666.66 ns 5962306a36Sopenharmony_ci * b0010 | 312 Hz | 312.500000 Hz | 3200000 ns 6062306a36Sopenharmony_ci * b0011 | 323 Hz | 323.275862 Hz | 3093333.33 ns 6162306a36Sopenharmony_ci * b0100 | 334 Hz | 334.821429 Hz | 2986666.66 ns 6262306a36Sopenharmony_ci * b0101 | 347 Hz | 347.222222 Hz | 2880000 ns 6362306a36Sopenharmony_ci * b0110 | 360 Hz | 360.576923 Hz | 2773333.33 ns 6462306a36Sopenharmony_ci * b0111 | 375 Hz | 375.000000 Hz | 2666666.66 ns 6562306a36Sopenharmony_ci * b1000 | 390 Hz | 390.625000 Hz | 2560000 ns 6662306a36Sopenharmony_ci * b1001 | 407 Hz | 407.608696 Hz | 2453333.33 ns 6762306a36Sopenharmony_ci * b1010 | 426 Hz | 426.136364 Hz | 2346666.66 ns 6862306a36Sopenharmony_ci * b1011 | 446 Hz | 446.428571 Hz | 2240000 ns 6962306a36Sopenharmony_ci * b1100 | 468 Hz | 468.750000 Hz | 2133333.33 ns 7062306a36Sopenharmony_ci * b1101 | 493 Hz | 493.421053 Hz | 2026666.66 ns 7162306a36Sopenharmony_ci * b1110 | 520 Hz | 520.833333 Hz | 1920000 ns 7262306a36Sopenharmony_ci * b1111 | 551 Hz | 551.470588 Hz | 1813333.33 ns 7362306a36Sopenharmony_ci * 7462306a36Sopenharmony_ci * 7562306a36Sopenharmony_ci * AB8500_PWM_CLKRATE is a multiple of 1024, so the division by 7662306a36Sopenharmony_ci * 1024 can be done in this factor without loss of precision. 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_ci div = min_t(u64, mul_u64_u64_div_u64(state->period, 7962306a36Sopenharmony_ci AB8500_PWM_CLKRATE >> 10, 8062306a36Sopenharmony_ci NSEC_PER_SEC), 32); /* 32 - FreqPWMOutx[3:0] */ 8162306a36Sopenharmony_ci if (div <= 16) 8262306a36Sopenharmony_ci /* requested period < 3413333.33 */ 8362306a36Sopenharmony_ci return -EINVAL; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci duty_steps = max_t(u64, mul_u64_u64_div_u64(state->duty_cycle, 8662306a36Sopenharmony_ci AB8500_PWM_CLKRATE, 8762306a36Sopenharmony_ci (u64)NSEC_PER_SEC * div), 1024); 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* 9162306a36Sopenharmony_ci * The hardware doesn't support duty_steps = 0 explicitly, but emits low 9262306a36Sopenharmony_ci * when disabled. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci if (!state->enabled || duty_steps == 0) { 9562306a36Sopenharmony_ci ret = abx500_mask_and_set_register_interruptible(chip->dev, 9662306a36Sopenharmony_ci AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 9762306a36Sopenharmony_ci 1 << ab8500->hwid, 0); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci if (ret < 0) 10062306a36Sopenharmony_ci dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", 10162306a36Sopenharmony_ci pwm->label, ret); 10262306a36Sopenharmony_ci return ret; 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci /* 10662306a36Sopenharmony_ci * The lower 8 bits of duty_steps is written to ... 10762306a36Sopenharmony_ci * AB8500_PWM_OUT_CTRL1_REG[0:7] 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci lower_val = (duty_steps - 1) & 0x00ff; 11062306a36Sopenharmony_ci /* 11162306a36Sopenharmony_ci * The two remaining high bits to 11262306a36Sopenharmony_ci * AB8500_PWM_OUT_CTRL2_REG[0:1]; together with FreqPWMOutx. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ci higher_val = ((duty_steps - 1) & 0x0300) >> 8 | (32 - div) << 4; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci reg = AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 11962306a36Sopenharmony_ci reg, lower_val); 12062306a36Sopenharmony_ci if (ret < 0) 12162306a36Sopenharmony_ci return ret; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 12462306a36Sopenharmony_ci (reg + 1), higher_val); 12562306a36Sopenharmony_ci if (ret < 0) 12662306a36Sopenharmony_ci return ret; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /* enable */ 12962306a36Sopenharmony_ci ret = abx500_mask_and_set_register_interruptible(chip->dev, 13062306a36Sopenharmony_ci AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 13162306a36Sopenharmony_ci 1 << ab8500->hwid, 1 << ab8500->hwid); 13262306a36Sopenharmony_ci if (ret < 0) 13362306a36Sopenharmony_ci dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", 13462306a36Sopenharmony_ci pwm->label, ret); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci return ret; 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic int ab8500_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, 14062306a36Sopenharmony_ci struct pwm_state *state) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci u8 ctrl7, lower_val, higher_val; 14362306a36Sopenharmony_ci int ret; 14462306a36Sopenharmony_ci struct ab8500_pwm_chip *ab8500 = ab8500_pwm_from_chip(chip); 14562306a36Sopenharmony_ci unsigned int div, duty_steps; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 14862306a36Sopenharmony_ci AB8500_PWM_OUT_CTRL7_REG, 14962306a36Sopenharmony_ci &ctrl7); 15062306a36Sopenharmony_ci if (ret) 15162306a36Sopenharmony_ci return ret; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci state->polarity = PWM_POLARITY_NORMAL; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci if (!(ctrl7 & 1 << ab8500->hwid)) { 15662306a36Sopenharmony_ci state->enabled = false; 15762306a36Sopenharmony_ci return 0; 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 16162306a36Sopenharmony_ci AB8500_PWM_OUT_CTRL1_REG + (ab8500->hwid * 2), 16262306a36Sopenharmony_ci &lower_val); 16362306a36Sopenharmony_ci if (ret) 16462306a36Sopenharmony_ci return ret; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci ret = abx500_get_register_interruptible(chip->dev, AB8500_MISC, 16762306a36Sopenharmony_ci AB8500_PWM_OUT_CTRL2_REG + (ab8500->hwid * 2), 16862306a36Sopenharmony_ci &higher_val); 16962306a36Sopenharmony_ci if (ret) 17062306a36Sopenharmony_ci return ret; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci div = 32 - ((higher_val & 0xf0) >> 4); 17362306a36Sopenharmony_ci duty_steps = ((higher_val & 3) << 8 | lower_val) + 1; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci state->period = DIV64_U64_ROUND_UP((u64)div << 10, AB8500_PWM_CLKRATE); 17662306a36Sopenharmony_ci state->duty_cycle = DIV64_U64_ROUND_UP((u64)div * duty_steps, AB8500_PWM_CLKRATE); 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci return 0; 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic const struct pwm_ops ab8500_pwm_ops = { 18262306a36Sopenharmony_ci .apply = ab8500_pwm_apply, 18362306a36Sopenharmony_ci .get_state = ab8500_pwm_get_state, 18462306a36Sopenharmony_ci .owner = THIS_MODULE, 18562306a36Sopenharmony_ci}; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistatic int ab8500_pwm_probe(struct platform_device *pdev) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci struct ab8500_pwm_chip *ab8500; 19062306a36Sopenharmony_ci int err; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci if (pdev->id < 1 || pdev->id > 31) 19362306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, -EINVAL, "Invalid device id %d\n", pdev->id); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci /* 19662306a36Sopenharmony_ci * Nothing to be done in probe, this is required to get the 19762306a36Sopenharmony_ci * device which is required for ab8500 read and write 19862306a36Sopenharmony_ci */ 19962306a36Sopenharmony_ci ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); 20062306a36Sopenharmony_ci if (ab8500 == NULL) 20162306a36Sopenharmony_ci return -ENOMEM; 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci ab8500->chip.dev = &pdev->dev; 20462306a36Sopenharmony_ci ab8500->chip.ops = &ab8500_pwm_ops; 20562306a36Sopenharmony_ci ab8500->chip.npwm = 1; 20662306a36Sopenharmony_ci ab8500->hwid = pdev->id - 1; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci err = devm_pwmchip_add(&pdev->dev, &ab8500->chip); 20962306a36Sopenharmony_ci if (err < 0) 21062306a36Sopenharmony_ci return dev_err_probe(&pdev->dev, err, "Failed to add pwm chip\n"); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci dev_dbg(&pdev->dev, "pwm probe successful\n"); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci return 0; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic struct platform_driver ab8500_pwm_driver = { 21862306a36Sopenharmony_ci .driver = { 21962306a36Sopenharmony_ci .name = "ab8500-pwm", 22062306a36Sopenharmony_ci }, 22162306a36Sopenharmony_ci .probe = ab8500_pwm_probe, 22262306a36Sopenharmony_ci}; 22362306a36Sopenharmony_cimodule_platform_driver(ab8500_pwm_driver); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ciMODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>"); 22662306a36Sopenharmony_ciMODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver"); 22762306a36Sopenharmony_ciMODULE_ALIAS("platform:ab8500-pwm"); 22862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 229