brintos

brintos / linux-shallow public Read only

0
0
Text · 7.9 KiB · a5b42b4 Raw
326 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Maxim MAX14656 / AL32 USB Charger Detector driver4 *5 * Copyright (C) 2014 LG Electronics, Inc6 * Copyright (C) 2016 Alexander Kurz <akurz@blala.de>7 *8 * Components from Maxim AL32 Charger detection Driver for MX50 Yoshi Board9 * Copyright (C) Amazon Technologies Inc. All rights reserved.10 * Manish Lachwani (lachwani@lab126.com)11 */12#include <linux/module.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/interrupt.h>17#include <linux/mod_devicetable.h>18#include <linux/slab.h>19#include <linux/workqueue.h>20#include <linux/power_supply.h>21#include <linux/devm-helpers.h>22 23#define MAX14656_MANUFACTURER	"Maxim Integrated"24#define MAX14656_NAME		"max14656"25 26#define MAX14656_DEVICE_ID	0x0027#define MAX14656_INTERRUPT_1	0x0128#define MAX14656_INTERRUPT_2	0x0229#define MAX14656_STATUS_1	0x0330#define MAX14656_STATUS_2	0x0431#define MAX14656_INTMASK_1	0x0532#define MAX14656_INTMASK_2	0x0633#define MAX14656_CONTROL_1	0x0734#define MAX14656_CONTROL_2	0x0835#define MAX14656_CONTROL_3	0x0936 37#define DEVICE_VENDOR_MASK	0xf038#define DEVICE_REV_MASK		0x0f39#define INT_EN_REG_MASK		BIT(4)40#define CHG_TYPE_INT_MASK	BIT(0)41#define STATUS1_VB_VALID_MASK	BIT(4)42#define STATUS1_CHG_TYPE_MASK	0xf43#define INT1_DCD_TIMEOUT_MASK	BIT(7)44#define CONTROL1_DEFAULT	0x0d45#define CONTROL1_INT_EN		BIT(4)46#define CONTROL1_INT_ACTIVE_HIGH	BIT(5)47#define CONTROL1_EDGE		BIT(7)48#define CONTROL2_DEFAULT	0x8e49#define CONTROL2_ADC_EN		BIT(0)50#define CONTROL3_DEFAULT	0x8d51 52enum max14656_chg_type {53	MAX14656_NO_CHARGER	= 0,54	MAX14656_SDP_CHARGER,55	MAX14656_CDP_CHARGER,56	MAX14656_DCP_CHARGER,57	MAX14656_APPLE_500MA_CHARGER,58	MAX14656_APPLE_1A_CHARGER,59	MAX14656_APPLE_2A_CHARGER,60	MAX14656_SPECIAL_500MA_CHARGER,61	MAX14656_APPLE_12W,62	MAX14656_CHARGER_LAST63};64 65static const struct max14656_chg_type_props {66	enum power_supply_type type;67} chg_type_props[] = {68	{ POWER_SUPPLY_TYPE_UNKNOWN },69	{ POWER_SUPPLY_TYPE_USB },70	{ POWER_SUPPLY_TYPE_USB_CDP },71	{ POWER_SUPPLY_TYPE_USB_DCP },72	{ POWER_SUPPLY_TYPE_USB_DCP },73	{ POWER_SUPPLY_TYPE_USB_DCP },74	{ POWER_SUPPLY_TYPE_USB_DCP },75	{ POWER_SUPPLY_TYPE_USB_DCP },76	{ POWER_SUPPLY_TYPE_USB },77};78 79struct max14656_chip {80	struct i2c_client	*client;81	struct power_supply	*detect_psy;82	struct power_supply_desc psy_desc;83	struct delayed_work	irq_work;84 85	int irq;86	int online;87};88 89static int max14656_read_reg(struct i2c_client *client, int reg, u8 *val)90{91	s32 ret;92 93	ret = i2c_smbus_read_byte_data(client, reg);94	if (ret < 0) {95		dev_err(&client->dev,96			"i2c read fail: can't read from %02x: %d\n",97			reg, ret);98		return ret;99	}100	*val = ret;101	return 0;102}103 104static int max14656_write_reg(struct i2c_client *client, int reg, u8 val)105{106	s32 ret;107 108	ret = i2c_smbus_write_byte_data(client, reg, val);109	if (ret < 0) {110		dev_err(&client->dev,111			"i2c write fail: can't write %02x to %02x: %d\n",112			val, reg, ret);113		return ret;114	}115	return 0;116}117 118static int max14656_read_block_reg(struct i2c_client *client, u8 reg,119				  u8 length, u8 *val)120{121	int ret;122 123	ret = i2c_smbus_read_i2c_block_data(client, reg, length, val);124	if (ret < 0) {125		dev_err(&client->dev, "failed to block read reg 0x%x: %d\n",126				reg, ret);127		return ret;128	}129 130	return 0;131}132 133#define        REG_TOTAL_NUM   5134static void max14656_irq_worker(struct work_struct *work)135{136	struct max14656_chip *chip =137		container_of(work, struct max14656_chip, irq_work.work);138 139	u8 buf[REG_TOTAL_NUM];140	u8 chg_type;141 142	max14656_read_block_reg(chip->client, MAX14656_DEVICE_ID,143				REG_TOTAL_NUM, buf);144 145	if ((buf[MAX14656_STATUS_1] & STATUS1_VB_VALID_MASK) &&146		(buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK)) {147		chg_type = buf[MAX14656_STATUS_1] & STATUS1_CHG_TYPE_MASK;148		if (chg_type < MAX14656_CHARGER_LAST)149			chip->psy_desc.type = chg_type_props[chg_type].type;150		else151			chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;152		chip->online = 1;153	} else {154		chip->online = 0;155		chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;156	}157 158	power_supply_changed(chip->detect_psy);159}160 161static irqreturn_t max14656_irq(int irq, void *dev_id)162{163	struct max14656_chip *chip = dev_id;164 165	schedule_delayed_work(&chip->irq_work, msecs_to_jiffies(100));166 167	return IRQ_HANDLED;168}169 170static int max14656_hw_init(struct max14656_chip *chip)171{172	uint8_t val = 0;173	uint8_t rev;174	struct i2c_client *client = chip->client;175 176	if (max14656_read_reg(client, MAX14656_DEVICE_ID, &val))177		return -ENODEV;178 179	if ((val & DEVICE_VENDOR_MASK) != 0x20) {180		dev_err(&client->dev, "wrong vendor ID %d\n",181			((val & DEVICE_VENDOR_MASK) >> 4));182		return -ENODEV;183	}184	rev = val & DEVICE_REV_MASK;185 186	/* Turn on ADC_EN */187	if (max14656_write_reg(client, MAX14656_CONTROL_2, CONTROL2_ADC_EN))188		return -EINVAL;189 190	/* turn on interrupts and low power mode */191	if (max14656_write_reg(client, MAX14656_CONTROL_1,192		CONTROL1_DEFAULT |193		CONTROL1_INT_EN |194		CONTROL1_INT_ACTIVE_HIGH |195		CONTROL1_EDGE))196		return -EINVAL;197 198	if (max14656_write_reg(client, MAX14656_INTMASK_1, 0x3))199		return -EINVAL;200 201	if (max14656_write_reg(client, MAX14656_INTMASK_2, 0x1))202		return -EINVAL;203 204	dev_info(&client->dev, "detected revision %d\n", rev);205	return 0;206}207 208static int max14656_get_property(struct power_supply *psy,209			    enum power_supply_property psp,210			    union power_supply_propval *val)211{212	struct max14656_chip *chip = power_supply_get_drvdata(psy);213 214	switch (psp) {215	case POWER_SUPPLY_PROP_ONLINE:216		val->intval = chip->online;217		break;218	case POWER_SUPPLY_PROP_MODEL_NAME:219		val->strval = MAX14656_NAME;220		break;221	case POWER_SUPPLY_PROP_MANUFACTURER:222		val->strval = MAX14656_MANUFACTURER;223		break;224	default:225		return -EINVAL;226	}227 228	return 0;229}230 231static enum power_supply_property max14656_battery_props[] = {232	POWER_SUPPLY_PROP_ONLINE,233	POWER_SUPPLY_PROP_MODEL_NAME,234	POWER_SUPPLY_PROP_MANUFACTURER,235};236 237static int max14656_probe(struct i2c_client *client)238{239	struct i2c_adapter *adapter = client->adapter;240	struct device *dev = &client->dev;241	struct power_supply_config psy_cfg = {};242	struct max14656_chip *chip;243	int irq = client->irq;244	int ret = 0;245 246	if (irq <= 0) {247		dev_err(dev, "invalid irq number: %d\n", irq);248		return -ENODEV;249	}250 251	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {252		dev_err(dev, "No support for SMBUS_BYTE_DATA\n");253		return -ENODEV;254	}255 256	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);257	if (!chip)258		return -ENOMEM;259 260	psy_cfg.drv_data = chip;261	chip->client = client;262	chip->online = 0;263	chip->psy_desc.name = MAX14656_NAME;264	chip->psy_desc.type = POWER_SUPPLY_TYPE_UNKNOWN;265	chip->psy_desc.properties = max14656_battery_props;266	chip->psy_desc.num_properties = ARRAY_SIZE(max14656_battery_props);267	chip->psy_desc.get_property = max14656_get_property;268	chip->irq = irq;269 270	ret = max14656_hw_init(chip);271	if (ret)272		return -ENODEV;273 274	chip->detect_psy = devm_power_supply_register(dev,275		       &chip->psy_desc, &psy_cfg);276	if (IS_ERR(chip->detect_psy)) {277		dev_err(dev, "power_supply_register failed\n");278		return -EINVAL;279	}280 281	ret = devm_delayed_work_autocancel(dev, &chip->irq_work,282					   max14656_irq_worker);283	if (ret) {284		dev_err(dev, "devm_delayed_work_autocancel %d failed\n", ret);285		return ret;286	}287 288	ret = devm_request_irq(dev, chip->irq, max14656_irq,289			       IRQF_TRIGGER_FALLING,290			       MAX14656_NAME, chip);291	if (ret) {292		dev_err(dev, "request_irq %d failed\n", chip->irq);293		return -EINVAL;294	}295	enable_irq_wake(chip->irq);296 297	schedule_delayed_work(&chip->irq_work, msecs_to_jiffies(2000));298 299	return 0;300}301 302static const struct i2c_device_id max14656_id[] = {303	{ "max14656" },304	{}305};306MODULE_DEVICE_TABLE(i2c, max14656_id);307 308static const struct of_device_id max14656_match_table[] = {309	{ .compatible = "maxim,max14656", },310	{}311};312MODULE_DEVICE_TABLE(of, max14656_match_table);313 314static struct i2c_driver max14656_i2c_driver = {315	.driver = {316		.name	= "max14656",317		.of_match_table = max14656_match_table,318	},319	.probe		= max14656_probe,320	.id_table	= max14656_id,321};322module_i2c_driver(max14656_i2c_driver);323 324MODULE_DESCRIPTION("MAX14656 USB charger detector");325MODULE_LICENSE("GPL v2");326