^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * R-Mobile TPU PWM driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2012 Renesas Solutions Corp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pwm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define TPU_CHANNEL_MAX 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define TPU_TSTR 0x00 /* Timer start register (shared) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define TPU_TCRn 0x00 /* Timer control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define TPU_TCR_CCLR_NONE (0 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define TPU_TCR_CCLR_TGRA (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define TPU_TCR_CCLR_TGRB (2 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define TPU_TCR_CCLR_TGRC (5 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define TPU_TCR_CCLR_TGRD (6 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define TPU_TCR_CKEG_RISING (0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define TPU_TCR_CKEG_FALLING (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define TPU_TCR_CKEG_BOTH (2 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define TPU_TMDRn 0x04 /* Timer mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TPU_TMDR_BFWT (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define TPU_TMDR_BFB (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TPU_TMDR_BFA (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TPU_TMDR_MD_NORMAL (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define TPU_TMDR_MD_PWM (2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define TPU_TIORn 0x08 /* Timer I/O control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TPU_TIOR_IOA_0 (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TPU_TIOR_IOA_0_CLR (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TPU_TIOR_IOA_0_SET (2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define TPU_TIOR_IOA_0_TOGGLE (3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TPU_TIOR_IOA_1 (4 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define TPU_TIOR_IOA_1_CLR (5 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TPU_TIOR_IOA_1_SET (6 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define TPU_TIOR_IOA_1_TOGGLE (7 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TPU_TIERn 0x0c /* Timer interrupt enable register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TPU_TSRn 0x10 /* Timer status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TPU_TCNTn 0x14 /* Timer counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define TPU_TGRAn 0x18 /* Timer general register A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define TPU_TGRBn 0x1c /* Timer general register B */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define TPU_TGRCn 0x20 /* Timer general register C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TPU_TGRDn 0x24 /* Timer general register D */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TPU_CHANNEL_OFFSET 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TPU_CHANNEL_SIZE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) enum tpu_pin_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) TPU_PIN_INACTIVE, /* Pin is driven inactive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) TPU_PIN_PWM, /* Pin is driven by PWM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) TPU_PIN_ACTIVE, /* Pin is driven active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct tpu_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct tpu_pwm_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool timer_on; /* Whether the timer is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct tpu_device *tpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) unsigned int channel; /* Channel number in the TPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) enum pwm_polarity polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) unsigned int prescaler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u16 period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 duty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct tpu_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct pwm_chip chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define to_tpu_device(c) container_of(c, struct tpu_device, chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static void tpu_pwm_write(struct tpu_pwm_device *pwm, int reg_nr, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) void __iomem *base = pwm->tpu->base + TPU_CHANNEL_OFFSET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) + pwm->channel * TPU_CHANNEL_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) iowrite16(value, base + reg_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void tpu_pwm_set_pin(struct tpu_pwm_device *pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) enum tpu_pin_state state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static const char * const states[] = { "inactive", "PWM", "active" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) dev_dbg(&pwm->tpu->pdev->dev, "%u: configuring pin as %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pwm->channel, states[state]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) case TPU_PIN_INACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) tpu_pwm_write(pwm, TPU_TIORn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pwm->polarity == PWM_POLARITY_INVERSED ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) TPU_TIOR_IOA_1 : TPU_TIOR_IOA_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case TPU_PIN_PWM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) tpu_pwm_write(pwm, TPU_TIORn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pwm->polarity == PWM_POLARITY_INVERSED ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) TPU_TIOR_IOA_0_SET : TPU_TIOR_IOA_1_CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case TPU_PIN_ACTIVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) tpu_pwm_write(pwm, TPU_TIORn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pwm->polarity == PWM_POLARITY_INVERSED ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) TPU_TIOR_IOA_0 : TPU_TIOR_IOA_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static void tpu_pwm_start_stop(struct tpu_pwm_device *pwm, int start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) spin_lock_irqsave(&pwm->tpu->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) value = ioread16(pwm->tpu->base + TPU_TSTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) value |= 1 << pwm->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) value &= ~(1 << pwm->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) iowrite16(value, pwm->tpu->base + TPU_TSTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spin_unlock_irqrestore(&pwm->tpu->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int tpu_pwm_timer_start(struct tpu_pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!pwm->timer_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Wake up device and enable clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pm_runtime_get_sync(&pwm->tpu->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ret = clk_prepare_enable(pwm->tpu->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) dev_err(&pwm->tpu->pdev->dev, "cannot enable clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pwm->timer_on = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * Make sure the channel is stopped, as we need to reconfigure it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * completely. First drive the pin to the inactive state to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * glitches.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) tpu_pwm_start_stop(pwm, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * - Clear TCNT on TGRB match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * - Count on rising edge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * - Set prescaler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * - Output 0 until TGRA, output 1 until TGRB (active low polarity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * - Output 1 until TGRA, output 0 until TGRB (active high polarity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * - PWM mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) tpu_pwm_write(pwm, TPU_TCRn, TPU_TCR_CCLR_TGRB | TPU_TCR_CKEG_RISING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) pwm->prescaler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) tpu_pwm_write(pwm, TPU_TMDRn, TPU_TMDR_MD_PWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) tpu_pwm_set_pin(pwm, TPU_PIN_PWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) tpu_pwm_write(pwm, TPU_TGRBn, pwm->period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dev_dbg(&pwm->tpu->pdev->dev, "%u: TGRA 0x%04x TGRB 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) pwm->channel, pwm->duty, pwm->period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* Start the channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) tpu_pwm_start_stop(pwm, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static void tpu_pwm_timer_stop(struct tpu_pwm_device *pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!pwm->timer_on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Disable channel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) tpu_pwm_start_stop(pwm, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Stop clock and mark device as idle. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) clk_disable_unprepare(pwm->tpu->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) pm_runtime_put(&pwm->tpu->pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) pwm->timer_on = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * PWM API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int tpu_pwm_request(struct pwm_chip *chip, struct pwm_device *_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct tpu_device *tpu = to_tpu_device(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct tpu_pwm_device *pwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (_pwm->hwpwm >= TPU_CHANNEL_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pwm = kzalloc(sizeof(*pwm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (pwm == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pwm->tpu = tpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pwm->channel = _pwm->hwpwm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) pwm->polarity = PWM_POLARITY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pwm->prescaler = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) pwm->period = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) pwm->duty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pwm->timer_on = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) pwm_set_chip_data(_pwm, pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void tpu_pwm_free(struct pwm_chip *chip, struct pwm_device *_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) tpu_pwm_timer_stop(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) kfree(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static int tpu_pwm_config(struct pwm_chip *chip, struct pwm_device *_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int duty_ns, int period_ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static const unsigned int prescalers[] = { 1, 4, 16, 64 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct tpu_device *tpu = to_tpu_device(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned int prescaler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) bool duty_only = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u32 clk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) u32 period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 duty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * Pick a prescaler to avoid overflowing the counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * TODO: Pick the highest acceptable prescaler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) clk_rate = clk_get_rate(tpu->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) for (prescaler = 0; prescaler < ARRAY_SIZE(prescalers); ++prescaler) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) period = clk_rate / prescalers[prescaler]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) / (NSEC_PER_SEC / period_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (period <= 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (prescaler == ARRAY_SIZE(prescalers) || period == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dev_err(&tpu->pdev->dev, "clock rate mismatch\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (duty_ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) duty = clk_rate / prescalers[prescaler]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) / (NSEC_PER_SEC / duty_ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (duty > period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) duty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dev_dbg(&tpu->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) "rate %u, prescaler %u, period %u, duty %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) clk_rate, prescalers[prescaler], period, duty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (pwm->prescaler == prescaler && pwm->period == period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) duty_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pwm->prescaler = prescaler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) pwm->period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) pwm->duty = duty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) /* If the channel is disabled we're done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (!pwm_is_enabled(_pwm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (duty_only && pwm->timer_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * If only the duty cycle changed and the timer is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * running, there's no need to reconfigure it completely, Just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * modify the duty cycle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) tpu_pwm_write(pwm, TPU_TGRAn, pwm->duty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_dbg(&tpu->pdev->dev, "%u: TGRA 0x%04x\n", pwm->channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) pwm->duty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Otherwise perform a full reconfiguration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret = tpu_pwm_timer_start(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (duty == 0 || duty == period) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * To avoid running the timer when not strictly required, handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * 0% and 100% duty cycles as fixed levels and stop the timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tpu_pwm_set_pin(pwm, duty ? TPU_PIN_ACTIVE : TPU_PIN_INACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) tpu_pwm_timer_stop(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int tpu_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *_pwm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) enum pwm_polarity polarity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) pwm->polarity = polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) ret = tpu_pwm_timer_start(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * To avoid running the timer when not strictly required, handle 0% and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * 100% duty cycles as fixed levels and stop the timer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (pwm->duty == 0 || pwm->duty == pwm->period) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) tpu_pwm_set_pin(pwm, pwm->duty ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) TPU_PIN_ACTIVE : TPU_PIN_INACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) tpu_pwm_timer_stop(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *_pwm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct tpu_pwm_device *pwm = pwm_get_chip_data(_pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* The timer must be running to modify the pin output configuration. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) tpu_pwm_timer_start(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) tpu_pwm_set_pin(pwm, TPU_PIN_INACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) tpu_pwm_timer_stop(pwm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) static const struct pwm_ops tpu_pwm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .request = tpu_pwm_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .free = tpu_pwm_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .config = tpu_pwm_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .set_polarity = tpu_pwm_set_polarity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .enable = tpu_pwm_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .disable = tpu_pwm_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* -----------------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * Probe and remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int tpu_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct tpu_device *tpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) tpu = devm_kzalloc(&pdev->dev, sizeof(*tpu), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (tpu == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) spin_lock_init(&tpu->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) tpu->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Map memory, get clock and pin control. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) tpu->base = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (IS_ERR(tpu->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return PTR_ERR(tpu->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) tpu->clk = devm_clk_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (IS_ERR(tpu->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_err(&pdev->dev, "cannot get clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return PTR_ERR(tpu->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /* Initialize and register the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) platform_set_drvdata(pdev, tpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) tpu->chip.dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) tpu->chip.ops = &tpu_pwm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) tpu->chip.of_xlate = of_pwm_xlate_with_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) tpu->chip.of_pwm_n_cells = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) tpu->chip.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) tpu->chip.npwm = TPU_CHANNEL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = pwmchip_add(&tpu->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_err(&pdev->dev, "failed to register PWM chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int tpu_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct tpu_device *tpu = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ret = pwmchip_remove(&tpu->chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static const struct of_device_id tpu_of_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) { .compatible = "renesas,tpu-r8a73a4", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { .compatible = "renesas,tpu-r8a7740", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { .compatible = "renesas,tpu-r8a7790", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { .compatible = "renesas,tpu", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) MODULE_DEVICE_TABLE(of, tpu_of_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) static struct platform_driver tpu_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .probe = tpu_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .remove = tpu_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .name = "renesas-tpu-pwm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .of_match_table = of_match_ptr(tpu_of_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) module_platform_driver(tpu_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) MODULE_DESCRIPTION("Renesas TPU PWM Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) MODULE_ALIAS("platform:renesas-tpu-pwm");