18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Maxim MAX14656 / AL32 USB Charger Detector driver
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2014 LG Electronics, Inc
68c2ecf20Sopenharmony_ci * Copyright (C) 2016 Alexander Kurz <akurz@blala.de>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Components from Maxim AL32 Charger detection Driver for MX50 Yoshi Board
98c2ecf20Sopenharmony_ci * Copyright (C) Amazon Technologies Inc. All rights reserved.
108c2ecf20Sopenharmony_ci * Manish Lachwani (lachwani@lab126.com)
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#include <linux/module.h>
138c2ecf20Sopenharmony_ci#include <linux/init.h>
148c2ecf20Sopenharmony_ci#include <linux/delay.h>
158c2ecf20Sopenharmony_ci#include <linux/i2c.h>
168c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
178c2ecf20Sopenharmony_ci#include <linux/slab.h>
188c2ecf20Sopenharmony_ci#include <linux/gpio.h>
198c2ecf20Sopenharmony_ci#include <linux/of_gpio.h>
208c2ecf20Sopenharmony_ci#include <linux/of_device.h>
218c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
228c2ecf20Sopenharmony_ci#include <linux/power_supply.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define MAX14656_MANUFACTURER	"Maxim Integrated"
258c2ecf20Sopenharmony_ci#define MAX14656_NAME		"max14656"
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define MAX14656_DEVICE_ID	0x00
288c2ecf20Sopenharmony_ci#define MAX14656_INTERRUPT_1	0x01
298c2ecf20Sopenharmony_ci#define MAX14656_INTERRUPT_2	0x02
308c2ecf20Sopenharmony_ci#define MAX14656_STATUS_1	0x03
318c2ecf20Sopenharmony_ci#define MAX14656_STATUS_2	0x04
328c2ecf20Sopenharmony_ci#define MAX14656_INTMASK_1	0x05
338c2ecf20Sopenharmony_ci#define MAX14656_INTMASK_2	0x06
348c2ecf20Sopenharmony_ci#define MAX14656_CONTROL_1	0x07
358c2ecf20Sopenharmony_ci#define MAX14656_CONTROL_2	0x08
368c2ecf20Sopenharmony_ci#define MAX14656_CONTROL_3	0x09
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#define DEVICE_VENDOR_MASK	0xf0
398c2ecf20Sopenharmony_ci#define DEVICE_REV_MASK		0x0f
408c2ecf20Sopenharmony_ci#define INT_EN_REG_MASK		BIT(4)
418c2ecf20Sopenharmony_ci#define CHG_TYPE_INT_MASK	BIT(0)
428c2ecf20Sopenharmony_ci#define STATUS1_VB_VALID_MASK	BIT(4)
438c2ecf20Sopenharmony_ci#define STATUS1_CHG_TYPE_MASK	0xf
448c2ecf20Sopenharmony_ci#define INT1_DCD_TIMEOUT_MASK	BIT(7)
458c2ecf20Sopenharmony_ci#define CONTROL1_DEFAULT	0x0d
468c2ecf20Sopenharmony_ci#define CONTROL1_INT_EN		BIT(4)
478c2ecf20Sopenharmony_ci#define CONTROL1_INT_ACTIVE_HIGH	BIT(5)
488c2ecf20Sopenharmony_ci#define CONTROL1_EDGE		BIT(7)
498c2ecf20Sopenharmony_ci#define CONTROL2_DEFAULT	0x8e
508c2ecf20Sopenharmony_ci#define CONTROL2_ADC_EN		BIT(0)
518c2ecf20Sopenharmony_ci#define CONTROL3_DEFAULT	0x8d
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_cienum max14656_chg_type {
548c2ecf20Sopenharmony_ci	MAX14656_NO_CHARGER	= 0,
558c2ecf20Sopenharmony_ci	MAX14656_SDP_CHARGER,
568c2ecf20Sopenharmony_ci	MAX14656_CDP_CHARGER,
578c2ecf20Sopenharmony_ci	MAX14656_DCP_CHARGER,
588c2ecf20Sopenharmony_ci	MAX14656_APPLE_500MA_CHARGER,
598c2ecf20Sopenharmony_ci	MAX14656_APPLE_1A_CHARGER,
608c2ecf20Sopenharmony_ci	MAX14656_APPLE_2A_CHARGER,
618c2ecf20Sopenharmony_ci	MAX14656_SPECIAL_500MA_CHARGER,
628c2ecf20Sopenharmony_ci	MAX14656_APPLE_12W,
638c2ecf20Sopenharmony_ci	MAX14656_CHARGER_LAST
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic const struct max14656_chg_type_props {
678c2ecf20Sopenharmony_ci	enum power_supply_type type;
688c2ecf20Sopenharmony_ci} chg_type_props[] = {
698c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_UNKNOWN },
708c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB },
718c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_CDP },
728c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_DCP },
738c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_DCP },
748c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_DCP },
758c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_DCP },
768c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB_DCP },
778c2ecf20Sopenharmony_ci	{ POWER_SUPPLY_TYPE_USB },
788c2ecf20Sopenharmony_ci};
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistruct max14656_chip {
818c2ecf20Sopenharmony_ci	struct i2c_client	*client;
828c2ecf20Sopenharmony_ci	struct power_supply	*detect_psy;
838c2ecf20Sopenharmony_ci	struct power_supply_desc psy_desc;
848c2ecf20Sopenharmony_ci	struct delayed_work	irq_work;
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci	int irq;
878c2ecf20Sopenharmony_ci	int online;
888c2ecf20Sopenharmony_ci};
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_cistatic int max14656_read_reg(struct i2c_client *client, int reg, u8 *val)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	s32 ret;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	ret = i2c_smbus_read_byte_data(client, reg);
958c2ecf20Sopenharmony_ci	if (ret < 0) {
968c2ecf20Sopenharmony_ci		dev_err(&client->dev,
978c2ecf20Sopenharmony_ci			"i2c read fail: can't read from %02x: %d\n",
988c2ecf20Sopenharmony_ci			reg, ret);
998c2ecf20Sopenharmony_ci		return ret;
1008c2ecf20Sopenharmony_ci	}
1018c2ecf20Sopenharmony_ci	*val = ret;
1028c2ecf20Sopenharmony_ci	return 0;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic int max14656_write_reg(struct i2c_client *client, int reg, u8 val)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	s32 ret;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	ret = i2c_smbus_write_byte_data(client, reg, val);
1108c2ecf20Sopenharmony_ci	if (ret < 0) {
1118c2ecf20Sopenharmony_ci		dev_err(&client->dev,
1128c2ecf20Sopenharmony_ci			"i2c write fail: can't write %02x to %02x: %d\n",
1138c2ecf20Sopenharmony_ci			val, reg, ret);
1148c2ecf20Sopenharmony_ci		return ret;
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci	return 0;
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic int max14656_read_block_reg(struct i2c_client *client, u8 reg,
1208c2ecf20Sopenharmony_ci				  u8 length, u8 *val)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	int ret;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	ret = i2c_smbus_read_i2c_block_data(client, reg, length, val);
1258c2ecf20Sopenharmony_ci	if (ret < 0) {
1268c2ecf20Sopenharmony_ci		dev_err(&client->dev, "failed to block read reg 0x%x: %d\n",
1278c2ecf20Sopenharmony_ci				reg, ret);
1288c2ecf20Sopenharmony_ci		return ret;
1298c2ecf20Sopenharmony_ci	}
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci	return 0;
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci#define        REG_TOTAL_NUM   5
1358c2ecf20Sopenharmony_cistatic void max14656_irq_worker(struct work_struct *work)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	struct max14656_chip *chip =
1388c2ecf20Sopenharmony_ci		container_of(work, struct max14656_chip, irq_work.work);
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	u8 buf[REG_TOTAL_NUM];
1418c2ecf20Sopenharmony_ci	u8 chg_type;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,
1448c2ecf20Sopenharmony_ci				REG_TOTAL_NUM, buf);
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	if ((buf[MAX14656_STATUS_1] & STATUS1_VB_VALID_MASK) &&
1478c2ecf20Sopenharmony_ci		(buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK)) {
1488c2ecf20Sopenharmony_ci		chg_type = buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK;
1498c2ecf20Sopenharmony_ci		if (chg_type < MAX14656_CHARGER_LAST)
1508c2ecf20Sopenharmony_ci			chip->psy_desc.type = chg_type_props[chg_type].type;
1518c2ecf20Sopenharmony_ci		else
1528c2ecf20Sopenharmony_ci			chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
1538c2ecf20Sopenharmony_ci		chip->online = 1;
1548c2ecf20Sopenharmony_ci	} else {
1558c2ecf20Sopenharmony_ci		chip->online = 0;
1568c2ecf20Sopenharmony_ci		chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
1578c2ecf20Sopenharmony_ci	}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci	power_supply_changed(chip->detect_psy);
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_cistatic irqreturn_t max14656_irq(int irq, void *dev_id)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	struct max14656_chip *chip = dev_id;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	schedule_delayed_work(&chip->irq_work, msecs_to_jiffies(100));
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_cistatic int max14656_hw_init(struct max14656_chip *chip)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	uint8_t val = 0;
1748c2ecf20Sopenharmony_ci	uint8_t rev;
1758c2ecf20Sopenharmony_ci	struct i2c_client *client = chip->client;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	if (max14656_read_reg(client, MAX14656_DEVICE_ID, &val))
1788c2ecf20Sopenharmony_ci		return -ENODEV;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	if ((val & DEVICE_VENDOR_MASK) != 0x20) {
1818c2ecf20Sopenharmony_ci		dev_err(&client->dev, "wrong vendor ID %d\n",
1828c2ecf20Sopenharmony_ci			((val & DEVICE_VENDOR_MASK) >> 4));
1838c2ecf20Sopenharmony_ci		return -ENODEV;
1848c2ecf20Sopenharmony_ci	}
1858c2ecf20Sopenharmony_ci	rev = val & DEVICE_REV_MASK;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	/* Turn on ADC_EN */
1888c2ecf20Sopenharmony_ci	if (max14656_write_reg(client, MAX14656_CONTROL_2, CONTROL2_ADC_EN))
1898c2ecf20Sopenharmony_ci		return -EINVAL;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	/* turn on interrupts and low power mode */
1928c2ecf20Sopenharmony_ci	if (max14656_write_reg(client, MAX14656_CONTROL_1,
1938c2ecf20Sopenharmony_ci		CONTROL1_DEFAULT |
1948c2ecf20Sopenharmony_ci		CONTROL1_INT_EN |
1958c2ecf20Sopenharmony_ci		CONTROL1_INT_ACTIVE_HIGH |
1968c2ecf20Sopenharmony_ci		CONTROL1_EDGE))
1978c2ecf20Sopenharmony_ci		return -EINVAL;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	if (max14656_write_reg(client, MAX14656_INTMASK_1, 0x3))
2008c2ecf20Sopenharmony_ci		return -EINVAL;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	if (max14656_write_reg(client, MAX14656_INTMASK_2, 0x1))
2038c2ecf20Sopenharmony_ci		return -EINVAL;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	dev_info(&client->dev, "detected revision %d\n", rev);
2068c2ecf20Sopenharmony_ci	return 0;
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_cistatic int max14656_get_property(struct power_supply *psy,
2108c2ecf20Sopenharmony_ci			    enum power_supply_property psp,
2118c2ecf20Sopenharmony_ci			    union power_supply_propval *val)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	struct max14656_chip *chip = power_supply_get_drvdata(psy);
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	switch (psp) {
2168c2ecf20Sopenharmony_ci	case POWER_SUPPLY_PROP_ONLINE:
2178c2ecf20Sopenharmony_ci		val->intval = chip->online;
2188c2ecf20Sopenharmony_ci		break;
2198c2ecf20Sopenharmony_ci	case POWER_SUPPLY_PROP_MODEL_NAME:
2208c2ecf20Sopenharmony_ci		val->strval = MAX14656_NAME;
2218c2ecf20Sopenharmony_ci		break;
2228c2ecf20Sopenharmony_ci	case POWER_SUPPLY_PROP_MANUFACTURER:
2238c2ecf20Sopenharmony_ci		val->strval = MAX14656_MANUFACTURER;
2248c2ecf20Sopenharmony_ci		break;
2258c2ecf20Sopenharmony_ci	default:
2268c2ecf20Sopenharmony_ci		return -EINVAL;
2278c2ecf20Sopenharmony_ci	}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	return 0;
2308c2ecf20Sopenharmony_ci}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic enum power_supply_property max14656_battery_props[] = {
2338c2ecf20Sopenharmony_ci	POWER_SUPPLY_PROP_ONLINE,
2348c2ecf20Sopenharmony_ci	POWER_SUPPLY_PROP_MODEL_NAME,
2358c2ecf20Sopenharmony_ci	POWER_SUPPLY_PROP_MANUFACTURER,
2368c2ecf20Sopenharmony_ci};
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cistatic void stop_irq_work(void *data)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	struct max14656_chip *chip = data;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	cancel_delayed_work_sync(&chip->irq_work);
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_cistatic int max14656_probe(struct i2c_client *client,
2478c2ecf20Sopenharmony_ci			  const struct i2c_device_id *id)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	struct i2c_adapter *adapter = client->adapter;
2508c2ecf20Sopenharmony_ci	struct device *dev = &client->dev;
2518c2ecf20Sopenharmony_ci	struct power_supply_config psy_cfg = {};
2528c2ecf20Sopenharmony_ci	struct max14656_chip *chip;
2538c2ecf20Sopenharmony_ci	int irq = client->irq;
2548c2ecf20Sopenharmony_ci	int ret = 0;
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci	if (irq <= 0) {
2578c2ecf20Sopenharmony_ci		dev_err(dev, "invalid irq number: %d\n", irq);
2588c2ecf20Sopenharmony_ci		return -ENODEV;
2598c2ecf20Sopenharmony_ci	}
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2628c2ecf20Sopenharmony_ci		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
2638c2ecf20Sopenharmony_ci		return -ENODEV;
2648c2ecf20Sopenharmony_ci	}
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
2678c2ecf20Sopenharmony_ci	if (!chip)
2688c2ecf20Sopenharmony_ci		return -ENOMEM;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	psy_cfg.drv_data = chip;
2718c2ecf20Sopenharmony_ci	chip->client = client;
2728c2ecf20Sopenharmony_ci	chip->online = 0;
2738c2ecf20Sopenharmony_ci	chip->psy_desc.name = MAX14656_NAME;
2748c2ecf20Sopenharmony_ci	chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;
2758c2ecf20Sopenharmony_ci	chip->psy_desc.properties = max14656_battery_props;
2768c2ecf20Sopenharmony_ci	chip->psy_desc.num_properties = ARRAY_SIZE(max14656_battery_props);
2778c2ecf20Sopenharmony_ci	chip->psy_desc.get_property = max14656_get_property;
2788c2ecf20Sopenharmony_ci	chip->irq = irq;
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci	ret = max14656_hw_init(chip);
2818c2ecf20Sopenharmony_ci	if (ret)
2828c2ecf20Sopenharmony_ci		return -ENODEV;
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	chip->detect_psy = devm_power_supply_register(dev,
2858c2ecf20Sopenharmony_ci		       &chip->psy_desc, &psy_cfg);
2868c2ecf20Sopenharmony_ci	if (IS_ERR(chip->detect_psy)) {
2878c2ecf20Sopenharmony_ci		dev_err(dev, "power_supply_register failed\n");
2888c2ecf20Sopenharmony_ci		return -EINVAL;
2898c2ecf20Sopenharmony_ci	}
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&chip->irq_work, max14656_irq_worker);
2928c2ecf20Sopenharmony_ci	ret = devm_add_action(dev, stop_irq_work, chip);
2938c2ecf20Sopenharmony_ci	if (ret) {
2948c2ecf20Sopenharmony_ci		dev_err(dev, "devm_add_action %d failed\n", ret);
2958c2ecf20Sopenharmony_ci		return ret;
2968c2ecf20Sopenharmony_ci	}
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	ret = devm_request_irq(dev, chip->irq, max14656_irq,
2998c2ecf20Sopenharmony_ci			       IRQF_TRIGGER_FALLING,
3008c2ecf20Sopenharmony_ci			       MAX14656_NAME, chip);
3018c2ecf20Sopenharmony_ci	if (ret) {
3028c2ecf20Sopenharmony_ci		dev_err(dev, "request_irq %d failed\n", chip->irq);
3038c2ecf20Sopenharmony_ci		return -EINVAL;
3048c2ecf20Sopenharmony_ci	}
3058c2ecf20Sopenharmony_ci	enable_irq_wake(chip->irq);
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	schedule_delayed_work(&chip->irq_work, msecs_to_jiffies(2000));
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci	return 0;
3108c2ecf20Sopenharmony_ci}
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_cistatic const struct i2c_device_id max14656_id[] = {
3138c2ecf20Sopenharmony_ci	{ "max14656", 0 },
3148c2ecf20Sopenharmony_ci	{}
3158c2ecf20Sopenharmony_ci};
3168c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, max14656_id);
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_cistatic const struct of_device_id max14656_match_table[] = {
3198c2ecf20Sopenharmony_ci	{ .compatible = "maxim,max14656", },
3208c2ecf20Sopenharmony_ci	{}
3218c2ecf20Sopenharmony_ci};
3228c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, max14656_match_table);
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic struct i2c_driver max14656_i2c_driver = {
3258c2ecf20Sopenharmony_ci	.driver = {
3268c2ecf20Sopenharmony_ci		.name	= "max14656",
3278c2ecf20Sopenharmony_ci		.of_match_table = max14656_match_table,
3288c2ecf20Sopenharmony_ci	},
3298c2ecf20Sopenharmony_ci	.probe		= max14656_probe,
3308c2ecf20Sopenharmony_ci	.id_table	= max14656_id,
3318c2ecf20Sopenharmony_ci};
3328c2ecf20Sopenharmony_cimodule_i2c_driver(max14656_i2c_driver);
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MAX14656 USB charger detector");
3358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2");
336