197960addSRahul Tanwar // SPDX-License-Identifier: GPL-2.0
297960addSRahul Tanwar /*
397960addSRahul Tanwar * Copyright (C) 2020 Intel Corporation.
497960addSRahul Tanwar *
597960addSRahul Tanwar * Limitations:
697960addSRahul Tanwar * - The hardware supports fixed period & configures only 2-wire mode.
797960addSRahul Tanwar * - Supports normal polarity. Does not support changing polarity.
897960addSRahul Tanwar * - When PWM is disabled, output of PWM will become 0(inactive). It doesn't
997960addSRahul Tanwar * keep track of running period.
1097960addSRahul Tanwar * - When duty cycle is changed, PWM output may be a mix of previous setting
1197960addSRahul Tanwar * and new setting for the first period. From second period, the output is
1297960addSRahul Tanwar * based on new setting.
1397960addSRahul Tanwar * - It is a dedicated PWM fan controller. There are no other consumers for
1497960addSRahul Tanwar * this PWM controller.
1597960addSRahul Tanwar */
1697960addSRahul Tanwar #include <linux/bitfield.h>
1797960addSRahul Tanwar #include <linux/clk.h>
1897960addSRahul Tanwar #include <linux/module.h>
1997960addSRahul Tanwar #include <linux/platform_device.h>
2097960addSRahul Tanwar #include <linux/mod_devicetable.h>
2197960addSRahul Tanwar #include <linux/pwm.h>
2297960addSRahul Tanwar #include <linux/regmap.h>
2397960addSRahul Tanwar #include <linux/reset.h>
2497960addSRahul Tanwar
2597960addSRahul Tanwar #define LGM_PWM_FAN_CON0 0x0
2697960addSRahul Tanwar #define LGM_PWM_FAN_EN_EN BIT(0)
2797960addSRahul Tanwar #define LGM_PWM_FAN_EN_DIS 0x0
2897960addSRahul Tanwar #define LGM_PWM_FAN_EN_MSK BIT(0)
2997960addSRahul Tanwar #define LGM_PWM_FAN_MODE_2WIRE 0x0
3097960addSRahul Tanwar #define LGM_PWM_FAN_MODE_MSK BIT(1)
3197960addSRahul Tanwar #define LGM_PWM_FAN_DC_MSK GENMASK(23, 16)
3297960addSRahul Tanwar
3397960addSRahul Tanwar #define LGM_PWM_FAN_CON1 0x4
3497960addSRahul Tanwar #define LGM_PWM_FAN_MAX_RPM_MSK GENMASK(15, 0)
3597960addSRahul Tanwar
3697960addSRahul Tanwar #define LGM_PWM_MAX_RPM (BIT(16) - 1)
3797960addSRahul Tanwar #define LGM_PWM_DEFAULT_RPM 4000
3897960addSRahul Tanwar #define LGM_PWM_MAX_DUTY_CYCLE (BIT(8) - 1)
3997960addSRahul Tanwar
4097960addSRahul Tanwar #define LGM_PWM_DC_BITS 8
4197960addSRahul Tanwar
4297960addSRahul Tanwar #define LGM_PWM_PERIOD_2WIRE_NS (40 * NSEC_PER_MSEC)
4397960addSRahul Tanwar
4497960addSRahul Tanwar struct lgm_pwm_chip {
4597960addSRahul Tanwar struct pwm_chip chip;
4697960addSRahul Tanwar struct regmap *regmap;
4797960addSRahul Tanwar u32 period;
4897960addSRahul Tanwar };
4997960addSRahul Tanwar
to_lgm_pwm_chip(struct pwm_chip * chip)5097960addSRahul Tanwar static inline struct lgm_pwm_chip *to_lgm_pwm_chip(struct pwm_chip *chip)
5197960addSRahul Tanwar {
5297960addSRahul Tanwar return container_of(chip, struct lgm_pwm_chip, chip);
5397960addSRahul Tanwar }
5497960addSRahul Tanwar
lgm_pwm_enable(struct pwm_chip * chip,bool enable)5597960addSRahul Tanwar static int lgm_pwm_enable(struct pwm_chip *chip, bool enable)
5697960addSRahul Tanwar {
5797960addSRahul Tanwar struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
5897960addSRahul Tanwar struct regmap *regmap = pc->regmap;
5997960addSRahul Tanwar
6097960addSRahul Tanwar return regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_EN_MSK,
6197960addSRahul Tanwar enable ? LGM_PWM_FAN_EN_EN : LGM_PWM_FAN_EN_DIS);
6297960addSRahul Tanwar }
6397960addSRahul Tanwar
lgm_pwm_apply(struct pwm_chip * chip,struct pwm_device * pwm,const struct pwm_state * state)6497960addSRahul Tanwar static int lgm_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
6597960addSRahul Tanwar const struct pwm_state *state)
6697960addSRahul Tanwar {
6797960addSRahul Tanwar struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
6897960addSRahul Tanwar u32 duty_cycle, val;
6997960addSRahul Tanwar int ret;
7097960addSRahul Tanwar
7197960addSRahul Tanwar /* The hardware only supports normal polarity and fixed period. */
7297960addSRahul Tanwar if (state->polarity != PWM_POLARITY_NORMAL || state->period < pc->period)
7397960addSRahul Tanwar return -EINVAL;
7497960addSRahul Tanwar
7597960addSRahul Tanwar if (!state->enabled)
7697960addSRahul Tanwar return lgm_pwm_enable(chip, 0);
7797960addSRahul Tanwar
7897960addSRahul Tanwar duty_cycle = min_t(u64, state->duty_cycle, pc->period);
7997960addSRahul Tanwar val = duty_cycle * LGM_PWM_MAX_DUTY_CYCLE / pc->period;
8097960addSRahul Tanwar
8197960addSRahul Tanwar ret = regmap_update_bits(pc->regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_DC_MSK,
8297960addSRahul Tanwar FIELD_PREP(LGM_PWM_FAN_DC_MSK, val));
8397960addSRahul Tanwar if (ret)
8497960addSRahul Tanwar return ret;
8597960addSRahul Tanwar
8697960addSRahul Tanwar return lgm_pwm_enable(chip, 1);
8797960addSRahul Tanwar }
8897960addSRahul Tanwar
lgm_pwm_get_state(struct pwm_chip * chip,struct pwm_device * pwm,struct pwm_state * state)89*6c452cffSUwe Kleine-König static int lgm_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
9097960addSRahul Tanwar struct pwm_state *state)
9197960addSRahul Tanwar {
9297960addSRahul Tanwar struct lgm_pwm_chip *pc = to_lgm_pwm_chip(chip);
9397960addSRahul Tanwar u32 duty, val;
9497960addSRahul Tanwar
9597960addSRahul Tanwar state->enabled = regmap_test_bits(pc->regmap, LGM_PWM_FAN_CON0,
9697960addSRahul Tanwar LGM_PWM_FAN_EN_EN);
9797960addSRahul Tanwar state->polarity = PWM_POLARITY_NORMAL;
9897960addSRahul Tanwar state->period = pc->period; /* fixed period */
9997960addSRahul Tanwar
10097960addSRahul Tanwar regmap_read(pc->regmap, LGM_PWM_FAN_CON0, &val);
10197960addSRahul Tanwar duty = FIELD_GET(LGM_PWM_FAN_DC_MSK, val);
10297960addSRahul Tanwar state->duty_cycle = DIV_ROUND_UP(duty * pc->period, LGM_PWM_MAX_DUTY_CYCLE);
103*6c452cffSUwe Kleine-König
104*6c452cffSUwe Kleine-König return 0;
10597960addSRahul Tanwar }
10697960addSRahul Tanwar
10797960addSRahul Tanwar static const struct pwm_ops lgm_pwm_ops = {
10897960addSRahul Tanwar .get_state = lgm_pwm_get_state,
10997960addSRahul Tanwar .apply = lgm_pwm_apply,
11097960addSRahul Tanwar .owner = THIS_MODULE,
11197960addSRahul Tanwar };
11297960addSRahul Tanwar
lgm_pwm_init(struct lgm_pwm_chip * pc)11397960addSRahul Tanwar static void lgm_pwm_init(struct lgm_pwm_chip *pc)
11497960addSRahul Tanwar {
11597960addSRahul Tanwar struct regmap *regmap = pc->regmap;
11697960addSRahul Tanwar u32 con0_val;
11797960addSRahul Tanwar
11897960addSRahul Tanwar con0_val = FIELD_PREP(LGM_PWM_FAN_MODE_MSK, LGM_PWM_FAN_MODE_2WIRE);
11997960addSRahul Tanwar pc->period = LGM_PWM_PERIOD_2WIRE_NS;
12097960addSRahul Tanwar regmap_update_bits(regmap, LGM_PWM_FAN_CON1, LGM_PWM_FAN_MAX_RPM_MSK,
12197960addSRahul Tanwar LGM_PWM_DEFAULT_RPM);
12297960addSRahul Tanwar regmap_update_bits(regmap, LGM_PWM_FAN_CON0, LGM_PWM_FAN_MODE_MSK,
12397960addSRahul Tanwar con0_val);
12497960addSRahul Tanwar }
12597960addSRahul Tanwar
12697960addSRahul Tanwar static const struct regmap_config lgm_pwm_regmap_config = {
12797960addSRahul Tanwar .reg_bits = 32,
12897960addSRahul Tanwar .reg_stride = 4,
12997960addSRahul Tanwar .val_bits = 32,
13097960addSRahul Tanwar };
13197960addSRahul Tanwar
lgm_clk_release(void * data)13297960addSRahul Tanwar static void lgm_clk_release(void *data)
13397960addSRahul Tanwar {
13497960addSRahul Tanwar struct clk *clk = data;
13597960addSRahul Tanwar
13697960addSRahul Tanwar clk_disable_unprepare(clk);
13797960addSRahul Tanwar }
13897960addSRahul Tanwar
lgm_clk_enable(struct device * dev,struct clk * clk)13997960addSRahul Tanwar static int lgm_clk_enable(struct device *dev, struct clk *clk)
14097960addSRahul Tanwar {
14197960addSRahul Tanwar int ret;
14297960addSRahul Tanwar
14397960addSRahul Tanwar ret = clk_prepare_enable(clk);
14497960addSRahul Tanwar if (ret)
14597960addSRahul Tanwar return ret;
14697960addSRahul Tanwar
14797960addSRahul Tanwar return devm_add_action_or_reset(dev, lgm_clk_release, clk);
14897960addSRahul Tanwar }
14997960addSRahul Tanwar
lgm_reset_control_release(void * data)15097960addSRahul Tanwar static void lgm_reset_control_release(void *data)
15197960addSRahul Tanwar {
15297960addSRahul Tanwar struct reset_control *rst = data;
15397960addSRahul Tanwar
15497960addSRahul Tanwar reset_control_assert(rst);
15597960addSRahul Tanwar }
15697960addSRahul Tanwar
lgm_reset_control_deassert(struct device * dev,struct reset_control * rst)15797960addSRahul Tanwar static int lgm_reset_control_deassert(struct device *dev, struct reset_control *rst)
15897960addSRahul Tanwar {
15997960addSRahul Tanwar int ret;
16097960addSRahul Tanwar
16197960addSRahul Tanwar ret = reset_control_deassert(rst);
16297960addSRahul Tanwar if (ret)
16397960addSRahul Tanwar return ret;
16497960addSRahul Tanwar
16597960addSRahul Tanwar return devm_add_action_or_reset(dev, lgm_reset_control_release, rst);
16697960addSRahul Tanwar }
16797960addSRahul Tanwar
lgm_pwm_probe(struct platform_device * pdev)16897960addSRahul Tanwar static int lgm_pwm_probe(struct platform_device *pdev)
16997960addSRahul Tanwar {
17097960addSRahul Tanwar struct device *dev = &pdev->dev;
17197960addSRahul Tanwar struct reset_control *rst;
17297960addSRahul Tanwar struct lgm_pwm_chip *pc;
17397960addSRahul Tanwar void __iomem *io_base;
17497960addSRahul Tanwar struct clk *clk;
17597960addSRahul Tanwar int ret;
17697960addSRahul Tanwar
17797960addSRahul Tanwar pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
17897960addSRahul Tanwar if (!pc)
17997960addSRahul Tanwar return -ENOMEM;
18097960addSRahul Tanwar
18197960addSRahul Tanwar io_base = devm_platform_ioremap_resource(pdev, 0);
18297960addSRahul Tanwar if (IS_ERR(io_base))
18397960addSRahul Tanwar return PTR_ERR(io_base);
18497960addSRahul Tanwar
18597960addSRahul Tanwar pc->regmap = devm_regmap_init_mmio(dev, io_base, &lgm_pwm_regmap_config);
18697960addSRahul Tanwar if (IS_ERR(pc->regmap))
18797960addSRahul Tanwar return dev_err_probe(dev, PTR_ERR(pc->regmap),
18897960addSRahul Tanwar "failed to init register map\n");
18997960addSRahul Tanwar
19097960addSRahul Tanwar clk = devm_clk_get(dev, NULL);
19197960addSRahul Tanwar if (IS_ERR(clk))
19297960addSRahul Tanwar return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n");
19397960addSRahul Tanwar
19497960addSRahul Tanwar ret = lgm_clk_enable(dev, clk);
19597960addSRahul Tanwar if (ret)
19697960addSRahul Tanwar return dev_err_probe(dev, ret, "failed to enable clock\n");
19797960addSRahul Tanwar
19897960addSRahul Tanwar rst = devm_reset_control_get_exclusive(dev, NULL);
19997960addSRahul Tanwar if (IS_ERR(rst))
20097960addSRahul Tanwar return dev_err_probe(dev, PTR_ERR(rst),
20197960addSRahul Tanwar "failed to get reset control\n");
20297960addSRahul Tanwar
20397960addSRahul Tanwar ret = lgm_reset_control_deassert(dev, rst);
20497960addSRahul Tanwar if (ret)
20597960addSRahul Tanwar return dev_err_probe(dev, ret, "cannot deassert reset control\n");
20697960addSRahul Tanwar
20797960addSRahul Tanwar pc->chip.dev = dev;
20897960addSRahul Tanwar pc->chip.ops = &lgm_pwm_ops;
20997960addSRahul Tanwar pc->chip.npwm = 1;
21097960addSRahul Tanwar
21197960addSRahul Tanwar lgm_pwm_init(pc);
21297960addSRahul Tanwar
213d8c11a65SUwe Kleine-König ret = devm_pwmchip_add(dev, &pc->chip);
21497960addSRahul Tanwar if (ret < 0)
21597960addSRahul Tanwar return dev_err_probe(dev, ret, "failed to add PWM chip\n");
21697960addSRahul Tanwar
21797960addSRahul Tanwar return 0;
21897960addSRahul Tanwar }
21997960addSRahul Tanwar
22097960addSRahul Tanwar static const struct of_device_id lgm_pwm_of_match[] = {
22197960addSRahul Tanwar { .compatible = "intel,lgm-pwm" },
22297960addSRahul Tanwar { }
22397960addSRahul Tanwar };
22497960addSRahul Tanwar MODULE_DEVICE_TABLE(of, lgm_pwm_of_match);
22597960addSRahul Tanwar
22697960addSRahul Tanwar static struct platform_driver lgm_pwm_driver = {
22797960addSRahul Tanwar .driver = {
22897960addSRahul Tanwar .name = "intel-pwm",
22997960addSRahul Tanwar .of_match_table = lgm_pwm_of_match,
23097960addSRahul Tanwar },
23197960addSRahul Tanwar .probe = lgm_pwm_probe,
23297960addSRahul Tanwar };
23397960addSRahul Tanwar module_platform_driver(lgm_pwm_driver);
23497960addSRahul Tanwar
23597960addSRahul Tanwar MODULE_LICENSE("GPL v2");
236