cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ltc2941-battery-gauge.c (16763B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * I2C client/driver for the Linear Technology LTC2941, LTC2942, LTC2943
      4 * and LTC2944 Battery Gas Gauge IC
      5 *
      6 * Copyright (C) 2014 Topic Embedded Systems
      7 *
      8 * Author: Auryn Verwegen
      9 * Author: Mike Looijmans
     10 */
     11#include <linux/devm-helpers.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/of_device.h>
     15#include <linux/types.h>
     16#include <linux/errno.h>
     17#include <linux/swab.h>
     18#include <linux/i2c.h>
     19#include <linux/delay.h>
     20#include <linux/power_supply.h>
     21#include <linux/slab.h>
     22
     23#define I16_MSB(x)			((x >> 8) & 0xFF)
     24#define I16_LSB(x)			(x & 0xFF)
     25
     26#define LTC294X_WORK_DELAY		10	/* Update delay in seconds */
     27
     28#define LTC294X_MAX_VALUE		0xFFFF
     29#define LTC294X_MID_SUPPLY		0x7FFF
     30
     31#define LTC2941_MAX_PRESCALER_EXP	7
     32#define LTC2943_MAX_PRESCALER_EXP	6
     33
     34enum ltc294x_reg {
     35	LTC294X_REG_STATUS		= 0x00,
     36	LTC294X_REG_CONTROL		= 0x01,
     37	LTC294X_REG_ACC_CHARGE_MSB	= 0x02,
     38	LTC294X_REG_ACC_CHARGE_LSB	= 0x03,
     39	LTC294X_REG_CHARGE_THR_HIGH_MSB	= 0x04,
     40	LTC294X_REG_CHARGE_THR_HIGH_LSB	= 0x05,
     41	LTC294X_REG_CHARGE_THR_LOW_MSB	= 0x06,
     42	LTC294X_REG_CHARGE_THR_LOW_LSB	= 0x07,
     43	LTC294X_REG_VOLTAGE_MSB		= 0x08,
     44	LTC294X_REG_VOLTAGE_LSB		= 0x09,
     45	LTC2942_REG_TEMPERATURE_MSB	= 0x0C,
     46	LTC2942_REG_TEMPERATURE_LSB	= 0x0D,
     47	LTC2943_REG_CURRENT_MSB		= 0x0E,
     48	LTC2943_REG_CURRENT_LSB		= 0x0F,
     49	LTC2943_REG_TEMPERATURE_MSB	= 0x14,
     50	LTC2943_REG_TEMPERATURE_LSB	= 0x15,
     51};
     52
     53enum ltc294x_id {
     54	LTC2941_ID,
     55	LTC2942_ID,
     56	LTC2943_ID,
     57	LTC2944_ID,
     58};
     59
     60#define LTC2941_REG_STATUS_CHIP_ID	BIT(7)
     61
     62#define LTC2942_REG_CONTROL_MODE_SCAN	(BIT(7) | BIT(6))
     63#define LTC2943_REG_CONTROL_MODE_SCAN	BIT(7)
     64#define LTC294X_REG_CONTROL_PRESCALER_MASK	(BIT(5) | BIT(4) | BIT(3))
     65#define LTC294X_REG_CONTROL_SHUTDOWN_MASK	(BIT(0))
     66#define LTC294X_REG_CONTROL_PRESCALER_SET(x) \
     67	((x << 3) & LTC294X_REG_CONTROL_PRESCALER_MASK)
     68#define LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED	0
     69#define LTC294X_REG_CONTROL_ADC_DISABLE(x)	((x) & ~(BIT(7) | BIT(6)))
     70
     71struct ltc294x_info {
     72	struct i2c_client *client;	/* I2C Client pointer */
     73	struct power_supply *supply;	/* Supply pointer */
     74	struct power_supply_desc supply_desc;	/* Supply description */
     75	struct delayed_work work;	/* Work scheduler */
     76	enum ltc294x_id id;		/* Chip type */
     77	int charge;	/* Last charge register content */
     78	int r_sense;	/* mOhm */
     79	int Qlsb;	/* nAh */
     80};
     81
     82static inline int convert_bin_to_uAh(
     83	const struct ltc294x_info *info, int Q)
     84{
     85	return ((Q * (info->Qlsb / 10))) / 100;
     86}
     87
     88static inline int convert_uAh_to_bin(
     89	const struct ltc294x_info *info, int uAh)
     90{
     91	int Q;
     92
     93	Q = (uAh * 100) / (info->Qlsb/10);
     94	return (Q < LTC294X_MAX_VALUE) ? Q : LTC294X_MAX_VALUE;
     95}
     96
     97static int ltc294x_read_regs(struct i2c_client *client,
     98	enum ltc294x_reg reg, u8 *buf, int num_regs)
     99{
    100	int ret;
    101	struct i2c_msg msgs[2] = { };
    102	u8 reg_start = reg;
    103
    104	msgs[0].addr	= client->addr;
    105	msgs[0].len	= 1;
    106	msgs[0].buf	= &reg_start;
    107
    108	msgs[1].addr	= client->addr;
    109	msgs[1].len	= num_regs;
    110	msgs[1].buf	= buf;
    111	msgs[1].flags	= I2C_M_RD;
    112
    113	ret = i2c_transfer(client->adapter, &msgs[0], 2);
    114	if (ret < 0) {
    115		dev_err(&client->dev, "ltc2941 read_reg(0x%x[%d]) failed: %pe\n",
    116			reg, num_regs, ERR_PTR(ret));
    117		return ret;
    118	}
    119
    120	dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n",
    121		__func__, reg, num_regs, *buf);
    122
    123	return 0;
    124}
    125
    126static int ltc294x_write_regs(struct i2c_client *client,
    127	enum ltc294x_reg reg, const u8 *buf, int num_regs)
    128{
    129	int ret;
    130	u8 reg_start = reg;
    131
    132	ret = i2c_smbus_write_i2c_block_data(client, reg_start, num_regs, buf);
    133	if (ret < 0) {
    134		dev_err(&client->dev, "ltc2941 write_reg(0x%x[%d]) failed: %pe\n",
    135			reg, num_regs, ERR_PTR(ret));
    136		return ret;
    137	}
    138
    139	dev_dbg(&client->dev, "%s (%#x, %d) -> %#x\n",
    140		__func__, reg, num_regs, *buf);
    141
    142	return 0;
    143}
    144
    145static int ltc294x_reset(const struct ltc294x_info *info, int prescaler_exp)
    146{
    147	int ret;
    148	u8 value;
    149	u8 control;
    150
    151	/* Read status and control registers */
    152	ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1);
    153	if (ret < 0)
    154		return ret;
    155
    156	control = LTC294X_REG_CONTROL_PRESCALER_SET(prescaler_exp) |
    157				LTC294X_REG_CONTROL_ALCC_CONFIG_DISABLED;
    158	/* Put device into "monitor" mode */
    159	switch (info->id) {
    160	case LTC2942_ID:	/* 2942 measures every 2 sec */
    161		control |= LTC2942_REG_CONTROL_MODE_SCAN;
    162		break;
    163	case LTC2943_ID:
    164	case LTC2944_ID:	/* 2943 and 2944 measure every 10 sec */
    165		control |= LTC2943_REG_CONTROL_MODE_SCAN;
    166		break;
    167	default:
    168		break;
    169	}
    170
    171	if (value != control) {
    172		ret = ltc294x_write_regs(info->client,
    173			LTC294X_REG_CONTROL, &control, 1);
    174		if (ret < 0)
    175			return ret;
    176	}
    177
    178	return 0;
    179}
    180
    181static int ltc294x_read_charge_register(const struct ltc294x_info *info,
    182					enum ltc294x_reg reg)
    183 {
    184	int ret;
    185	u8 datar[2];
    186
    187	ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
    188	if (ret < 0)
    189		return ret;
    190	return (datar[0] << 8) + datar[1];
    191}
    192
    193static int ltc294x_get_charge(const struct ltc294x_info *info,
    194				enum ltc294x_reg reg, int *val)
    195{
    196	int value = ltc294x_read_charge_register(info, reg);
    197
    198	if (value < 0)
    199		return value;
    200	/* When r_sense < 0, this counts up when the battery discharges */
    201	if (info->Qlsb < 0)
    202		value -= 0xFFFF;
    203	*val = convert_bin_to_uAh(info, value);
    204	return 0;
    205}
    206
    207static int ltc294x_set_charge_now(const struct ltc294x_info *info, int val)
    208{
    209	int ret;
    210	u8 dataw[2];
    211	u8 ctrl_reg;
    212	s32 value;
    213
    214	value = convert_uAh_to_bin(info, val);
    215	/* Direction depends on how sense+/- were connected */
    216	if (info->Qlsb < 0)
    217		value += 0xFFFF;
    218	if ((value < 0) || (value > 0xFFFF)) /* input validation */
    219		return -EINVAL;
    220
    221	/* Read control register */
    222	ret = ltc294x_read_regs(info->client,
    223		LTC294X_REG_CONTROL, &ctrl_reg, 1);
    224	if (ret < 0)
    225		return ret;
    226	/* Disable analog section */
    227	ctrl_reg |= LTC294X_REG_CONTROL_SHUTDOWN_MASK;
    228	ret = ltc294x_write_regs(info->client,
    229		LTC294X_REG_CONTROL, &ctrl_reg, 1);
    230	if (ret < 0)
    231		return ret;
    232	/* Set new charge value */
    233	dataw[0] = I16_MSB(value);
    234	dataw[1] = I16_LSB(value);
    235	ret = ltc294x_write_regs(info->client,
    236		LTC294X_REG_ACC_CHARGE_MSB, &dataw[0], 2);
    237	if (ret < 0)
    238		goto error_exit;
    239	/* Enable analog section */
    240error_exit:
    241	ctrl_reg &= ~LTC294X_REG_CONTROL_SHUTDOWN_MASK;
    242	ret = ltc294x_write_regs(info->client,
    243		LTC294X_REG_CONTROL, &ctrl_reg, 1);
    244
    245	return ret < 0 ? ret : 0;
    246}
    247
    248static int ltc294x_set_charge_thr(const struct ltc294x_info *info,
    249					enum ltc294x_reg reg, int val)
    250{
    251	u8 dataw[2];
    252	s32 value;
    253
    254	value = convert_uAh_to_bin(info, val);
    255	/* Direction depends on how sense+/- were connected */
    256	if (info->Qlsb < 0)
    257		value += 0xFFFF;
    258	if ((value < 0) || (value > 0xFFFF)) /* input validation */
    259		return -EINVAL;
    260
    261	/* Set new charge value */
    262	dataw[0] = I16_MSB(value);
    263	dataw[1] = I16_LSB(value);
    264	return ltc294x_write_regs(info->client, reg, &dataw[0], 2);
    265}
    266
    267static int ltc294x_get_charge_counter(
    268	const struct ltc294x_info *info, int *val)
    269{
    270	int value = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB);
    271
    272	if (value < 0)
    273		return value;
    274	value -= LTC294X_MID_SUPPLY;
    275	*val = convert_bin_to_uAh(info, value);
    276	return 0;
    277}
    278
    279static int ltc294x_get_voltage(const struct ltc294x_info *info, int *val)
    280{
    281	int ret;
    282	u8 datar[2];
    283	u32 value;
    284
    285	ret = ltc294x_read_regs(info->client,
    286		LTC294X_REG_VOLTAGE_MSB, &datar[0], 2);
    287	value = (datar[0] << 8) | datar[1];
    288	switch (info->id) {
    289	case LTC2943_ID:
    290		value *= 23600 * 2;
    291		value /= 0xFFFF;
    292		value *= 1000 / 2;
    293		break;
    294	case LTC2944_ID:
    295		value *= 70800 / 5*4;
    296		value /= 0xFFFF;
    297		value *= 1000 * 5/4;
    298		break;
    299	default:
    300		value *= 6000 * 10;
    301		value /= 0xFFFF;
    302		value *= 1000 / 10;
    303		break;
    304	}
    305	*val = value;
    306	return ret;
    307}
    308
    309static int ltc294x_get_current(const struct ltc294x_info *info, int *val)
    310{
    311	int ret;
    312	u8 datar[2];
    313	s32 value;
    314
    315	ret = ltc294x_read_regs(info->client,
    316		LTC2943_REG_CURRENT_MSB, &datar[0], 2);
    317	value = (datar[0] << 8) | datar[1];
    318	value -= 0x7FFF;
    319	if (info->id == LTC2944_ID)
    320		value *= 64000;
    321	else
    322		value *= 60000;
    323	/* Value is in range -32k..+32k, r_sense is usually 10..50 mOhm,
    324	 * the formula below keeps everything in s32 range while preserving
    325	 * enough digits */
    326	*val = 1000 * (value / (info->r_sense * 0x7FFF)); /* in uA */
    327	return ret;
    328}
    329
    330static int ltc294x_get_temperature(const struct ltc294x_info *info, int *val)
    331{
    332	enum ltc294x_reg reg;
    333	int ret;
    334	u8 datar[2];
    335	u32 value;
    336
    337	if (info->id == LTC2942_ID) {
    338		reg = LTC2942_REG_TEMPERATURE_MSB;
    339		value = 6000;	/* Full-scale is 600 Kelvin */
    340	} else {
    341		reg = LTC2943_REG_TEMPERATURE_MSB;
    342		value = 5100;	/* Full-scale is 510 Kelvin */
    343	}
    344	ret = ltc294x_read_regs(info->client, reg, &datar[0], 2);
    345	value *= (datar[0] << 8) | datar[1];
    346	/* Convert to tenths of degree Celsius */
    347	*val = value / 0xFFFF - 2722;
    348	return ret;
    349}
    350
    351static int ltc294x_get_property(struct power_supply *psy,
    352				enum power_supply_property prop,
    353				union power_supply_propval *val)
    354{
    355	struct ltc294x_info *info = power_supply_get_drvdata(psy);
    356
    357	switch (prop) {
    358	case POWER_SUPPLY_PROP_CHARGE_FULL:
    359		return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_HIGH_MSB,
    360						&val->intval);
    361	case POWER_SUPPLY_PROP_CHARGE_EMPTY:
    362		return ltc294x_get_charge(info, LTC294X_REG_CHARGE_THR_LOW_MSB,
    363						&val->intval);
    364	case POWER_SUPPLY_PROP_CHARGE_NOW:
    365		return ltc294x_get_charge(info, LTC294X_REG_ACC_CHARGE_MSB,
    366						&val->intval);
    367	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
    368		return ltc294x_get_charge_counter(info, &val->intval);
    369	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
    370		return ltc294x_get_voltage(info, &val->intval);
    371	case POWER_SUPPLY_PROP_CURRENT_NOW:
    372		return ltc294x_get_current(info, &val->intval);
    373	case POWER_SUPPLY_PROP_TEMP:
    374		return ltc294x_get_temperature(info, &val->intval);
    375	default:
    376		return -EINVAL;
    377	}
    378}
    379
    380static int ltc294x_set_property(struct power_supply *psy,
    381	enum power_supply_property psp,
    382	const union power_supply_propval *val)
    383{
    384	struct ltc294x_info *info = power_supply_get_drvdata(psy);
    385
    386	switch (psp) {
    387	case POWER_SUPPLY_PROP_CHARGE_FULL:
    388		return ltc294x_set_charge_thr(info,
    389			LTC294X_REG_CHARGE_THR_HIGH_MSB, val->intval);
    390	case POWER_SUPPLY_PROP_CHARGE_EMPTY:
    391		return ltc294x_set_charge_thr(info,
    392			LTC294X_REG_CHARGE_THR_LOW_MSB, val->intval);
    393	case POWER_SUPPLY_PROP_CHARGE_NOW:
    394		return ltc294x_set_charge_now(info, val->intval);
    395	default:
    396		return -EPERM;
    397	}
    398}
    399
    400static int ltc294x_property_is_writeable(
    401	struct power_supply *psy, enum power_supply_property psp)
    402{
    403	switch (psp) {
    404	case POWER_SUPPLY_PROP_CHARGE_FULL:
    405	case POWER_SUPPLY_PROP_CHARGE_EMPTY:
    406	case POWER_SUPPLY_PROP_CHARGE_NOW:
    407		return 1;
    408	default:
    409		return 0;
    410	}
    411}
    412
    413static void ltc294x_update(struct ltc294x_info *info)
    414{
    415	int charge = ltc294x_read_charge_register(info, LTC294X_REG_ACC_CHARGE_MSB);
    416
    417	if (charge != info->charge) {
    418		info->charge = charge;
    419		power_supply_changed(info->supply);
    420	}
    421}
    422
    423static void ltc294x_work(struct work_struct *work)
    424{
    425	struct ltc294x_info *info;
    426
    427	info = container_of(work, struct ltc294x_info, work.work);
    428	ltc294x_update(info);
    429	schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
    430}
    431
    432static enum power_supply_property ltc294x_properties[] = {
    433	POWER_SUPPLY_PROP_CHARGE_COUNTER,
    434	POWER_SUPPLY_PROP_CHARGE_FULL,
    435	POWER_SUPPLY_PROP_CHARGE_EMPTY,
    436	POWER_SUPPLY_PROP_CHARGE_NOW,
    437	POWER_SUPPLY_PROP_VOLTAGE_NOW,
    438	POWER_SUPPLY_PROP_TEMP,
    439	POWER_SUPPLY_PROP_CURRENT_NOW,
    440};
    441
    442static int ltc294x_i2c_probe(struct i2c_client *client,
    443	const struct i2c_device_id *id)
    444{
    445	struct power_supply_config psy_cfg = {};
    446	struct ltc294x_info *info;
    447	struct device_node *np;
    448	int ret;
    449	u32 prescaler_exp;
    450	s32 r_sense;
    451	u8 status;
    452
    453	info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
    454	if (info == NULL)
    455		return -ENOMEM;
    456
    457	i2c_set_clientdata(client, info);
    458
    459	np = of_node_get(client->dev.of_node);
    460
    461	info->id = (enum ltc294x_id) (uintptr_t) of_device_get_match_data(
    462							&client->dev);
    463	info->supply_desc.name = np->name;
    464
    465	/* r_sense can be negative, when sense+ is connected to the battery
    466	 * instead of the sense-. This results in reversed measurements. */
    467	ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense);
    468	if (ret < 0)
    469		return dev_err_probe(&client->dev, ret,
    470			"Could not find lltc,resistor-sense in devicetree\n");
    471	info->r_sense = r_sense;
    472
    473	ret = of_property_read_u32(np, "lltc,prescaler-exponent",
    474		&prescaler_exp);
    475	if (ret < 0) {
    476		dev_warn(&client->dev,
    477			"lltc,prescaler-exponent not in devicetree\n");
    478		prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
    479	}
    480
    481	if (info->id == LTC2943_ID) {
    482		if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
    483			prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
    484		info->Qlsb = ((340 * 50000) / r_sense) >>
    485			     (12 - 2*prescaler_exp);
    486	} else {
    487		if (prescaler_exp > LTC2941_MAX_PRESCALER_EXP)
    488			prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
    489		info->Qlsb = ((85 * 50000) / r_sense) >>
    490			     (7 - prescaler_exp);
    491	}
    492
    493	/* Read status register to check for LTC2942 */
    494	if (info->id == LTC2941_ID || info->id == LTC2942_ID) {
    495		ret = ltc294x_read_regs(client, LTC294X_REG_STATUS, &status, 1);
    496		if (ret < 0)
    497			return dev_err_probe(&client->dev, ret,
    498				"Could not read status register\n");
    499		if (status & LTC2941_REG_STATUS_CHIP_ID)
    500			info->id = LTC2941_ID;
    501		else
    502			info->id = LTC2942_ID;
    503	}
    504
    505	info->client = client;
    506	info->supply_desc.type = POWER_SUPPLY_TYPE_BATTERY;
    507	info->supply_desc.properties = ltc294x_properties;
    508	switch (info->id) {
    509	case LTC2944_ID:
    510	case LTC2943_ID:
    511		info->supply_desc.num_properties =
    512			ARRAY_SIZE(ltc294x_properties);
    513		break;
    514	case LTC2942_ID:
    515		info->supply_desc.num_properties =
    516			ARRAY_SIZE(ltc294x_properties) - 1;
    517		break;
    518	case LTC2941_ID:
    519	default:
    520		info->supply_desc.num_properties =
    521			ARRAY_SIZE(ltc294x_properties) - 3;
    522		break;
    523	}
    524	info->supply_desc.get_property = ltc294x_get_property;
    525	info->supply_desc.set_property = ltc294x_set_property;
    526	info->supply_desc.property_is_writeable = ltc294x_property_is_writeable;
    527	info->supply_desc.external_power_changed	= NULL;
    528
    529	psy_cfg.drv_data = info;
    530
    531	ret = devm_delayed_work_autocancel(&client->dev, &info->work,
    532					   ltc294x_work);
    533	if (ret)
    534		return ret;
    535
    536	ret = ltc294x_reset(info, prescaler_exp);
    537	if (ret < 0)
    538		return dev_err_probe(&client->dev, ret,
    539			"Communication with chip failed\n");
    540
    541	info->supply = devm_power_supply_register(&client->dev,
    542						  &info->supply_desc, &psy_cfg);
    543	if (IS_ERR(info->supply))
    544		return dev_err_probe(&client->dev, PTR_ERR(info->supply),
    545			"failed to register ltc2941\n");
    546
    547	schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
    548
    549	return 0;
    550}
    551
    552static void ltc294x_i2c_shutdown(struct i2c_client *client)
    553{
    554	struct ltc294x_info *info = i2c_get_clientdata(client);
    555	int ret;
    556	u8 value;
    557	u8 control;
    558
    559	/* The LTC2941 does not need any special handling */
    560	if (info->id == LTC2941_ID)
    561		return;
    562
    563	/* Read control register */
    564	ret = ltc294x_read_regs(info->client, LTC294X_REG_CONTROL, &value, 1);
    565	if (ret < 0)
    566		return;
    567
    568	/* Disable continuous ADC conversion as this drains the battery */
    569	control = LTC294X_REG_CONTROL_ADC_DISABLE(value);
    570	if (control != value)
    571		ltc294x_write_regs(info->client, LTC294X_REG_CONTROL,
    572			&control, 1);
    573}
    574
    575#ifdef CONFIG_PM_SLEEP
    576
    577static int ltc294x_suspend(struct device *dev)
    578{
    579	struct i2c_client *client = to_i2c_client(dev);
    580	struct ltc294x_info *info = i2c_get_clientdata(client);
    581
    582	cancel_delayed_work(&info->work);
    583	return 0;
    584}
    585
    586static int ltc294x_resume(struct device *dev)
    587{
    588	struct i2c_client *client = to_i2c_client(dev);
    589	struct ltc294x_info *info = i2c_get_clientdata(client);
    590
    591	schedule_delayed_work(&info->work, LTC294X_WORK_DELAY * HZ);
    592	return 0;
    593}
    594
    595static SIMPLE_DEV_PM_OPS(ltc294x_pm_ops, ltc294x_suspend, ltc294x_resume);
    596#define LTC294X_PM_OPS (&ltc294x_pm_ops)
    597
    598#else
    599#define LTC294X_PM_OPS NULL
    600#endif /* CONFIG_PM_SLEEP */
    601
    602
    603static const struct i2c_device_id ltc294x_i2c_id[] = {
    604	{ "ltc2941", LTC2941_ID, },
    605	{ "ltc2942", LTC2942_ID, },
    606	{ "ltc2943", LTC2943_ID, },
    607	{ "ltc2944", LTC2944_ID, },
    608	{ },
    609};
    610MODULE_DEVICE_TABLE(i2c, ltc294x_i2c_id);
    611
    612static const struct of_device_id ltc294x_i2c_of_match[] = {
    613	{
    614		.compatible = "lltc,ltc2941",
    615		.data = (void *)LTC2941_ID,
    616	},
    617	{
    618		.compatible = "lltc,ltc2942",
    619		.data = (void *)LTC2942_ID,
    620	},
    621	{
    622		.compatible = "lltc,ltc2943",
    623		.data = (void *)LTC2943_ID,
    624	},
    625	{
    626		.compatible = "lltc,ltc2944",
    627		.data = (void *)LTC2944_ID,
    628	},
    629	{ },
    630};
    631MODULE_DEVICE_TABLE(of, ltc294x_i2c_of_match);
    632
    633static struct i2c_driver ltc294x_driver = {
    634	.driver = {
    635		.name	= "LTC2941",
    636		.of_match_table = ltc294x_i2c_of_match,
    637		.pm	= LTC294X_PM_OPS,
    638	},
    639	.probe		= ltc294x_i2c_probe,
    640	.shutdown	= ltc294x_i2c_shutdown,
    641	.id_table	= ltc294x_i2c_id,
    642};
    643module_i2c_driver(ltc294x_driver);
    644
    645MODULE_AUTHOR("Auryn Verwegen, Topic Embedded Systems");
    646MODULE_AUTHOR("Mike Looijmans, Topic Embedded Products");
    647MODULE_DESCRIPTION("LTC2941/LTC2942/LTC2943/LTC2944 Battery Gas Gauge IC driver");
    648MODULE_LICENSE("GPL");