1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 Intel Corporation. All rights reserved.
5 * Author: Shobhit Kumar <shobhit.kumar@intel.com>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10 #include <linux/mfd/intel_soc_pmic.h>
11 #include <linux/pwm.h>
13 #define PWM0_CLK_DIV 0x4B
14 #define PWM_OUTPUT_ENABLE BIT(7)
15 #define PWM_DIV_CLK_0 0x00 /* DIVIDECLK = BASECLK */
16 #define PWM_DIV_CLK_100 0x63 /* DIVIDECLK = BASECLK/100 */
17 #define PWM_DIV_CLK_128 0x7F /* DIVIDECLK = BASECLK/128 */
19 #define PWM0_DUTY_CYCLE 0x4E
20 #define BACKLIGHT_EN 0x51
22 #define PWM_MAX_LEVEL 0xFF
24 #define PWM_BASE_CLK_MHZ 6 /* 6 MHz */
25 #define PWM_MAX_PERIOD_NS 5461334 /* 183 Hz */
28 * struct crystalcove_pwm - Crystal Cove PWM controller
29 * @regmap: the regmap from the parent device.
31 struct crystalcove_pwm
{
32 struct regmap
*regmap
;
35 static inline struct crystalcove_pwm
*to_crc_pwm(struct pwm_chip
*chip
)
37 return pwmchip_get_drvdata(chip
);
40 static int crc_pwm_calc_clk_div(int period_ns
)
44 clk_div
= PWM_BASE_CLK_MHZ
* period_ns
/ (256 * NSEC_PER_USEC
);
45 /* clk_div 1 - 128, maps to register values 0-127 */
52 static int crc_pwm_apply(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
53 const struct pwm_state
*state
)
55 struct crystalcove_pwm
*crc_pwm
= to_crc_pwm(chip
);
56 struct device
*dev
= pwmchip_parent(chip
);
59 if (state
->period
> PWM_MAX_PERIOD_NS
) {
60 dev_err(dev
, "un-supported period_ns\n");
64 if (state
->polarity
!= PWM_POLARITY_NORMAL
)
67 if (pwm_is_enabled(pwm
) && !state
->enabled
) {
68 err
= regmap_write(crc_pwm
->regmap
, BACKLIGHT_EN
, 0);
70 dev_err(dev
, "Error writing BACKLIGHT_EN %d\n", err
);
75 if (pwm_get_duty_cycle(pwm
) != state
->duty_cycle
||
76 pwm_get_period(pwm
) != state
->period
) {
77 u64 level
= state
->duty_cycle
* PWM_MAX_LEVEL
;
79 do_div(level
, state
->period
);
81 err
= regmap_write(crc_pwm
->regmap
, PWM0_DUTY_CYCLE
, level
);
83 dev_err(dev
, "Error writing PWM0_DUTY_CYCLE %d\n", err
);
88 if (pwm_is_enabled(pwm
) && state
->enabled
&&
89 pwm_get_period(pwm
) != state
->period
) {
90 /* changing the clk divisor, clear PWM_OUTPUT_ENABLE first */
91 err
= regmap_write(crc_pwm
->regmap
, PWM0_CLK_DIV
, 0);
93 dev_err(dev
, "Error writing PWM0_CLK_DIV %d\n", err
);
98 if (pwm_get_period(pwm
) != state
->period
||
99 pwm_is_enabled(pwm
) != state
->enabled
) {
100 int clk_div
= crc_pwm_calc_clk_div(state
->period
);
101 int pwm_output_enable
= state
->enabled
? PWM_OUTPUT_ENABLE
: 0;
103 err
= regmap_write(crc_pwm
->regmap
, PWM0_CLK_DIV
,
104 clk_div
| pwm_output_enable
);
106 dev_err(dev
, "Error writing PWM0_CLK_DIV %d\n", err
);
111 if (!pwm_is_enabled(pwm
) && state
->enabled
) {
112 err
= regmap_write(crc_pwm
->regmap
, BACKLIGHT_EN
, 1);
114 dev_err(dev
, "Error writing BACKLIGHT_EN %d\n", err
);
122 static int crc_pwm_get_state(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
123 struct pwm_state
*state
)
125 struct crystalcove_pwm
*crc_pwm
= to_crc_pwm(chip
);
126 struct device
*dev
= pwmchip_parent(chip
);
127 unsigned int clk_div
, clk_div_reg
, duty_cycle_reg
;
130 error
= regmap_read(crc_pwm
->regmap
, PWM0_CLK_DIV
, &clk_div_reg
);
132 dev_err(dev
, "Error reading PWM0_CLK_DIV %d\n", error
);
136 error
= regmap_read(crc_pwm
->regmap
, PWM0_DUTY_CYCLE
, &duty_cycle_reg
);
138 dev_err(dev
, "Error reading PWM0_DUTY_CYCLE %d\n", error
);
142 clk_div
= (clk_div_reg
& ~PWM_OUTPUT_ENABLE
) + 1;
145 DIV_ROUND_UP(clk_div
* NSEC_PER_USEC
* 256, PWM_BASE_CLK_MHZ
);
147 DIV_ROUND_UP_ULL(duty_cycle_reg
* state
->period
, PWM_MAX_LEVEL
);
148 state
->polarity
= PWM_POLARITY_NORMAL
;
149 state
->enabled
= !!(clk_div_reg
& PWM_OUTPUT_ENABLE
);
154 static const struct pwm_ops crc_pwm_ops
= {
155 .apply
= crc_pwm_apply
,
156 .get_state
= crc_pwm_get_state
,
159 static int crystalcove_pwm_probe(struct platform_device
*pdev
)
161 struct pwm_chip
*chip
;
162 struct crystalcove_pwm
*crc_pwm
;
163 struct device
*dev
= pdev
->dev
.parent
;
164 struct intel_soc_pmic
*pmic
= dev_get_drvdata(dev
);
166 chip
= devm_pwmchip_alloc(&pdev
->dev
, 1, sizeof(*crc_pwm
));
168 return PTR_ERR(chip
);
169 crc_pwm
= to_crc_pwm(chip
);
171 chip
->ops
= &crc_pwm_ops
;
173 /* get the PMIC regmap */
174 crc_pwm
->regmap
= pmic
->regmap
;
176 return devm_pwmchip_add(&pdev
->dev
, chip
);
179 static struct platform_driver crystalcove_pwm_driver
= {
180 .probe
= crystalcove_pwm_probe
,
182 .name
= "crystal_cove_pwm",
185 module_platform_driver(crystalcove_pwm_driver
);
187 MODULE_ALIAS("platform:crystal_cove_pwm");
188 MODULE_DESCRIPTION("Intel Crystalcove (CRC) PWM support");
189 MODULE_LICENSE("GPL");