143b41566SSimon Glass /*
243b41566SSimon Glass * Copyright (c) 2015 Google, Inc
343b41566SSimon Glass * Written by Simon Glass <sjg@chromium.org>
443b41566SSimon Glass *
543b41566SSimon Glass * SPDX-License-Identifier: GPL-2.0+
643b41566SSimon Glass */
743b41566SSimon Glass
843b41566SSimon Glass #include <common.h>
943b41566SSimon Glass #include <dm.h>
1043b41566SSimon Glass #include <errno.h>
1143b41566SSimon Glass #include <pwm.h>
1243b41566SSimon Glass #include <asm/test.h>
1343b41566SSimon Glass
1443b41566SSimon Glass DECLARE_GLOBAL_DATA_PTR;
1543b41566SSimon Glass
1643b41566SSimon Glass enum {
1743b41566SSimon Glass NUM_CHANNELS = 3,
1843b41566SSimon Glass };
1943b41566SSimon Glass
2043b41566SSimon Glass struct sandbox_pwm_chan {
2143b41566SSimon Glass uint period_ns;
2243b41566SSimon Glass uint duty_ns;
2343b41566SSimon Glass bool enable;
24*5540e25aSKever Yang bool polarity;
2543b41566SSimon Glass };
2643b41566SSimon Glass
2743b41566SSimon Glass struct sandbox_pwm_priv {
2843b41566SSimon Glass struct sandbox_pwm_chan chan[NUM_CHANNELS];
2943b41566SSimon Glass };
3043b41566SSimon Glass
sandbox_pwm_set_config(struct udevice * dev,uint channel,uint period_ns,uint duty_ns)3143b41566SSimon Glass static int sandbox_pwm_set_config(struct udevice *dev, uint channel,
3243b41566SSimon Glass uint period_ns, uint duty_ns)
3343b41566SSimon Glass {
3443b41566SSimon Glass struct sandbox_pwm_priv *priv = dev_get_priv(dev);
3543b41566SSimon Glass struct sandbox_pwm_chan *chan;
3643b41566SSimon Glass
3743b41566SSimon Glass if (channel >= NUM_CHANNELS)
3843b41566SSimon Glass return -ENOSPC;
3943b41566SSimon Glass chan = &priv->chan[channel];
4043b41566SSimon Glass chan->period_ns = period_ns;
4143b41566SSimon Glass chan->duty_ns = duty_ns;
4243b41566SSimon Glass
4343b41566SSimon Glass return 0;
4443b41566SSimon Glass }
4543b41566SSimon Glass
sandbox_pwm_set_enable(struct udevice * dev,uint channel,bool enable)4643b41566SSimon Glass static int sandbox_pwm_set_enable(struct udevice *dev, uint channel,
4743b41566SSimon Glass bool enable)
4843b41566SSimon Glass {
4943b41566SSimon Glass struct sandbox_pwm_priv *priv = dev_get_priv(dev);
5043b41566SSimon Glass struct sandbox_pwm_chan *chan;
5143b41566SSimon Glass
5243b41566SSimon Glass if (channel >= NUM_CHANNELS)
5343b41566SSimon Glass return -ENOSPC;
5443b41566SSimon Glass chan = &priv->chan[channel];
5543b41566SSimon Glass chan->enable = enable;
5643b41566SSimon Glass
5743b41566SSimon Glass return 0;
5843b41566SSimon Glass }
5943b41566SSimon Glass
sandbox_pwm_set_invert(struct udevice * dev,uint channel,bool polarity)60*5540e25aSKever Yang static int sandbox_pwm_set_invert(struct udevice *dev, uint channel,
61*5540e25aSKever Yang bool polarity)
62*5540e25aSKever Yang {
63*5540e25aSKever Yang struct sandbox_pwm_priv *priv = dev_get_priv(dev);
64*5540e25aSKever Yang struct sandbox_pwm_chan *chan;
65*5540e25aSKever Yang
66*5540e25aSKever Yang if (channel >= NUM_CHANNELS)
67*5540e25aSKever Yang return -ENOSPC;
68*5540e25aSKever Yang chan = &priv->chan[channel];
69*5540e25aSKever Yang chan->polarity = polarity;
70*5540e25aSKever Yang
71*5540e25aSKever Yang return 0;
72*5540e25aSKever Yang }
73*5540e25aSKever Yang
7443b41566SSimon Glass static const struct pwm_ops sandbox_pwm_ops = {
7543b41566SSimon Glass .set_config = sandbox_pwm_set_config,
7643b41566SSimon Glass .set_enable = sandbox_pwm_set_enable,
77*5540e25aSKever Yang .set_invert = sandbox_pwm_set_invert,
7843b41566SSimon Glass };
7943b41566SSimon Glass
8043b41566SSimon Glass static const struct udevice_id sandbox_pwm_ids[] = {
8143b41566SSimon Glass { .compatible = "sandbox,pwm" },
8243b41566SSimon Glass { }
8343b41566SSimon Glass };
8443b41566SSimon Glass
8543b41566SSimon Glass U_BOOT_DRIVER(warm_pwm_sandbox) = {
8643b41566SSimon Glass .name = "pwm_sandbox",
8743b41566SSimon Glass .id = UCLASS_PWM,
8843b41566SSimon Glass .of_match = sandbox_pwm_ids,
8943b41566SSimon Glass .ops = &sandbox_pwm_ops,
9043b41566SSimon Glass .priv_auto_alloc_size = sizeof(struct sandbox_pwm_priv),
9143b41566SSimon Glass };
92