1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) ST-Ericsson SA 2010 4 * 5 * Author: Arun R Murthy <arun.murthy@stericsson.com> 6 */ 7 #include <linux/err.h> 8 #include <linux/platform_device.h> 9 #include <linux/slab.h> 10 #include <linux/pwm.h> 11 #include <linux/mfd/abx500.h> 12 #include <linux/mfd/abx500/ab8500.h> 13 #include <linux/module.h> 14 15 /* 16 * PWM Out generators 17 * Bank: 0x10 18 */ 19 #define AB8500_PWM_OUT_CTRL1_REG 0x60 20 #define AB8500_PWM_OUT_CTRL2_REG 0x61 21 #define AB8500_PWM_OUT_CTRL7_REG 0x66 22 23 struct ab8500_pwm_chip { 24 struct pwm_chip chip; 25 }; 26 27 static int ab8500_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, 28 const struct pwm_state *state) 29 { 30 int ret; 31 u8 reg; 32 unsigned int higher_val, lower_val; 33 34 if (state->polarity != PWM_POLARITY_NORMAL) 35 return -EINVAL; 36 37 if (!state->enabled) { 38 ret = abx500_mask_and_set_register_interruptible(chip->dev, 39 AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 40 1 << (chip->base - 1), 0); 41 42 if (ret < 0) 43 dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", 44 pwm->label, ret); 45 return ret; 46 } 47 48 /* 49 * get the first 8 bits that are be written to 50 * AB8500_PWM_OUT_CTRL1_REG[0:7] 51 */ 52 lower_val = state->duty_cycle & 0x00FF; 53 /* 54 * get bits [9:10] that are to be written to 55 * AB8500_PWM_OUT_CTRL2_REG[0:1] 56 */ 57 higher_val = ((state->duty_cycle & 0x0300) >> 8); 58 59 reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2); 60 61 ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 62 reg, (u8)lower_val); 63 if (ret < 0) 64 return ret; 65 66 ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC, 67 (reg + 1), (u8)higher_val); 68 if (ret < 0) 69 return ret; 70 71 ret = abx500_mask_and_set_register_interruptible(chip->dev, 72 AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG, 73 1 << (chip->base - 1), 1 << (chip->base - 1)); 74 if (ret < 0) 75 dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", 76 pwm->label, ret); 77 78 return ret; 79 } 80 81 static const struct pwm_ops ab8500_pwm_ops = { 82 .apply = ab8500_pwm_apply, 83 .owner = THIS_MODULE, 84 }; 85 86 static int ab8500_pwm_probe(struct platform_device *pdev) 87 { 88 struct ab8500_pwm_chip *ab8500; 89 int err; 90 91 /* 92 * Nothing to be done in probe, this is required to get the 93 * device which is required for ab8500 read and write 94 */ 95 ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); 96 if (ab8500 == NULL) 97 return -ENOMEM; 98 99 ab8500->chip.dev = &pdev->dev; 100 ab8500->chip.ops = &ab8500_pwm_ops; 101 ab8500->chip.npwm = 1; 102 103 err = pwmchip_add(&ab8500->chip); 104 if (err < 0) 105 return dev_err_probe(&pdev->dev, err, "Failed to add pwm chip\n"); 106 107 dev_dbg(&pdev->dev, "pwm probe successful\n"); 108 platform_set_drvdata(pdev, ab8500); 109 110 return 0; 111 } 112 113 static int ab8500_pwm_remove(struct platform_device *pdev) 114 { 115 struct ab8500_pwm_chip *ab8500 = platform_get_drvdata(pdev); 116 int err; 117 118 err = pwmchip_remove(&ab8500->chip); 119 if (err < 0) 120 return err; 121 122 dev_dbg(&pdev->dev, "pwm driver removed\n"); 123 124 return 0; 125 } 126 127 static struct platform_driver ab8500_pwm_driver = { 128 .driver = { 129 .name = "ab8500-pwm", 130 }, 131 .probe = ab8500_pwm_probe, 132 .remove = ab8500_pwm_remove, 133 }; 134 module_platform_driver(ab8500_pwm_driver); 135 136 MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>"); 137 MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver"); 138 MODULE_ALIAS("platform:ab8500-pwm"); 139 MODULE_LICENSE("GPL v2"); 140