xref: /openbmc/linux/drivers/mfd/intel-lpss-acpi.c (revision d918e0d5)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
24b45efe8SAndy Shevchenko /*
34b45efe8SAndy Shevchenko  * Intel LPSS ACPI support.
44b45efe8SAndy Shevchenko  *
54b45efe8SAndy Shevchenko  * Copyright (C) 2015, Intel Corporation
64b45efe8SAndy Shevchenko  *
74b45efe8SAndy Shevchenko  * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
84b45efe8SAndy Shevchenko  *          Mika Westerberg <mika.westerberg@linux.intel.com>
94b45efe8SAndy Shevchenko  */
104b45efe8SAndy Shevchenko 
114b45efe8SAndy Shevchenko #include <linux/acpi.h>
124b45efe8SAndy Shevchenko #include <linux/ioport.h>
134b45efe8SAndy Shevchenko #include <linux/kernel.h>
144b45efe8SAndy Shevchenko #include <linux/module.h>
154b45efe8SAndy Shevchenko #include <linux/pm_runtime.h>
164b45efe8SAndy Shevchenko #include <linux/platform_device.h>
17028af594SMika Westerberg #include <linux/property.h>
185a2d27c2SAndy Shevchenko #include <linux/pxa2xx_ssp.h>
194b45efe8SAndy Shevchenko 
204b45efe8SAndy Shevchenko #include "intel-lpss.h"
214b45efe8SAndy Shevchenko 
225a2d27c2SAndy Shevchenko static const struct property_entry spt_spi_properties[] = {
235a2d27c2SAndy Shevchenko 	PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_SPT_SSP),
245a2d27c2SAndy Shevchenko 	{ }
255a2d27c2SAndy Shevchenko };
265a2d27c2SAndy Shevchenko 
275a2d27c2SAndy Shevchenko static const struct software_node spt_spi_node = {
285a2d27c2SAndy Shevchenko 	.properties = spt_spi_properties,
295a2d27c2SAndy Shevchenko };
305a2d27c2SAndy Shevchenko 
31c5b90cb2SAndy Shevchenko static const struct intel_lpss_platform_info spt_info = {
32c5b90cb2SAndy Shevchenko 	.clk_rate = 120000000,
335a2d27c2SAndy Shevchenko 	.swnode = &spt_spi_node,
34c5b90cb2SAndy Shevchenko };
35c5b90cb2SAndy Shevchenko 
369677e6f7SAndy Shevchenko static const struct property_entry spt_i2c_properties[] = {
37028af594SMika Westerberg 	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230),
38028af594SMika Westerberg 	{ },
39028af594SMika Westerberg };
40028af594SMika Westerberg 
4103152e35SHeikki Krogerus static const struct software_node spt_i2c_node = {
4203152e35SHeikki Krogerus 	.properties = spt_i2c_properties,
4303152e35SHeikki Krogerus };
4403152e35SHeikki Krogerus 
45028af594SMika Westerberg static const struct intel_lpss_platform_info spt_i2c_info = {
46028af594SMika Westerberg 	.clk_rate = 120000000,
4703152e35SHeikki Krogerus 	.swnode = &spt_i2c_node,
48028af594SMika Westerberg };
49028af594SMika Westerberg 
509677e6f7SAndy Shevchenko static const struct property_entry uart_properties[] = {
51c5b90cb2SAndy Shevchenko 	PROPERTY_ENTRY_U32("reg-io-width", 4),
52c5b90cb2SAndy Shevchenko 	PROPERTY_ENTRY_U32("reg-shift", 2),
53c5b90cb2SAndy Shevchenko 	PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
54c5b90cb2SAndy Shevchenko 	{ },
55c5b90cb2SAndy Shevchenko };
56c5b90cb2SAndy Shevchenko 
5703152e35SHeikki Krogerus static const struct software_node uart_node = {
5803152e35SHeikki Krogerus 	.properties = uart_properties,
5903152e35SHeikki Krogerus };
6003152e35SHeikki Krogerus 
61c5b90cb2SAndy Shevchenko static const struct intel_lpss_platform_info spt_uart_info = {
62c5b90cb2SAndy Shevchenko 	.clk_rate = 120000000,
63c5b90cb2SAndy Shevchenko 	.clk_con_id = "baudclk",
6403152e35SHeikki Krogerus 	.swnode = &uart_node,
65c5b90cb2SAndy Shevchenko };
66c5b90cb2SAndy Shevchenko 
675a2d27c2SAndy Shevchenko static const struct property_entry bxt_spi_properties[] = {
685a2d27c2SAndy Shevchenko 	PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BXT_SSP),
695a2d27c2SAndy Shevchenko 	{ }
705a2d27c2SAndy Shevchenko };
715a2d27c2SAndy Shevchenko 
725a2d27c2SAndy Shevchenko static const struct software_node bxt_spi_node = {
735a2d27c2SAndy Shevchenko 	.properties = bxt_spi_properties,
745a2d27c2SAndy Shevchenko };
755a2d27c2SAndy Shevchenko 
766a636ec0SMika Westerberg static const struct intel_lpss_platform_info bxt_info = {
776a636ec0SMika Westerberg 	.clk_rate = 100000000,
785a2d27c2SAndy Shevchenko 	.swnode = &bxt_spi_node,
796a636ec0SMika Westerberg };
806a636ec0SMika Westerberg 
819677e6f7SAndy Shevchenko static const struct property_entry bxt_i2c_properties[] = {
820343b2f4SMika Westerberg 	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42),
830343b2f4SMika Westerberg 	PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
840343b2f4SMika Westerberg 	PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
850343b2f4SMika Westerberg 	{ },
860343b2f4SMika Westerberg };
870343b2f4SMika Westerberg 
8803152e35SHeikki Krogerus static const struct software_node bxt_i2c_node = {
8903152e35SHeikki Krogerus 	.properties = bxt_i2c_properties,
9003152e35SHeikki Krogerus };
9103152e35SHeikki Krogerus 
926a636ec0SMika Westerberg static const struct intel_lpss_platform_info bxt_i2c_info = {
936a636ec0SMika Westerberg 	.clk_rate = 133000000,
9403152e35SHeikki Krogerus 	.swnode = &bxt_i2c_node,
956a636ec0SMika Westerberg };
966a636ec0SMika Westerberg 
979677e6f7SAndy Shevchenko static const struct property_entry apl_i2c_properties[] = {
98c50cdd62SJarkko Nikula 	PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207),
99c50cdd62SJarkko Nikula 	PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171),
100c50cdd62SJarkko Nikula 	PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208),
101c50cdd62SJarkko Nikula 	{ },
102c50cdd62SJarkko Nikula };
103c50cdd62SJarkko Nikula 
10403152e35SHeikki Krogerus static const struct software_node apl_i2c_node = {
10503152e35SHeikki Krogerus 	.properties = apl_i2c_properties,
10603152e35SHeikki Krogerus };
10703152e35SHeikki Krogerus 
108c50cdd62SJarkko Nikula static const struct intel_lpss_platform_info apl_i2c_info = {
109c50cdd62SJarkko Nikula 	.clk_rate = 133000000,
11003152e35SHeikki Krogerus 	.swnode = &apl_i2c_node,
111c50cdd62SJarkko Nikula };
112c50cdd62SJarkko Nikula 
1135a2d27c2SAndy Shevchenko static const struct property_entry cnl_spi_properties[] = {
1145a2d27c2SAndy Shevchenko 	PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP),
1155a2d27c2SAndy Shevchenko 	{ }
1165a2d27c2SAndy Shevchenko };
1175a2d27c2SAndy Shevchenko 
1185a2d27c2SAndy Shevchenko static const struct software_node cnl_spi_node = {
1195a2d27c2SAndy Shevchenko 	.properties = cnl_spi_properties,
1205a2d27c2SAndy Shevchenko };
1215a2d27c2SAndy Shevchenko 
1225a2d27c2SAndy Shevchenko static const struct intel_lpss_platform_info cnl_info = {
1235a2d27c2SAndy Shevchenko 	.clk_rate = 120000000,
1245a2d27c2SAndy Shevchenko 	.swnode = &cnl_spi_node,
1255a2d27c2SAndy Shevchenko };
1265a2d27c2SAndy Shevchenko 
12732979fcfSAndy Shevchenko static const struct intel_lpss_platform_info cnl_i2c_info = {
12832979fcfSAndy Shevchenko 	.clk_rate = 216000000,
12932979fcfSAndy Shevchenko 	.swnode = &spt_i2c_node,
13032979fcfSAndy Shevchenko };
13132979fcfSAndy Shevchenko 
1324b45efe8SAndy Shevchenko static const struct acpi_device_id intel_lpss_acpi_ids[] = {
1334b45efe8SAndy Shevchenko 	/* SPT */
134c5b90cb2SAndy Shevchenko 	{ "INT3440", (kernel_ulong_t)&spt_info },
135c5b90cb2SAndy Shevchenko 	{ "INT3441", (kernel_ulong_t)&spt_info },
136c5b90cb2SAndy Shevchenko 	{ "INT3442", (kernel_ulong_t)&spt_i2c_info },
137c5b90cb2SAndy Shevchenko 	{ "INT3443", (kernel_ulong_t)&spt_i2c_info },
138c5b90cb2SAndy Shevchenko 	{ "INT3444", (kernel_ulong_t)&spt_i2c_info },
139c5b90cb2SAndy Shevchenko 	{ "INT3445", (kernel_ulong_t)&spt_i2c_info },
140028af594SMika Westerberg 	{ "INT3446", (kernel_ulong_t)&spt_i2c_info },
141028af594SMika Westerberg 	{ "INT3447", (kernel_ulong_t)&spt_i2c_info },
142c5b90cb2SAndy Shevchenko 	{ "INT3448", (kernel_ulong_t)&spt_uart_info },
143c5b90cb2SAndy Shevchenko 	{ "INT3449", (kernel_ulong_t)&spt_uart_info },
144c5b90cb2SAndy Shevchenko 	{ "INT344A", (kernel_ulong_t)&spt_uart_info },
14532979fcfSAndy Shevchenko 	/* CNL */
1465a2d27c2SAndy Shevchenko 	{ "INT34B0", (kernel_ulong_t)&cnl_info },
1475a2d27c2SAndy Shevchenko 	{ "INT34B1", (kernel_ulong_t)&cnl_info },
14832979fcfSAndy Shevchenko 	{ "INT34B2", (kernel_ulong_t)&cnl_i2c_info },
14932979fcfSAndy Shevchenko 	{ "INT34B3", (kernel_ulong_t)&cnl_i2c_info },
15032979fcfSAndy Shevchenko 	{ "INT34B4", (kernel_ulong_t)&cnl_i2c_info },
15132979fcfSAndy Shevchenko 	{ "INT34B5", (kernel_ulong_t)&cnl_i2c_info },
15232979fcfSAndy Shevchenko 	{ "INT34B6", (kernel_ulong_t)&cnl_i2c_info },
15332979fcfSAndy Shevchenko 	{ "INT34B7", (kernel_ulong_t)&cnl_i2c_info },
15432979fcfSAndy Shevchenko 	{ "INT34B8", (kernel_ulong_t)&spt_uart_info },
15532979fcfSAndy Shevchenko 	{ "INT34B9", (kernel_ulong_t)&spt_uart_info },
15632979fcfSAndy Shevchenko 	{ "INT34BA", (kernel_ulong_t)&spt_uart_info },
1575a2d27c2SAndy Shevchenko 	{ "INT34BC", (kernel_ulong_t)&cnl_info },
1586a636ec0SMika Westerberg 	/* BXT */
1596a636ec0SMika Westerberg 	{ "80860AAC", (kernel_ulong_t)&bxt_i2c_info },
1606a636ec0SMika Westerberg 	{ "80860ABC", (kernel_ulong_t)&bxt_info },
1616a636ec0SMika Westerberg 	{ "80860AC2", (kernel_ulong_t)&bxt_info },
1626a636ec0SMika Westerberg 	/* APL */
163c50cdd62SJarkko Nikula 	{ "80865AAC", (kernel_ulong_t)&apl_i2c_info },
1646a636ec0SMika Westerberg 	{ "80865ABC", (kernel_ulong_t)&bxt_info },
1656a636ec0SMika Westerberg 	{ "80865AC2", (kernel_ulong_t)&bxt_info },
1664b45efe8SAndy Shevchenko 	{ }
1674b45efe8SAndy Shevchenko };
1684b45efe8SAndy Shevchenko MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids);
1694b45efe8SAndy Shevchenko 
intel_lpss_acpi_probe(struct platform_device * pdev)1704b45efe8SAndy Shevchenko static int intel_lpss_acpi_probe(struct platform_device *pdev)
1714b45efe8SAndy Shevchenko {
1724b45efe8SAndy Shevchenko 	struct intel_lpss_platform_info *info;
1734b45efe8SAndy Shevchenko 	const struct acpi_device_id *id;
174c9e14308SAndy Shevchenko 	int ret;
1754b45efe8SAndy Shevchenko 
1764b45efe8SAndy Shevchenko 	id = acpi_match_device(intel_lpss_acpi_ids, &pdev->dev);
1774b45efe8SAndy Shevchenko 	if (!id)
1784b45efe8SAndy Shevchenko 		return -ENODEV;
1794b45efe8SAndy Shevchenko 
1804b45efe8SAndy Shevchenko 	info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info),
1814b45efe8SAndy Shevchenko 			    GFP_KERNEL);
1824b45efe8SAndy Shevchenko 	if (!info)
1834b45efe8SAndy Shevchenko 		return -ENOMEM;
1844b45efe8SAndy Shevchenko 
1854b45efe8SAndy Shevchenko 	info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
186*d918e0d5SJiasheng Jiang 	if (!info->mem)
187*d918e0d5SJiasheng Jiang 		return -ENODEV;
188*d918e0d5SJiasheng Jiang 
1894b45efe8SAndy Shevchenko 	info->irq = platform_get_irq(pdev, 0);
1904b45efe8SAndy Shevchenko 
191c9e14308SAndy Shevchenko 	ret = intel_lpss_probe(&pdev->dev, info);
192c9e14308SAndy Shevchenko 	if (ret)
193c9e14308SAndy Shevchenko 		return ret;
194c9e14308SAndy Shevchenko 
1954b45efe8SAndy Shevchenko 	pm_runtime_set_active(&pdev->dev);
1964b45efe8SAndy Shevchenko 	pm_runtime_enable(&pdev->dev);
1974b45efe8SAndy Shevchenko 
198c9e14308SAndy Shevchenko 	return 0;
1994b45efe8SAndy Shevchenko }
2004b45efe8SAndy Shevchenko 
intel_lpss_acpi_remove(struct platform_device * pdev)2014b45efe8SAndy Shevchenko static int intel_lpss_acpi_remove(struct platform_device *pdev)
2024b45efe8SAndy Shevchenko {
2034b45efe8SAndy Shevchenko 	intel_lpss_remove(&pdev->dev);
2044b45efe8SAndy Shevchenko 	pm_runtime_disable(&pdev->dev);
2054b45efe8SAndy Shevchenko 
2064b45efe8SAndy Shevchenko 	return 0;
2074b45efe8SAndy Shevchenko }
2084b45efe8SAndy Shevchenko 
2094b45efe8SAndy Shevchenko static INTEL_LPSS_PM_OPS(intel_lpss_acpi_pm_ops);
2104b45efe8SAndy Shevchenko 
2114b45efe8SAndy Shevchenko static struct platform_driver intel_lpss_acpi_driver = {
2124b45efe8SAndy Shevchenko 	.probe = intel_lpss_acpi_probe,
2134b45efe8SAndy Shevchenko 	.remove = intel_lpss_acpi_remove,
2144b45efe8SAndy Shevchenko 	.driver = {
2154b45efe8SAndy Shevchenko 		.name = "intel-lpss",
2164b45efe8SAndy Shevchenko 		.acpi_match_table = intel_lpss_acpi_ids,
2174b45efe8SAndy Shevchenko 		.pm = &intel_lpss_acpi_pm_ops,
2184b45efe8SAndy Shevchenko 	},
2194b45efe8SAndy Shevchenko };
2204b45efe8SAndy Shevchenko 
2214b45efe8SAndy Shevchenko module_platform_driver(intel_lpss_acpi_driver);
2224b45efe8SAndy Shevchenko 
2234b45efe8SAndy Shevchenko MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
2244b45efe8SAndy Shevchenko MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
2254b45efe8SAndy Shevchenko MODULE_DESCRIPTION("Intel LPSS ACPI driver");
2264b45efe8SAndy Shevchenko MODULE_LICENSE("GPL v2");
227