mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 14:33:24 -04:00
Merge tag 'pwm/for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux
Pull pwm updates from Uwe Kleine-König: "A bunch of cleanups - in C and Rust - and a devicetree and driver extension for a new SoC variant. Thanks to Biju Das, Francis Laniel, Guru Das Srinagesh, Markus Elfring, Mikko Perttunen, Thierry Reding, and Yi-Wei Wang for their changes and further Alexandre Courbot, Benno Lossin, Chen Wang, Geert Uytterhoeven, Jon Hunter, Laurent Pinchart, Michal Wilczynski, Mikko Perttunen, and Rob Herring for valuable review feedback" * tag 'pwm/for-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ukleinek/linux: pwm: th1520: use vertical import style rust: pwm: replace `core::mem::zeroed` with `pin_init::zeroed` pwm: rzg2l-gpt: Drop unused rzg2l_gpt_chip parameter from rzg2l_gpt_calculate_prescale() pwm: Use seq_putc() calls in pwm_dbg_show() pwm: tegra: Add support for Tegra264 pwm: tegra: Parametrize duty and scale field widths pwm: tegra: Modify read/write accessors for multi-register channel pwm: tegra: Avoid hard-coded max clock frequency pwm: tegra: Prefix driver-local macros and functions dt-bindings: pwm: Document Tegra264 controller pwm: lpss-pci: Unify coding style of pci_device_id array pwm: Unify coding style of of_device_id arrays pwm: Unify coding style of acpi_device_id arrays pwm: Use named initializers for arrays of acpi_device_id pwm: pca9685: Drop unused assignment of acpi_device_id driver data pwm: pxa: Depend on OF and simplify accordingly pwm: Use named initializers for platform_device_id arrays pwm: mc33xs2410: Initialize spi_device_id arrays using member names
This commit is contained in:
@@ -16,6 +16,7 @@ properties:
|
||||
- enum:
|
||||
- nvidia,tegra20-pwm
|
||||
- nvidia,tegra186-pwm
|
||||
- nvidia,tegra264-pwm
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
|
||||
@@ -569,7 +569,7 @@ config PWM_PCA9685
|
||||
config PWM_PXA
|
||||
tristate "PXA PWM support"
|
||||
depends on ARCH_PXA || ARCH_MMP || ARCH_SPACEMIT || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
depends on HAS_IOMEM && OF
|
||||
help
|
||||
Generic PWM framework driver for PXA.
|
||||
|
||||
|
||||
@@ -2647,14 +2647,14 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
|
||||
if (test_bit(PWMF_REQUESTED, &pwm->flags))
|
||||
seq_puts(s, " requested");
|
||||
|
||||
seq_puts(s, "\n");
|
||||
seq_putc(s, '\n');
|
||||
|
||||
seq_printf(s, " requested configuration: %3sabled, %llu/%llu ns, %s polarity",
|
||||
state.enabled ? "en" : "dis", state.duty_cycle, state.period,
|
||||
state.polarity ? "inverse" : "normal");
|
||||
if (state.usage_power)
|
||||
seq_puts(s, ", usage_power");
|
||||
seq_puts(s, "\n");
|
||||
seq_putc(s, '\n');
|
||||
|
||||
if (pwmchip_supports_waveform(chip)) {
|
||||
struct pwm_waveform wf;
|
||||
@@ -2677,7 +2677,7 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
|
||||
seq_printf(s, " actual configuration: read out error: %pe", ERR_PTR(err));
|
||||
}
|
||||
|
||||
seq_puts(s, "\n");
|
||||
seq_putc(s, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -202,8 +202,8 @@ static const struct adp5585_pwm_chip adp5589_pwm_chip_info = {
|
||||
};
|
||||
|
||||
static const struct platform_device_id adp5585_pwm_id_table[] = {
|
||||
{ "adp5585-pwm", (kernel_ulong_t)&adp5585_pwm_chip_info },
|
||||
{ "adp5589-pwm", (kernel_ulong_t)&adp5589_pwm_chip_info },
|
||||
{ .name = "adp5585-pwm", .driver_data = (kernel_ulong_t)&adp5585_pwm_chip_info },
|
||||
{ .name = "adp5589-pwm", .driver_data = (kernel_ulong_t)&adp5589_pwm_chip_info },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, adp5585_pwm_id_table);
|
||||
|
||||
@@ -141,7 +141,7 @@ static int apple_pwm_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id apple_pwm_of_match[] = {
|
||||
{ .compatible = "apple,s5l-fpwm" },
|
||||
{}
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apple_pwm_of_match);
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ static int argon_fan_hat_i2c_probe(struct i2c_client *i2c)
|
||||
|
||||
static const struct of_device_id argon_fan_hat_dt_ids[] = {
|
||||
{ .compatible = "argon40,fan-hat" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, argon_fan_hat_dt_ids);
|
||||
|
||||
|
||||
@@ -217,23 +217,20 @@ static const struct of_device_id atmel_hlcdc_dt_ids[] = {
|
||||
.compatible = "atmel,at91sam9n12-hlcdc",
|
||||
/* 9n12 has same errata as 9x5 HLCDC PWM */
|
||||
.data = &atmel_hlcdc_pwm_at91sam9x5_errata,
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "atmel,at91sam9x5-hlcdc",
|
||||
.data = &atmel_hlcdc_pwm_at91sam9x5_errata,
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "atmel,sama5d2-hlcdc",
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "atmel,sama5d3-hlcdc",
|
||||
.data = &atmel_hlcdc_pwm_sama5d3_errata,
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "atmel,sama5d4-hlcdc",
|
||||
.data = &atmel_hlcdc_pwm_sama5d3_errata,
|
||||
}, {
|
||||
.compatible = "microchip,sam9x60-hlcdc",
|
||||
},
|
||||
{ .compatible = "microchip,sam9x60-hlcdc", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, atmel_hlcdc_dt_ids);
|
||||
|
||||
@@ -374,9 +374,9 @@ static struct atmel_tcb_config tcb_sama5d2_config = {
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_tcb_of_match[] = {
|
||||
{ .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, },
|
||||
{ .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, },
|
||||
{ .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, },
|
||||
{ .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config },
|
||||
{ .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config },
|
||||
{ .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
|
||||
@@ -441,9 +441,8 @@ static const struct of_device_id atmel_pwm_dt_ids[] = {
|
||||
}, {
|
||||
.compatible = "microchip,sam9x60-pwm",
|
||||
.data = &mchp_sam9x60_pwm_data,
|
||||
}, {
|
||||
/* sentinel */
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ static int iproc_pwmc_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id bcm_iproc_pwmc_dt[] = {
|
||||
{ .compatible = "brcm,iproc-pwm" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm_iproc_pwmc_dt);
|
||||
|
||||
|
||||
@@ -319,7 +319,7 @@ static int kona_pwmc_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id bcm_kona_pwmc_dt[] = {
|
||||
{ .compatible = "brcm,kona-pwm" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm_kona_pwmc_dt);
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(bcm2835_pwm_pm_ops, bcm2835_pwm_suspend,
|
||||
bcm2835_pwm_resume);
|
||||
|
||||
static const struct of_device_id bcm2835_pwm_of_match[] = {
|
||||
{ .compatible = "brcm,bcm2835-pwm", },
|
||||
{ .compatible = "brcm,bcm2835-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm2835_pwm_of_match);
|
||||
|
||||
@@ -190,7 +190,7 @@ static const struct pwm_ops berlin_pwm_ops = {
|
||||
|
||||
static const struct of_device_id berlin_pwm_match[] = {
|
||||
{ .compatible = "marvell,berlin-pwm" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, berlin_pwm_match);
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ static const struct pwm_ops brcmstb_pwm_ops = {
|
||||
};
|
||||
|
||||
static const struct of_device_id brcmstb_pwm_of_match[] = {
|
||||
{ .compatible = "brcm,bcm7038-pwm", },
|
||||
{ .compatible = "brcm,bcm7038-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, brcmstb_pwm_of_match);
|
||||
|
||||
@@ -119,7 +119,7 @@ static void pwm_clk_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id pwm_clk_dt_ids[] = {
|
||||
{ .compatible = "clk-pwm", },
|
||||
{ .compatible = "clk-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_clk_dt_ids);
|
||||
|
||||
@@ -91,7 +91,7 @@ static int clps711x_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id clps711x_pwm_dt_ids[] = {
|
||||
{ .compatible = "cirrus,ep7209-pwm", },
|
||||
{ .compatible = "cirrus,ep7209-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clps711x_pwm_dt_ids);
|
||||
|
||||
@@ -267,7 +267,7 @@ static int cros_ec_pwm_probe(struct platform_device *pdev)
|
||||
static const struct of_device_id cros_ec_pwm_of_match[] = {
|
||||
{ .compatible = "google,cros-ec-pwm" },
|
||||
{ .compatible = "google,cros-ec-pwm-type" },
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cros_ec_pwm_of_match);
|
||||
#endif
|
||||
|
||||
@@ -266,7 +266,7 @@ static const struct of_device_id hibvt_pwm_of_match[] = {
|
||||
.data = &hi3559v100_shub_soc_info },
|
||||
{ .compatible = "hisilicon,hi3559v100-pwm",
|
||||
.data = &hi3559v100_soc_info },
|
||||
{ }
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hibvt_pwm_of_match);
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(imx_tpm_pwm_pm,
|
||||
pwm_imx_tpm_suspend, pwm_imx_tpm_resume);
|
||||
|
||||
static const struct of_device_id imx_tpm_pwm_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx7ulp-pwm", },
|
||||
{ .compatible = "fsl,imx7ulp-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, imx_tpm_pwm_dt_ids);
|
||||
|
||||
@@ -151,7 +151,7 @@ static const struct pwm_ops pwm_imx1_ops = {
|
||||
};
|
||||
|
||||
static const struct of_device_id pwm_imx1_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx1-pwm", },
|
||||
{ .compatible = "fsl,imx1-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_imx1_dt_ids);
|
||||
|
||||
@@ -378,7 +378,7 @@ static const struct pwm_ops pwm_imx27_ops = {
|
||||
};
|
||||
|
||||
static const struct of_device_id pwm_imx27_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx27-pwm", },
|
||||
{ .compatible = "fsl,imx27-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_imx27_dt_ids);
|
||||
|
||||
@@ -245,8 +245,8 @@ static int ipq_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id pwm_ipq_dt_match[] = {
|
||||
{ .compatible = "qcom,ipq6018-pwm", },
|
||||
{}
|
||||
{ .compatible = "qcom,ipq6018-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_ipq_dt_match);
|
||||
|
||||
|
||||
@@ -261,7 +261,7 @@ static const struct of_device_id jz4740_pwm_dt_ids[] = {
|
||||
{ .compatible = "ingenic,jz4740-pwm", .data = &jz4740_soc_info },
|
||||
{ .compatible = "ingenic,jz4725b-pwm", .data = &jz4725b_soc_info },
|
||||
{ .compatible = "ingenic,x1000-pwm", .data = &x1000_soc_info },
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jz4740_pwm_dt_ids);
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ static const struct of_device_id pwm_loongson_of_ids[] = {
|
||||
MODULE_DEVICE_TABLE(of, pwm_loongson_of_ids);
|
||||
|
||||
static const struct acpi_device_id pwm_loongson_acpi_ids[] = {
|
||||
{ "LOON0006" },
|
||||
{ .id = "LOON0006" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, pwm_loongson_acpi_ids);
|
||||
|
||||
@@ -296,7 +296,7 @@ static int lp3943_pwm_probe(struct platform_device *pdev)
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id lp3943_pwm_of_match[] = {
|
||||
{ .compatible = "ti,lp3943-pwm", },
|
||||
{ .compatible = "ti,lp3943-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lp3943_pwm_of_match);
|
||||
|
||||
@@ -329,7 +329,7 @@ static const struct pwm_ops lpc18xx_pwm_ops = {
|
||||
|
||||
static const struct of_device_id lpc18xx_pwm_of_match[] = {
|
||||
{ .compatible = "nxp,lpc1850-sct-pwm" },
|
||||
{}
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpc18xx_pwm_of_match);
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id lpc32xx_pwm_dt_ids[] = {
|
||||
{ .compatible = "nxp,lpc3220-pwm", },
|
||||
{ .compatible = "nxp,lpc3220-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpc32xx_pwm_dt_ids);
|
||||
|
||||
@@ -57,7 +57,7 @@ static const struct pci_device_id pwm_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x2289), .driver_data = (unsigned long)&pwm_lpss_bsw_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x31c8), .driver_data = (unsigned long)&pwm_lpss_bxt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x5ac8), .driver_data = (unsigned long)&pwm_lpss_bxt_info },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
|
||||
|
||||
|
||||
@@ -58,11 +58,11 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct acpi_device_id pwm_lpss_acpi_match[] = {
|
||||
{ "80860F09", (unsigned long)&pwm_lpss_byt_info },
|
||||
{ "80862288", (unsigned long)&pwm_lpss_bsw_info },
|
||||
{ "80862289", (unsigned long)&pwm_lpss_bsw_info },
|
||||
{ "80865AC8", (unsigned long)&pwm_lpss_bxt_info },
|
||||
{ },
|
||||
{ .id = "80860F09", .driver_data = (unsigned long)&pwm_lpss_byt_info },
|
||||
{ .id = "80862288", .driver_data = (unsigned long)&pwm_lpss_bsw_info },
|
||||
{ .id = "80862289", .driver_data = (unsigned long)&pwm_lpss_bsw_info },
|
||||
{ .id = "80865AC8", .driver_data = (unsigned long)&pwm_lpss_bxt_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ static int mc33xs2410_probe(struct spi_device *spi)
|
||||
}
|
||||
|
||||
static const struct spi_device_id mc33xs2410_spi_id[] = {
|
||||
{ "mc33xs2410" },
|
||||
{ .name = "mc33xs2410" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, mc33xs2410_spi_id);
|
||||
|
||||
@@ -627,7 +627,7 @@ static const struct of_device_id pwm_mediatek_of_match[] = {
|
||||
{ .compatible = "mediatek,mt8183-pwm", .data = &mt8183_pwm_data },
|
||||
{ .compatible = "mediatek,mt8365-pwm", .data = &mt8365_pwm_data },
|
||||
{ .compatible = "mediatek,mt8516-pwm", .data = &mt8516_pwm_data },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_mediatek_of_match);
|
||||
|
||||
|
||||
@@ -596,15 +596,14 @@ static const struct of_device_id meson_pwm_matches[] = {
|
||||
{
|
||||
.compatible = "amlogic,meson8-pwm-v2",
|
||||
.data = &pwm_meson8_v2_data
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "amlogic,meson-axg-pwm-v2",
|
||||
.data = &pwm_meson_axg_v2_data
|
||||
},
|
||||
{
|
||||
}, {
|
||||
.compatible = "amlogic,meson-g12-pwm-v2",
|
||||
.data = &pwm_meson_axg_v2_data
|
||||
},
|
||||
|
||||
/* The following compatibles are obsolete */
|
||||
{
|
||||
.compatible = "amlogic,meson8b-pwm",
|
||||
@@ -642,7 +641,7 @@ static const struct of_device_id meson_pwm_matches[] = {
|
||||
.compatible = "amlogic,meson-s4-pwm",
|
||||
.data = &pwm_s4_data
|
||||
},
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, meson_pwm_matches);
|
||||
|
||||
|
||||
@@ -295,10 +295,10 @@ static const struct mtk_pwm_data mt8183_pwm_data = {
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_disp_pwm_of_match[] = {
|
||||
{ .compatible = "mediatek,mt2701-disp-pwm", .data = &mt2701_pwm_data},
|
||||
{ .compatible = "mediatek,mt6595-disp-pwm", .data = &mt8173_pwm_data},
|
||||
{ .compatible = "mediatek,mt8173-disp-pwm", .data = &mt8173_pwm_data},
|
||||
{ .compatible = "mediatek,mt8183-disp-pwm", .data = &mt8183_pwm_data},
|
||||
{ .compatible = "mediatek,mt2701-disp-pwm", .data = &mt2701_pwm_data },
|
||||
{ .compatible = "mediatek,mt6595-disp-pwm", .data = &mt8173_pwm_data },
|
||||
{ .compatible = "mediatek,mt8173-disp-pwm", .data = &mt8173_pwm_data },
|
||||
{ .compatible = "mediatek,mt8183-disp-pwm", .data = &mt8183_pwm_data },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match);
|
||||
|
||||
@@ -163,7 +163,7 @@ static int mxs_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id mxs_pwm_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx23-pwm", },
|
||||
{ .compatible = "fsl,imx23-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mxs_pwm_dt_ids);
|
||||
|
||||
@@ -444,8 +444,8 @@ static void pwm_omap_dmtimer_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
|
||||
{.compatible = "ti,omap-dmtimer-pwm"},
|
||||
{}
|
||||
{ .compatible = "ti,omap-dmtimer-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_omap_dmtimer_of_match);
|
||||
|
||||
|
||||
@@ -544,13 +544,13 @@ static const struct i2c_device_id pca9685_id[] = {
|
||||
MODULE_DEVICE_TABLE(i2c, pca9685_id);
|
||||
|
||||
static const struct acpi_device_id pca9685_acpi_ids[] = {
|
||||
{ "INT3492", 0 },
|
||||
{ /* sentinel */ },
|
||||
{ .id = "INT3492" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, pca9685_acpi_ids);
|
||||
|
||||
static const struct of_device_id pca9685_dt_ids[] = {
|
||||
{ .compatible = "nxp,pca9685-pwm", },
|
||||
{ .compatible = "nxp,pca9685-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pca9685_dt_ids);
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
#define HAS_SECONDARY_PWM 0x10
|
||||
|
||||
static const struct platform_device_id pwm_id_table[] = {
|
||||
/* PWM has_secondary_pwm? */
|
||||
{ "pxa25x-pwm", 0 },
|
||||
{ "pxa27x-pwm", HAS_SECONDARY_PWM },
|
||||
{ "pxa168-pwm", 0 },
|
||||
{ "pxa910-pwm", 0 },
|
||||
{ },
|
||||
/* PWM has_secondary_pwm? */
|
||||
{ .name = "pxa25x-pwm", .driver_data = 0 },
|
||||
{ .name = "pxa27x-pwm", .driver_data = HAS_SECONDARY_PWM },
|
||||
{ .name = "pxa168-pwm", .driver_data = 0 },
|
||||
{ .name = "pxa910-pwm", .driver_data = 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, pwm_id_table);
|
||||
|
||||
@@ -136,7 +136,6 @@ static const struct pwm_ops pxa_pwm_ops = {
|
||||
.apply = pxa_pwm_apply,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/*
|
||||
* Device tree users must create one device instance for each PWM channel.
|
||||
* Hence we dispense with the HAS_SECONDARY_PWM and "tell" the original driver
|
||||
@@ -144,16 +143,13 @@ static const struct pwm_ops pxa_pwm_ops = {
|
||||
* supported identically.
|
||||
*/
|
||||
static const struct of_device_id pwm_of_match[] = {
|
||||
{ .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]},
|
||||
{ .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]},
|
||||
{ .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]},
|
||||
{ .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0]},
|
||||
{ .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0] },
|
||||
{ .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0] },
|
||||
{ .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0] },
|
||||
{ .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0] },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_of_match);
|
||||
#else
|
||||
#define pwm_of_match NULL
|
||||
#endif
|
||||
|
||||
static int pwm_probe(struct platform_device *pdev)
|
||||
{
|
||||
@@ -165,7 +161,7 @@ static int pwm_probe(struct platform_device *pdev)
|
||||
struct reset_control *rst;
|
||||
int ret = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF) && id == NULL)
|
||||
if (id == NULL)
|
||||
id = of_device_get_match_data(dev);
|
||||
|
||||
if (id == NULL)
|
||||
@@ -191,9 +187,7 @@ static int pwm_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(rst);
|
||||
|
||||
chip->ops = &pxa_pwm_ops;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF))
|
||||
chip->of_xlate = of_pwm_single_xlate;
|
||||
chip->of_xlate = of_pwm_single_xlate;
|
||||
|
||||
pc->mmio_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(pc->mmio_base))
|
||||
|
||||
@@ -177,7 +177,7 @@ static int raspberrypi_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id raspberrypi_pwm_of_match[] = {
|
||||
{ .compatible = "raspberrypi,firmware-poe-pwm", },
|
||||
{ .compatible = "raspberrypi,firmware-poe-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, raspberrypi_pwm_of_match);
|
||||
|
||||
@@ -248,8 +248,8 @@ static void rcar_pwm_remove(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id rcar_pwm_of_table[] = {
|
||||
{ .compatible = "renesas,pwm-rcar", },
|
||||
{ },
|
||||
{ .compatible = "renesas,pwm-rcar" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rcar_pwm_of_table);
|
||||
|
||||
|
||||
@@ -479,11 +479,11 @@ static int tpu_probe(struct platform_device *pdev)
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id tpu_of_table[] = {
|
||||
{ .compatible = "renesas,tpu-r8a73a4", },
|
||||
{ .compatible = "renesas,tpu-r8a7740", },
|
||||
{ .compatible = "renesas,tpu-r8a7790", },
|
||||
{ .compatible = "renesas,tpu", },
|
||||
{ },
|
||||
{ .compatible = "renesas,tpu-r8a73a4" },
|
||||
{ .compatible = "renesas,tpu-r8a7740" },
|
||||
{ .compatible = "renesas,tpu-r8a7790" },
|
||||
{ .compatible = "renesas,tpu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, tpu_of_table);
|
||||
|
||||
@@ -292,10 +292,10 @@ static const struct rockchip_pwm_data pwm_data_v3 = {
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_pwm_dt_ids[] = {
|
||||
{ .compatible = "rockchip,rk2928-pwm", .data = &pwm_data_v1},
|
||||
{ .compatible = "rockchip,rk3288-pwm", .data = &pwm_data_v2},
|
||||
{ .compatible = "rockchip,vop-pwm", .data = &pwm_data_vop},
|
||||
{ .compatible = "rockchip,rk3328-pwm", .data = &pwm_data_v3},
|
||||
{ .compatible = "rockchip,rk2928-pwm", .data = &pwm_data_v1 },
|
||||
{ .compatible = "rockchip,rk3288-pwm", .data = &pwm_data_v2 },
|
||||
{ .compatible = "rockchip,vop-pwm", .data = &pwm_data_vop },
|
||||
{ .compatible = "rockchip,rk3328-pwm", .data = &pwm_data_v3 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rockchip_pwm_dt_ids);
|
||||
|
||||
@@ -118,8 +118,7 @@ static void rzg2l_gpt_modify(struct rzg2l_gpt_chip *rzg2l_gpt, u32 reg, u32 clr,
|
||||
(rzg2l_gpt_read(rzg2l_gpt, reg) & ~clr) | set);
|
||||
}
|
||||
|
||||
static u8 rzg2l_gpt_calculate_prescale(struct rzg2l_gpt_chip *rzg2l_gpt,
|
||||
u64 period_ticks)
|
||||
static u8 rzg2l_gpt_calculate_prescale(u64 period_ticks)
|
||||
{
|
||||
u32 prescaled_period_ticks;
|
||||
u8 prescale;
|
||||
@@ -286,7 +285,7 @@ static int rzg2l_gpt_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
}
|
||||
}
|
||||
|
||||
prescale = rzg2l_gpt_calculate_prescale(rzg2l_gpt, period_ticks);
|
||||
prescale = rzg2l_gpt_calculate_prescale(period_ticks);
|
||||
pv = rzg2l_gpt_calculate_pv_or_dc(period_ticks, prescale);
|
||||
|
||||
duty_ticks = mul_u64_u64_div_u64(state->duty_cycle, rzg2l_gpt->rate_khz, USEC_PER_SEC);
|
||||
@@ -437,7 +436,7 @@ static int rzg2l_gpt_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id rzg2l_gpt_of_table[] = {
|
||||
{ .compatible = "renesas,rzg2l-gpt", },
|
||||
{ .compatible = "renesas,rzg2l-gpt" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rzg2l_gpt_of_table);
|
||||
|
||||
@@ -501,7 +501,7 @@ static const struct of_device_id samsung_pwm_matches[] = {
|
||||
{ .compatible = "samsung,s5p6440-pwm", .data = &s5p64x0_variant },
|
||||
{ .compatible = "samsung,s5pc100-pwm", .data = &s5pc100_variant },
|
||||
{ .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, samsung_pwm_matches);
|
||||
|
||||
|
||||
@@ -355,7 +355,7 @@ static void pwm_sifive_remove(struct platform_device *dev)
|
||||
|
||||
static const struct of_device_id pwm_sifive_of_match[] = {
|
||||
{ .compatible = "sifive,pwm0" },
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, pwm_sifive_of_match);
|
||||
|
||||
|
||||
@@ -244,7 +244,7 @@ static int sl28cpld_pwm_probe(struct platform_device *pdev)
|
||||
|
||||
static const struct of_device_id sl28cpld_pwm_of_match[] = {
|
||||
{ .compatible = "kontron,sl28cpld-pwm" },
|
||||
{}
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sl28cpld_pwm_of_match);
|
||||
|
||||
|
||||
@@ -225,11 +225,10 @@ static const struct sg2042_chip_data sg2044_chip_data = {
|
||||
static const struct of_device_id sg2042_pwm_ids[] = {
|
||||
{
|
||||
.compatible = "sophgo,sg2042-pwm",
|
||||
.data = &sg2042_chip_data
|
||||
},
|
||||
{
|
||||
.data = &sg2042_chip_data,
|
||||
}, {
|
||||
.compatible = "sophgo,sg2044-pwm",
|
||||
.data = &sg2044_chip_data
|
||||
.data = &sg2044_chip_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -276,8 +276,8 @@ static int sprd_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id sprd_pwm_of_match[] = {
|
||||
{ .compatible = "sprd,ums512-pwm", },
|
||||
{ },
|
||||
{ .compatible = "sprd,ums512-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sprd_pwm_of_match);
|
||||
|
||||
|
||||
@@ -625,7 +625,7 @@ static int sti_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id sti_pwm_of_match[] = {
|
||||
{ .compatible = "st,sti-pwm", },
|
||||
{ .compatible = "st,sti-pwm" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sti_pwm_of_match);
|
||||
|
||||
@@ -412,8 +412,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_lp_pm_ops, stm32_pwm_lp_suspend,
|
||||
stm32_pwm_lp_resume);
|
||||
|
||||
static const struct of_device_id stm32_pwm_lp_of_match[] = {
|
||||
{ .compatible = "st,stm32-pwm-lp", },
|
||||
{},
|
||||
{ .compatible = "st,stm32-pwm-lp" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_pwm_lp_of_match);
|
||||
|
||||
|
||||
@@ -918,9 +918,9 @@ static int stm32_pwm_resume(struct device *dev)
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(stm32_pwm_pm_ops, stm32_pwm_suspend, stm32_pwm_resume);
|
||||
|
||||
static const struct of_device_id stm32_pwm_of_match[] = {
|
||||
{ .compatible = "st,stm32-pwm", },
|
||||
{ .compatible = "st,stm32mp25-pwm", },
|
||||
{ /* end node */ },
|
||||
{ .compatible = "st,stm32-pwm" },
|
||||
{ .compatible = "st,stm32mp25-pwm" },
|
||||
{ /* end node */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
|
||||
.data = &sun50i_h6_pwm_data,
|
||||
}, {
|
||||
/* sentinel */
|
||||
},
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sun4i_pwm_dt_ids);
|
||||
|
||||
|
||||
@@ -213,8 +213,8 @@ static int sunplus_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id sunplus_pwm_of_match[] = {
|
||||
{ .compatible = "sunplus,sp7021-pwm", },
|
||||
{}
|
||||
{ .compatible = "sunplus,sp7021-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunplus_pwm_of_match);
|
||||
|
||||
|
||||
@@ -7,23 +7,62 @@
|
||||
* Copyright (c) 2010-2020, NVIDIA Corporation.
|
||||
* Based on arch/arm/plat-mxc/pwm.c by Sascha Hauer <s.hauer@pengutronix.de>
|
||||
*
|
||||
* Overview of Tegra Pulse Width Modulator Register:
|
||||
* 1. 13-bit: Frequency division (SCALE)
|
||||
* 2. 8-bit : Pulse division (DUTY)
|
||||
* 3. 1-bit : Enable bit
|
||||
* Overview of Tegra Pulse Width Modulator Register
|
||||
* CSR_0 of Tegra20, Tegra186, and Tegra194:
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | Bit | Field | Description |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 31 | ENB | Enable Pulse width modulator. |
|
||||
* | | | 0 = DISABLE, 1 = ENABLE. |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 30:16 | PWM_0 | Pulse width that needs to be programmed. |
|
||||
* | | | 0 = Always low. |
|
||||
* | | | 1 = 1 / 256 pulse high. |
|
||||
* | | | 2 = 2 / 256 pulse high. |
|
||||
* | | | N = N / 256 pulse high. |
|
||||
* | | | Only 8 bits are usable [23:16]. |
|
||||
* | | | Bit[24] can be programmed to 1 to achieve 100% duty |
|
||||
* | | | cycle. In this case the other bits [23:16] are set to |
|
||||
* | | | don’t care. |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 12:0 | PFM_0 | Frequency divider that needs to be programmed, also known |
|
||||
* | | | as SCALE. Division by (1 + PFM_0). |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
*
|
||||
* The PWM clock frequency is divided by 256 before subdividing it based
|
||||
* on the programmable frequency division value to generate the required
|
||||
* frequency for PWM output. The maximum output frequency that can be
|
||||
* achieved is (max rate of source clock) / 256.
|
||||
* e.g. if source clock rate is 408 MHz, maximum output frequency can be:
|
||||
* 408 MHz/256 = 1.6 MHz.
|
||||
* CSR_0 of Tegra264:
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | Bit | Field | Description |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 31:16 | PWM_0 | Pulse width that needs to be programmed. |
|
||||
* | | | 0 = Always low. |
|
||||
* | | | 1 = 1 / (1 + CSR_1.DEPTH) pulse high. |
|
||||
* | | | 2 = 2 / (1 + CSR_1.DEPTH) pulse high. |
|
||||
* | | | N = N / (1 + CSR_1.DEPTH) pulse high. |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 15:0 | PFM_0 | Frequency divider that needs to be programmed, also known |
|
||||
* | | | as SCALE. Division by (1 + PFM_0). |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
*
|
||||
* CSR_1 of Tegra264:
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | Bit | Field | Description |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 31 | ENB | Enable Pulse width modulator. |
|
||||
* | | | 0 = DISABLE, 1 = ENABLE. |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
* | 30:15 | DEPTH | Depth for pulse width modulator. This controls the pulse |
|
||||
* | | | time generated. Division by (1 + CSR_1.DEPTH). |
|
||||
* +-------+-------+-----------------------------------------------------------+
|
||||
*
|
||||
* The PWM clock frequency is divided by DEPTH = (1 + CSR_1.DEPTH) before
|
||||
* subdividing it based on the programmable frequency division value to
|
||||
* generate the required frequency for PWM output. DEPTH is fixed to 256
|
||||
* before Tegra264. The maximum output frequency that can be achieved is
|
||||
* (max rate of source clock) / DEPTH.
|
||||
* e.g. if source clock rate is 408 MHz, and DEPTH = 256, maximum output
|
||||
* frequency can be: 408 MHz / 256 ~= 1.6 MHz.
|
||||
* This 1.6 MHz frequency can further be divided using SCALE value in PWM.
|
||||
*
|
||||
* PWM pulse width: 8 bits are usable [23:16] for varying pulse width.
|
||||
* To achieve 100% duty cycle, program Bit [24] of this register to
|
||||
* 1’b1. In which case the other bits [23:16] are set to don't care.
|
||||
*
|
||||
* Limitations:
|
||||
* - When PWM is disabled, the output is driven to inactive.
|
||||
* - It does not allow the current PWM period to complete and
|
||||
@@ -51,17 +90,20 @@
|
||||
|
||||
#include <soc/tegra/common.h>
|
||||
|
||||
#define PWM_ENABLE (1 << 31)
|
||||
#define PWM_DUTY_WIDTH 8
|
||||
#define PWM_DUTY_SHIFT 16
|
||||
#define PWM_SCALE_WIDTH 13
|
||||
#define PWM_SCALE_SHIFT 0
|
||||
#define TEGRA_PWM_ENABLE (1 << 31)
|
||||
#define TEGRA_PWM_DUTY_SHIFT 16
|
||||
#define TEGRA_PWM_SCALE_SHIFT 0
|
||||
|
||||
#define TEGRA_PWM_CSR_0 0
|
||||
#define TEGRA_PWM_CSR_1 4
|
||||
|
||||
#define TEGRA_PWM_DEPTH 256
|
||||
|
||||
struct tegra_pwm_soc {
|
||||
unsigned int num_channels;
|
||||
unsigned int enable_reg;
|
||||
|
||||
/* Maximum IP frequency for given SoCs */
|
||||
unsigned long max_frequency;
|
||||
unsigned int scale_width;
|
||||
};
|
||||
|
||||
struct tegra_pwm_chip {
|
||||
@@ -81,14 +123,18 @@ static inline struct tegra_pwm_chip *to_tegra_pwm_chip(struct pwm_chip *chip)
|
||||
return pwmchip_get_drvdata(chip);
|
||||
}
|
||||
|
||||
static inline u32 pwm_readl(struct tegra_pwm_chip *pc, unsigned int offset)
|
||||
static inline u32 tegra_pwm_readl(struct pwm_device *pwm, unsigned int offset)
|
||||
{
|
||||
return readl(pc->regs + (offset << 4));
|
||||
struct tegra_pwm_chip *chip = to_tegra_pwm_chip(pwm->chip);
|
||||
|
||||
return readl(chip->regs + (pwm->hwpwm * 16) + offset);
|
||||
}
|
||||
|
||||
static inline void pwm_writel(struct tegra_pwm_chip *pc, unsigned int offset, u32 value)
|
||||
static inline void tegra_pwm_writel(struct pwm_device *pwm, unsigned int offset, u32 value)
|
||||
{
|
||||
writel(value, pc->regs + (offset << 4));
|
||||
struct tegra_pwm_chip *chip = to_tegra_pwm_chip(pwm->chip);
|
||||
|
||||
writel(value, chip->regs + (pwm->hwpwm * 16) + offset);
|
||||
}
|
||||
|
||||
static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
@@ -102,22 +148,22 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
|
||||
/*
|
||||
* Convert from duty_ns / period_ns to a fixed number of duty ticks
|
||||
* per (1 << PWM_DUTY_WIDTH) cycles and make sure to round to the
|
||||
* per TEGRA_PWM_DEPTH cycles and make sure to round to the
|
||||
* nearest integer during division.
|
||||
*/
|
||||
c *= (1 << PWM_DUTY_WIDTH);
|
||||
c *= TEGRA_PWM_DEPTH;
|
||||
c = DIV_ROUND_CLOSEST_ULL(c, period_ns);
|
||||
|
||||
val = (u32)c << PWM_DUTY_SHIFT;
|
||||
val = (u32)c << TEGRA_PWM_DUTY_SHIFT;
|
||||
|
||||
/*
|
||||
* min period = max clock limit >> PWM_DUTY_WIDTH
|
||||
* min period = max clock limit / TEGRA_PWM_DEPTH
|
||||
*/
|
||||
if (period_ns < pc->min_period_ns)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Compute the prescaler value for which (1 << PWM_DUTY_WIDTH)
|
||||
* Compute the prescaler value for which TEGRA_PWM_DEPTH
|
||||
* cycles at the PWM clock rate will take period_ns nanoseconds.
|
||||
*
|
||||
* num_channels: If single instance of PWM controller has multiple
|
||||
@@ -131,7 +177,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
*/
|
||||
if (pc->soc->num_channels == 1) {
|
||||
/*
|
||||
* Rate is multiplied with 2^PWM_DUTY_WIDTH so that it matches
|
||||
* Rate is multiplied with TEGRA_PWM_DEPTH so that it matches
|
||||
* with the maximum possible rate that the controller can
|
||||
* provide. Any further lower value can be derived by setting
|
||||
* PFM bits[0:12].
|
||||
@@ -141,7 +187,7 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
* source clock rate as required_clk_rate, PWM controller will
|
||||
* be able to configure the requested period.
|
||||
*/
|
||||
required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC << PWM_DUTY_WIDTH,
|
||||
required_clk_rate = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * TEGRA_PWM_DEPTH,
|
||||
period_ns);
|
||||
|
||||
if (required_clk_rate > clk_round_rate(pc->clk, required_clk_rate))
|
||||
@@ -163,9 +209,9 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
pc->clk_rate = clk_get_rate(pc->clk);
|
||||
}
|
||||
|
||||
/* Consider precision in PWM_SCALE_WIDTH rate calculation */
|
||||
/* Consider precision in scale_width rate calculation */
|
||||
rate = mul_u64_u64_div_u64(pc->clk_rate, period_ns,
|
||||
(u64)NSEC_PER_SEC << PWM_DUTY_WIDTH);
|
||||
(u64)NSEC_PER_SEC * TEGRA_PWM_DEPTH);
|
||||
|
||||
/*
|
||||
* Since the actual PWM divider is the register's frequency divider
|
||||
@@ -181,10 +227,10 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
* Make sure that the rate will fit in the register's frequency
|
||||
* divider field.
|
||||
*/
|
||||
if (rate >> PWM_SCALE_WIDTH)
|
||||
if (rate >> pc->soc->scale_width)
|
||||
return -EINVAL;
|
||||
|
||||
val |= rate << PWM_SCALE_SHIFT;
|
||||
val |= rate << TEGRA_PWM_SCALE_SHIFT;
|
||||
|
||||
/*
|
||||
* If the PWM channel is disabled, make sure to turn on the clock
|
||||
@@ -194,10 +240,11 @@ static int tegra_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
err = pm_runtime_resume_and_get(pwmchip_parent(chip));
|
||||
if (err)
|
||||
return err;
|
||||
} else
|
||||
val |= PWM_ENABLE;
|
||||
} else if (pc->soc->enable_reg == TEGRA_PWM_CSR_0) {
|
||||
val |= TEGRA_PWM_ENABLE;
|
||||
}
|
||||
|
||||
pwm_writel(pc, pwm->hwpwm, val);
|
||||
tegra_pwm_writel(pwm, TEGRA_PWM_CSR_0, val);
|
||||
|
||||
/*
|
||||
* If the PWM is not enabled, turn the clock off again to save power.
|
||||
@@ -218,9 +265,9 @@ static int tegra_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
val = pwm_readl(pc, pwm->hwpwm);
|
||||
val |= PWM_ENABLE;
|
||||
pwm_writel(pc, pwm->hwpwm, val);
|
||||
val = tegra_pwm_readl(pwm, pc->soc->enable_reg);
|
||||
val |= TEGRA_PWM_ENABLE;
|
||||
tegra_pwm_writel(pwm, pc->soc->enable_reg, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -230,9 +277,9 @@ static void tegra_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
|
||||
struct tegra_pwm_chip *pc = to_tegra_pwm_chip(chip);
|
||||
u32 val;
|
||||
|
||||
val = pwm_readl(pc, pwm->hwpwm);
|
||||
val &= ~PWM_ENABLE;
|
||||
pwm_writel(pc, pwm->hwpwm, val);
|
||||
val = tegra_pwm_readl(pwm, pc->soc->enable_reg);
|
||||
val &= ~TEGRA_PWM_ENABLE;
|
||||
tegra_pwm_writel(pwm, pc->soc->enable_reg, val);
|
||||
|
||||
pm_runtime_put_sync(pwmchip_parent(chip));
|
||||
}
|
||||
@@ -303,7 +350,7 @@ static int tegra_pwm_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
/* Set maximum frequency of the IP */
|
||||
ret = dev_pm_opp_set_rate(&pdev->dev, pc->soc->max_frequency);
|
||||
ret = dev_pm_opp_set_rate(&pdev->dev, ULONG_MAX);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Failed to set max frequency: %d\n", ret);
|
||||
goto put_pm;
|
||||
@@ -315,10 +362,15 @@ static int tegra_pwm_probe(struct platform_device *pdev)
|
||||
* so that PWM period can be calculated more accurately.
|
||||
*/
|
||||
pc->clk_rate = clk_get_rate(pc->clk);
|
||||
if (pc->clk_rate < TEGRA_PWM_DEPTH) {
|
||||
dev_err(&pdev->dev, "clock maximum frequency out of range\n");
|
||||
ret = -ERANGE;
|
||||
goto put_pm;
|
||||
}
|
||||
|
||||
/* Set minimum limit of PWM period for the IP */
|
||||
pc->min_period_ns =
|
||||
(NSEC_PER_SEC / (pc->soc->max_frequency >> PWM_DUTY_WIDTH)) + 1;
|
||||
(NSEC_PER_SEC / (pc->clk_rate / TEGRA_PWM_DEPTH)) + 1;
|
||||
|
||||
pc->rst = devm_reset_control_get_exclusive(&pdev->dev, "pwm");
|
||||
if (IS_ERR(pc->rst)) {
|
||||
@@ -397,23 +449,27 @@ static int __maybe_unused tegra_pwm_runtime_resume(struct device *dev)
|
||||
|
||||
static const struct tegra_pwm_soc tegra20_pwm_soc = {
|
||||
.num_channels = 4,
|
||||
.max_frequency = 48000000UL,
|
||||
.enable_reg = TEGRA_PWM_CSR_0,
|
||||
.scale_width = 13,
|
||||
};
|
||||
|
||||
static const struct tegra_pwm_soc tegra186_pwm_soc = {
|
||||
.num_channels = 1,
|
||||
.max_frequency = 102000000UL,
|
||||
.enable_reg = TEGRA_PWM_CSR_0,
|
||||
.scale_width = 13,
|
||||
};
|
||||
|
||||
static const struct tegra_pwm_soc tegra194_pwm_soc = {
|
||||
static const struct tegra_pwm_soc tegra264_pwm_soc = {
|
||||
.num_channels = 1,
|
||||
.max_frequency = 408000000UL,
|
||||
.enable_reg = TEGRA_PWM_CSR_1,
|
||||
.scale_width = 16,
|
||||
};
|
||||
|
||||
static const struct of_device_id tegra_pwm_of_match[] = {
|
||||
{ .compatible = "nvidia,tegra20-pwm", .data = &tegra20_pwm_soc },
|
||||
{ .compatible = "nvidia,tegra186-pwm", .data = &tegra186_pwm_soc },
|
||||
{ .compatible = "nvidia,tegra194-pwm", .data = &tegra194_pwm_soc },
|
||||
{ .compatible = "nvidia,tegra194-pwm", .data = &tegra186_pwm_soc },
|
||||
{ .compatible = "nvidia,tegra264-pwm", .data = &tegra264_pwm_soc },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
|
||||
|
||||
@@ -211,9 +211,9 @@ static const struct pwm_ops ecap_pwm_ops = {
|
||||
};
|
||||
|
||||
static const struct of_device_id ecap_of_match[] = {
|
||||
{ .compatible = "ti,am3352-ecap" },
|
||||
{ .compatible = "ti,am33xx-ecap" },
|
||||
{},
|
||||
{ .compatible = "ti,am3352-ecap" },
|
||||
{ .compatible = "ti,am33xx-ecap" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ecap_of_match);
|
||||
|
||||
|
||||
@@ -407,7 +407,7 @@ static const struct pwm_ops ehrpwm_pwm_ops = {
|
||||
static const struct of_device_id ehrpwm_of_match[] = {
|
||||
{ .compatible = "ti,am3352-ehrpwm" },
|
||||
{ .compatible = "ti,am33xx-ehrpwm" },
|
||||
{},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ehrpwm_of_match);
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ static int twl_pwmled_probe(struct platform_device *pdev)
|
||||
static const struct of_device_id twl_pwmled_of_match[] = {
|
||||
{ .compatible = "ti,twl4030-pwmled" },
|
||||
{ .compatible = "ti,twl6030-pwmled" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, twl_pwmled_of_match);
|
||||
#endif
|
||||
|
||||
@@ -362,7 +362,7 @@ static int twl_pwm_probe(struct platform_device *pdev)
|
||||
static const struct of_device_id twl_pwm_of_match[] = {
|
||||
{ .compatible = "ti,twl4030-pwm" },
|
||||
{ .compatible = "ti,twl6030-pwm" },
|
||||
{ },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, twl_pwm_of_match);
|
||||
#endif
|
||||
|
||||
@@ -156,7 +156,7 @@ static int visconti_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id visconti_pwm_of_match[] = {
|
||||
{ .compatible = "toshiba,visconti-pwm", },
|
||||
{ .compatible = "toshiba,visconti-pwm" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, visconti_pwm_of_match);
|
||||
|
||||
@@ -226,7 +226,7 @@ static const struct pwm_ops vt8500_pwm_ops = {
|
||||
};
|
||||
|
||||
static const struct of_device_id vt8500_pwm_dt_ids[] = {
|
||||
{ .compatible = "via,vt8500-pwm", },
|
||||
{ .compatible = "via,vt8500-pwm" },
|
||||
{ /* Sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids);
|
||||
|
||||
@@ -281,8 +281,8 @@ static int xilinx_pwm_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id xilinx_pwm_of_match[] = {
|
||||
{ .compatible = "xlnx,xps-timer-1.00.a", },
|
||||
{},
|
||||
{ .compatible = "xlnx,xps-timer-1.00.a" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, xilinx_pwm_of_match);
|
||||
|
||||
|
||||
@@ -23,15 +23,21 @@
|
||||
use core::ops::Deref;
|
||||
use kernel::{
|
||||
clk::Clk,
|
||||
device::{Bound, Core, Device},
|
||||
device::{
|
||||
Bound,
|
||||
Core,
|
||||
Device, //
|
||||
},
|
||||
devres,
|
||||
io::{
|
||||
mem::IoMem,
|
||||
Io, //
|
||||
},
|
||||
of, platform,
|
||||
of,
|
||||
platform,
|
||||
prelude::*,
|
||||
pwm, time,
|
||||
pwm,
|
||||
time, //
|
||||
};
|
||||
|
||||
const TH1520_MAX_PWM_NUM: u32 = 6;
|
||||
|
||||
@@ -494,9 +494,7 @@ pub(crate) fn as_raw(&self) -> *const bindings::pwm_ops {
|
||||
/// This is used to bridge Rust trait implementations to the C `struct pwm_ops`
|
||||
/// expected by the kernel.
|
||||
pub const fn create_pwm_ops<T: PwmOps>() -> PwmOpsVTable {
|
||||
// SAFETY: `core::mem::zeroed()` is unsafe. For `pwm_ops`, all fields are
|
||||
// `Option<extern "C" fn(...)>` or data, so a zeroed pattern (None/0) is valid initially.
|
||||
let mut ops: bindings::pwm_ops = unsafe { core::mem::zeroed() };
|
||||
let mut ops: bindings::pwm_ops = pin_init::zeroed();
|
||||
|
||||
ops.request = Some(Adapter::<T>::request_callback);
|
||||
ops.capture = Some(Adapter::<T>::capture_callback);
|
||||
|
||||
Reference in New Issue
Block a user