18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Intel LPSS ACPI support. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2015, Intel Corporation 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com> 88c2ecf20Sopenharmony_ci * Mika Westerberg <mika.westerberg@linux.intel.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/acpi.h> 128c2ecf20Sopenharmony_ci#include <linux/ioport.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/pm_runtime.h> 168c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 178c2ecf20Sopenharmony_ci#include <linux/property.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#include "intel-lpss.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info spt_info = { 228c2ecf20Sopenharmony_ci .clk_rate = 120000000, 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic struct property_entry spt_i2c_properties[] = { 268c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 230), 278c2ecf20Sopenharmony_ci { }, 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info spt_i2c_info = { 318c2ecf20Sopenharmony_ci .clk_rate = 120000000, 328c2ecf20Sopenharmony_ci .properties = spt_i2c_properties, 338c2ecf20Sopenharmony_ci}; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic struct property_entry uart_properties[] = { 368c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("reg-io-width", 4), 378c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("reg-shift", 2), 388c2ecf20Sopenharmony_ci PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"), 398c2ecf20Sopenharmony_ci { }, 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info spt_uart_info = { 438c2ecf20Sopenharmony_ci .clk_rate = 120000000, 448c2ecf20Sopenharmony_ci .clk_con_id = "baudclk", 458c2ecf20Sopenharmony_ci .properties = uart_properties, 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info bxt_info = { 498c2ecf20Sopenharmony_ci .clk_rate = 100000000, 508c2ecf20Sopenharmony_ci}; 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistatic struct property_entry bxt_i2c_properties[] = { 538c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 42), 548c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 558c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 568c2ecf20Sopenharmony_ci { }, 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info bxt_i2c_info = { 608c2ecf20Sopenharmony_ci .clk_rate = 133000000, 618c2ecf20Sopenharmony_ci .properties = bxt_i2c_properties, 628c2ecf20Sopenharmony_ci}; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic struct property_entry apl_i2c_properties[] = { 658c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-sda-hold-time-ns", 207), 668c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-sda-falling-time-ns", 171), 678c2ecf20Sopenharmony_ci PROPERTY_ENTRY_U32("i2c-scl-falling-time-ns", 208), 688c2ecf20Sopenharmony_ci { }, 698c2ecf20Sopenharmony_ci}; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_cistatic const struct intel_lpss_platform_info apl_i2c_info = { 728c2ecf20Sopenharmony_ci .clk_rate = 133000000, 738c2ecf20Sopenharmony_ci .properties = apl_i2c_properties, 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic const struct acpi_device_id intel_lpss_acpi_ids[] = { 778c2ecf20Sopenharmony_ci /* SPT */ 788c2ecf20Sopenharmony_ci { "INT3440", (kernel_ulong_t)&spt_info }, 798c2ecf20Sopenharmony_ci { "INT3441", (kernel_ulong_t)&spt_info }, 808c2ecf20Sopenharmony_ci { "INT3442", (kernel_ulong_t)&spt_i2c_info }, 818c2ecf20Sopenharmony_ci { "INT3443", (kernel_ulong_t)&spt_i2c_info }, 828c2ecf20Sopenharmony_ci { "INT3444", (kernel_ulong_t)&spt_i2c_info }, 838c2ecf20Sopenharmony_ci { "INT3445", (kernel_ulong_t)&spt_i2c_info }, 848c2ecf20Sopenharmony_ci { "INT3446", (kernel_ulong_t)&spt_i2c_info }, 858c2ecf20Sopenharmony_ci { "INT3447", (kernel_ulong_t)&spt_i2c_info }, 868c2ecf20Sopenharmony_ci { "INT3448", (kernel_ulong_t)&spt_uart_info }, 878c2ecf20Sopenharmony_ci { "INT3449", (kernel_ulong_t)&spt_uart_info }, 888c2ecf20Sopenharmony_ci { "INT344A", (kernel_ulong_t)&spt_uart_info }, 898c2ecf20Sopenharmony_ci /* BXT */ 908c2ecf20Sopenharmony_ci { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, 918c2ecf20Sopenharmony_ci { "80860ABC", (kernel_ulong_t)&bxt_info }, 928c2ecf20Sopenharmony_ci { "80860AC2", (kernel_ulong_t)&bxt_info }, 938c2ecf20Sopenharmony_ci /* APL */ 948c2ecf20Sopenharmony_ci { "80865AAC", (kernel_ulong_t)&apl_i2c_info }, 958c2ecf20Sopenharmony_ci { "80865ABC", (kernel_ulong_t)&bxt_info }, 968c2ecf20Sopenharmony_ci { "80865AC2", (kernel_ulong_t)&bxt_info }, 978c2ecf20Sopenharmony_ci { } 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cistatic int intel_lpss_acpi_probe(struct platform_device *pdev) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct intel_lpss_platform_info *info; 1048c2ecf20Sopenharmony_ci const struct acpi_device_id *id; 1058c2ecf20Sopenharmony_ci int ret; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci id = acpi_match_device(intel_lpss_acpi_ids, &pdev->dev); 1088c2ecf20Sopenharmony_ci if (!id) 1098c2ecf20Sopenharmony_ci return -ENODEV; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci info = devm_kmemdup(&pdev->dev, (void *)id->driver_data, sizeof(*info), 1128c2ecf20Sopenharmony_ci GFP_KERNEL); 1138c2ecf20Sopenharmony_ci if (!info) 1148c2ecf20Sopenharmony_ci return -ENOMEM; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1178c2ecf20Sopenharmony_ci if (!info->mem) 1188c2ecf20Sopenharmony_ci return -ENODEV; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci info->irq = platform_get_irq(pdev, 0); 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci ret = intel_lpss_probe(&pdev->dev, info); 1238c2ecf20Sopenharmony_ci if (ret) 1248c2ecf20Sopenharmony_ci return ret; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci pm_runtime_set_active(&pdev->dev); 1278c2ecf20Sopenharmony_ci pm_runtime_enable(&pdev->dev); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci return 0; 1308c2ecf20Sopenharmony_ci} 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic int intel_lpss_acpi_remove(struct platform_device *pdev) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci intel_lpss_remove(&pdev->dev); 1358c2ecf20Sopenharmony_ci pm_runtime_disable(&pdev->dev); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci return 0; 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic INTEL_LPSS_PM_OPS(intel_lpss_acpi_pm_ops); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_cistatic struct platform_driver intel_lpss_acpi_driver = { 1438c2ecf20Sopenharmony_ci .probe = intel_lpss_acpi_probe, 1448c2ecf20Sopenharmony_ci .remove = intel_lpss_acpi_remove, 1458c2ecf20Sopenharmony_ci .driver = { 1468c2ecf20Sopenharmony_ci .name = "intel-lpss", 1478c2ecf20Sopenharmony_ci .acpi_match_table = intel_lpss_acpi_ids, 1488c2ecf20Sopenharmony_ci .pm = &intel_lpss_acpi_pm_ops, 1498c2ecf20Sopenharmony_ci }, 1508c2ecf20Sopenharmony_ci}; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_cimodule_platform_driver(intel_lpss_acpi_driver); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ciMODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); 1558c2ecf20Sopenharmony_ciMODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 1568c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Intel LPSS ACPI driver"); 1578c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 158