18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Driver for the ADC on Freescale Semiconductor MC13783 and MC13892 PMICs. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. 68c2ecf20Sopenharmony_ci * Copyright (C) 2009 Sascha Hauer, Pengutronix 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/mfd/mc13xxx.h> 108c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 118c2ecf20Sopenharmony_ci#include <linux/hwmon-sysfs.h> 128c2ecf20Sopenharmony_ci#include <linux/kernel.h> 138c2ecf20Sopenharmony_ci#include <linux/module.h> 148c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h> 158c2ecf20Sopenharmony_ci#include <linux/hwmon.h> 168c2ecf20Sopenharmony_ci#include <linux/slab.h> 178c2ecf20Sopenharmony_ci#include <linux/init.h> 188c2ecf20Sopenharmony_ci#include <linux/err.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define DRIVER_NAME "mc13783-adc" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* platform device id driver data */ 238c2ecf20Sopenharmony_ci#define MC13783_ADC_16CHANS 1 248c2ecf20Sopenharmony_ci#define MC13783_ADC_BPDIV2 2 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistruct mc13783_adc_priv { 278c2ecf20Sopenharmony_ci struct mc13xxx *mc13xxx; 288c2ecf20Sopenharmony_ci struct device *hwmon_dev; 298c2ecf20Sopenharmony_ci char name[PLATFORM_NAME_SIZE]; 308c2ecf20Sopenharmony_ci}; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic ssize_t name_show(struct device *dev, struct device_attribute *devattr, 338c2ecf20Sopenharmony_ci char *buf) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci struct mc13783_adc_priv *priv = dev_get_drvdata(dev); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return sprintf(buf, "%s\n", priv->name); 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic int mc13783_adc_read(struct device *dev, 418c2ecf20Sopenharmony_ci struct device_attribute *devattr, unsigned int *val) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci struct mc13783_adc_priv *priv = dev_get_drvdata(dev); 448c2ecf20Sopenharmony_ci struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 458c2ecf20Sopenharmony_ci unsigned int channel = attr->index; 468c2ecf20Sopenharmony_ci unsigned int sample[4]; 478c2ecf20Sopenharmony_ci int ret; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci ret = mc13xxx_adc_do_conversion(priv->mc13xxx, 508c2ecf20Sopenharmony_ci MC13XXX_ADC_MODE_MULT_CHAN, 518c2ecf20Sopenharmony_ci channel, 0, 0, sample); 528c2ecf20Sopenharmony_ci if (ret) 538c2ecf20Sopenharmony_ci return ret; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* ADIN7 subchannels */ 568c2ecf20Sopenharmony_ci if (channel >= 16) 578c2ecf20Sopenharmony_ci channel = 7; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci channel &= 0x7; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci *val = (sample[channel % 4] >> (channel > 3 ? 14 : 2)) & 0x3ff; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci} 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic ssize_t mc13783_adc_bp_show(struct device *dev, 678c2ecf20Sopenharmony_ci struct device_attribute *devattr, 688c2ecf20Sopenharmony_ci char *buf) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci unsigned val; 718c2ecf20Sopenharmony_ci struct platform_device *pdev = to_platform_device(dev); 728c2ecf20Sopenharmony_ci kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 738c2ecf20Sopenharmony_ci int ret = mc13783_adc_read(dev, devattr, &val); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci if (ret) 768c2ecf20Sopenharmony_ci return ret; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (driver_data & MC13783_ADC_BPDIV2) 798c2ecf20Sopenharmony_ci val = DIV_ROUND_CLOSEST(val * 9, 2); 808c2ecf20Sopenharmony_ci else 818c2ecf20Sopenharmony_ci /* 828c2ecf20Sopenharmony_ci * BP (channel 2) reports with offset 2.4V to the actual value 838c2ecf20Sopenharmony_ci * to fit the input range of the ADC. unit = 2.25mV = 9/4 mV. 848c2ecf20Sopenharmony_ci */ 858c2ecf20Sopenharmony_ci val = DIV_ROUND_CLOSEST(val * 9, 4) + 2400; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", val); 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic ssize_t mc13783_adc_gp_show(struct device *dev, 918c2ecf20Sopenharmony_ci struct device_attribute *devattr, 928c2ecf20Sopenharmony_ci char *buf) 938c2ecf20Sopenharmony_ci{ 948c2ecf20Sopenharmony_ci unsigned val; 958c2ecf20Sopenharmony_ci int ret = mc13783_adc_read(dev, devattr, &val); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (ret) 988c2ecf20Sopenharmony_ci return ret; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* 1018c2ecf20Sopenharmony_ci * input range is [0, 2.3V], val has 10 bits, so each bit 1028c2ecf20Sopenharmony_ci * is worth 9/4 mV. 1038c2ecf20Sopenharmony_ci */ 1048c2ecf20Sopenharmony_ci val = DIV_ROUND_CLOSEST(val * 9, 4); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", val); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic ssize_t mc13783_adc_uid_show(struct device *dev, 1108c2ecf20Sopenharmony_ci struct device_attribute *devattr, 1118c2ecf20Sopenharmony_ci char *buf) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci unsigned int val; 1148c2ecf20Sopenharmony_ci struct platform_device *pdev = to_platform_device(dev); 1158c2ecf20Sopenharmony_ci kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 1168c2ecf20Sopenharmony_ci int ret = mc13783_adc_read(dev, devattr, &val); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci if (ret) 1198c2ecf20Sopenharmony_ci return ret; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (driver_data & MC13783_ADC_BPDIV2) 1228c2ecf20Sopenharmony_ci /* MC13892 have 1/2 divider, input range is [0, 4.800V] */ 1238c2ecf20Sopenharmony_ci val = DIV_ROUND_CLOSEST(val * 4800, 1024); 1248c2ecf20Sopenharmony_ci else 1258c2ecf20Sopenharmony_ci /* MC13783 have 0.9 divider, input range is [0, 2.555V] */ 1268c2ecf20Sopenharmony_ci val = DIV_ROUND_CLOSEST(val * 2555, 1024); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci return sprintf(buf, "%u\n", val); 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic ssize_t mc13783_adc_temp_show(struct device *dev, 1328c2ecf20Sopenharmony_ci struct device_attribute *devattr, 1338c2ecf20Sopenharmony_ci char *buf) 1348c2ecf20Sopenharmony_ci{ 1358c2ecf20Sopenharmony_ci unsigned int val; 1368c2ecf20Sopenharmony_ci struct platform_device *pdev = to_platform_device(dev); 1378c2ecf20Sopenharmony_ci kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 1388c2ecf20Sopenharmony_ci int ret = mc13783_adc_read(dev, devattr, &val); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci if (ret) 1418c2ecf20Sopenharmony_ci return ret; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if (driver_data & MC13783_ADC_BPDIV2) { 1448c2ecf20Sopenharmony_ci /* 1458c2ecf20Sopenharmony_ci * MC13892: 1468c2ecf20Sopenharmony_ci * Die Temperature Read Out Code at 25C 680 1478c2ecf20Sopenharmony_ci * Temperature change per LSB +0.4244C 1488c2ecf20Sopenharmony_ci */ 1498c2ecf20Sopenharmony_ci ret = DIV_ROUND_CLOSEST(-2635920 + val * 4244, 10); 1508c2ecf20Sopenharmony_ci } else { 1518c2ecf20Sopenharmony_ci /* 1528c2ecf20Sopenharmony_ci * MC13783: 1538c2ecf20Sopenharmony_ci * Die Temperature Read Out Code at 25C 282 1548c2ecf20Sopenharmony_ci * Temperature change per LSB -1.14C 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ci ret = 346480 - 1140 * val; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci return sprintf(buf, "%d\n", ret); 1608c2ecf20Sopenharmony_ci} 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_cistatic DEVICE_ATTR_RO(name); 1638c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in2_input, mc13783_adc_bp, 2); 1648c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in5_input, mc13783_adc_gp, 5); 1658c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in6_input, mc13783_adc_gp, 6); 1668c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in7_input, mc13783_adc_gp, 7); 1678c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in8_input, mc13783_adc_gp, 8); 1688c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in9_input, mc13783_adc_gp, 9); 1698c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in10_input, mc13783_adc_gp, 10); 1708c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in11_input, mc13783_adc_gp, 11); 1718c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in12_input, mc13783_adc_gp, 12); 1728c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in13_input, mc13783_adc_gp, 13); 1738c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in14_input, mc13783_adc_gp, 14); 1748c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in15_input, mc13783_adc_gp, 15); 1758c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(in16_input, mc13783_adc_uid, 16); 1768c2ecf20Sopenharmony_cistatic SENSOR_DEVICE_ATTR_RO(temp1_input, mc13783_adc_temp, 17); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic struct attribute *mc13783_attr_base[] = { 1798c2ecf20Sopenharmony_ci &dev_attr_name.attr, 1808c2ecf20Sopenharmony_ci &sensor_dev_attr_in2_input.dev_attr.attr, 1818c2ecf20Sopenharmony_ci &sensor_dev_attr_in5_input.dev_attr.attr, 1828c2ecf20Sopenharmony_ci &sensor_dev_attr_in6_input.dev_attr.attr, 1838c2ecf20Sopenharmony_ci &sensor_dev_attr_in7_input.dev_attr.attr, 1848c2ecf20Sopenharmony_ci &sensor_dev_attr_in16_input.dev_attr.attr, 1858c2ecf20Sopenharmony_ci &sensor_dev_attr_temp1_input.dev_attr.attr, 1868c2ecf20Sopenharmony_ci NULL 1878c2ecf20Sopenharmony_ci}; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic const struct attribute_group mc13783_group_base = { 1908c2ecf20Sopenharmony_ci .attrs = mc13783_attr_base, 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci/* these are only used if MC13783_ADC_16CHANS is provided in driver data */ 1948c2ecf20Sopenharmony_cistatic struct attribute *mc13783_attr_16chans[] = { 1958c2ecf20Sopenharmony_ci &sensor_dev_attr_in8_input.dev_attr.attr, 1968c2ecf20Sopenharmony_ci &sensor_dev_attr_in9_input.dev_attr.attr, 1978c2ecf20Sopenharmony_ci &sensor_dev_attr_in10_input.dev_attr.attr, 1988c2ecf20Sopenharmony_ci &sensor_dev_attr_in11_input.dev_attr.attr, 1998c2ecf20Sopenharmony_ci NULL 2008c2ecf20Sopenharmony_ci}; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic const struct attribute_group mc13783_group_16chans = { 2038c2ecf20Sopenharmony_ci .attrs = mc13783_attr_16chans, 2048c2ecf20Sopenharmony_ci}; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* last four channels may be occupied by the touchscreen */ 2078c2ecf20Sopenharmony_cistatic struct attribute *mc13783_attr_ts[] = { 2088c2ecf20Sopenharmony_ci &sensor_dev_attr_in12_input.dev_attr.attr, 2098c2ecf20Sopenharmony_ci &sensor_dev_attr_in13_input.dev_attr.attr, 2108c2ecf20Sopenharmony_ci &sensor_dev_attr_in14_input.dev_attr.attr, 2118c2ecf20Sopenharmony_ci &sensor_dev_attr_in15_input.dev_attr.attr, 2128c2ecf20Sopenharmony_ci NULL 2138c2ecf20Sopenharmony_ci}; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic const struct attribute_group mc13783_group_ts = { 2168c2ecf20Sopenharmony_ci .attrs = mc13783_attr_ts, 2178c2ecf20Sopenharmony_ci}; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic int mc13783_adc_use_touchscreen(struct platform_device *pdev) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); 2228c2ecf20Sopenharmony_ci unsigned flags = mc13xxx_get_flags(priv->mc13xxx); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci return flags & MC13XXX_USE_TOUCHSCREEN; 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic int __init mc13783_adc_probe(struct platform_device *pdev) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci struct mc13783_adc_priv *priv; 2308c2ecf20Sopenharmony_ci int ret; 2318c2ecf20Sopenharmony_ci const struct platform_device_id *id = platform_get_device_id(pdev); 2328c2ecf20Sopenharmony_ci char *dash; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 2358c2ecf20Sopenharmony_ci if (!priv) 2368c2ecf20Sopenharmony_ci return -ENOMEM; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); 2398c2ecf20Sopenharmony_ci snprintf(priv->name, ARRAY_SIZE(priv->name), "%s", id->name); 2408c2ecf20Sopenharmony_ci dash = strchr(priv->name, '-'); 2418c2ecf20Sopenharmony_ci if (dash) 2428c2ecf20Sopenharmony_ci *dash = '\0'; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, priv); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci /* Register sysfs hooks */ 2478c2ecf20Sopenharmony_ci ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_base); 2488c2ecf20Sopenharmony_ci if (ret) 2498c2ecf20Sopenharmony_ci return ret; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci if (id->driver_data & MC13783_ADC_16CHANS) { 2528c2ecf20Sopenharmony_ci ret = sysfs_create_group(&pdev->dev.kobj, 2538c2ecf20Sopenharmony_ci &mc13783_group_16chans); 2548c2ecf20Sopenharmony_ci if (ret) 2558c2ecf20Sopenharmony_ci goto out_err_create_16chans; 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if (!mc13783_adc_use_touchscreen(pdev)) { 2598c2ecf20Sopenharmony_ci ret = sysfs_create_group(&pdev->dev.kobj, &mc13783_group_ts); 2608c2ecf20Sopenharmony_ci if (ret) 2618c2ecf20Sopenharmony_ci goto out_err_create_ts; 2628c2ecf20Sopenharmony_ci } 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci priv->hwmon_dev = hwmon_device_register(&pdev->dev); 2658c2ecf20Sopenharmony_ci if (IS_ERR(priv->hwmon_dev)) { 2668c2ecf20Sopenharmony_ci ret = PTR_ERR(priv->hwmon_dev); 2678c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 2688c2ecf20Sopenharmony_ci "hwmon_device_register failed with %d.\n", ret); 2698c2ecf20Sopenharmony_ci goto out_err_register; 2708c2ecf20Sopenharmony_ci } 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci return 0; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ciout_err_register: 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci if (!mc13783_adc_use_touchscreen(pdev)) 2778c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); 2788c2ecf20Sopenharmony_ciout_err_create_ts: 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (id->driver_data & MC13783_ADC_16CHANS) 2818c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); 2828c2ecf20Sopenharmony_ciout_err_create_16chans: 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); 2858c2ecf20Sopenharmony_ci return ret; 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_cistatic int mc13783_adc_remove(struct platform_device *pdev) 2898c2ecf20Sopenharmony_ci{ 2908c2ecf20Sopenharmony_ci struct mc13783_adc_priv *priv = platform_get_drvdata(pdev); 2918c2ecf20Sopenharmony_ci kernel_ulong_t driver_data = platform_get_device_id(pdev)->driver_data; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci hwmon_device_unregister(priv->hwmon_dev); 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci if (!mc13783_adc_use_touchscreen(pdev)) 2968c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_ts); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci if (driver_data & MC13783_ADC_16CHANS) 2998c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_16chans); 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci sysfs_remove_group(&pdev->dev.kobj, &mc13783_group_base); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci return 0; 3048c2ecf20Sopenharmony_ci} 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_cistatic const struct platform_device_id mc13783_adc_idtable[] = { 3078c2ecf20Sopenharmony_ci { 3088c2ecf20Sopenharmony_ci .name = "mc13783-adc", 3098c2ecf20Sopenharmony_ci .driver_data = MC13783_ADC_16CHANS, 3108c2ecf20Sopenharmony_ci }, { 3118c2ecf20Sopenharmony_ci .name = "mc13892-adc", 3128c2ecf20Sopenharmony_ci .driver_data = MC13783_ADC_BPDIV2, 3138c2ecf20Sopenharmony_ci }, { 3148c2ecf20Sopenharmony_ci /* sentinel */ 3158c2ecf20Sopenharmony_ci } 3168c2ecf20Sopenharmony_ci}; 3178c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(platform, mc13783_adc_idtable); 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic struct platform_driver mc13783_adc_driver = { 3208c2ecf20Sopenharmony_ci .remove = mc13783_adc_remove, 3218c2ecf20Sopenharmony_ci .driver = { 3228c2ecf20Sopenharmony_ci .name = DRIVER_NAME, 3238c2ecf20Sopenharmony_ci }, 3248c2ecf20Sopenharmony_ci .id_table = mc13783_adc_idtable, 3258c2ecf20Sopenharmony_ci}; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cimodule_platform_driver_probe(mc13783_adc_driver, mc13783_adc_probe); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MC13783 ADC driver"); 3308c2ecf20Sopenharmony_ciMODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 3318c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 332