brintos

brintos / linux-shallow public Read only

0
0
Text · 16.5 KiB · 8271489 Raw
675 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Core driver for TI TPS6586x PMIC family4 *5 * Copyright (c) 2010 CompuLab Ltd.6 * Mike Rapoport <mike@compulab.co.il>7 *8 * Based on da903x.c.9 * Copyright (C) 2008 Compulab, Ltd.10 * Mike Rapoport <mike@compulab.co.il>11 * Copyright (C) 2006-2008 Marvell International Ltd.12 * Eric Miao <eric.miao@marvell.com>13 */14 15#include <linux/interrupt.h>16#include <linux/irq.h>17#include <linux/irqdomain.h>18#include <linux/kernel.h>19#include <linux/module.h>20#include <linux/mutex.h>21#include <linux/slab.h>22#include <linux/err.h>23#include <linux/i2c.h>24#include <linux/platform_device.h>25#include <linux/reboot.h>26#include <linux/regmap.h>27#include <linux/of.h>28 29#include <linux/mfd/core.h>30#include <linux/mfd/tps6586x.h>31 32#define TPS6586X_SUPPLYENE	0x1433#define SOFT_RST_BIT		BIT(0)34#define EXITSLREQ_BIT		BIT(1)35#define SLEEP_MODE_BIT		BIT(3)36 37/* interrupt control registers */38#define TPS6586X_INT_ACK1	0xb539#define TPS6586X_INT_ACK2	0xb640#define TPS6586X_INT_ACK3	0xb741#define TPS6586X_INT_ACK4	0xb842 43/* interrupt mask registers */44#define TPS6586X_INT_MASK1	0xb045#define TPS6586X_INT_MASK2	0xb146#define TPS6586X_INT_MASK3	0xb247#define TPS6586X_INT_MASK4	0xb348#define TPS6586X_INT_MASK5	0xb449 50/* device id */51#define TPS6586X_VERSIONCRC	0xcd52 53/* Maximum register */54#define TPS6586X_MAX_REGISTER	TPS6586X_VERSIONCRC55 56struct tps6586x_irq_data {57	u8	mask_reg;58	u8	mask_mask;59};60 61#define TPS6586X_IRQ(_reg, _mask)				\62	{							\63		.mask_reg = (_reg) - TPS6586X_INT_MASK1,	\64		.mask_mask = (_mask),				\65	}66 67static const struct tps6586x_irq_data tps6586x_irqs[] = {68	[TPS6586X_INT_PLDO_0]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 0),69	[TPS6586X_INT_PLDO_1]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 1),70	[TPS6586X_INT_PLDO_2]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 2),71	[TPS6586X_INT_PLDO_3]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 3),72	[TPS6586X_INT_PLDO_4]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 4),73	[TPS6586X_INT_PLDO_5]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 5),74	[TPS6586X_INT_PLDO_6]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 6),75	[TPS6586X_INT_PLDO_7]	= TPS6586X_IRQ(TPS6586X_INT_MASK1, 1 << 7),76	[TPS6586X_INT_COMP_DET]	= TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 0),77	[TPS6586X_INT_ADC]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 1),78	[TPS6586X_INT_PLDO_8]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 2),79	[TPS6586X_INT_PLDO_9]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 3),80	[TPS6586X_INT_PSM_0]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 4),81	[TPS6586X_INT_PSM_1]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 5),82	[TPS6586X_INT_PSM_2]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 6),83	[TPS6586X_INT_PSM_3]	= TPS6586X_IRQ(TPS6586X_INT_MASK2, 1 << 7),84	[TPS6586X_INT_RTC_ALM1]	= TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 4),85	[TPS6586X_INT_ACUSB_OVP] = TPS6586X_IRQ(TPS6586X_INT_MASK5, 0x03),86	[TPS6586X_INT_USB_DET]	= TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 2),87	[TPS6586X_INT_AC_DET]	= TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 3),88	[TPS6586X_INT_BAT_DET]	= TPS6586X_IRQ(TPS6586X_INT_MASK3, 1 << 0),89	[TPS6586X_INT_CHG_STAT]	= TPS6586X_IRQ(TPS6586X_INT_MASK4, 0xfc),90	[TPS6586X_INT_CHG_TEMP]	= TPS6586X_IRQ(TPS6586X_INT_MASK3, 0x06),91	[TPS6586X_INT_PP]	= TPS6586X_IRQ(TPS6586X_INT_MASK3, 0xf0),92	[TPS6586X_INT_RESUME]	= TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 5),93	[TPS6586X_INT_LOW_SYS]	= TPS6586X_IRQ(TPS6586X_INT_MASK5, 1 << 6),94	[TPS6586X_INT_RTC_ALM2] = TPS6586X_IRQ(TPS6586X_INT_MASK4, 1 << 1),95};96 97static const struct resource tps6586x_rtc_resources[] = {98	{99		.start  = TPS6586X_INT_RTC_ALM1,100		.end	= TPS6586X_INT_RTC_ALM1,101		.flags	= IORESOURCE_IRQ,102	},103};104 105static const struct mfd_cell tps6586x_cell[] = {106	{107		.name = "tps6586x-gpio",108	},109	{110		.name = "tps6586x-regulator",111	},112	{113		.name = "tps6586x-rtc",114		.num_resources = ARRAY_SIZE(tps6586x_rtc_resources),115		.resources = &tps6586x_rtc_resources[0],116	},117	{118		.name = "tps6586x-onkey",119	},120};121 122struct tps6586x {123	struct device		*dev;124	struct i2c_client	*client;125	struct regmap		*regmap;126	int			version;127 128	int			irq;129	struct irq_chip		irq_chip;130	struct mutex		irq_lock;131	int			irq_base;132	u32			irq_en;133	u8			mask_reg[5];134	struct irq_domain	*irq_domain;135};136 137static inline struct tps6586x *dev_to_tps6586x(struct device *dev)138{139	return i2c_get_clientdata(to_i2c_client(dev));140}141 142int tps6586x_write(struct device *dev, int reg, uint8_t val)143{144	struct tps6586x *tps6586x = dev_to_tps6586x(dev);145 146	return regmap_write(tps6586x->regmap, reg, val);147}148EXPORT_SYMBOL_GPL(tps6586x_write);149 150int tps6586x_writes(struct device *dev, int reg, int len, uint8_t *val)151{152	struct tps6586x *tps6586x = dev_to_tps6586x(dev);153 154	return regmap_bulk_write(tps6586x->regmap, reg, val, len);155}156EXPORT_SYMBOL_GPL(tps6586x_writes);157 158int tps6586x_read(struct device *dev, int reg, uint8_t *val)159{160	struct tps6586x *tps6586x = dev_to_tps6586x(dev);161	unsigned int rval;162	int ret;163 164	ret = regmap_read(tps6586x->regmap, reg, &rval);165	if (!ret)166		*val = rval;167	return ret;168}169EXPORT_SYMBOL_GPL(tps6586x_read);170 171int tps6586x_reads(struct device *dev, int reg, int len, uint8_t *val)172{173	struct tps6586x *tps6586x = dev_to_tps6586x(dev);174 175	return regmap_bulk_read(tps6586x->regmap, reg, val, len);176}177EXPORT_SYMBOL_GPL(tps6586x_reads);178 179int tps6586x_set_bits(struct device *dev, int reg, uint8_t bit_mask)180{181	struct tps6586x *tps6586x = dev_to_tps6586x(dev);182 183	return regmap_update_bits(tps6586x->regmap, reg, bit_mask, bit_mask);184}185EXPORT_SYMBOL_GPL(tps6586x_set_bits);186 187int tps6586x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)188{189	struct tps6586x *tps6586x = dev_to_tps6586x(dev);190 191	return regmap_update_bits(tps6586x->regmap, reg, bit_mask, 0);192}193EXPORT_SYMBOL_GPL(tps6586x_clr_bits);194 195int tps6586x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)196{197	struct tps6586x *tps6586x = dev_to_tps6586x(dev);198 199	return regmap_update_bits(tps6586x->regmap, reg, mask, val);200}201EXPORT_SYMBOL_GPL(tps6586x_update);202 203int tps6586x_irq_get_virq(struct device *dev, int irq)204{205	struct tps6586x *tps6586x = dev_to_tps6586x(dev);206 207	return irq_create_mapping(tps6586x->irq_domain, irq);208}209EXPORT_SYMBOL_GPL(tps6586x_irq_get_virq);210 211int tps6586x_get_version(struct device *dev)212{213	struct tps6586x *tps6586x = dev_get_drvdata(dev);214 215	return tps6586x->version;216}217EXPORT_SYMBOL_GPL(tps6586x_get_version);218 219static int __remove_subdev(struct device *dev, void *unused)220{221	platform_device_unregister(to_platform_device(dev));222	return 0;223}224 225static int tps6586x_remove_subdevs(struct tps6586x *tps6586x)226{227	return device_for_each_child(tps6586x->dev, NULL, __remove_subdev);228}229 230static void tps6586x_irq_lock(struct irq_data *data)231{232	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);233 234	mutex_lock(&tps6586x->irq_lock);235}236 237static void tps6586x_irq_enable(struct irq_data *irq_data)238{239	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);240	unsigned int __irq = irq_data->hwirq;241	const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];242 243	tps6586x->mask_reg[data->mask_reg] &= ~data->mask_mask;244	tps6586x->irq_en |= (1 << __irq);245}246 247static void tps6586x_irq_disable(struct irq_data *irq_data)248{249	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);250 251	unsigned int __irq = irq_data->hwirq;252	const struct tps6586x_irq_data *data = &tps6586x_irqs[__irq];253 254	tps6586x->mask_reg[data->mask_reg] |= data->mask_mask;255	tps6586x->irq_en &= ~(1 << __irq);256}257 258static void tps6586x_irq_sync_unlock(struct irq_data *data)259{260	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(data);261	int i;262 263	for (i = 0; i < ARRAY_SIZE(tps6586x->mask_reg); i++) {264		int ret;265		ret = tps6586x_write(tps6586x->dev,266					    TPS6586X_INT_MASK1 + i,267					    tps6586x->mask_reg[i]);268		WARN_ON(ret);269	}270 271	mutex_unlock(&tps6586x->irq_lock);272}273 274static int tps6586x_irq_set_wake(struct irq_data *irq_data, unsigned int on)275{276	struct tps6586x *tps6586x = irq_data_get_irq_chip_data(irq_data);277	return irq_set_irq_wake(tps6586x->irq, on);278}279 280static struct irq_chip tps6586x_irq_chip = {281	.name = "tps6586x",282	.irq_bus_lock = tps6586x_irq_lock,283	.irq_bus_sync_unlock = tps6586x_irq_sync_unlock,284	.irq_disable = tps6586x_irq_disable,285	.irq_enable = tps6586x_irq_enable,286	.irq_set_wake = pm_sleep_ptr(tps6586x_irq_set_wake),287};288 289static int tps6586x_irq_map(struct irq_domain *h, unsigned int virq,290				irq_hw_number_t hw)291{292	struct tps6586x *tps6586x = h->host_data;293 294	irq_set_chip_data(virq, tps6586x);295	irq_set_chip_and_handler(virq, &tps6586x_irq_chip, handle_simple_irq);296	irq_set_nested_thread(virq, 1);297	irq_set_noprobe(virq);298 299	return 0;300}301 302static const struct irq_domain_ops tps6586x_domain_ops = {303	.map    = tps6586x_irq_map,304	.xlate  = irq_domain_xlate_twocell,305};306 307static irqreturn_t tps6586x_irq(int irq, void *data)308{309	struct tps6586x *tps6586x = data;310	uint32_t acks;311	__le32 val;312	int ret = 0;313 314	ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,315			     sizeof(acks), (uint8_t *)&val);316 317	if (ret < 0) {318		dev_err(tps6586x->dev, "failed to read interrupt status\n");319		return IRQ_NONE;320	}321 322	acks = le32_to_cpu(val);323 324	while (acks) {325		int i = __ffs(acks);326 327		if (tps6586x->irq_en & (1 << i))328			handle_nested_irq(329				irq_find_mapping(tps6586x->irq_domain, i));330 331		acks &= ~(1 << i);332	}333 334	return IRQ_HANDLED;335}336 337static int tps6586x_irq_init(struct tps6586x *tps6586x, int irq,338				       int irq_base)339{340	int i, ret;341	u8 tmp[4];342	int new_irq_base;343	int irq_num = ARRAY_SIZE(tps6586x_irqs);344 345	tps6586x->irq = irq;346 347	mutex_init(&tps6586x->irq_lock);348	for (i = 0; i < 5; i++) {349		tps6586x->mask_reg[i] = 0xff;350		tps6586x_write(tps6586x->dev, TPS6586X_INT_MASK1 + i, 0xff);351	}352 353	tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1, sizeof(tmp), tmp);354 355	if  (irq_base > 0) {356		new_irq_base = irq_alloc_descs(irq_base, 0, irq_num, -1);357		if (new_irq_base < 0) {358			dev_err(tps6586x->dev,359				"Failed to alloc IRQs: %d\n", new_irq_base);360			return new_irq_base;361		}362	} else {363		new_irq_base = 0;364	}365 366	tps6586x->irq_domain = irq_domain_add_simple(tps6586x->dev->of_node,367				irq_num, new_irq_base, &tps6586x_domain_ops,368				tps6586x);369	if (!tps6586x->irq_domain) {370		dev_err(tps6586x->dev, "Failed to create IRQ domain\n");371		return -ENOMEM;372	}373	ret = request_threaded_irq(irq, NULL, tps6586x_irq, IRQF_ONESHOT,374				   "tps6586x", tps6586x);375 376	if (!ret)377		device_init_wakeup(tps6586x->dev, 1);378 379	return ret;380}381 382static int tps6586x_add_subdevs(struct tps6586x *tps6586x,383					  struct tps6586x_platform_data *pdata)384{385	struct tps6586x_subdev_info *subdev;386	struct platform_device *pdev;387	int i, ret = 0;388 389	for (i = 0; i < pdata->num_subdevs; i++) {390		subdev = &pdata->subdevs[i];391 392		pdev = platform_device_alloc(subdev->name, subdev->id);393		if (!pdev) {394			ret = -ENOMEM;395			goto failed;396		}397 398		pdev->dev.parent = tps6586x->dev;399		pdev->dev.platform_data = subdev->platform_data;400		pdev->dev.of_node = subdev->of_node;401 402		ret = platform_device_add(pdev);403		if (ret) {404			platform_device_put(pdev);405			goto failed;406		}407	}408	return 0;409 410failed:411	tps6586x_remove_subdevs(tps6586x);412	return ret;413}414 415#ifdef CONFIG_OF416static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)417{418	struct device_node *np = client->dev.of_node;419	struct tps6586x_platform_data *pdata;420 421	pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);422	if (!pdata)423		return NULL;424 425	pdata->num_subdevs = 0;426	pdata->subdevs = NULL;427	pdata->gpio_base = -1;428	pdata->irq_base = -1;429	pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");430 431	return pdata;432}433 434static const struct of_device_id tps6586x_of_match[] = {435	{ .compatible = "ti,tps6586x", },436	{ },437};438#else439static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *client)440{441	return NULL;442}443#endif444 445static bool is_volatile_reg(struct device *dev, unsigned int reg)446{447	/* Cache all interrupt mask register */448	if ((reg >= TPS6586X_INT_MASK1) && (reg <= TPS6586X_INT_MASK5))449		return false;450 451	return true;452}453 454static const struct regmap_config tps6586x_regmap_config = {455	.reg_bits = 8,456	.val_bits = 8,457	.max_register = TPS6586X_MAX_REGISTER,458	.volatile_reg = is_volatile_reg,459	.cache_type = REGCACHE_MAPLE,460};461 462static int tps6586x_power_off_handler(struct sys_off_data *data)463{464	int ret;465 466	/* Put the PMIC into sleep state. This takes at least 20ms. */467	ret = tps6586x_clr_bits(data->dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT);468	if (ret)469		return notifier_from_errno(ret);470 471	ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);472	if (ret)473		return notifier_from_errno(ret);474 475	mdelay(50);476	return notifier_from_errno(-ETIME);477}478 479static int tps6586x_restart_handler(struct sys_off_data *data)480{481	int ret;482 483	/* Put the PMIC into hard reboot state. This takes at least 20ms. */484	ret = tps6586x_set_bits(data->dev, TPS6586X_SUPPLYENE, SOFT_RST_BIT);485	if (ret)486		return notifier_from_errno(ret);487 488	mdelay(50);489	return notifier_from_errno(-ETIME);490}491 492static void tps6586x_print_version(struct i2c_client *client, int version)493{494	const char *name;495 496	switch (version) {497	case TPS658621A:498		name = "TPS658621A";499		break;500	case TPS658621CD:501		name = "TPS658621C/D";502		break;503	case TPS658623:504		name = "TPS658623";505		break;506	case TPS658640:507	case TPS658640v2:508		name = "TPS658640";509		break;510	case TPS658643:511		name = "TPS658643";512		break;513	default:514		name = "TPS6586X";515		break;516	}517 518	dev_info(&client->dev, "Found %s, VERSIONCRC is %02x\n", name, version);519}520 521static int tps6586x_i2c_probe(struct i2c_client *client)522{523	struct tps6586x_platform_data *pdata = dev_get_platdata(&client->dev);524	struct tps6586x *tps6586x;525	int ret;526	int version;527 528	if (!pdata && client->dev.of_node)529		pdata = tps6586x_parse_dt(client);530 531	if (!pdata) {532		dev_err(&client->dev, "tps6586x requires platform data\n");533		return -ENOTSUPP;534	}535 536	version = i2c_smbus_read_byte_data(client, TPS6586X_VERSIONCRC);537	if (version < 0) {538		dev_err(&client->dev, "Chip ID read failed: %d\n", version);539		return -EIO;540	}541 542	tps6586x = devm_kzalloc(&client->dev, sizeof(*tps6586x), GFP_KERNEL);543	if (!tps6586x)544		return -ENOMEM;545 546	tps6586x->version = version;547	tps6586x_print_version(client, tps6586x->version);548 549	tps6586x->client = client;550	tps6586x->dev = &client->dev;551	i2c_set_clientdata(client, tps6586x);552 553	tps6586x->regmap = devm_regmap_init_i2c(client,554					&tps6586x_regmap_config);555	if (IS_ERR(tps6586x->regmap)) {556		ret = PTR_ERR(tps6586x->regmap);557		dev_err(&client->dev, "regmap init failed: %d\n", ret);558		return ret;559	}560 561 562	if (client->irq) {563		ret = tps6586x_irq_init(tps6586x, client->irq,564					pdata->irq_base);565		if (ret) {566			dev_err(&client->dev, "IRQ init failed: %d\n", ret);567			return ret;568		}569	}570 571	ret = mfd_add_devices(tps6586x->dev, -1,572			      tps6586x_cell, ARRAY_SIZE(tps6586x_cell),573			      NULL, 0, tps6586x->irq_domain);574	if (ret < 0) {575		dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret);576		goto err_mfd_add;577	}578 579	ret = tps6586x_add_subdevs(tps6586x, pdata);580	if (ret) {581		dev_err(&client->dev, "add devices failed: %d\n", ret);582		goto err_add_devs;583	}584 585	if (pdata->pm_off) {586		ret = devm_register_power_off_handler(&client->dev, &tps6586x_power_off_handler,587						      NULL);588		if (ret) {589			dev_err(&client->dev, "register power off handler failed: %d\n", ret);590			goto err_add_devs;591		}592 593		ret = devm_register_restart_handler(&client->dev, &tps6586x_restart_handler,594						    NULL);595		if (ret) {596			dev_err(&client->dev, "register restart handler failed: %d\n", ret);597			goto err_add_devs;598		}599	}600 601	return 0;602 603err_add_devs:604	mfd_remove_devices(tps6586x->dev);605err_mfd_add:606	if (client->irq)607		free_irq(client->irq, tps6586x);608	return ret;609}610 611static void tps6586x_i2c_remove(struct i2c_client *client)612{613	struct tps6586x *tps6586x = i2c_get_clientdata(client);614 615	tps6586x_remove_subdevs(tps6586x);616	mfd_remove_devices(tps6586x->dev);617	if (client->irq)618		free_irq(client->irq, tps6586x);619}620 621static int __maybe_unused tps6586x_i2c_suspend(struct device *dev)622{623	struct tps6586x *tps6586x = dev_get_drvdata(dev);624 625	if (tps6586x->client->irq)626		disable_irq(tps6586x->client->irq);627 628	return 0;629}630 631static int __maybe_unused tps6586x_i2c_resume(struct device *dev)632{633	struct tps6586x *tps6586x = dev_get_drvdata(dev);634 635	if (tps6586x->client->irq)636		enable_irq(tps6586x->client->irq);637 638	return 0;639}640 641static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend,642			 tps6586x_i2c_resume);643 644static const struct i2c_device_id tps6586x_id_table[] = {645	{ "tps6586x" },646	{ }647};648MODULE_DEVICE_TABLE(i2c, tps6586x_id_table);649 650static struct i2c_driver tps6586x_driver = {651	.driver	= {652		.name	= "tps6586x",653		.of_match_table = of_match_ptr(tps6586x_of_match),654		.pm	= &tps6586x_pm_ops,655	},656	.probe		= tps6586x_i2c_probe,657	.remove		= tps6586x_i2c_remove,658	.id_table	= tps6586x_id_table,659};660 661static int __init tps6586x_init(void)662{663	return i2c_add_driver(&tps6586x_driver);664}665subsys_initcall(tps6586x_init);666 667static void __exit tps6586x_exit(void)668{669	i2c_del_driver(&tps6586x_driver);670}671module_exit(tps6586x_exit);672 673MODULE_DESCRIPTION("TPS6586X core driver");674MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");675