162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * AMD MP2 platform driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Setup the I2C adapters enumerated in the ACPI namespace. 662306a36Sopenharmony_ci * MP2 controllers have 2 separate busses, up to 2 I2C adapters may be listed. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Authors: Nehal Bakulchandra Shah <Nehal-bakulchandra.shah@amd.com> 962306a36Sopenharmony_ci * Elie Morisse <syniurge@gmail.com> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/acpi.h> 1362306a36Sopenharmony_ci#include <linux/kernel.h> 1462306a36Sopenharmony_ci#include <linux/module.h> 1562306a36Sopenharmony_ci#include <linux/platform_device.h> 1662306a36Sopenharmony_ci#include <linux/slab.h> 1762306a36Sopenharmony_ci#include <linux/types.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include "i2c-amd-mp2.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define AMD_MP2_I2C_MAX_RW_LENGTH ((1 << 12) - 1) 2262306a36Sopenharmony_ci#define AMD_I2C_TIMEOUT (msecs_to_jiffies(250)) 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/** 2562306a36Sopenharmony_ci * struct amd_i2c_dev - MP2 bus/i2c adapter context 2662306a36Sopenharmony_ci * @common: shared context with the MP2 PCI driver 2762306a36Sopenharmony_ci * @pdev: platform driver node 2862306a36Sopenharmony_ci * @adap: i2c adapter 2962306a36Sopenharmony_ci * @cmd_complete: xfer completion object 3062306a36Sopenharmony_ci */ 3162306a36Sopenharmony_cistruct amd_i2c_dev { 3262306a36Sopenharmony_ci struct amd_i2c_common common; 3362306a36Sopenharmony_ci struct platform_device *pdev; 3462306a36Sopenharmony_ci struct i2c_adapter adap; 3562306a36Sopenharmony_ci struct completion cmd_complete; 3662306a36Sopenharmony_ci}; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#define amd_i2c_dev_common(__common) \ 3962306a36Sopenharmony_ci container_of(__common, struct amd_i2c_dev, common) 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic int i2c_amd_dma_map(struct amd_i2c_common *i2c_common) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci struct device *dev_pci = &i2c_common->mp2_dev->pci_dev->dev; 4462306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common); 4562306a36Sopenharmony_ci enum dma_data_direction dma_direction = 4662306a36Sopenharmony_ci i2c_common->msg->flags & I2C_M_RD ? 4762306a36Sopenharmony_ci DMA_FROM_DEVICE : DMA_TO_DEVICE; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci i2c_common->dma_buf = i2c_get_dma_safe_msg_buf(i2c_common->msg, 0); 5062306a36Sopenharmony_ci i2c_common->dma_addr = dma_map_single(dev_pci, i2c_common->dma_buf, 5162306a36Sopenharmony_ci i2c_common->msg->len, 5262306a36Sopenharmony_ci dma_direction); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci if (unlikely(dma_mapping_error(dev_pci, i2c_common->dma_addr))) { 5562306a36Sopenharmony_ci dev_err(&i2c_dev->pdev->dev, 5662306a36Sopenharmony_ci "Error while mapping dma buffer %p\n", 5762306a36Sopenharmony_ci i2c_common->dma_buf); 5862306a36Sopenharmony_ci return -EIO; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return 0; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic void i2c_amd_dma_unmap(struct amd_i2c_common *i2c_common) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci struct device *dev_pci = &i2c_common->mp2_dev->pci_dev->dev; 6762306a36Sopenharmony_ci enum dma_data_direction dma_direction = 6862306a36Sopenharmony_ci i2c_common->msg->flags & I2C_M_RD ? 6962306a36Sopenharmony_ci DMA_FROM_DEVICE : DMA_TO_DEVICE; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci dma_unmap_single(dev_pci, i2c_common->dma_addr, 7262306a36Sopenharmony_ci i2c_common->msg->len, dma_direction); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci i2c_put_dma_safe_msg_buf(i2c_common->dma_buf, i2c_common->msg, true); 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic void i2c_amd_start_cmd(struct amd_i2c_dev *i2c_dev) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci struct amd_i2c_common *i2c_common = &i2c_dev->common; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci reinit_completion(&i2c_dev->cmd_complete); 8262306a36Sopenharmony_ci i2c_common->cmd_success = false; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_cistatic void i2c_amd_cmd_completion(struct amd_i2c_common *i2c_common) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common); 8862306a36Sopenharmony_ci union i2c_event *event = &i2c_common->eventval; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (event->r.status == i2c_readcomplete_event) 9162306a36Sopenharmony_ci dev_dbg(&i2c_dev->pdev->dev, "readdata:%*ph\n", event->r.length, 9262306a36Sopenharmony_ci i2c_common->msg->buf); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci complete(&i2c_dev->cmd_complete); 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic int i2c_amd_check_cmd_completion(struct amd_i2c_dev *i2c_dev) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci struct amd_i2c_common *i2c_common = &i2c_dev->common; 10062306a36Sopenharmony_ci unsigned long timeout; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci timeout = wait_for_completion_timeout(&i2c_dev->cmd_complete, 10362306a36Sopenharmony_ci i2c_dev->adap.timeout); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if ((i2c_common->reqcmd == i2c_read || 10662306a36Sopenharmony_ci i2c_common->reqcmd == i2c_write) && 10762306a36Sopenharmony_ci i2c_common->msg->len > 32) 10862306a36Sopenharmony_ci i2c_amd_dma_unmap(i2c_common); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci if (timeout == 0) { 11162306a36Sopenharmony_ci amd_mp2_rw_timeout(i2c_common); 11262306a36Sopenharmony_ci return -ETIMEDOUT; 11362306a36Sopenharmony_ci } 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci amd_mp2_process_event(i2c_common); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (!i2c_common->cmd_success) 11862306a36Sopenharmony_ci return -EIO; 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci return 0; 12162306a36Sopenharmony_ci} 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_cistatic int i2c_amd_enable_set(struct amd_i2c_dev *i2c_dev, bool enable) 12462306a36Sopenharmony_ci{ 12562306a36Sopenharmony_ci struct amd_i2c_common *i2c_common = &i2c_dev->common; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci i2c_amd_start_cmd(i2c_dev); 12862306a36Sopenharmony_ci amd_mp2_bus_enable_set(i2c_common, enable); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci return i2c_amd_check_cmd_completion(i2c_dev); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic int i2c_amd_xfer_msg(struct amd_i2c_dev *i2c_dev, struct i2c_msg *pmsg) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci struct amd_i2c_common *i2c_common = &i2c_dev->common; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci i2c_amd_start_cmd(i2c_dev); 13862306a36Sopenharmony_ci i2c_common->msg = pmsg; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (pmsg->len > 32) 14162306a36Sopenharmony_ci if (i2c_amd_dma_map(i2c_common)) 14262306a36Sopenharmony_ci return -EIO; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (pmsg->flags & I2C_M_RD) 14562306a36Sopenharmony_ci amd_mp2_rw(i2c_common, i2c_read); 14662306a36Sopenharmony_ci else 14762306a36Sopenharmony_ci amd_mp2_rw(i2c_common, i2c_write); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci return i2c_amd_check_cmd_completion(i2c_dev); 15062306a36Sopenharmony_ci} 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic int i2c_amd_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = i2c_get_adapdata(adap); 15562306a36Sopenharmony_ci int i; 15662306a36Sopenharmony_ci struct i2c_msg *pmsg; 15762306a36Sopenharmony_ci int err = 0; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci /* the adapter might have been deleted while waiting for the bus lock */ 16062306a36Sopenharmony_ci if (unlikely(!i2c_dev->common.mp2_dev)) 16162306a36Sopenharmony_ci return -EINVAL; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci amd_mp2_pm_runtime_get(i2c_dev->common.mp2_dev); 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci for (i = 0; i < num; i++) { 16662306a36Sopenharmony_ci pmsg = &msgs[i]; 16762306a36Sopenharmony_ci err = i2c_amd_xfer_msg(i2c_dev, pmsg); 16862306a36Sopenharmony_ci if (err) 16962306a36Sopenharmony_ci break; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci amd_mp2_pm_runtime_put(i2c_dev->common.mp2_dev); 17362306a36Sopenharmony_ci return err ? err : num; 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic u32 i2c_amd_func(struct i2c_adapter *a) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic const struct i2c_algorithm i2c_amd_algorithm = { 18262306a36Sopenharmony_ci .master_xfer = i2c_amd_xfer, 18362306a36Sopenharmony_ci .functionality = i2c_amd_func, 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci#ifdef CONFIG_PM 18762306a36Sopenharmony_cistatic int i2c_amd_suspend(struct amd_i2c_common *i2c_common) 18862306a36Sopenharmony_ci{ 18962306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci i2c_amd_enable_set(i2c_dev, false); 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic int i2c_amd_resume(struct amd_i2c_common *i2c_common) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = amd_i2c_dev_common(i2c_common); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci return i2c_amd_enable_set(i2c_dev, true); 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ci#endif 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic const u32 supported_speeds[] = { 20462306a36Sopenharmony_ci I2C_MAX_HIGH_SPEED_MODE_FREQ, 20562306a36Sopenharmony_ci I2C_MAX_TURBO_MODE_FREQ, 20662306a36Sopenharmony_ci I2C_MAX_FAST_MODE_PLUS_FREQ, 20762306a36Sopenharmony_ci I2C_MAX_FAST_MODE_FREQ, 20862306a36Sopenharmony_ci I2C_MAX_STANDARD_MODE_FREQ, 20962306a36Sopenharmony_ci}; 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_cistatic enum speed_enum i2c_amd_get_bus_speed(struct platform_device *pdev) 21262306a36Sopenharmony_ci{ 21362306a36Sopenharmony_ci u32 acpi_speed; 21462306a36Sopenharmony_ci int i; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev); 21762306a36Sopenharmony_ci /* round down to the lowest standard speed */ 21862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(supported_speeds); i++) { 21962306a36Sopenharmony_ci if (acpi_speed >= supported_speeds[i]) 22062306a36Sopenharmony_ci break; 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci acpi_speed = i < ARRAY_SIZE(supported_speeds) ? supported_speeds[i] : 0; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci switch (acpi_speed) { 22562306a36Sopenharmony_ci case I2C_MAX_STANDARD_MODE_FREQ: 22662306a36Sopenharmony_ci return speed100k; 22762306a36Sopenharmony_ci case I2C_MAX_FAST_MODE_FREQ: 22862306a36Sopenharmony_ci return speed400k; 22962306a36Sopenharmony_ci case I2C_MAX_FAST_MODE_PLUS_FREQ: 23062306a36Sopenharmony_ci return speed1000k; 23162306a36Sopenharmony_ci case I2C_MAX_TURBO_MODE_FREQ: 23262306a36Sopenharmony_ci return speed1400k; 23362306a36Sopenharmony_ci case I2C_MAX_HIGH_SPEED_MODE_FREQ: 23462306a36Sopenharmony_ci return speed3400k; 23562306a36Sopenharmony_ci default: 23662306a36Sopenharmony_ci return speed400k; 23762306a36Sopenharmony_ci } 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cistatic const struct i2c_adapter_quirks amd_i2c_dev_quirks = { 24162306a36Sopenharmony_ci .max_read_len = AMD_MP2_I2C_MAX_RW_LENGTH, 24262306a36Sopenharmony_ci .max_write_len = AMD_MP2_I2C_MAX_RW_LENGTH, 24362306a36Sopenharmony_ci}; 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic int i2c_amd_probe(struct platform_device *pdev) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci struct device *dev = &pdev->dev; 24862306a36Sopenharmony_ci int ret; 24962306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev; 25062306a36Sopenharmony_ci struct amd_mp2_dev *mp2_dev; 25162306a36Sopenharmony_ci u64 uid; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci ret = acpi_dev_uid_to_integer(ACPI_COMPANION(dev), &uid); 25462306a36Sopenharmony_ci if (ret) 25562306a36Sopenharmony_ci return dev_err_probe(dev, ret, "missing UID/bus id!\n"); 25662306a36Sopenharmony_ci if (uid >= 2) 25762306a36Sopenharmony_ci return dev_err_probe(dev, -EINVAL, "incorrect UID/bus id \"%llu\"!\n", uid); 25862306a36Sopenharmony_ci dev_dbg(dev, "bus id is %llu\n", uid); 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci /* The ACPI namespace doesn't contain information about which MP2 PCI 26162306a36Sopenharmony_ci * device an AMDI0011 ACPI device is related to, so assume that there's 26262306a36Sopenharmony_ci * only one MP2 PCI device per system. 26362306a36Sopenharmony_ci */ 26462306a36Sopenharmony_ci mp2_dev = amd_mp2_find_device(); 26562306a36Sopenharmony_ci if (!mp2_dev || !mp2_dev->probed) 26662306a36Sopenharmony_ci /* The MP2 PCI device should get probed later */ 26762306a36Sopenharmony_ci return -EPROBE_DEFER; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); 27062306a36Sopenharmony_ci if (!i2c_dev) 27162306a36Sopenharmony_ci return -ENOMEM; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci i2c_dev->common.bus_id = uid; 27462306a36Sopenharmony_ci i2c_dev->common.mp2_dev = mp2_dev; 27562306a36Sopenharmony_ci i2c_dev->pdev = pdev; 27662306a36Sopenharmony_ci platform_set_drvdata(pdev, i2c_dev); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci i2c_dev->common.cmd_completion = &i2c_amd_cmd_completion; 27962306a36Sopenharmony_ci#ifdef CONFIG_PM 28062306a36Sopenharmony_ci i2c_dev->common.suspend = &i2c_amd_suspend; 28162306a36Sopenharmony_ci i2c_dev->common.resume = &i2c_amd_resume; 28262306a36Sopenharmony_ci#endif 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* Register the adapter */ 28562306a36Sopenharmony_ci amd_mp2_pm_runtime_get(mp2_dev); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci i2c_dev->common.reqcmd = i2c_none; 28862306a36Sopenharmony_ci if (amd_mp2_register_cb(&i2c_dev->common)) 28962306a36Sopenharmony_ci return -EINVAL; 29062306a36Sopenharmony_ci device_link_add(&i2c_dev->pdev->dev, &mp2_dev->pci_dev->dev, 29162306a36Sopenharmony_ci DL_FLAG_AUTOREMOVE_CONSUMER); 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci i2c_dev->common.i2c_speed = i2c_amd_get_bus_speed(pdev); 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci /* Setup i2c adapter description */ 29662306a36Sopenharmony_ci i2c_dev->adap.owner = THIS_MODULE; 29762306a36Sopenharmony_ci i2c_dev->adap.algo = &i2c_amd_algorithm; 29862306a36Sopenharmony_ci i2c_dev->adap.quirks = &amd_i2c_dev_quirks; 29962306a36Sopenharmony_ci i2c_dev->adap.dev.parent = &pdev->dev; 30062306a36Sopenharmony_ci i2c_dev->adap.algo_data = i2c_dev; 30162306a36Sopenharmony_ci i2c_dev->adap.timeout = AMD_I2C_TIMEOUT; 30262306a36Sopenharmony_ci ACPI_COMPANION_SET(&i2c_dev->adap.dev, ACPI_COMPANION(&pdev->dev)); 30362306a36Sopenharmony_ci i2c_dev->adap.dev.of_node = pdev->dev.of_node; 30462306a36Sopenharmony_ci snprintf(i2c_dev->adap.name, sizeof(i2c_dev->adap.name), 30562306a36Sopenharmony_ci "AMD MP2 i2c bus %u", i2c_dev->common.bus_id); 30662306a36Sopenharmony_ci i2c_set_adapdata(&i2c_dev->adap, i2c_dev); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci init_completion(&i2c_dev->cmd_complete); 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci /* Enable the bus */ 31162306a36Sopenharmony_ci if (i2c_amd_enable_set(i2c_dev, true)) 31262306a36Sopenharmony_ci dev_err(&pdev->dev, "initial bus enable failed\n"); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci /* Attach to the i2c layer */ 31562306a36Sopenharmony_ci ret = i2c_add_adapter(&i2c_dev->adap); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci amd_mp2_pm_runtime_put(mp2_dev); 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci if (ret < 0) 32062306a36Sopenharmony_ci dev_err(&pdev->dev, "i2c add adapter failed = %d\n", ret); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci return ret; 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic void i2c_amd_remove(struct platform_device *pdev) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci struct amd_i2c_dev *i2c_dev = platform_get_drvdata(pdev); 32862306a36Sopenharmony_ci struct amd_i2c_common *i2c_common = &i2c_dev->common; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci i2c_lock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER); 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci i2c_amd_enable_set(i2c_dev, false); 33362306a36Sopenharmony_ci amd_mp2_unregister_cb(i2c_common); 33462306a36Sopenharmony_ci i2c_common->mp2_dev = NULL; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci i2c_unlock_bus(&i2c_dev->adap, I2C_LOCK_ROOT_ADAPTER); 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci i2c_del_adapter(&i2c_dev->adap); 33962306a36Sopenharmony_ci} 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_cistatic const struct acpi_device_id i2c_amd_acpi_match[] = { 34262306a36Sopenharmony_ci { "AMDI0011" }, 34362306a36Sopenharmony_ci { }, 34462306a36Sopenharmony_ci}; 34562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_cistatic struct platform_driver i2c_amd_plat_driver = { 34862306a36Sopenharmony_ci .probe = i2c_amd_probe, 34962306a36Sopenharmony_ci .remove_new = i2c_amd_remove, 35062306a36Sopenharmony_ci .driver = { 35162306a36Sopenharmony_ci .name = "i2c_amd_mp2", 35262306a36Sopenharmony_ci .acpi_match_table = ACPI_PTR(i2c_amd_acpi_match), 35362306a36Sopenharmony_ci }, 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_cimodule_platform_driver(i2c_amd_plat_driver); 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ciMODULE_DESCRIPTION("AMD(R) MP2 I2C Platform Driver"); 35862306a36Sopenharmony_ciMODULE_AUTHOR("Nehal Shah <nehal-bakulchandra.shah@amd.com>"); 35962306a36Sopenharmony_ciMODULE_AUTHOR("Elie Morisse <syniurge@gmail.com>"); 36062306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 361